1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly 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 #include "MCTargetDesc/RISCVBaseInfo.h" 11 #include "MCTargetDesc/RISCVMCExpr.h" 12 #include "MCTargetDesc/RISCVMCTargetDesc.h" 13 #include "MCTargetDesc/RISCVTargetStreamer.h" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInstBuilder.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 #include "llvm/MC/MCStreamer.h" 25 #include "llvm/MC/MCSubtargetInfo.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/MathExtras.h" 28 #include "llvm/Support/TargetRegistry.h" 29 30 #include <limits> 31 32 using namespace llvm; 33 34 // Include the auto-generated portion of the compress emitter. 35 #define GEN_COMPRESS_INSTR 36 #include "RISCVGenCompressInstEmitter.inc" 37 38 namespace { 39 struct RISCVOperand; 40 41 class RISCVAsmParser : public MCTargetAsmParser { 42 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 43 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 44 45 RISCVTargetStreamer &getTargetStreamer() { 46 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 47 return static_cast<RISCVTargetStreamer &>(TS); 48 } 49 50 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 51 unsigned Kind) override; 52 53 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 54 int64_t Lower, int64_t Upper, Twine Msg); 55 56 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 57 OperandVector &Operands, MCStreamer &Out, 58 uint64_t &ErrorInfo, 59 bool MatchingInlineAsm) override; 60 61 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 62 63 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 64 SMLoc NameLoc, OperandVector &Operands) override; 65 66 bool ParseDirective(AsmToken DirectiveID) override; 67 68 // Helper to actually emit an instruction to the MCStreamer. Also, when 69 // possible, compression of the instruction is performed. 70 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 71 72 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 73 // synthesize the desired immedate value into the destination register. 74 void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out); 75 76 /// Helper for processing MC instructions that have been successfully matched 77 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 78 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 79 /// in this method. 80 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 81 82 // Auto-generated instruction matching functions 83 #define GET_ASSEMBLER_HEADER 84 #include "RISCVGenAsmMatcher.inc" 85 86 OperandMatchResultTy parseImmediate(OperandVector &Operands); 87 OperandMatchResultTy parseRegister(OperandVector &Operands, 88 bool AllowParens = false); 89 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 90 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 91 92 bool parseOperand(OperandVector &Operands, bool ForceImmediate); 93 94 bool parseDirectiveOption(); 95 96 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 97 if (!(getSTI().getFeatureBits()[Feature])) { 98 MCSubtargetInfo &STI = copySTI(); 99 setAvailableFeatures( 100 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 101 } 102 } 103 104 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 105 if (getSTI().getFeatureBits()[Feature]) { 106 MCSubtargetInfo &STI = copySTI(); 107 setAvailableFeatures( 108 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 109 } 110 } 111 public: 112 enum RISCVMatchResultTy { 113 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 114 #define GET_OPERAND_DIAGNOSTIC_TYPES 115 #include "RISCVGenAsmMatcher.inc" 116 #undef GET_OPERAND_DIAGNOSTIC_TYPES 117 }; 118 119 static bool classifySymbolRef(const MCExpr *Expr, 120 RISCVMCExpr::VariantKind &Kind, 121 int64_t &Addend); 122 123 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 124 const MCInstrInfo &MII, const MCTargetOptions &Options) 125 : MCTargetAsmParser(Options, STI, MII) { 126 Parser.addAliasForDirective(".half", ".2byte"); 127 Parser.addAliasForDirective(".hword", ".2byte"); 128 Parser.addAliasForDirective(".word", ".4byte"); 129 Parser.addAliasForDirective(".dword", ".8byte"); 130 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 131 } 132 }; 133 134 /// RISCVOperand - Instances of this class represent a parsed machine 135 /// instruction 136 struct RISCVOperand : public MCParsedAsmOperand { 137 138 enum KindTy { 139 Token, 140 Register, 141 Immediate, 142 } Kind; 143 144 bool IsRV64; 145 146 struct RegOp { 147 unsigned RegNum; 148 }; 149 150 struct ImmOp { 151 const MCExpr *Val; 152 }; 153 154 SMLoc StartLoc, EndLoc; 155 union { 156 StringRef Tok; 157 RegOp Reg; 158 ImmOp Imm; 159 }; 160 161 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 162 163 public: 164 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 165 Kind = o.Kind; 166 IsRV64 = o.IsRV64; 167 StartLoc = o.StartLoc; 168 EndLoc = o.EndLoc; 169 switch (Kind) { 170 case Register: 171 Reg = o.Reg; 172 break; 173 case Immediate: 174 Imm = o.Imm; 175 break; 176 case Token: 177 Tok = o.Tok; 178 break; 179 } 180 } 181 182 bool isToken() const override { return Kind == Token; } 183 bool isReg() const override { return Kind == Register; } 184 bool isImm() const override { return Kind == Immediate; } 185 bool isMem() const override { return false; } 186 187 bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const { 188 const MCExpr *Val = getImm(); 189 bool Ret = false; 190 if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) { 191 Ret = RE->evaluateAsConstant(Imm); 192 VK = RE->getKind(); 193 } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) { 194 Ret = true; 195 VK = RISCVMCExpr::VK_RISCV_None; 196 Imm = CE->getValue(); 197 } 198 return Ret; 199 } 200 201 // True if operand is a symbol with no modifiers, or a constant with no 202 // modifiers and isShiftedInt<N-1, 1>(Op). 203 template <int N> bool isBareSimmNLsb0() const { 204 int64_t Imm; 205 RISCVMCExpr::VariantKind VK; 206 if (!isImm()) 207 return false; 208 bool IsConstantImm = evaluateConstantImm(Imm, VK); 209 bool IsValid; 210 if (!IsConstantImm) 211 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 212 else 213 IsValid = isShiftedInt<N - 1, 1>(Imm); 214 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 215 } 216 217 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 218 219 bool isBareSymbol() const { 220 int64_t Imm; 221 RISCVMCExpr::VariantKind VK; 222 // Must be of 'immediate' type but not a constant. 223 if (!isImm() || evaluateConstantImm(Imm, VK)) 224 return false; 225 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 226 VK == RISCVMCExpr::VK_RISCV_None; 227 } 228 229 /// Return true if the operand is a valid for the fence instruction e.g. 230 /// ('iorw'). 231 bool isFenceArg() const { 232 if (!isImm()) 233 return false; 234 const MCExpr *Val = getImm(); 235 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 236 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 237 return false; 238 239 StringRef Str = SVal->getSymbol().getName(); 240 // Letters must be unique, taken from 'iorw', and in ascending order. This 241 // holds as long as each individual character is one of 'iorw' and is 242 // greater than the previous character. 243 char Prev = '\0'; 244 for (char c : Str) { 245 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 246 return false; 247 if (c <= Prev) 248 return false; 249 Prev = c; 250 } 251 return true; 252 } 253 254 /// Return true if the operand is a valid floating point rounding mode. 255 bool isFRMArg() const { 256 if (!isImm()) 257 return false; 258 const MCExpr *Val = getImm(); 259 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 260 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 261 return false; 262 263 StringRef Str = SVal->getSymbol().getName(); 264 265 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 266 } 267 268 bool isImmXLen() const { 269 int64_t Imm; 270 RISCVMCExpr::VariantKind VK; 271 if (!isImm()) 272 return false; 273 bool IsConstantImm = evaluateConstantImm(Imm, VK); 274 // Given only Imm, ensuring that the actually specified constant is either 275 // a signed or unsigned 64-bit number is unfortunately impossible. 276 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); 277 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None; 278 } 279 280 bool isUImmLog2XLen() const { 281 int64_t Imm; 282 RISCVMCExpr::VariantKind VK; 283 if (!isImm()) 284 return false; 285 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) 286 return false; 287 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 288 } 289 290 bool isUImmLog2XLenNonZero() const { 291 int64_t Imm; 292 RISCVMCExpr::VariantKind VK; 293 if (!isImm()) 294 return false; 295 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) 296 return false; 297 if (Imm == 0) 298 return false; 299 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 300 } 301 302 bool isUImm5() const { 303 int64_t Imm; 304 RISCVMCExpr::VariantKind VK; 305 if (!isImm()) 306 return false; 307 bool IsConstantImm = evaluateConstantImm(Imm, VK); 308 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 309 } 310 311 bool isUImm5NonZero() const { 312 int64_t Imm; 313 RISCVMCExpr::VariantKind VK; 314 if (!isImm()) 315 return false; 316 bool IsConstantImm = evaluateConstantImm(Imm, VK); 317 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 318 VK == RISCVMCExpr::VK_RISCV_None; 319 } 320 321 bool isSImm6() const { 322 RISCVMCExpr::VariantKind VK; 323 int64_t Imm; 324 bool IsValid; 325 bool IsConstantImm = evaluateConstantImm(Imm, VK); 326 if (!IsConstantImm) 327 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 328 else 329 IsValid = isInt<6>(Imm); 330 return IsValid && 331 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 332 } 333 334 bool isSImm6NonZero() const { 335 RISCVMCExpr::VariantKind VK; 336 int64_t Imm; 337 bool IsValid; 338 bool IsConstantImm = evaluateConstantImm(Imm, VK); 339 if (!IsConstantImm) 340 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 341 else 342 IsValid = ((Imm != 0) && isInt<6>(Imm)); 343 return IsValid && 344 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 345 } 346 347 bool isCLUIImm() const { 348 int64_t Imm; 349 RISCVMCExpr::VariantKind VK; 350 bool IsConstantImm = evaluateConstantImm(Imm, VK); 351 return IsConstantImm && (Imm != 0) && 352 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 353 VK == RISCVMCExpr::VK_RISCV_None; 354 } 355 356 bool isUImm7Lsb00() const { 357 int64_t Imm; 358 RISCVMCExpr::VariantKind VK; 359 bool IsConstantImm = evaluateConstantImm(Imm, VK); 360 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 361 VK == RISCVMCExpr::VK_RISCV_None; 362 } 363 364 bool isUImm8Lsb00() const { 365 int64_t Imm; 366 RISCVMCExpr::VariantKind VK; 367 bool IsConstantImm = evaluateConstantImm(Imm, VK); 368 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 369 VK == RISCVMCExpr::VK_RISCV_None; 370 } 371 372 bool isUImm8Lsb000() const { 373 int64_t Imm; 374 RISCVMCExpr::VariantKind VK; 375 bool IsConstantImm = evaluateConstantImm(Imm, VK); 376 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 377 VK == RISCVMCExpr::VK_RISCV_None; 378 } 379 380 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 381 382 bool isUImm9Lsb000() const { 383 int64_t Imm; 384 RISCVMCExpr::VariantKind VK; 385 bool IsConstantImm = evaluateConstantImm(Imm, VK); 386 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 387 VK == RISCVMCExpr::VK_RISCV_None; 388 } 389 390 bool isUImm10Lsb00NonZero() const { 391 int64_t Imm; 392 RISCVMCExpr::VariantKind VK; 393 bool IsConstantImm = evaluateConstantImm(Imm, VK); 394 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 395 VK == RISCVMCExpr::VK_RISCV_None; 396 } 397 398 bool isSImm12() const { 399 RISCVMCExpr::VariantKind VK; 400 int64_t Imm; 401 bool IsValid; 402 if (!isImm()) 403 return false; 404 bool IsConstantImm = evaluateConstantImm(Imm, VK); 405 if (!IsConstantImm) 406 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 407 else 408 IsValid = isInt<12>(Imm); 409 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 410 VK == RISCVMCExpr::VK_RISCV_LO || 411 VK == RISCVMCExpr::VK_RISCV_PCREL_LO); 412 } 413 414 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 415 416 bool isUImm12() const { 417 int64_t Imm; 418 RISCVMCExpr::VariantKind VK; 419 if (!isImm()) 420 return false; 421 bool IsConstantImm = evaluateConstantImm(Imm, VK); 422 return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 423 } 424 425 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 426 427 bool isSImm10Lsb0000NonZero() const { 428 int64_t Imm; 429 RISCVMCExpr::VariantKind VK; 430 bool IsConstantImm = evaluateConstantImm(Imm, VK); 431 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 432 VK == RISCVMCExpr::VK_RISCV_None; 433 } 434 435 bool isUImm20() const { 436 RISCVMCExpr::VariantKind VK; 437 int64_t Imm; 438 bool IsValid; 439 if (!isImm()) 440 return false; 441 bool IsConstantImm = evaluateConstantImm(Imm, VK); 442 if (!IsConstantImm) 443 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 444 else 445 IsValid = isUInt<20>(Imm); 446 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 447 VK == RISCVMCExpr::VK_RISCV_HI || 448 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 449 } 450 451 bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); } 452 453 /// getStartLoc - Gets location of the first token of this operand 454 SMLoc getStartLoc() const override { return StartLoc; } 455 /// getEndLoc - Gets location of the last token of this operand 456 SMLoc getEndLoc() const override { return EndLoc; } 457 /// True if this operand is for an RV64 instruction 458 bool isRV64() const { return IsRV64; } 459 460 unsigned getReg() const override { 461 assert(Kind == Register && "Invalid type access!"); 462 return Reg.RegNum; 463 } 464 465 const MCExpr *getImm() const { 466 assert(Kind == Immediate && "Invalid type access!"); 467 return Imm.Val; 468 } 469 470 StringRef getToken() const { 471 assert(Kind == Token && "Invalid type access!"); 472 return Tok; 473 } 474 475 void print(raw_ostream &OS) const override { 476 switch (Kind) { 477 case Immediate: 478 OS << *getImm(); 479 break; 480 case Register: 481 OS << "<register x"; 482 OS << getReg() << ">"; 483 break; 484 case Token: 485 OS << "'" << getToken() << "'"; 486 break; 487 } 488 } 489 490 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 491 bool IsRV64) { 492 auto Op = make_unique<RISCVOperand>(Token); 493 Op->Tok = Str; 494 Op->StartLoc = S; 495 Op->EndLoc = S; 496 Op->IsRV64 = IsRV64; 497 return Op; 498 } 499 500 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 501 SMLoc E, bool IsRV64) { 502 auto Op = make_unique<RISCVOperand>(Register); 503 Op->Reg.RegNum = RegNo; 504 Op->StartLoc = S; 505 Op->EndLoc = E; 506 Op->IsRV64 = IsRV64; 507 return Op; 508 } 509 510 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 511 SMLoc E, bool IsRV64) { 512 auto Op = make_unique<RISCVOperand>(Immediate); 513 Op->Imm.Val = Val; 514 Op->StartLoc = S; 515 Op->EndLoc = E; 516 Op->IsRV64 = IsRV64; 517 return Op; 518 } 519 520 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 521 assert(Expr && "Expr shouldn't be null!"); 522 int64_t Imm = 0; 523 bool IsConstant = false; 524 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 525 IsConstant = RE->evaluateAsConstant(Imm); 526 } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) { 527 IsConstant = true; 528 Imm = CE->getValue(); 529 } 530 531 if (IsConstant) 532 Inst.addOperand(MCOperand::createImm(Imm)); 533 else 534 Inst.addOperand(MCOperand::createExpr(Expr)); 535 } 536 537 // Used by the TableGen Code 538 void addRegOperands(MCInst &Inst, unsigned N) const { 539 assert(N == 1 && "Invalid number of operands!"); 540 Inst.addOperand(MCOperand::createReg(getReg())); 541 } 542 543 void addImmOperands(MCInst &Inst, unsigned N) const { 544 assert(N == 1 && "Invalid number of operands!"); 545 addExpr(Inst, getImm()); 546 } 547 548 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 549 assert(N == 1 && "Invalid number of operands!"); 550 // isFenceArg has validated the operand, meaning this cast is safe 551 auto SE = cast<MCSymbolRefExpr>(getImm()); 552 553 unsigned Imm = 0; 554 for (char c : SE->getSymbol().getName()) { 555 switch (c) { 556 default: llvm_unreachable("FenceArg must contain only [iorw]"); 557 case 'i': Imm |= RISCVFenceField::I; break; 558 case 'o': Imm |= RISCVFenceField::O; break; 559 case 'r': Imm |= RISCVFenceField::R; break; 560 case 'w': Imm |= RISCVFenceField::W; break; 561 } 562 } 563 Inst.addOperand(MCOperand::createImm(Imm)); 564 } 565 566 // Returns the rounding mode represented by this RISCVOperand. Should only 567 // be called after checking isFRMArg. 568 RISCVFPRndMode::RoundingMode getRoundingMode() const { 569 // isFRMArg has validated the operand, meaning this cast is safe. 570 auto SE = cast<MCSymbolRefExpr>(getImm()); 571 RISCVFPRndMode::RoundingMode FRM = 572 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 573 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 574 return FRM; 575 } 576 577 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 578 assert(N == 1 && "Invalid number of operands!"); 579 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 580 } 581 }; 582 } // end anonymous namespace. 583 584 #define GET_REGISTER_MATCHER 585 #define GET_MATCHER_IMPLEMENTATION 586 #include "RISCVGenAsmMatcher.inc" 587 588 // Return the matching FPR64 register for the given FPR32. 589 // FIXME: Ideally this function could be removed in favour of using 590 // information from TableGen. 591 unsigned convertFPR32ToFPR64(unsigned Reg) { 592 switch (Reg) { 593 default: 594 llvm_unreachable("Not a recognised FPR32 register"); 595 case RISCV::F0_32: return RISCV::F0_64; 596 case RISCV::F1_32: return RISCV::F1_64; 597 case RISCV::F2_32: return RISCV::F2_64; 598 case RISCV::F3_32: return RISCV::F3_64; 599 case RISCV::F4_32: return RISCV::F4_64; 600 case RISCV::F5_32: return RISCV::F5_64; 601 case RISCV::F6_32: return RISCV::F6_64; 602 case RISCV::F7_32: return RISCV::F7_64; 603 case RISCV::F8_32: return RISCV::F8_64; 604 case RISCV::F9_32: return RISCV::F9_64; 605 case RISCV::F10_32: return RISCV::F10_64; 606 case RISCV::F11_32: return RISCV::F11_64; 607 case RISCV::F12_32: return RISCV::F12_64; 608 case RISCV::F13_32: return RISCV::F13_64; 609 case RISCV::F14_32: return RISCV::F14_64; 610 case RISCV::F15_32: return RISCV::F15_64; 611 case RISCV::F16_32: return RISCV::F16_64; 612 case RISCV::F17_32: return RISCV::F17_64; 613 case RISCV::F18_32: return RISCV::F18_64; 614 case RISCV::F19_32: return RISCV::F19_64; 615 case RISCV::F20_32: return RISCV::F20_64; 616 case RISCV::F21_32: return RISCV::F21_64; 617 case RISCV::F22_32: return RISCV::F22_64; 618 case RISCV::F23_32: return RISCV::F23_64; 619 case RISCV::F24_32: return RISCV::F24_64; 620 case RISCV::F25_32: return RISCV::F25_64; 621 case RISCV::F26_32: return RISCV::F26_64; 622 case RISCV::F27_32: return RISCV::F27_64; 623 case RISCV::F28_32: return RISCV::F28_64; 624 case RISCV::F29_32: return RISCV::F29_64; 625 case RISCV::F30_32: return RISCV::F30_64; 626 case RISCV::F31_32: return RISCV::F31_64; 627 } 628 } 629 630 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 631 unsigned Kind) { 632 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 633 if (!Op.isReg()) 634 return Match_InvalidOperand; 635 636 unsigned Reg = Op.getReg(); 637 bool IsRegFPR32 = 638 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 639 bool IsRegFPR32C = 640 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 641 642 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 643 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 644 if ((IsRegFPR32 && Kind == MCK_FPR64) || 645 (IsRegFPR32C && Kind == MCK_FPR64C)) { 646 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 647 return Match_Success; 648 } 649 return Match_InvalidOperand; 650 } 651 652 bool RISCVAsmParser::generateImmOutOfRangeError( 653 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 654 Twine Msg = "immediate must be an integer in the range") { 655 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 656 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 657 } 658 659 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 660 OperandVector &Operands, 661 MCStreamer &Out, 662 uint64_t &ErrorInfo, 663 bool MatchingInlineAsm) { 664 MCInst Inst; 665 666 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 667 default: 668 break; 669 case Match_Success: 670 return processInstruction(Inst, IDLoc, Out); 671 case Match_MissingFeature: 672 return Error(IDLoc, "instruction use requires an option to be enabled"); 673 case Match_MnemonicFail: 674 return Error(IDLoc, "unrecognized instruction mnemonic"); 675 case Match_InvalidOperand: { 676 SMLoc ErrorLoc = IDLoc; 677 if (ErrorInfo != ~0U) { 678 if (ErrorInfo >= Operands.size()) 679 return Error(ErrorLoc, "too few operands for instruction"); 680 681 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 682 if (ErrorLoc == SMLoc()) 683 ErrorLoc = IDLoc; 684 } 685 return Error(ErrorLoc, "invalid operand for instruction"); 686 } 687 case Match_InvalidImmXLen: 688 if (isRV64()) { 689 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 690 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 691 } 692 return generateImmOutOfRangeError(Operands, ErrorInfo, 693 std::numeric_limits<int32_t>::min(), 694 std::numeric_limits<uint32_t>::max()); 695 case Match_InvalidUImmLog2XLen: 696 if (isRV64()) 697 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 698 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 699 case Match_InvalidUImmLog2XLenNonZero: 700 if (isRV64()) 701 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 702 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 703 case Match_InvalidUImm5: 704 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 705 case Match_InvalidSImm6: 706 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 707 (1 << 5) - 1); 708 case Match_InvalidSImm6NonZero: 709 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 710 (1 << 5) - 1, 711 "immediate must be non-zero in the range"); 712 case Match_InvalidCLUIImm: 713 return generateImmOutOfRangeError( 714 Operands, ErrorInfo, 1, (1 << 5) - 1, 715 "immediate must be in [0xfffe0, 0xfffff] or"); 716 case Match_InvalidUImm7Lsb00: 717 return generateImmOutOfRangeError( 718 Operands, ErrorInfo, 0, (1 << 7) - 4, 719 "immediate must be a multiple of 4 bytes in the range"); 720 case Match_InvalidUImm8Lsb00: 721 return generateImmOutOfRangeError( 722 Operands, ErrorInfo, 0, (1 << 8) - 4, 723 "immediate must be a multiple of 4 bytes in the range"); 724 case Match_InvalidUImm8Lsb000: 725 return generateImmOutOfRangeError( 726 Operands, ErrorInfo, 0, (1 << 8) - 8, 727 "immediate must be a multiple of 8 bytes in the range"); 728 case Match_InvalidSImm9Lsb0: 729 return generateImmOutOfRangeError( 730 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 731 "immediate must be a multiple of 2 bytes in the range"); 732 case Match_InvalidUImm9Lsb000: 733 return generateImmOutOfRangeError( 734 Operands, ErrorInfo, 0, (1 << 9) - 8, 735 "immediate must be a multiple of 8 bytes in the range"); 736 case Match_InvalidUImm10Lsb00NonZero: 737 return generateImmOutOfRangeError( 738 Operands, ErrorInfo, 4, (1 << 10) - 4, 739 "immediate must be a multiple of 4 bytes in the range"); 740 case Match_InvalidSImm10Lsb0000NonZero: 741 return generateImmOutOfRangeError( 742 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 743 "immediate must be a multiple of 16 bytes and non-zero in the range"); 744 case Match_InvalidSImm12: 745 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), 746 (1 << 11) - 1); 747 case Match_InvalidSImm12Lsb0: 748 return generateImmOutOfRangeError( 749 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 750 "immediate must be a multiple of 2 bytes in the range"); 751 case Match_InvalidUImm12: 752 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 753 case Match_InvalidSImm13Lsb0: 754 return generateImmOutOfRangeError( 755 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 756 "immediate must be a multiple of 2 bytes in the range"); 757 case Match_InvalidUImm20: 758 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); 759 case Match_InvalidSImm21Lsb0: 760 return generateImmOutOfRangeError( 761 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 762 "immediate must be a multiple of 2 bytes in the range"); 763 case Match_InvalidFenceArg: { 764 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 765 return Error( 766 ErrorLoc, 767 "operand must be formed of letters selected in-order from 'iorw'"); 768 } 769 case Match_InvalidFRMArg: { 770 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 771 return Error( 772 ErrorLoc, 773 "operand must be a valid floating point rounding mode mnemonic"); 774 } 775 case Match_InvalidBareSymbol: { 776 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 777 return Error(ErrorLoc, "operand must be a bare symbol name"); 778 } 779 } 780 781 llvm_unreachable("Unknown match type detected!"); 782 } 783 784 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 785 SMLoc &EndLoc) { 786 const AsmToken &Tok = getParser().getTok(); 787 StartLoc = Tok.getLoc(); 788 EndLoc = Tok.getEndLoc(); 789 RegNo = 0; 790 StringRef Name = getLexer().getTok().getIdentifier(); 791 792 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 793 getParser().Lex(); // Eat identifier token. 794 return false; 795 } 796 797 return Error(StartLoc, "invalid register name"); 798 } 799 800 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 801 bool AllowParens) { 802 SMLoc FirstS = getLoc(); 803 bool HadParens = false; 804 AsmToken Buf[2]; 805 806 // If this a parenthesised register name is allowed, parse it atomically 807 if (AllowParens && getLexer().is(AsmToken::LParen)) { 808 size_t ReadCount = getLexer().peekTokens(Buf); 809 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 810 HadParens = true; 811 getParser().Lex(); // Eat '(' 812 } 813 } 814 815 switch (getLexer().getKind()) { 816 default: 817 return MatchOperand_NoMatch; 818 case AsmToken::Identifier: 819 StringRef Name = getLexer().getTok().getIdentifier(); 820 unsigned RegNo = MatchRegisterName(Name); 821 if (RegNo == 0) { 822 RegNo = MatchRegisterAltName(Name); 823 if (RegNo == 0) { 824 if (HadParens) 825 getLexer().UnLex(Buf[0]); 826 return MatchOperand_NoMatch; 827 } 828 } 829 if (HadParens) 830 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 831 SMLoc S = getLoc(); 832 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 833 getLexer().Lex(); 834 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 835 } 836 837 if (HadParens) { 838 getParser().Lex(); // Eat ')' 839 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 840 } 841 842 return MatchOperand_Success; 843 } 844 845 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 846 SMLoc S = getLoc(); 847 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 848 const MCExpr *Res; 849 850 switch (getLexer().getKind()) { 851 default: 852 return MatchOperand_NoMatch; 853 case AsmToken::LParen: 854 case AsmToken::Minus: 855 case AsmToken::Plus: 856 case AsmToken::Integer: 857 case AsmToken::String: 858 if (getParser().parseExpression(Res)) 859 return MatchOperand_ParseFail; 860 break; 861 case AsmToken::Identifier: { 862 StringRef Identifier; 863 if (getParser().parseIdentifier(Identifier)) 864 return MatchOperand_ParseFail; 865 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 866 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 867 break; 868 } 869 case AsmToken::Percent: 870 return parseOperandWithModifier(Operands); 871 } 872 873 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 874 return MatchOperand_Success; 875 } 876 877 OperandMatchResultTy 878 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 879 SMLoc S = getLoc(); 880 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 881 882 if (getLexer().getKind() != AsmToken::Percent) { 883 Error(getLoc(), "expected '%' for operand modifier"); 884 return MatchOperand_ParseFail; 885 } 886 887 getParser().Lex(); // Eat '%' 888 889 if (getLexer().getKind() != AsmToken::Identifier) { 890 Error(getLoc(), "expected valid identifier for operand modifier"); 891 return MatchOperand_ParseFail; 892 } 893 StringRef Identifier = getParser().getTok().getIdentifier(); 894 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 895 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 896 Error(getLoc(), "unrecognized operand modifier"); 897 return MatchOperand_ParseFail; 898 } 899 900 getParser().Lex(); // Eat the identifier 901 if (getLexer().getKind() != AsmToken::LParen) { 902 Error(getLoc(), "expected '('"); 903 return MatchOperand_ParseFail; 904 } 905 getParser().Lex(); // Eat '(' 906 907 const MCExpr *SubExpr; 908 if (getParser().parseParenExpression(SubExpr, E)) { 909 return MatchOperand_ParseFail; 910 } 911 912 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 913 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 914 return MatchOperand_Success; 915 } 916 917 OperandMatchResultTy 918 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 919 if (getLexer().isNot(AsmToken::LParen)) { 920 Error(getLoc(), "expected '('"); 921 return MatchOperand_ParseFail; 922 } 923 924 getParser().Lex(); // Eat '(' 925 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 926 927 if (parseRegister(Operands) != MatchOperand_Success) { 928 Error(getLoc(), "expected register"); 929 return MatchOperand_ParseFail; 930 } 931 932 if (getLexer().isNot(AsmToken::RParen)) { 933 Error(getLoc(), "expected ')'"); 934 return MatchOperand_ParseFail; 935 } 936 937 getParser().Lex(); // Eat ')' 938 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 939 940 return MatchOperand_Success; 941 } 942 943 /// Looks at a token type and creates the relevant operand from this 944 /// information, adding to Operands. If operand was parsed, returns false, else 945 /// true. If ForceImmediate is true, no attempt will be made to parse the 946 /// operand as a register, which is needed for pseudoinstructions such as 947 /// call. 948 bool RISCVAsmParser::parseOperand(OperandVector &Operands, 949 bool ForceImmediate) { 950 // Attempt to parse token as register, unless ForceImmediate. 951 if (!ForceImmediate && parseRegister(Operands, true) == MatchOperand_Success) 952 return false; 953 954 // Attempt to parse token as an immediate 955 if (parseImmediate(Operands) == MatchOperand_Success) { 956 // Parse memory base register if present 957 if (getLexer().is(AsmToken::LParen)) 958 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 959 return false; 960 } 961 962 // Finally we have exhausted all options and must declare defeat. 963 Error(getLoc(), "unknown operand"); 964 return true; 965 } 966 967 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 968 StringRef Name, SMLoc NameLoc, 969 OperandVector &Operands) { 970 // First operand is token for instruction 971 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 972 973 // If there are no more operands, then finish 974 if (getLexer().is(AsmToken::EndOfStatement)) 975 return false; 976 977 // Parse first operand 978 bool ForceImmediate = (Name == "call" || Name == "tail"); 979 if (parseOperand(Operands, ForceImmediate)) 980 return true; 981 982 // Parse until end of statement, consuming commas between operands 983 while (getLexer().is(AsmToken::Comma)) { 984 // Consume comma token 985 getLexer().Lex(); 986 987 // Parse next operand 988 if (parseOperand(Operands, false)) 989 return true; 990 } 991 992 if (getLexer().isNot(AsmToken::EndOfStatement)) { 993 SMLoc Loc = getLexer().getLoc(); 994 getParser().eatToEndOfStatement(); 995 return Error(Loc, "unexpected token"); 996 } 997 998 getParser().Lex(); // Consume the EndOfStatement. 999 return false; 1000 } 1001 1002 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1003 RISCVMCExpr::VariantKind &Kind, 1004 int64_t &Addend) { 1005 Kind = RISCVMCExpr::VK_RISCV_None; 1006 Addend = 0; 1007 1008 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1009 Kind = RE->getKind(); 1010 Expr = RE->getSubExpr(); 1011 } 1012 1013 // It's a simple symbol reference or constant with no addend. 1014 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1015 return true; 1016 1017 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1018 if (!BE) 1019 return false; 1020 1021 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1022 return false; 1023 1024 if (BE->getOpcode() != MCBinaryExpr::Add && 1025 BE->getOpcode() != MCBinaryExpr::Sub) 1026 return false; 1027 1028 // We are able to support the subtraction of two symbol references 1029 if (BE->getOpcode() == MCBinaryExpr::Sub && 1030 isa<MCSymbolRefExpr>(BE->getRHS())) 1031 return true; 1032 1033 // See if the addend is a constant, otherwise there's more going 1034 // on here than we can deal with. 1035 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1036 if (!AddendExpr) 1037 return false; 1038 1039 Addend = AddendExpr->getValue(); 1040 if (BE->getOpcode() == MCBinaryExpr::Sub) 1041 Addend = -Addend; 1042 1043 // It's some symbol reference + a constant addend 1044 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1045 } 1046 1047 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1048 // This returns false if this function recognizes the directive 1049 // regardless of whether it is successfully handles or reports an 1050 // error. Otherwise it returns true to give the generic parser a 1051 // chance at recognizing it. 1052 StringRef IDVal = DirectiveID.getString(); 1053 1054 if (IDVal == ".option") 1055 return parseDirectiveOption(); 1056 1057 return true; 1058 } 1059 1060 bool RISCVAsmParser::parseDirectiveOption() { 1061 MCAsmParser &Parser = getParser(); 1062 // Get the option token. 1063 AsmToken Tok = Parser.getTok(); 1064 // At the moment only identifiers are supported. 1065 if (Tok.isNot(AsmToken::Identifier)) 1066 return Error(Parser.getTok().getLoc(), 1067 "unexpected token, expected identifier"); 1068 1069 StringRef Option = Tok.getIdentifier(); 1070 1071 if (Option == "rvc") { 1072 getTargetStreamer().emitDirectiveOptionRVC(); 1073 1074 Parser.Lex(); 1075 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1076 return Error(Parser.getTok().getLoc(), 1077 "unexpected token, expected end of statement"); 1078 1079 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1080 return false; 1081 } 1082 1083 if (Option == "norvc") { 1084 getTargetStreamer().emitDirectiveOptionNoRVC(); 1085 1086 Parser.Lex(); 1087 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1088 return Error(Parser.getTok().getLoc(), 1089 "unexpected token, expected end of statement"); 1090 1091 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1092 return false; 1093 } 1094 1095 // Unknown option. 1096 Warning(Parser.getTok().getLoc(), 1097 "unknown option, expected 'rvc' or 'norvc'"); 1098 Parser.eatToEndOfStatement(); 1099 return false; 1100 } 1101 1102 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1103 MCInst CInst; 1104 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1105 CInst.setLoc(Inst.getLoc()); 1106 S.EmitInstruction((Res ? CInst : Inst), getSTI()); 1107 } 1108 1109 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value, 1110 MCStreamer &Out) { 1111 if (isInt<32>(Value)) { 1112 // Emits the MC instructions for loading a 32-bit constant into a register. 1113 // 1114 // Depending on the active bits in the immediate Value v, the following 1115 // instruction sequences are emitted: 1116 // 1117 // v == 0 : ADDI(W) 1118 // v[0,12) != 0 && v[12,32) == 0 : ADDI(W) 1119 // v[0,12) == 0 && v[12,32) != 0 : LUI 1120 // v[0,32) != 0 : LUI+ADDI(W) 1121 // 1122 int64_t Hi20 = ((Value + 0x800) >> 12) & 0xFFFFF; 1123 int64_t Lo12 = SignExtend64<12>(Value); 1124 unsigned SrcReg = RISCV::X0; 1125 1126 if (Hi20) { 1127 emitToStreamer(Out, 1128 MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Hi20)); 1129 SrcReg = DestReg; 1130 } 1131 1132 if (Lo12 || Hi20 == 0) { 1133 unsigned AddiOpcode = 1134 STI->hasFeature(RISCV::Feature64Bit) ? RISCV::ADDIW : RISCV::ADDI; 1135 emitToStreamer(Out, MCInstBuilder(AddiOpcode) 1136 .addReg(DestReg) 1137 .addReg(SrcReg) 1138 .addImm(Lo12)); 1139 } 1140 return; 1141 } 1142 assert(STI->hasFeature(RISCV::Feature64Bit) && 1143 "Target must be 64-bit to support a >32-bit constant"); 1144 1145 // In the worst case, for a full 64-bit constant, a sequence of 8 instructions 1146 // (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note 1147 // that the first two instructions (LUI+ADDIW) can contribute up to 32 bits 1148 // while the following ADDI instructions contribute up to 12 bits each. 1149 // 1150 // On the first glance, implementing this seems to be possible by simply 1151 // emitting the most significant 32 bits (LUI+ADDIW) followed by as many left 1152 // shift (SLLI) and immediate additions (ADDI) as needed. However, due to the 1153 // fact that ADDI performs a sign extended addition, doing it like that would 1154 // only be possible when at most 11 bits of the ADDI instructions are used. 1155 // Using all 12 bits of the ADDI instructions, like done by GAS, actually 1156 // requires that the constant is processed starting with the least significant 1157 // bit. 1158 // 1159 // In the following, constants are processed from LSB to MSB but instruction 1160 // emission is performed from MSB to LSB by recursively calling 1161 // emitLoadImm. In each recursion, first the lowest 12 bits are removed 1162 // from the constant and the optimal shift amount, which can be greater than 1163 // 12 bits if the constant is sparse, is determined. Then, the shifted 1164 // remaining constant is processed recursively and gets emitted as soon as it 1165 // fits into 32 bits. The emission of the shifts and additions is subsequently 1166 // performed when the recursion returns. 1167 // 1168 int64_t Lo12 = SignExtend64<12>(Value); 1169 int64_t Hi52 = (Value + 0x800) >> 12; 1170 int ShiftAmount = 12 + findFirstSet((uint64_t)Hi52); 1171 Hi52 = SignExtend64(Hi52 >> (ShiftAmount - 12), 64 - ShiftAmount); 1172 1173 emitLoadImm(DestReg, Hi52, Out); 1174 1175 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 1176 .addReg(DestReg) 1177 .addReg(DestReg) 1178 .addImm(ShiftAmount)); 1179 1180 if (Lo12) 1181 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1182 .addReg(DestReg) 1183 .addReg(DestReg) 1184 .addImm(Lo12)); 1185 } 1186 1187 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1188 MCStreamer &Out) { 1189 Inst.setLoc(IDLoc); 1190 1191 if (Inst.getOpcode() == RISCV::PseudoLI) { 1192 auto Reg = Inst.getOperand(0).getReg(); 1193 int64_t Imm = Inst.getOperand(1).getImm(); 1194 // On RV32 the immediate here can either be a signed or an unsigned 1195 // 32-bit number. Sign extension has to be performed to ensure that Imm 1196 // represents the expected signed 64-bit number. 1197 if (!isRV64()) 1198 Imm = SignExtend64<32>(Imm); 1199 emitLoadImm(Reg, Imm, Out); 1200 return false; 1201 } 1202 1203 emitToStreamer(Out, Inst); 1204 return false; 1205 } 1206 1207 extern "C" void LLVMInitializeRISCVAsmParser() { 1208 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 1209 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 1210 } 1211