2068 lines · cpp
1//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/HexagonMCAsmInfo.h"10#include "MCTargetDesc/HexagonMCChecker.h"11#include "MCTargetDesc/HexagonMCELFStreamer.h"12#include "MCTargetDesc/HexagonMCExpr.h"13#include "MCTargetDesc/HexagonMCInstrInfo.h"14#include "MCTargetDesc/HexagonMCTargetDesc.h"15#include "MCTargetDesc/HexagonShuffler.h"16#include "MCTargetDesc/HexagonTargetStreamer.h"17#include "TargetInfo/HexagonTargetInfo.h"18#include "llvm/ADT/STLExtras.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/ADT/StringExtras.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/ADT/Twine.h"23#include "llvm/BinaryFormat/ELF.h"24#include "llvm/MC/MCAssembler.h"25#include "llvm/MC/MCContext.h"26#include "llvm/MC/MCDirectives.h"27#include "llvm/MC/MCELFStreamer.h"28#include "llvm/MC/MCExpr.h"29#include "llvm/MC/MCInst.h"30#include "llvm/MC/MCParser/AsmLexer.h"31#include "llvm/MC/MCParser/MCAsmParser.h"32#include "llvm/MC/MCParser/MCAsmParserExtension.h"33#include "llvm/MC/MCParser/MCParsedAsmOperand.h"34#include "llvm/MC/MCParser/MCTargetAsmParser.h"35#include "llvm/MC/MCRegisterInfo.h"36#include "llvm/MC/MCSectionELF.h"37#include "llvm/MC/MCStreamer.h"38#include "llvm/MC/MCSubtargetInfo.h"39#include "llvm/MC/MCSymbol.h"40#include "llvm/MC/MCValue.h"41#include "llvm/MC/TargetRegistry.h"42#include "llvm/Support/Casting.h"43#include "llvm/Support/CommandLine.h"44#include "llvm/Support/Compiler.h"45#include "llvm/Support/Debug.h"46#include "llvm/Support/ErrorHandling.h"47#include "llvm/Support/Format.h"48#include "llvm/Support/HexagonAttributes.h"49#include "llvm/Support/MathExtras.h"50#include "llvm/Support/SMLoc.h"51#include "llvm/Support/SourceMgr.h"52#include "llvm/Support/raw_ostream.h"53#include <cassert>54#include <cctype>55#include <cstddef>56#include <cstdint>57#include <memory>58#include <string>59#include <utility>60 61#define DEBUG_TYPE "mcasmparser"62 63using namespace llvm;64 65static cl::opt<bool> WarnMissingParenthesis(66 "mwarn-missing-parenthesis",67 cl::desc("Warn for missing parenthesis around predicate registers"),68 cl::init(true));69static cl::opt<bool> ErrorMissingParenthesis(70 "merror-missing-parenthesis",71 cl::desc("Error for missing parenthesis around predicate registers"),72 cl::init(false));73static cl::opt<bool> WarnSignedMismatch(74 "mwarn-sign-mismatch",75 cl::desc("Warn for mismatching a signed and unsigned value"),76 cl::init(false));77static cl::opt<bool> WarnNoncontigiousRegister(78 "mwarn-noncontigious-register",79 cl::desc("Warn for register names that aren't contigious"), cl::init(true));80static cl::opt<bool> ErrorNoncontigiousRegister(81 "merror-noncontigious-register",82 cl::desc("Error for register names that aren't contigious"),83 cl::init(false));84static cl::opt<bool> AddBuildAttributes("hexagon-add-build-attributes");85namespace {86 87struct HexagonOperand;88 89class HexagonAsmParser : public MCTargetAsmParser {90 91 HexagonTargetStreamer &getTargetStreamer() {92 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();93 return static_cast<HexagonTargetStreamer &>(TS);94 }95 96 MCAsmParser &Parser;97 MCInst MCB;98 bool InBrackets;99 100 MCAsmParser &getParser() const { return Parser; }101 MCAssembler *getAssembler() const {102 MCAssembler *Assembler = nullptr;103 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())104 if (!Parser.getStreamer().hasRawTextSupport()) {105 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());106 Assembler = &MES->getAssembler();107 }108 return Assembler;109 }110 111 AsmLexer &getLexer() const { return Parser.getLexer(); }112 113 bool equalIsAsmAssignment() override { return false; }114 bool isLabel(AsmToken &Token) override;115 bool tokenIsStartOfStatement(AsmToken::TokenKind Token) override;116 117 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }118 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }119 bool ParseDirectiveFalign(unsigned Size, SMLoc L);120 121 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;122 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,123 SMLoc &EndLoc) override;124 bool ParseDirectiveSubsection(SMLoc L);125 bool ParseDirectiveComm(bool IsLocal, SMLoc L);126 127 bool parseDirectiveAttribute(SMLoc L);128 129 bool RegisterMatchesArch(MCRegister MatchNum) const;130 131 bool matchBundleOptions();132 bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);133 bool finishBundle(SMLoc IDLoc, MCStreamer &Out);134 void canonicalizeImmediates(MCInst &MCI);135 bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,136 OperandVector &InstOperands, uint64_t &ErrorInfo,137 bool MatchingInlineAsm);138 void eatToEndOfPacket();139 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,140 OperandVector &Operands, MCStreamer &Out,141 uint64_t &ErrorInfo,142 bool MatchingInlineAsm) override;143 144 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,145 unsigned Kind) override;146 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);147 int processInstruction(MCInst &Inst, OperandVector const &Operands,148 SMLoc IDLoc);149 150 MCRegister matchRegister(StringRef Name);151 152 /// @name Auto-generated Match Functions153 /// {154 155#define GET_ASSEMBLER_HEADER156#include "HexagonGenAsmMatcher.inc"157 158 /// }159 160public:161 HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,162 const MCInstrInfo &MII, const MCTargetOptions &Options)163 : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),164 InBrackets(false) {165 MCB.setOpcode(Hexagon::BUNDLE);166 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));167 168 Parser.addAliasForDirective(".half", ".2byte");169 Parser.addAliasForDirective(".hword", ".2byte");170 Parser.addAliasForDirective(".word", ".4byte");171 172 MCAsmParserExtension::Initialize(_Parser);173 174 if (AddBuildAttributes)175 getTargetStreamer().emitTargetAttributes(*STI);176 }177 178 bool splitIdentifier(OperandVector &Operands);179 bool parseOperand(OperandVector &Operands);180 bool parseInstruction(OperandVector &Operands);181 bool implicitExpressionLocation(OperandVector &Operands);182 bool parseExpressionOrOperand(OperandVector &Operands);183 bool parseExpression(MCExpr const *&Expr);184 185 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,186 SMLoc NameLoc, OperandVector &Operands) override {187 llvm_unreachable("Unimplemented");188 }189 190 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,191 OperandVector &Operands) override;192 193 bool ParseDirective(AsmToken DirectiveID) override;194};195 196/// HexagonOperand - Instances of this class represent a parsed Hexagon machine197/// instruction.198struct HexagonOperand : public MCParsedAsmOperand {199 enum KindTy { Token, Immediate, Register } Kind;200 MCContext &Context;201 202 SMLoc StartLoc, EndLoc;203 204 struct TokTy {205 const char *Data;206 unsigned Length;207 };208 209 struct RegTy {210 MCRegister RegNum;211 };212 213 struct ImmTy {214 const MCExpr *Val;215 };216 217 union {218 struct TokTy Tok;219 struct RegTy Reg;220 struct ImmTy Imm;221 };222 223 HexagonOperand(KindTy K, MCContext &Context) : Kind(K), Context(Context) {}224 225public:226 HexagonOperand(const HexagonOperand &o)227 : MCParsedAsmOperand(), Context(o.Context) {228 Kind = o.Kind;229 StartLoc = o.StartLoc;230 EndLoc = o.EndLoc;231 switch (Kind) {232 case Register:233 Reg = o.Reg;234 break;235 case Immediate:236 Imm = o.Imm;237 break;238 case Token:239 Tok = o.Tok;240 break;241 }242 }243 244 /// getStartLoc - Get the location of the first token of this operand.245 SMLoc getStartLoc() const override { return StartLoc; }246 247 /// getEndLoc - Get the location of the last token of this operand.248 SMLoc getEndLoc() const override { return EndLoc; }249 250 MCRegister getReg() const override {251 assert(Kind == Register && "Invalid access!");252 return Reg.RegNum;253 }254 255 const MCExpr *getImm() const {256 assert(Kind == Immediate && "Invalid access!");257 return Imm.Val;258 }259 260 bool isToken() const override { return Kind == Token; }261 bool isImm() const override { return Kind == Immediate; }262 bool isMem() const override { llvm_unreachable("No isMem"); }263 bool isReg() const override { return Kind == Register; }264 265 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,266 bool isRelocatable, bool Extendable) const {267 if (Kind == Immediate) {268 const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());269 if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)270 return false;271 int64_t Res;272 if (myMCExpr->evaluateAsAbsolute(Res)) {273 int bits = immBits + zeroBits;274 // Field bit range is zerobits + bits275 // zeroBits must be 0276 if (Res & ((1 << zeroBits) - 1))277 return false;278 if (isSigned) {279 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))280 return true;281 } else {282 if (bits == 64)283 return true;284 if (Res >= 0)285 return ((uint64_t)Res < (uint64_t)(1ULL << bits));286 else {287 const int64_t high_bit_set = 1ULL << 63;288 const uint64_t mask = (high_bit_set >> (63 - bits));289 return (((uint64_t)Res & mask) == mask);290 }291 }292 } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)293 return true;294 else if (myMCExpr->getKind() == MCExpr::Binary ||295 myMCExpr->getKind() == MCExpr::Unary)296 return true;297 }298 return false;299 }300 301 bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }302 bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }303 bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }304 bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }305 306 bool ism32_0Imm() const { return true; }307 308 bool isf32Imm() const { return false; }309 bool isf64Imm() const { return false; }310 bool iss32_0Imm() const { return true; }311 bool iss31_1Imm() const { return true; }312 bool iss30_2Imm() const { return true; }313 bool iss29_3Imm() const { return true; }314 bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }315 bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }316 bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }317 bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }318 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }319 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }320 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }321 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }322 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }323 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }324 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }325 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }326 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }327 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }328 329 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }330 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; }334 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }335 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); }340 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); }345 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); }348 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }349 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }350 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }351 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }352 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }353 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }354 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }355 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }356 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }357 358 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 }366 bool issgp10Const() const {367 if (!isReg())368 return false;369 return getReg() == Hexagon::SGP1_0;370 }371 bool iss11_0Imm() const {372 return CheckImmRange(11 + 26, 0, true, true, true);373 }374 bool iss11_1Imm() const {375 return CheckImmRange(11 + 26, 1, true, true, true);376 }377 bool iss11_2Imm() const {378 return CheckImmRange(11 + 26, 2, true, true, true);379 }380 bool iss11_3Imm() const {381 return CheckImmRange(11 + 26, 3, true, true, true);382 }383 bool isu32_0MustExt() const { return isImm(); }384 385 void addRegOperands(MCInst &Inst, unsigned N) const {386 assert(N == 1 && "Invalid number of operands!");387 Inst.addOperand(MCOperand::createReg(getReg()));388 }389 390 void addImmOperands(MCInst &Inst, unsigned N) const {391 assert(N == 1 && "Invalid number of operands!");392 Inst.addOperand(MCOperand::createExpr(getImm()));393 }394 395 void addSignedImmOperands(MCInst &Inst, unsigned N) const {396 assert(N == 1 && "Invalid number of operands!");397 HexagonMCExpr *Expr =398 const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));399 int64_t Value;400 if (!Expr->evaluateAsAbsolute(Value)) {401 Inst.addOperand(MCOperand::createExpr(Expr));402 return;403 }404 int64_t Extended = SignExtend64(Value, 32);405 HexagonMCExpr *NewExpr = HexagonMCExpr::create(406 MCConstantExpr::create(Extended, Context), Context);407 if ((Extended < 0) != (Value < 0))408 NewExpr->setSignMismatch();409 NewExpr->setMustExtend(Expr->mustExtend());410 NewExpr->setMustNotExtend(Expr->mustNotExtend());411 Inst.addOperand(MCOperand::createExpr(NewExpr));412 }413 414 void addn1ConstOperands(MCInst &Inst, unsigned N) const {415 addImmOperands(Inst, N);416 }417 void addsgp10ConstOperands(MCInst &Inst, unsigned N) const {418 addRegOperands(Inst, N);419 }420 421 StringRef getToken() const {422 assert(Kind == Token && "Invalid access!");423 return StringRef(Tok.Data, Tok.Length);424 }425 426 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;427 428 static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,429 StringRef Str, SMLoc S) {430 HexagonOperand *Op = new HexagonOperand(Token, Context);431 Op->Tok.Data = Str.data();432 Op->Tok.Length = Str.size();433 Op->StartLoc = S;434 Op->EndLoc = S;435 return std::unique_ptr<HexagonOperand>(Op);436 }437 438 static std::unique_ptr<HexagonOperand>439 CreateReg(MCContext &Context, MCRegister Reg, SMLoc S, SMLoc E) {440 HexagonOperand *Op = new HexagonOperand(Register, Context);441 Op->Reg.RegNum = Reg;442 Op->StartLoc = S;443 Op->EndLoc = E;444 return std::unique_ptr<HexagonOperand>(Op);445 }446 447 static std::unique_ptr<HexagonOperand>448 CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {449 HexagonOperand *Op = new HexagonOperand(Immediate, Context);450 Op->Imm.Val = Val;451 Op->StartLoc = S;452 Op->EndLoc = E;453 return std::unique_ptr<HexagonOperand>(Op);454 }455};456 457} // end anonymous namespace458 459void HexagonOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {460 switch (Kind) {461 case Immediate:462 HexagonMCAsmInfo(Triple()).printExpr(OS, *getImm());463 break;464 case Register:465 OS << "<register R";466 OS << getReg().id() << ">";467 break;468 case Token:469 OS << "'" << getToken() << "'";470 break;471 }472}473 474bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {475 LLVM_DEBUG(dbgs() << "Bundle:");476 LLVM_DEBUG(MCB.dump_pretty(dbgs()));477 LLVM_DEBUG(dbgs() << "--\n");478 479 MCB.setLoc(IDLoc);480 481 // Check the bundle for errors.482 const MCRegisterInfo *RI = getContext().getRegisterInfo();483 MCSubtargetInfo const &STI = getSTI();484 485 MCInst OrigBundle = MCB;486 HexagonMCChecker Check(getContext(), MII, STI, MCB, *RI, true);487 488 bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(489 MII, STI, getContext(), MCB, &Check, true);490 491 if (CheckOk) {492 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {493 assert(!HexagonMCInstrInfo::isInnerLoop(MCB));494 assert(!HexagonMCInstrInfo::isOuterLoop(MCB));495 // Empty packets are valid yet aren't emitted496 return false;497 }498 499 assert(HexagonMCInstrInfo::isBundle(MCB));500 501 Out.emitInstruction(MCB, STI);502 } else503 return true; // Error504 505 return false; // No error506}507 508bool HexagonAsmParser::matchBundleOptions() {509 MCAsmParser &Parser = getParser();510 while (true) {511 if (!Parser.getTok().is(AsmToken::Colon))512 return false;513 Lex();514 char const *MemNoShuffMsg =515 "invalid instruction packet: mem_noshuf specifier not "516 "supported with this architecture";517 StringRef Option = Parser.getTok().getString();518 auto IDLoc = Parser.getTok().getLoc();519 if (Option.compare_insensitive("endloop01") == 0) {520 HexagonMCInstrInfo::setInnerLoop(MCB);521 HexagonMCInstrInfo::setOuterLoop(MCB);522 } else if (Option.compare_insensitive("endloop0") == 0) {523 HexagonMCInstrInfo::setInnerLoop(MCB);524 } else if (Option.compare_insensitive("endloop1") == 0) {525 HexagonMCInstrInfo::setOuterLoop(MCB);526 } else if (Option.compare_insensitive("mem_noshuf") == 0) {527 if (getSTI().hasFeature(Hexagon::FeatureMemNoShuf))528 HexagonMCInstrInfo::setMemReorderDisabled(MCB);529 else530 return getParser().Error(IDLoc, MemNoShuffMsg);531 } else if (Option.compare_insensitive("mem_no_order") == 0) {532 // Nothing.533 } else534 return getParser().Error(IDLoc, llvm::Twine("'") + Option +535 "' is not a valid bundle option");536 Lex();537 }538}539 540// For instruction aliases, immediates are generated rather than541// MCConstantExpr. Convert them for uniform MCExpr.542// Also check for signed/unsigned mismatches and warn543void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {544 MCInst NewInst;545 NewInst.setOpcode(MCI.getOpcode());546 for (MCOperand &I : MCI)547 if (I.isImm()) {548 int64_t Value(I.getImm());549 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(550 MCConstantExpr::create(Value, getContext()), getContext())));551 } else {552 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&553 WarnSignedMismatch)554 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");555 NewInst.addOperand(I);556 }557 MCI = NewInst;558}559 560bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,561 OperandVector &InstOperands,562 uint64_t &ErrorInfo,563 bool MatchingInlineAsm) {564 // Perform matching with tablegen asmmatcher generated function565 int result =566 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);567 if (result == Match_Success) {568 MCI.setLoc(IDLoc);569 canonicalizeImmediates(MCI);570 result = processInstruction(MCI, InstOperands, IDLoc);571 572 LLVM_DEBUG(dbgs() << "Insn:");573 LLVM_DEBUG(MCI.dump_pretty(dbgs()));574 LLVM_DEBUG(dbgs() << "\n\n");575 576 MCI.setLoc(IDLoc);577 }578 579 // Create instruction operand for bundle instruction580 // Break this into a separate function Code here is less readable581 // Think about how to get an instruction error to report correctly.582 // SMLoc will return the "{"583 switch (result) {584 default:585 break;586 case Match_Success:587 return false;588 case Match_MissingFeature:589 return Error(IDLoc, "invalid instruction");590 case Match_MnemonicFail:591 return Error(IDLoc, "unrecognized instruction");592 case Match_InvalidOperand:593 [[fallthrough]];594 case Match_InvalidTiedOperand:595 SMLoc ErrorLoc = IDLoc;596 if (ErrorInfo != ~0U) {597 if (ErrorInfo >= InstOperands.size())598 return Error(IDLoc, "too few operands for instruction");599 600 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))601 ->getStartLoc();602 if (ErrorLoc == SMLoc())603 ErrorLoc = IDLoc;604 }605 return Error(ErrorLoc, "invalid operand for instruction");606 }607 llvm_unreachable("Implement any new match types added!");608}609 610void HexagonAsmParser::eatToEndOfPacket() {611 assert(InBrackets);612 AsmLexer &Lexer = getLexer();613 while (!Lexer.is(AsmToken::RCurly))614 Lexer.Lex();615 Lexer.Lex();616 InBrackets = false;617}618 619bool HexagonAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,620 OperandVector &Operands,621 MCStreamer &Out,622 uint64_t &ErrorInfo,623 bool MatchingInlineAsm) {624 if (!InBrackets) {625 MCB.clear();626 MCB.addOperand(MCOperand::createImm(0));627 }628 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);629 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {630 assert(Operands.size() == 1 && "Brackets should be by themselves");631 if (InBrackets) {632 getParser().Error(IDLoc, "Already in a packet");633 InBrackets = false;634 return true;635 }636 InBrackets = true;637 return false;638 }639 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {640 assert(Operands.size() == 1 && "Brackets should be by themselves");641 if (!InBrackets) {642 getParser().Error(IDLoc, "Not in a packet");643 return true;644 }645 InBrackets = false;646 if (matchBundleOptions())647 return true;648 return finishBundle(IDLoc, Out);649 }650 MCInst *SubInst = getParser().getContext().createMCInst();651 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,652 MatchingInlineAsm)) {653 if (InBrackets)654 eatToEndOfPacket();655 return true;656 }657 HexagonMCInstrInfo::extendIfNeeded(658 getParser().getContext(), MII, MCB, *SubInst);659 MCB.addOperand(MCOperand::createInst(SubInst));660 if (!InBrackets)661 return finishBundle(IDLoc, Out);662 return false;663}664/// parseDirectiveAttribute665/// ::= .attribute int, int666/// ::= .attribute Tag_name, int667bool HexagonAsmParser::parseDirectiveAttribute(SMLoc L) {668 MCAsmParser &Parser = getParser();669 int64_t Tag;670 SMLoc TagLoc = Parser.getTok().getLoc();671 if (Parser.getTok().is(AsmToken::Identifier)) {672 StringRef Name = Parser.getTok().getIdentifier();673 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(674 Name, HexagonAttrs::getHexagonAttributeTags());675 if (!Ret)676 return Error(TagLoc, "attribute name not recognized: " + Name);677 Tag = *Ret;678 Parser.Lex();679 } else {680 const MCExpr *AttrExpr;681 682 TagLoc = Parser.getTok().getLoc();683 if (Parser.parseExpression(AttrExpr))684 return true;685 686 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);687 if (check(!CE, TagLoc, "expected numeric constant"))688 return true;689 690 Tag = CE->getValue();691 }692 693 if (Parser.parseComma())694 return true;695 696 // We currently only have integer values.697 int64_t IntegerValue = 0;698 SMLoc ValueExprLoc = Parser.getTok().getLoc();699 const MCExpr *ValueExpr;700 if (Parser.parseExpression(ValueExpr))701 return true;702 703 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);704 if (!CE)705 return Error(ValueExprLoc, "expected numeric constant");706 IntegerValue = CE->getValue();707 708 if (Parser.parseEOL())709 return true;710 711 getTargetStreamer().emitAttribute(Tag, IntegerValue);712 return false;713}714 715/// ParseDirective parses the Hexagon specific directives716bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {717 StringRef IDVal = DirectiveID.getIdentifier();718 if (IDVal.lower() == ".falign")719 return ParseDirectiveFalign(256, DirectiveID.getLoc());720 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))721 return ParseDirectiveComm(true, DirectiveID.getLoc());722 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))723 return ParseDirectiveComm(false, DirectiveID.getLoc());724 if (IDVal.lower() == ".subsection")725 return ParseDirectiveSubsection(DirectiveID.getLoc());726 if (IDVal == ".attribute")727 return parseDirectiveAttribute(DirectiveID.getLoc());728 729 return true;730}731bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {732 const MCExpr *Subsection = nullptr;733 int64_t Res;734 735 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&736 "Invalid subsection directive");737 getParser().parseExpression(Subsection);738 739 if (!Subsection->evaluateAsAbsolute(Res))740 return Error(L, "Cannot evaluate subsection number");741 742 if (getLexer().isNot(AsmToken::EndOfStatement))743 return TokError("unexpected token in directive");744 745 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the746 // negative subsections together and in the same order but at the opposite747 // end of the section. Only legacy hexagon-gcc created assembly code748 // used negative subsections.749 if ((Res < 0) && (Res > -8193))750 Res += 8192;751 getStreamer().switchSection(getStreamer().getCurrentSectionOnly(), Res);752 return false;753}754 755/// ::= .falign [expression]756bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {757 758 int64_t MaxBytesToFill = 15;759 760 // if there is an argument761 if (getLexer().isNot(AsmToken::EndOfStatement)) {762 const MCExpr *Value;763 SMLoc ExprLoc = L;764 765 // Make sure we have a number (false is returned if expression is a number)766 if (!getParser().parseExpression(Value)) {767 // Make sure this is a number that is in range768 auto *MCE = cast<MCConstantExpr>(Value);769 uint64_t IntValue = MCE->getValue();770 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))771 return Error(ExprLoc, "literal value out of range (256) for falign");772 MaxBytesToFill = IntValue;773 Lex();774 } else {775 return Error(ExprLoc, "not a valid expression for falign directive");776 }777 }778 779 getTargetStreamer().emitFAlign(16, MaxBytesToFill);780 Lex();781 782 return false;783}784 785// This is largely a copy of AsmParser's ParseDirectiveComm extended to786// accept a 3rd argument, AccessAlignment which indicates the smallest787// memory access made to the symbol, expressed in bytes. If no788// AccessAlignment is specified it defaults to the Alignment Value.789// Hexagon's .lcomm:790// .lcomm Symbol, Length, Alignment, AccessAlignment791bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {792 // FIXME: need better way to detect if AsmStreamer (upstream removed793 // getKind())794 if (getStreamer().hasRawTextSupport())795 return true; // Only object file output requires special treatment.796 797 StringRef Name;798 if (getParser().parseIdentifier(Name))799 return TokError("expected identifier in directive");800 // Handle the identifier as the key symbol.801 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);802 803 if (getLexer().isNot(AsmToken::Comma))804 return TokError("unexpected token in directive");805 Lex();806 807 int64_t Size;808 SMLoc SizeLoc = getLexer().getLoc();809 if (getParser().parseAbsoluteExpression(Size))810 return true;811 812 int64_t ByteAlignment = 1;813 SMLoc ByteAlignmentLoc;814 if (getLexer().is(AsmToken::Comma)) {815 Lex();816 ByteAlignmentLoc = getLexer().getLoc();817 if (getParser().parseAbsoluteExpression(ByteAlignment))818 return true;819 if (!isPowerOf2_64(ByteAlignment))820 return Error(ByteAlignmentLoc, "alignment must be a power of 2");821 }822 823 int64_t AccessAlignment = 0;824 if (getLexer().is(AsmToken::Comma)) {825 // The optional access argument specifies the size of the smallest memory826 // access to be made to the symbol, expressed in bytes.827 SMLoc AccessAlignmentLoc;828 Lex();829 AccessAlignmentLoc = getLexer().getLoc();830 if (getParser().parseAbsoluteExpression(AccessAlignment))831 return true;832 833 if (!isPowerOf2_64(AccessAlignment))834 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");835 }836 837 if (getLexer().isNot(AsmToken::EndOfStatement))838 return TokError("unexpected token in '.comm' or '.lcomm' directive");839 840 Lex();841 842 // NOTE: a size of zero for a .comm should create a undefined symbol843 // but a size of .lcomm creates a bss symbol of size zero.844 if (Size < 0)845 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "846 "be less than zero");847 848 // NOTE: The alignment in the directive is a power of 2 value, the assembler849 // may internally end up wanting an alignment in bytes.850 // FIXME: Diagnose overflow.851 if (ByteAlignment < 0)852 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "853 "alignment, can't be less than zero");854 855 if (!Sym->isUndefined())856 return Error(Loc, "invalid symbol redefinition");857 858 HexagonMCELFStreamer &HexagonELFStreamer =859 static_cast<HexagonMCELFStreamer &>(getStreamer());860 if (IsLocal) {861 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(862 Sym, Size, Align(ByteAlignment), AccessAlignment);863 return false;864 }865 866 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, Align(ByteAlignment),867 AccessAlignment);868 return false;869}870 871// validate register against architecture872bool HexagonAsmParser::RegisterMatchesArch(MCRegister MatchNum) const {873 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))874 if (!getSTI().hasFeature(Hexagon::ArchV62))875 return false;876 return true;877}878 879// extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmLexer();880 881/// Force static initialization.882extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void883LLVMInitializeHexagonAsmParser() {884 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());885}886 887#define GET_MATCHER_IMPLEMENTATION888#define GET_REGISTER_MATCHER889#include "HexagonGenAsmMatcher.inc"890 891static bool previousEqual(OperandVector &Operands, size_t Index,892 StringRef String) {893 if (Index >= Operands.size())894 return false;895 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];896 if (!Operand.isToken())897 return false;898 return static_cast<HexagonOperand &>(Operand).getToken().equals_insensitive(899 String);900}901 902static bool previousIsLoop(OperandVector &Operands, size_t Index) {903 return previousEqual(Operands, Index, "loop0") ||904 previousEqual(Operands, Index, "loop1") ||905 previousEqual(Operands, Index, "sp1loop0") ||906 previousEqual(Operands, Index, "sp2loop0") ||907 previousEqual(Operands, Index, "sp3loop0");908}909 910bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {911 AsmToken const &Token = getParser().getTok();912 StringRef String = Token.getString();913 SMLoc Loc = Token.getLoc();914 Lex();915 do {916 std::pair<StringRef, StringRef> HeadTail = String.split('.');917 if (!HeadTail.first.empty())918 Operands.push_back(919 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));920 if (!HeadTail.second.empty())921 Operands.push_back(HexagonOperand::CreateToken(922 getContext(), String.substr(HeadTail.first.size(), 1), Loc));923 String = HeadTail.second;924 } while (!String.empty());925 return false;926}927 928bool HexagonAsmParser::parseOperand(OperandVector &Operands) {929 MCRegister Register;930 SMLoc Begin;931 SMLoc End;932 AsmLexer &Lexer = getLexer();933 if (!parseRegister(Register, Begin, End)) {934 if (!ErrorMissingParenthesis)935 switch (Register.id()) {936 default:937 break;938 case Hexagon::P0:939 case Hexagon::P1:940 case Hexagon::P2:941 case Hexagon::P3:942 if (previousEqual(Operands, 0, "if")) {943 if (WarnMissingParenthesis)944 Warning(Begin, "Missing parenthesis around predicate register");945 static char const *LParen = "(";946 static char const *RParen = ")";947 Operands.push_back(948 HexagonOperand::CreateToken(getContext(), LParen, Begin));949 Operands.push_back(950 HexagonOperand::CreateReg(getContext(), Register, Begin, End));951 const AsmToken &MaybeDotNew = Lexer.getTok();952 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&953 MaybeDotNew.getString().equals_insensitive(".new"))954 splitIdentifier(Operands);955 Operands.push_back(956 HexagonOperand::CreateToken(getContext(), RParen, Begin));957 return false;958 }959 if (previousEqual(Operands, 0, "!") &&960 previousEqual(Operands, 1, "if")) {961 if (WarnMissingParenthesis)962 Warning(Begin, "Missing parenthesis around predicate register");963 static char const *LParen = "(";964 static char const *RParen = ")";965 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(966 getContext(), LParen, Begin));967 Operands.push_back(968 HexagonOperand::CreateReg(getContext(), Register, Begin, End));969 const AsmToken &MaybeDotNew = Lexer.getTok();970 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&971 MaybeDotNew.getString().equals_insensitive(".new"))972 splitIdentifier(Operands);973 Operands.push_back(974 HexagonOperand::CreateToken(getContext(), RParen, Begin));975 return false;976 }977 break;978 }979 Operands.push_back(980 HexagonOperand::CreateReg(getContext(), Register, Begin, End));981 return false;982 }983 return splitIdentifier(Operands);984}985 986bool HexagonAsmParser::isLabel(AsmToken &Token) {987 AsmLexer &Lexer = getLexer();988 AsmToken const &Second = Lexer.getTok();989 AsmToken Third = Lexer.peekTok();990 StringRef String = Token.getString();991 if (Token.is(AsmToken::TokenKind::LCurly) ||992 Token.is(AsmToken::TokenKind::RCurly))993 return false;994 // special case for parsing vwhist256:sat995 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&996 Third.getString().lower() == "sat")997 return false;998 if (!Token.is(AsmToken::TokenKind::Identifier))999 return true;1000 if (!matchRegister(String.lower()))1001 return true;1002 assert(Second.is(AsmToken::Colon));1003 StringRef Raw(String.data(), Third.getString().data() - String.data() +1004 Third.getString().size());1005 std::string Collapsed = std::string(Raw);1006 llvm::erase_if(Collapsed, isSpace);1007 StringRef Whole = Collapsed;1008 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');1009 if (!matchRegister(DotSplit.first.lower()))1010 return true;1011 return false;1012}1013 1014bool HexagonAsmParser::tokenIsStartOfStatement(AsmToken::TokenKind Token) {1015 return Token == AsmToken::LCurly || Token == AsmToken::RCurly;1016}1017 1018bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,1019 SMLoc &Loc) {1020 if (!Contigious && ErrorNoncontigiousRegister) {1021 Error(Loc, "Register name is not contigious");1022 return true;1023 }1024 if (!Contigious && WarnNoncontigiousRegister)1025 Warning(Loc, "Register name is not contigious");1026 return false;1027}1028 1029bool HexagonAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1030 SMLoc &EndLoc) {1031 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();1032}1033 1034ParseStatus HexagonAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1035 SMLoc &EndLoc) {1036 AsmLexer &Lexer = getLexer();1037 StartLoc = getLexer().getLoc();1038 SmallVector<AsmToken, 5> Lookahead;1039 StringRef RawString(Lexer.getTok().getString().data(), 0);1040 bool Again = Lexer.is(AsmToken::Identifier);1041 bool NeededWorkaround = false;1042 while (Again) {1043 AsmToken const &Token = Lexer.getTok();1044 RawString = StringRef(RawString.data(), Token.getString().data() -1045 RawString.data() +1046 Token.getString().size());1047 Lookahead.push_back(Token);1048 Lexer.Lex();1049 bool Contigious = Lexer.getTok().getString().data() ==1050 Lookahead.back().getString().data() +1051 Lookahead.back().getString().size();1052 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||1053 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||1054 Lexer.is(AsmToken::Colon);1055 bool Workaround =1056 Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);1057 Again = (Contigious && Type) || (Workaround && Type);1058 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));1059 }1060 std::string Collapsed = std::string(RawString);1061 llvm::erase_if(Collapsed, isSpace);1062 StringRef FullString = Collapsed;1063 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');1064 MCRegister DotReg = matchRegister(DotSplit.first.lower());1065 if (DotReg && RegisterMatchesArch(DotReg)) {1066 if (DotSplit.second.empty()) {1067 Reg = DotReg;1068 EndLoc = Lexer.getLoc();1069 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))1070 return ParseStatus::NoMatch;1071 return ParseStatus::Success;1072 } else {1073 Reg = DotReg;1074 size_t First = RawString.find('.');1075 StringRef DotString (RawString.data() + First, RawString.size() - First);1076 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));1077 EndLoc = Lexer.getLoc();1078 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))1079 return ParseStatus::NoMatch;1080 return ParseStatus::Success;1081 }1082 }1083 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');1084 MCRegister ColonReg = matchRegister(ColonSplit.first.lower());1085 if (ColonReg && RegisterMatchesArch(DotReg)) {1086 do {1087 Lexer.UnLex(Lookahead.pop_back_val());1088 } while (!Lookahead.empty() && !Lexer.is(AsmToken::Colon));1089 Reg = ColonReg;1090 EndLoc = Lexer.getLoc();1091 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))1092 return ParseStatus::NoMatch;1093 return ParseStatus::Success;1094 }1095 while (!Lookahead.empty()) {1096 Lexer.UnLex(Lookahead.pop_back_val());1097 }1098 return ParseStatus::NoMatch;1099}1100 1101bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {1102 if (previousEqual(Operands, 0, "call"))1103 return true;1104 if (previousEqual(Operands, 0, "jump"))1105 if (!getLexer().getTok().is(AsmToken::Colon))1106 return true;1107 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))1108 return true;1109 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&1110 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))1111 return true;1112 return false;1113}1114 1115bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {1116 SmallVector<AsmToken, 4> Tokens;1117 AsmLexer &Lexer = getLexer();1118 bool Done = false;1119 static char const *Comma = ",";1120 do {1121 Tokens.emplace_back(Lexer.getTok());1122 Lex();1123 switch (Tokens.back().getKind()) {1124 case AsmToken::TokenKind::Hash:1125 if (Tokens.size() > 1)1126 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {1127 Tokens.insert(Tokens.end() - 2,1128 AsmToken(AsmToken::TokenKind::Comma, Comma));1129 Done = true;1130 }1131 break;1132 case AsmToken::TokenKind::RCurly:1133 case AsmToken::TokenKind::EndOfStatement:1134 case AsmToken::TokenKind::Eof:1135 Done = true;1136 break;1137 default:1138 break;1139 }1140 } while (!Done);1141 while (!Tokens.empty()) {1142 Lexer.UnLex(Tokens.back());1143 Tokens.pop_back();1144 }1145 SMLoc Loc = Lexer.getLoc();1146 return getParser().parseExpression(Expr, Loc);1147}1148 1149bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {1150 if (implicitExpressionLocation(Operands)) {1151 MCAsmParser &Parser = getParser();1152 SMLoc Loc = Parser.getLexer().getLoc();1153 MCExpr const *Expr = nullptr;1154 bool Error = parseExpression(Expr);1155 Expr = HexagonMCExpr::create(Expr, getContext());1156 if (!Error)1157 Operands.push_back(1158 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));1159 return Error;1160 }1161 return parseOperand(Operands);1162}1163 1164/// Parse an instruction.1165bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {1166 MCAsmParser &Parser = getParser();1167 AsmLexer &Lexer = getLexer();1168 while (true) {1169 AsmToken const &Token = Parser.getTok();1170 switch (Token.getKind()) {1171 case AsmToken::Eof:1172 case AsmToken::EndOfStatement: {1173 Lex();1174 return false;1175 }1176 case AsmToken::LCurly: {1177 if (!Operands.empty())1178 return true;1179 Operands.push_back(HexagonOperand::CreateToken(1180 getContext(), Token.getString(), Token.getLoc()));1181 Lex();1182 return false;1183 }1184 case AsmToken::RCurly: {1185 if (Operands.empty()) {1186 Operands.push_back(HexagonOperand::CreateToken(1187 getContext(), Token.getString(), Token.getLoc()));1188 Lex();1189 }1190 return false;1191 }1192 case AsmToken::Comma: {1193 Lex();1194 continue;1195 }1196 case AsmToken::EqualEqual:1197 case AsmToken::ExclaimEqual:1198 case AsmToken::GreaterEqual:1199 case AsmToken::GreaterGreater:1200 case AsmToken::LessEqual:1201 case AsmToken::LessLess: {1202 Operands.push_back(HexagonOperand::CreateToken(1203 getContext(), Token.getString().substr(0, 1), Token.getLoc()));1204 Operands.push_back(HexagonOperand::CreateToken(1205 getContext(), Token.getString().substr(1, 1), Token.getLoc()));1206 Lex();1207 continue;1208 }1209 case AsmToken::Hash: {1210 bool MustNotExtend = false;1211 bool ImplicitExpression = implicitExpressionLocation(Operands);1212 SMLoc ExprLoc = Lexer.getLoc();1213 if (!ImplicitExpression)1214 Operands.push_back(HexagonOperand::CreateToken(1215 getContext(), Token.getString(), Token.getLoc()));1216 Lex();1217 bool MustExtend = false;1218 bool HiOnly = false;1219 bool LoOnly = false;1220 if (Lexer.is(AsmToken::Hash)) {1221 Lex();1222 MustExtend = true;1223 } else if (ImplicitExpression)1224 MustNotExtend = true;1225 AsmToken const &Token = Parser.getTok();1226 if (Token.is(AsmToken::Identifier)) {1227 StringRef String = Token.getString();1228 if (String.lower() == "hi") {1229 HiOnly = true;1230 } else if (String.lower() == "lo") {1231 LoOnly = true;1232 }1233 if (HiOnly || LoOnly) {1234 AsmToken LParen = Lexer.peekTok();1235 if (!LParen.is(AsmToken::LParen)) {1236 HiOnly = false;1237 LoOnly = false;1238 } else {1239 Lex();1240 }1241 }1242 }1243 MCExpr const *Expr = nullptr;1244 if (parseExpression(Expr))1245 return true;1246 int64_t Value;1247 MCContext &Context = Parser.getContext();1248 assert(Expr != nullptr);1249 if (Expr->evaluateAsAbsolute(Value)) {1250 if (HiOnly)1251 Expr = MCBinaryExpr::createLShr(1252 Expr, MCConstantExpr::create(16, Context), Context);1253 if (HiOnly || LoOnly)1254 Expr = MCBinaryExpr::createAnd(1255 Expr, MCConstantExpr::create(0xffff, Context), Context);1256 } else {1257 MCValue Value;1258 if (Expr->evaluateAsRelocatable(Value, nullptr)) {1259 if (!Value.isAbsolute()) {1260 switch (HexagonMCExpr::VariantKind(Value.getSpecifier())) {1261 case HexagonMCExpr::VK_TPREL:1262 case HexagonMCExpr::VK_DTPREL:1263 // Don't lazy extend these expression variants1264 MustNotExtend = !MustExtend;1265 break;1266 default:1267 break;1268 }1269 }1270 }1271 }1272 Expr = HexagonMCExpr::create(Expr, Context);1273 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);1274 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);1275 std::unique_ptr<HexagonOperand> Operand =1276 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);1277 Operands.push_back(std::move(Operand));1278 continue;1279 }1280 default:1281 break;1282 }1283 if (parseExpressionOrOperand(Operands))1284 return true;1285 }1286}1287 1288bool HexagonAsmParser::parseInstruction(ParseInstructionInfo &Info,1289 StringRef Name, AsmToken ID,1290 OperandVector &Operands) {1291 getLexer().UnLex(ID);1292 return parseInstruction(Operands);1293}1294 1295static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,1296 MCOperand &MO2) {1297 MCInst TmpInst;1298 TmpInst.setOpcode(opCode);1299 TmpInst.addOperand(Rdd);1300 TmpInst.addOperand(MO1);1301 TmpInst.addOperand(MO2);1302 1303 return TmpInst;1304}1305 1306// Define this matcher function after the auto-generated include so we1307// have the match class enum definitions.1308unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,1309 unsigned Kind) {1310 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);1311 1312 switch (Kind) {1313 case MCK_0: {1314 int64_t Value;1315 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 01316 ? Match_Success1317 : Match_InvalidOperand;1318 }1319 case MCK_1: {1320 int64_t Value;1321 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 11322 ? Match_Success1323 : Match_InvalidOperand;1324 }1325 }1326 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {1327 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);1328 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)1329 return Match_Success;1330 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)1331 return Match_Success;1332 }1333 1334 LLVM_DEBUG(dbgs() << "Unmatched Operand:");1335 LLVM_DEBUG(Op->dump());1336 LLVM_DEBUG(dbgs() << "\n");1337 1338 return Match_InvalidOperand;1339}1340 1341// FIXME: Calls to OutOfRange should propagate failure up to parseStatement.1342bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {1343 std::string errStr;1344 raw_string_ostream ES(errStr);1345 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";1346 if (Max >= 0)1347 ES << "0-" << Max;1348 else1349 ES << Max << "-" << (-Max - 1);1350 return Parser.printError(IDLoc, ES.str());1351}1352 1353int HexagonAsmParser::processInstruction(MCInst &Inst,1354 OperandVector const &Operands,1355 SMLoc IDLoc) {1356 MCContext &Context = getParser().getContext();1357 const MCRegisterInfo *RI = getContext().getRegisterInfo();1358 const std::string r = "r";1359 const std::string Colon = ":";1360 using RegPairVals = std::pair<unsigned, unsigned>;1361 auto GetRegPair = [this, r](RegPairVals RegPair) {1362 const std::string R1 = r + utostr(RegPair.first);1363 const std::string R2 = r + utostr(RegPair.second);1364 1365 return std::make_pair(matchRegister(R1), matchRegister(R2));1366 };1367 auto GetScalarRegs = [RI, GetRegPair](MCRegister RegPair) {1368 const unsigned Lower = RI->getEncodingValue(RegPair);1369 const RegPairVals RegPair_ = std::make_pair(Lower + 1, Lower);1370 1371 return GetRegPair(RegPair_);1372 };1373 auto GetVecRegs = [GetRegPair](MCRegister VecRegPair) {1374 const RegPairVals RegPair =1375 HexagonMCInstrInfo::GetVecRegPairIndices(VecRegPair);1376 1377 return GetRegPair(RegPair);1378 };1379 1380 bool is32bit = false; // used to distinguish between CONST32 and CONST641381 switch (Inst.getOpcode()) {1382 default:1383 if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {1384 SMDiagnostic Diag = getSourceManager().GetMessage(1385 IDLoc, SourceMgr::DK_Error,1386 "Found pseudo instruction with no expansion");1387 Diag.print("", errs());1388 report_fatal_error("Invalid pseudo instruction");1389 }1390 break;1391 1392 case Hexagon::J2_trap1:1393 if (!getSTI().hasFeature(Hexagon::ArchV65)) {1394 MCOperand &Rx = Inst.getOperand(0);1395 MCOperand &Ry = Inst.getOperand(1);1396 if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {1397 Error(IDLoc, "trap1 can only have register r0 as operand");1398 return Match_InvalidOperand;1399 }1400 }1401 break;1402 1403 case Hexagon::A2_iconst: {1404 Inst.setOpcode(Hexagon::A2_addi);1405 MCOperand Reg = Inst.getOperand(0);1406 MCOperand S27 = Inst.getOperand(1);1407 HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());1408 HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());1409 Inst.clear();1410 Inst.addOperand(Reg);1411 Inst.addOperand(MCOperand::createReg(Hexagon::R0));1412 Inst.addOperand(S27);1413 break;1414 }1415 case Hexagon::M4_mpyrr_addr:1416 case Hexagon::S4_addi_asl_ri:1417 case Hexagon::S4_addi_lsr_ri:1418 case Hexagon::S4_andi_asl_ri:1419 case Hexagon::S4_andi_lsr_ri:1420 case Hexagon::S4_ori_asl_ri:1421 case Hexagon::S4_ori_lsr_ri:1422 case Hexagon::S4_or_andix:1423 case Hexagon::S4_subi_asl_ri:1424 case Hexagon::S4_subi_lsr_ri: {1425 MCOperand &Ry = Inst.getOperand(0);1426 MCOperand &src = Inst.getOperand(2);1427 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))1428 return Match_InvalidOperand;1429 break;1430 }1431 1432 case Hexagon::C2_cmpgei: {1433 MCOperand &MO = Inst.getOperand(2);1434 MO.setExpr(HexagonMCExpr::create(1435 MCBinaryExpr::createSub(MO.getExpr(),1436 MCConstantExpr::create(1, Context), Context),1437 Context));1438 Inst.setOpcode(Hexagon::C2_cmpgti);1439 break;1440 }1441 1442 case Hexagon::C2_cmpgeui: {1443 MCOperand &MO = Inst.getOperand(2);1444 int64_t Value;1445 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);1446 (void)Success;1447 assert(Success && "Assured by matcher");1448 if (Value == 0) {1449 MCInst TmpInst;1450 MCOperand &Pd = Inst.getOperand(0);1451 MCOperand &Rt = Inst.getOperand(1);1452 TmpInst.setOpcode(Hexagon::C2_cmpeq);1453 TmpInst.addOperand(Pd);1454 TmpInst.addOperand(Rt);1455 TmpInst.addOperand(Rt);1456 Inst = TmpInst;1457 } else {1458 MO.setExpr(HexagonMCExpr::create(1459 MCBinaryExpr::createSub(MO.getExpr(),1460 MCConstantExpr::create(1, Context), Context),1461 Context));1462 Inst.setOpcode(Hexagon::C2_cmpgtui);1463 }1464 break;1465 }1466 1467 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"1468 case Hexagon::A2_tfrp: {1469 MCOperand &MO = Inst.getOperand(1);1470 const std::pair<MCRegister, MCRegister> RegPair =1471 GetScalarRegs(MO.getReg());1472 MO.setReg(RegPair.first);1473 Inst.addOperand(MCOperand::createReg(RegPair.second));1474 Inst.setOpcode(Hexagon::A2_combinew);1475 break;1476 }1477 1478 case Hexagon::A2_tfrpt:1479 case Hexagon::A2_tfrpf: {1480 MCOperand &MO = Inst.getOperand(2);1481 const std::pair<MCRegister, MCRegister> RegPair =1482 GetScalarRegs(MO.getReg());1483 MO.setReg(RegPair.first);1484 Inst.addOperand(MCOperand::createReg(RegPair.second));1485 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)1486 ? Hexagon::C2_ccombinewt1487 : Hexagon::C2_ccombinewf);1488 break;1489 }1490 case Hexagon::A2_tfrptnew:1491 case Hexagon::A2_tfrpfnew: {1492 MCOperand &MO = Inst.getOperand(2);1493 const std::pair<MCRegister, MCRegister> RegPair =1494 GetScalarRegs(MO.getReg());1495 MO.setReg(RegPair.first);1496 Inst.addOperand(MCOperand::createReg(RegPair.second));1497 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)1498 ? Hexagon::C2_ccombinewnewt1499 : Hexagon::C2_ccombinewnewf);1500 break;1501 }1502 1503 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"1504 case Hexagon::V6_vassignp: {1505 MCOperand &MO = Inst.getOperand(1);1506 const std::pair<MCRegister, MCRegister> RegPair = GetVecRegs(MO.getReg());1507 MO.setReg(RegPair.first);1508 Inst.addOperand(MCOperand::createReg(RegPair.second));1509 Inst.setOpcode(Hexagon::V6_vcombine);1510 break;1511 }1512 1513 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "1514 case Hexagon::CONST32:1515 is32bit = true;1516 [[fallthrough]];1517 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "1518 case Hexagon::CONST64:1519 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())1520 if (!Parser.getStreamer().hasRawTextSupport()) {1521 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());1522 MCOperand &MO_1 = Inst.getOperand(1);1523 MCOperand &MO_0 = Inst.getOperand(0);1524 1525 // push section onto section stack1526 MES->pushSection();1527 1528 std::string myCharStr;1529 MCSectionELF *mySection;1530 1531 // check if this as an immediate or a symbol1532 int64_t Value;1533 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);1534 if (Absolute) {1535 // Create a new section - one for each constant1536 // Some or all of the zeros are replaced with the given immediate.1537 if (is32bit) {1538 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));1539 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")1540 .drop_back(myImmStr.size())1541 .str() +1542 myImmStr;1543 } else {1544 std::string myImmStr = utohexstr(Value);1545 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")1546 .drop_back(myImmStr.size())1547 .str() +1548 myImmStr;1549 }1550 1551 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,1552 ELF::SHF_ALLOC | ELF::SHF_WRITE);1553 } else if (MO_1.isExpr()) {1554 // .lita - for expressions1555 myCharStr = ".lita";1556 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,1557 ELF::SHF_ALLOC | ELF::SHF_WRITE);1558 } else1559 llvm_unreachable("unexpected type of machine operand!");1560 1561 MES->switchSection(mySection);1562 unsigned byteSize = is32bit ? 4 : 8;1563 getStreamer().emitCodeAlignment(Align(byteSize), &getSTI(), byteSize);1564 1565 MCSymbol *Sym;1566 1567 // for symbols, get rid of prepended ".gnu.linkonce.lx."1568 1569 // emit symbol if needed1570 if (Absolute) {1571 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));1572 if (Sym->isUndefined()) {1573 getStreamer().emitLabel(Sym);1574 getStreamer().emitSymbolAttribute(Sym, MCSA_Global);1575 getStreamer().emitIntValue(Value, byteSize);1576 }1577 } else if (MO_1.isExpr()) {1578 const char *StringStart = nullptr;1579 const char *StringEnd = nullptr;1580 if (*Operands[4]->getStartLoc().getPointer() == '#') {1581 StringStart = Operands[5]->getStartLoc().getPointer();1582 StringEnd = Operands[6]->getStartLoc().getPointer();1583 } else { // no pound1584 StringStart = Operands[4]->getStartLoc().getPointer();1585 StringEnd = Operands[5]->getStartLoc().getPointer();1586 }1587 1588 unsigned size = StringEnd - StringStart;1589 std::string DotConst = ".CONST_";1590 Sym = getContext().getOrCreateSymbol(DotConst +1591 StringRef(StringStart, size));1592 1593 if (Sym->isUndefined()) {1594 // case where symbol is not yet defined: emit symbol1595 getStreamer().emitLabel(Sym);1596 getStreamer().emitSymbolAttribute(Sym, MCSA_Local);1597 getStreamer().emitValue(MO_1.getExpr(), 4);1598 }1599 } else1600 llvm_unreachable("unexpected type of machine operand!");1601 1602 MES->popSection();1603 1604 if (Sym) {1605 MCInst TmpInst;1606 if (is32bit) // 32 bit1607 TmpInst.setOpcode(Hexagon::L2_loadrigp);1608 else // 64 bit1609 TmpInst.setOpcode(Hexagon::L2_loadrdgp);1610 1611 TmpInst.addOperand(MO_0);1612 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(1613 MCSymbolRefExpr::create(Sym, getContext()), getContext())));1614 Inst = TmpInst;1615 }1616 }1617 break;1618 1619 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"1620 case Hexagon::A2_tfrpi: {1621 MCOperand &Rdd = Inst.getOperand(0);1622 MCOperand &MO = Inst.getOperand(1);1623 int64_t Value;1624 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;1625 MCOperand imm(MCOperand::createExpr(1626 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));1627 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);1628 break;1629 }1630 1631 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"1632 case Hexagon::TFRI64_V4: {1633 MCOperand &Rdd = Inst.getOperand(0);1634 MCOperand &MO = Inst.getOperand(1);1635 int64_t Value;1636 if (MO.getExpr()->evaluateAsAbsolute(Value)) {1637 int s8 = Hi_32(Value);1638 if (!isInt<8>(s8))1639 OutOfRange(IDLoc, s8, -128);1640 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(1641 MCConstantExpr::create(s8, Context), Context))); // upper 321642 auto Expr = HexagonMCExpr::create(1643 MCConstantExpr::create(Lo_32(Value), Context), Context);1644 HexagonMCInstrInfo::setMustExtend(1645 *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));1646 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 321647 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);1648 } else {1649 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(1650 MCConstantExpr::create(0, Context), Context))); // upper 321651 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);1652 }1653 break;1654 }1655 1656 // Handle $Rdd = combine(##imm, #imm)"1657 case Hexagon::TFRI64_V2_ext: {1658 MCOperand &Rdd = Inst.getOperand(0);1659 MCOperand &MO1 = Inst.getOperand(1);1660 MCOperand &MO2 = Inst.getOperand(2);1661 int64_t Value;1662 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {1663 int s8 = Value;1664 if (s8 < -128 || s8 > 127)1665 OutOfRange(IDLoc, s8, -128);1666 }1667 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);1668 break;1669 }1670 1671 // Handle $Rdd = combine(#imm, ##imm)"1672 case Hexagon::A4_combineii: {1673 MCOperand &Rdd = Inst.getOperand(0);1674 MCOperand &MO1 = Inst.getOperand(1);1675 int64_t Value;1676 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {1677 int s8 = Value;1678 if (s8 < -128 || s8 > 127)1679 OutOfRange(IDLoc, s8, -128);1680 }1681 MCOperand &MO2 = Inst.getOperand(2);1682 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);1683 break;1684 }1685 1686 case Hexagon::S2_tableidxb_goodsyntax:1687 Inst.setOpcode(Hexagon::S2_tableidxb);1688 break;1689 1690 case Hexagon::S2_tableidxh_goodsyntax: {1691 MCInst TmpInst;1692 MCOperand &Rx = Inst.getOperand(0);1693 MCOperand &Rs = Inst.getOperand(2);1694 MCOperand &Imm4 = Inst.getOperand(3);1695 MCOperand &Imm6 = Inst.getOperand(4);1696 Imm6.setExpr(HexagonMCExpr::create(1697 MCBinaryExpr::createSub(Imm6.getExpr(),1698 MCConstantExpr::create(1, Context), Context),1699 Context));1700 TmpInst.setOpcode(Hexagon::S2_tableidxh);1701 TmpInst.addOperand(Rx);1702 TmpInst.addOperand(Rx);1703 TmpInst.addOperand(Rs);1704 TmpInst.addOperand(Imm4);1705 TmpInst.addOperand(Imm6);1706 Inst = TmpInst;1707 break;1708 }1709 1710 case Hexagon::S2_tableidxw_goodsyntax: {1711 MCInst TmpInst;1712 MCOperand &Rx = Inst.getOperand(0);1713 MCOperand &Rs = Inst.getOperand(2);1714 MCOperand &Imm4 = Inst.getOperand(3);1715 MCOperand &Imm6 = Inst.getOperand(4);1716 Imm6.setExpr(HexagonMCExpr::create(1717 MCBinaryExpr::createSub(Imm6.getExpr(),1718 MCConstantExpr::create(2, Context), Context),1719 Context));1720 TmpInst.setOpcode(Hexagon::S2_tableidxw);1721 TmpInst.addOperand(Rx);1722 TmpInst.addOperand(Rx);1723 TmpInst.addOperand(Rs);1724 TmpInst.addOperand(Imm4);1725 TmpInst.addOperand(Imm6);1726 Inst = TmpInst;1727 break;1728 }1729 1730 case Hexagon::S2_tableidxd_goodsyntax: {1731 MCInst TmpInst;1732 MCOperand &Rx = Inst.getOperand(0);1733 MCOperand &Rs = Inst.getOperand(2);1734 MCOperand &Imm4 = Inst.getOperand(3);1735 MCOperand &Imm6 = Inst.getOperand(4);1736 Imm6.setExpr(HexagonMCExpr::create(1737 MCBinaryExpr::createSub(Imm6.getExpr(),1738 MCConstantExpr::create(3, Context), Context),1739 Context));1740 TmpInst.setOpcode(Hexagon::S2_tableidxd);1741 TmpInst.addOperand(Rx);1742 TmpInst.addOperand(Rx);1743 TmpInst.addOperand(Rs);1744 TmpInst.addOperand(Imm4);1745 TmpInst.addOperand(Imm6);1746 Inst = TmpInst;1747 break;1748 }1749 1750 case Hexagon::M2_mpyui:1751 Inst.setOpcode(Hexagon::M2_mpyi);1752 break;1753 case Hexagon::M2_mpysmi: {1754 MCInst TmpInst;1755 MCOperand &Rd = Inst.getOperand(0);1756 MCOperand &Rs = Inst.getOperand(1);1757 MCOperand &Imm = Inst.getOperand(2);1758 int64_t Value;1759 MCExpr const &Expr = *Imm.getExpr();1760 bool Absolute = Expr.evaluateAsAbsolute(Value);1761 if (!Absolute)1762 return Match_InvalidOperand;1763 if (!HexagonMCInstrInfo::mustExtend(Expr) &&1764 ((Value <= -256) || Value >= 256))1765 return Match_InvalidOperand;1766 if (Value < 0 && Value > -256) {1767 Imm.setExpr(HexagonMCExpr::create(1768 MCConstantExpr::create(Value * -1, Context), Context));1769 TmpInst.setOpcode(Hexagon::M2_mpysin);1770 } else1771 TmpInst.setOpcode(Hexagon::M2_mpysip);1772 TmpInst.addOperand(Rd);1773 TmpInst.addOperand(Rs);1774 TmpInst.addOperand(Imm);1775 Inst = TmpInst;1776 break;1777 }1778 1779 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {1780 MCOperand &Imm = Inst.getOperand(2);1781 MCInst TmpInst;1782 int64_t Value;1783 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);1784 if (!Absolute)1785 return Match_InvalidOperand;1786 if (Value == 0) { // convert to $Rd = $Rs1787 TmpInst.setOpcode(Hexagon::A2_tfr);1788 MCOperand &Rd = Inst.getOperand(0);1789 MCOperand &Rs = Inst.getOperand(1);1790 TmpInst.addOperand(Rd);1791 TmpInst.addOperand(Rs);1792 } else {1793 Imm.setExpr(HexagonMCExpr::create(1794 MCBinaryExpr::createSub(Imm.getExpr(),1795 MCConstantExpr::create(1, Context), Context),1796 Context));1797 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);1798 MCOperand &Rd = Inst.getOperand(0);1799 MCOperand &Rs = Inst.getOperand(1);1800 TmpInst.addOperand(Rd);1801 TmpInst.addOperand(Rs);1802 TmpInst.addOperand(Imm);1803 }1804 Inst = TmpInst;1805 break;1806 }1807 1808 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {1809 MCOperand &Rdd = Inst.getOperand(0);1810 MCOperand &Rss = Inst.getOperand(1);1811 MCOperand &Imm = Inst.getOperand(2);1812 int64_t Value;1813 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);1814 if (!Absolute)1815 return Match_InvalidOperand;1816 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])1817 MCInst TmpInst;1818 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());1819 std::string R1 = r + utostr(RegPairNum + 1);1820 StringRef Reg1(R1);1821 Rss.setReg(matchRegister(Reg1));1822 // Add a new operand for the second register in the pair.1823 std::string R2 = r + utostr(RegPairNum);1824 StringRef Reg2(R2);1825 TmpInst.setOpcode(Hexagon::A2_combinew);1826 TmpInst.addOperand(Rdd);1827 TmpInst.addOperand(Rss);1828 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));1829 Inst = TmpInst;1830 } else {1831 Imm.setExpr(HexagonMCExpr::create(1832 MCBinaryExpr::createSub(Imm.getExpr(),1833 MCConstantExpr::create(1, Context), Context),1834 Context));1835 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);1836 }1837 break;1838 }1839 1840 case Hexagon::A4_boundscheck: {1841 MCOperand &Rs = Inst.getOperand(1);1842 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());1843 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:21844 Inst.setOpcode(Hexagon::A4_boundscheck_hi);1845 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);1846 StringRef RegPair = Name;1847 Rs.setReg(matchRegister(RegPair));1848 } else { // raw:lo1849 Inst.setOpcode(Hexagon::A4_boundscheck_lo);1850 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);1851 StringRef RegPair = Name;1852 Rs.setReg(matchRegister(RegPair));1853 }1854 break;1855 }1856 1857 case Hexagon::A2_addsp: {1858 MCOperand &Rs = Inst.getOperand(1);1859 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());1860 if (RegNum & 1) { // Odd mapped to raw:hi1861 Inst.setOpcode(Hexagon::A2_addsph);1862 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);1863 StringRef RegPair = Name;1864 Rs.setReg(matchRegister(RegPair));1865 } else { // Even mapped raw:lo1866 Inst.setOpcode(Hexagon::A2_addspl);1867 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);1868 StringRef RegPair = Name;1869 Rs.setReg(matchRegister(RegPair));1870 }1871 break;1872 }1873 1874 case Hexagon::M2_vrcmpys_s1: {1875 MCOperand &Rt = Inst.getOperand(2);1876 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());1877 if (RegNum & 1) { // Odd mapped to sat:raw:hi1878 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);1879 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);1880 StringRef RegPair = Name;1881 Rt.setReg(matchRegister(RegPair));1882 } else { // Even mapped sat:raw:lo1883 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);1884 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);1885 StringRef RegPair = Name;1886 Rt.setReg(matchRegister(RegPair));1887 }1888 break;1889 }1890 1891 case Hexagon::M2_vrcmpys_acc_s1: {1892 MCInst TmpInst;1893 MCOperand &Rxx = Inst.getOperand(0);1894 MCOperand &Rss = Inst.getOperand(2);1895 MCOperand &Rt = Inst.getOperand(3);1896 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());1897 if (RegNum & 1) { // Odd mapped to sat:raw:hi1898 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);1899 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);1900 StringRef RegPair = Name;1901 Rt.setReg(matchRegister(RegPair));1902 } else { // Even mapped sat:raw:lo1903 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);1904 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);1905 StringRef RegPair = Name;1906 Rt.setReg(matchRegister(RegPair));1907 }1908 // Registers are in different positions1909 TmpInst.addOperand(Rxx);1910 TmpInst.addOperand(Rxx);1911 TmpInst.addOperand(Rss);1912 TmpInst.addOperand(Rt);1913 Inst = TmpInst;1914 break;1915 }1916 1917 case Hexagon::M2_vrcmpys_s1rp: {1918 MCOperand &Rt = Inst.getOperand(2);1919 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());1920 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi1921 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);1922 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);1923 StringRef RegPair = Name;1924 Rt.setReg(matchRegister(RegPair));1925 } else { // Even mapped rnd:sat:raw:lo1926 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);1927 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);1928 StringRef RegPair = Name;1929 Rt.setReg(matchRegister(RegPair));1930 }1931 break;1932 }1933 1934 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {1935 MCOperand &Imm = Inst.getOperand(2);1936 int64_t Value;1937 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);1938 if (!Absolute)1939 return Match_InvalidOperand;1940 if (Value == 0)1941 Inst.setOpcode(Hexagon::S2_vsathub);1942 else {1943 Imm.setExpr(HexagonMCExpr::create(1944 MCBinaryExpr::createSub(Imm.getExpr(),1945 MCConstantExpr::create(1, Context), Context),1946 Context));1947 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);1948 }1949 break;1950 }1951 1952 case Hexagon::S5_vasrhrnd_goodsyntax: {1953 MCOperand &Rdd = Inst.getOperand(0);1954 MCOperand &Rss = Inst.getOperand(1);1955 MCOperand &Imm = Inst.getOperand(2);1956 int64_t Value;1957 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);1958 if (!Absolute)1959 return Match_InvalidOperand;1960 if (Value == 0) {1961 MCInst TmpInst;1962 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());1963 std::string R1 = r + utostr(RegPairNum + 1);1964 StringRef Reg1(R1);1965 Rss.setReg(matchRegister(Reg1));1966 // Add a new operand for the second register in the pair.1967 std::string R2 = r + utostr(RegPairNum);1968 StringRef Reg2(R2);1969 TmpInst.setOpcode(Hexagon::A2_combinew);1970 TmpInst.addOperand(Rdd);1971 TmpInst.addOperand(Rss);1972 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));1973 Inst = TmpInst;1974 } else {1975 Imm.setExpr(HexagonMCExpr::create(1976 MCBinaryExpr::createSub(Imm.getExpr(),1977 MCConstantExpr::create(1, Context), Context),1978 Context));1979 Inst.setOpcode(Hexagon::S5_vasrhrnd);1980 }1981 break;1982 }1983 1984 case Hexagon::A2_not: {1985 MCInst TmpInst;1986 MCOperand &Rd = Inst.getOperand(0);1987 MCOperand &Rs = Inst.getOperand(1);1988 TmpInst.setOpcode(Hexagon::A2_subri);1989 TmpInst.addOperand(Rd);1990 TmpInst.addOperand(MCOperand::createExpr(1991 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));1992 TmpInst.addOperand(Rs);1993 Inst = TmpInst;1994 break;1995 }1996 case Hexagon::PS_loadrubabs:1997 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))1998 Inst.setOpcode(Hexagon::L2_loadrubgp);1999 break;2000 case Hexagon::PS_loadrbabs:2001 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))2002 Inst.setOpcode(Hexagon::L2_loadrbgp);2003 break;2004 case Hexagon::PS_loadruhabs:2005 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))2006 Inst.setOpcode(Hexagon::L2_loadruhgp);2007 break;2008 case Hexagon::PS_loadrhabs:2009 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))2010 Inst.setOpcode(Hexagon::L2_loadrhgp);2011 break;2012 case Hexagon::PS_loadriabs:2013 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))2014 Inst.setOpcode(Hexagon::L2_loadrigp);2015 break;2016 case Hexagon::PS_loadrdabs:2017 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))2018 Inst.setOpcode(Hexagon::L2_loadrdgp);2019 break;2020 case Hexagon::PS_storerbabs:2021 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2022 Inst.setOpcode(Hexagon::S2_storerbgp);2023 break;2024 case Hexagon::PS_storerhabs:2025 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2026 Inst.setOpcode(Hexagon::S2_storerhgp);2027 break;2028 case Hexagon::PS_storerfabs:2029 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2030 Inst.setOpcode(Hexagon::S2_storerfgp);2031 break;2032 case Hexagon::PS_storeriabs:2033 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2034 Inst.setOpcode(Hexagon::S2_storerigp);2035 break;2036 case Hexagon::PS_storerdabs:2037 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2038 Inst.setOpcode(Hexagon::S2_storerdgp);2039 break;2040 case Hexagon::PS_storerbnewabs:2041 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2042 Inst.setOpcode(Hexagon::S2_storerbnewgp);2043 break;2044 case Hexagon::PS_storerhnewabs:2045 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2046 Inst.setOpcode(Hexagon::S2_storerhnewgp);2047 break;2048 case Hexagon::PS_storerinewabs:2049 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))2050 Inst.setOpcode(Hexagon::S2_storerinewgp);2051 break;2052 case Hexagon::A2_zxtb: {2053 Inst.setOpcode(Hexagon::A2_andir);2054 Inst.addOperand(2055 MCOperand::createExpr(MCConstantExpr::create(255, Context)));2056 break;2057 }2058 } // switch2059 2060 return Match_Success;2061}2062 2063MCRegister HexagonAsmParser::matchRegister(StringRef Name) {2064 if (MCRegister Reg = MatchRegisterName(Name))2065 return Reg;2066 return MatchRegisterAltName(Name);2067}2068