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