1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/RISCVAsmBackend.h" 10 #include "MCTargetDesc/RISCVMCExpr.h" 11 #include "MCTargetDesc/RISCVMCTargetDesc.h" 12 #include "MCTargetDesc/RISCVTargetStreamer.h" 13 #include "TargetInfo/RISCVTargetInfo.h" 14 #include "Utils/RISCVBaseInfo.h" 15 #include "Utils/RISCVMatInt.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/MC/MCAssembler.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstBuilder.h" 24 #include "llvm/MC/MCObjectFileInfo.h" 25 #include "llvm/MC/MCParser/MCAsmLexer.h" 26 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 27 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 28 #include "llvm/MC/MCRegisterInfo.h" 29 #include "llvm/MC/MCStreamer.h" 30 #include "llvm/MC/MCSubtargetInfo.h" 31 #include "llvm/Support/Casting.h" 32 #include "llvm/Support/MathExtras.h" 33 #include "llvm/Support/TargetRegistry.h" 34 35 #include <limits> 36 37 using namespace llvm; 38 39 // Include the auto-generated portion of the compress emitter. 40 #define GEN_COMPRESS_INSTR 41 #include "RISCVGenCompressInstEmitter.inc" 42 43 namespace { 44 struct RISCVOperand; 45 46 class RISCVAsmParser : public MCTargetAsmParser { 47 SmallVector<FeatureBitset, 4> FeatureBitStack; 48 49 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 50 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 51 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); } 52 53 RISCVTargetStreamer &getTargetStreamer() { 54 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 55 return static_cast<RISCVTargetStreamer &>(TS); 56 } 57 58 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 59 unsigned Kind) override; 60 61 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 62 int64_t Lower, int64_t Upper, Twine Msg); 63 64 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 65 OperandVector &Operands, MCStreamer &Out, 66 uint64_t &ErrorInfo, 67 bool MatchingInlineAsm) override; 68 69 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 70 71 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 72 SMLoc NameLoc, OperandVector &Operands) override; 73 74 bool ParseDirective(AsmToken DirectiveID) override; 75 76 // Helper to actually emit an instruction to the MCStreamer. Also, when 77 // possible, compression of the instruction is performed. 78 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 79 80 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 81 // synthesize the desired immedate value into the destination register. 82 void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out); 83 84 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 85 // helpers such as emitLoadLocalAddress and emitLoadAddress. 86 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 87 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 88 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 89 90 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 91 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 92 93 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 94 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 95 96 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 97 // addressing. 98 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 99 100 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 101 // addressing. 102 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 103 104 // Helper to emit pseudo load/store instruction with a symbol. 105 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 106 MCStreamer &Out, bool HasTmpReg); 107 108 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 109 // Enforcing this using a restricted register class for the second input 110 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 111 // 'add' is an overloaded mnemonic. 112 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 113 114 /// Helper for processing MC instructions that have been successfully matched 115 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 116 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 117 /// in this method. 118 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 119 MCStreamer &Out); 120 121 // Auto-generated instruction matching functions 122 #define GET_ASSEMBLER_HEADER 123 #include "RISCVGenAsmMatcher.inc" 124 125 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 126 OperandMatchResultTy parseImmediate(OperandVector &Operands); 127 OperandMatchResultTy parseRegister(OperandVector &Operands, 128 bool AllowParens = false); 129 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 130 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); 131 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 132 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 133 OperandMatchResultTy parseCallSymbol(OperandVector &Operands); 134 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 135 136 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 137 138 bool parseDirectiveOption(); 139 140 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 141 if (!(getSTI().getFeatureBits()[Feature])) { 142 MCSubtargetInfo &STI = copySTI(); 143 setAvailableFeatures( 144 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 145 } 146 } 147 148 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 149 if (getSTI().getFeatureBits()[Feature]) { 150 MCSubtargetInfo &STI = copySTI(); 151 setAvailableFeatures( 152 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 153 } 154 } 155 156 void pushFeatureBits() { 157 FeatureBitStack.push_back(getSTI().getFeatureBits()); 158 } 159 160 bool popFeatureBits() { 161 if (FeatureBitStack.empty()) 162 return true; 163 164 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 165 copySTI().setFeatureBits(FeatureBits); 166 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 167 168 return false; 169 } 170 public: 171 enum RISCVMatchResultTy { 172 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 173 #define GET_OPERAND_DIAGNOSTIC_TYPES 174 #include "RISCVGenAsmMatcher.inc" 175 #undef GET_OPERAND_DIAGNOSTIC_TYPES 176 }; 177 178 static bool classifySymbolRef(const MCExpr *Expr, 179 RISCVMCExpr::VariantKind &Kind, 180 int64_t &Addend); 181 182 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 183 const MCInstrInfo &MII, const MCTargetOptions &Options) 184 : MCTargetAsmParser(Options, STI, MII) { 185 Parser.addAliasForDirective(".half", ".2byte"); 186 Parser.addAliasForDirective(".hword", ".2byte"); 187 Parser.addAliasForDirective(".word", ".4byte"); 188 Parser.addAliasForDirective(".dword", ".8byte"); 189 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 190 } 191 }; 192 193 /// RISCVOperand - Instances of this class represent a parsed machine 194 /// instruction 195 struct RISCVOperand : public MCParsedAsmOperand { 196 197 enum KindTy { 198 Token, 199 Register, 200 Immediate, 201 SystemRegister 202 } Kind; 203 204 bool IsRV64; 205 206 struct RegOp { 207 unsigned RegNum; 208 }; 209 210 struct ImmOp { 211 const MCExpr *Val; 212 }; 213 214 struct SysRegOp { 215 const char *Data; 216 unsigned Length; 217 unsigned Encoding; 218 // FIXME: Add the Encoding parsed fields as needed for checks, 219 // e.g.: read/write or user/supervisor/machine privileges. 220 }; 221 222 SMLoc StartLoc, EndLoc; 223 union { 224 StringRef Tok; 225 RegOp Reg; 226 ImmOp Imm; 227 struct SysRegOp SysReg; 228 }; 229 230 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 231 232 public: 233 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 234 Kind = o.Kind; 235 IsRV64 = o.IsRV64; 236 StartLoc = o.StartLoc; 237 EndLoc = o.EndLoc; 238 switch (Kind) { 239 case Register: 240 Reg = o.Reg; 241 break; 242 case Immediate: 243 Imm = o.Imm; 244 break; 245 case Token: 246 Tok = o.Tok; 247 break; 248 case SystemRegister: 249 SysReg = o.SysReg; 250 break; 251 } 252 } 253 254 bool isToken() const override { return Kind == Token; } 255 bool isReg() const override { return Kind == Register; } 256 bool isImm() const override { return Kind == Immediate; } 257 bool isMem() const override { return false; } 258 bool isSystemRegister() const { return Kind == SystemRegister; } 259 260 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 261 RISCVMCExpr::VariantKind &VK) { 262 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 263 VK = RE->getKind(); 264 return RE->evaluateAsConstant(Imm); 265 } 266 267 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 268 VK = RISCVMCExpr::VK_RISCV_None; 269 Imm = CE->getValue(); 270 return true; 271 } 272 273 return false; 274 } 275 276 // True if operand is a symbol with no modifiers, or a constant with no 277 // modifiers and isShiftedInt<N-1, 1>(Op). 278 template <int N> bool isBareSimmNLsb0() const { 279 int64_t Imm; 280 RISCVMCExpr::VariantKind VK; 281 if (!isImm()) 282 return false; 283 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 284 bool IsValid; 285 if (!IsConstantImm) 286 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 287 else 288 IsValid = isShiftedInt<N - 1, 1>(Imm); 289 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 290 } 291 292 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 293 294 bool isBareSymbol() const { 295 int64_t Imm; 296 RISCVMCExpr::VariantKind VK; 297 // Must be of 'immediate' type but not a constant. 298 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 299 return false; 300 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 301 VK == RISCVMCExpr::VK_RISCV_None; 302 } 303 304 bool isCallSymbol() const { 305 int64_t Imm; 306 RISCVMCExpr::VariantKind VK; 307 // Must be of 'immediate' type but not a constant. 308 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 309 return false; 310 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 311 (VK == RISCVMCExpr::VK_RISCV_CALL || 312 VK == RISCVMCExpr::VK_RISCV_CALL_PLT); 313 } 314 315 bool isTPRelAddSymbol() const { 316 int64_t Imm; 317 RISCVMCExpr::VariantKind VK; 318 // Must be of 'immediate' type but not a constant. 319 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 320 return false; 321 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 322 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; 323 } 324 325 bool isCSRSystemRegister() const { return isSystemRegister(); } 326 327 /// Return true if the operand is a valid for the fence instruction e.g. 328 /// ('iorw'). 329 bool isFenceArg() const { 330 if (!isImm()) 331 return false; 332 const MCExpr *Val = getImm(); 333 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 334 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 335 return false; 336 337 StringRef Str = SVal->getSymbol().getName(); 338 // Letters must be unique, taken from 'iorw', and in ascending order. This 339 // holds as long as each individual character is one of 'iorw' and is 340 // greater than the previous character. 341 char Prev = '\0'; 342 for (char c : Str) { 343 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 344 return false; 345 if (c <= Prev) 346 return false; 347 Prev = c; 348 } 349 return true; 350 } 351 352 /// Return true if the operand is a valid floating point rounding mode. 353 bool isFRMArg() const { 354 if (!isImm()) 355 return false; 356 const MCExpr *Val = getImm(); 357 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 358 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 359 return false; 360 361 StringRef Str = SVal->getSymbol().getName(); 362 363 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 364 } 365 366 bool isImmXLenLI() const { 367 int64_t Imm; 368 RISCVMCExpr::VariantKind VK; 369 if (!isImm()) 370 return false; 371 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 372 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) 373 return true; 374 // Given only Imm, ensuring that the actually specified constant is either 375 // a signed or unsigned 64-bit number is unfortunately impossible. 376 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); 377 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None; 378 } 379 380 bool isUImmLog2XLen() const { 381 int64_t Imm; 382 RISCVMCExpr::VariantKind VK; 383 if (!isImm()) 384 return false; 385 if (!evaluateConstantImm(getImm(), Imm, VK) || 386 VK != RISCVMCExpr::VK_RISCV_None) 387 return false; 388 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 389 } 390 391 bool isUImmLog2XLenNonZero() const { 392 int64_t Imm; 393 RISCVMCExpr::VariantKind VK; 394 if (!isImm()) 395 return false; 396 if (!evaluateConstantImm(getImm(), Imm, VK) || 397 VK != RISCVMCExpr::VK_RISCV_None) 398 return false; 399 if (Imm == 0) 400 return false; 401 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 402 } 403 404 bool isUImm5() const { 405 int64_t Imm; 406 RISCVMCExpr::VariantKind VK; 407 if (!isImm()) 408 return false; 409 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 410 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 411 } 412 413 bool isUImm5NonZero() const { 414 int64_t Imm; 415 RISCVMCExpr::VariantKind VK; 416 if (!isImm()) 417 return false; 418 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 419 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 420 VK == RISCVMCExpr::VK_RISCV_None; 421 } 422 423 bool isSImm6() const { 424 if (!isImm()) 425 return false; 426 RISCVMCExpr::VariantKind VK; 427 int64_t Imm; 428 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 429 return IsConstantImm && isInt<6>(Imm) && 430 VK == RISCVMCExpr::VK_RISCV_None; 431 } 432 433 bool isSImm6NonZero() const { 434 if (!isImm()) 435 return false; 436 RISCVMCExpr::VariantKind VK; 437 int64_t Imm; 438 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 439 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 440 VK == RISCVMCExpr::VK_RISCV_None; 441 } 442 443 bool isCLUIImm() const { 444 if (!isImm()) 445 return false; 446 int64_t Imm; 447 RISCVMCExpr::VariantKind VK; 448 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 449 return IsConstantImm && (Imm != 0) && 450 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 451 VK == RISCVMCExpr::VK_RISCV_None; 452 } 453 454 bool isUImm7Lsb00() const { 455 if (!isImm()) 456 return false; 457 int64_t Imm; 458 RISCVMCExpr::VariantKind VK; 459 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 460 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 461 VK == RISCVMCExpr::VK_RISCV_None; 462 } 463 464 bool isUImm8Lsb00() const { 465 if (!isImm()) 466 return false; 467 int64_t Imm; 468 RISCVMCExpr::VariantKind VK; 469 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 470 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 471 VK == RISCVMCExpr::VK_RISCV_None; 472 } 473 474 bool isUImm8Lsb000() const { 475 if (!isImm()) 476 return false; 477 int64_t Imm; 478 RISCVMCExpr::VariantKind VK; 479 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 480 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 481 VK == RISCVMCExpr::VK_RISCV_None; 482 } 483 484 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 485 486 bool isUImm9Lsb000() const { 487 if (!isImm()) 488 return false; 489 int64_t Imm; 490 RISCVMCExpr::VariantKind VK; 491 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 492 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 493 VK == RISCVMCExpr::VK_RISCV_None; 494 } 495 496 bool isUImm10Lsb00NonZero() const { 497 if (!isImm()) 498 return false; 499 int64_t Imm; 500 RISCVMCExpr::VariantKind VK; 501 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 502 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 503 VK == RISCVMCExpr::VK_RISCV_None; 504 } 505 506 bool isSImm12() const { 507 RISCVMCExpr::VariantKind VK; 508 int64_t Imm; 509 bool IsValid; 510 if (!isImm()) 511 return false; 512 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 513 if (!IsConstantImm) 514 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 515 else 516 IsValid = isInt<12>(Imm); 517 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 518 VK == RISCVMCExpr::VK_RISCV_LO || 519 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 520 VK == RISCVMCExpr::VK_RISCV_TPREL_LO); 521 } 522 523 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 524 525 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 526 527 bool isSImm10Lsb0000NonZero() const { 528 if (!isImm()) 529 return false; 530 int64_t Imm; 531 RISCVMCExpr::VariantKind VK; 532 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 533 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 534 VK == RISCVMCExpr::VK_RISCV_None; 535 } 536 537 bool isUImm20LUI() const { 538 RISCVMCExpr::VariantKind VK; 539 int64_t Imm; 540 bool IsValid; 541 if (!isImm()) 542 return false; 543 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 544 if (!IsConstantImm) { 545 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 546 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI || 547 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 548 } else { 549 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 550 VK == RISCVMCExpr::VK_RISCV_HI || 551 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 552 } 553 } 554 555 bool isUImm20AUIPC() const { 556 RISCVMCExpr::VariantKind VK; 557 int64_t Imm; 558 bool IsValid; 559 if (!isImm()) 560 return false; 561 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 562 if (!IsConstantImm) { 563 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 564 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 565 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 566 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 567 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 568 } else { 569 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 570 VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 571 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 572 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 573 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 574 } 575 } 576 577 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 578 579 bool isImmZero() const { 580 if (!isImm()) 581 return false; 582 int64_t Imm; 583 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 584 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 585 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; 586 } 587 588 /// getStartLoc - Gets location of the first token of this operand 589 SMLoc getStartLoc() const override { return StartLoc; } 590 /// getEndLoc - Gets location of the last token of this operand 591 SMLoc getEndLoc() const override { return EndLoc; } 592 /// True if this operand is for an RV64 instruction 593 bool isRV64() const { return IsRV64; } 594 595 unsigned getReg() const override { 596 assert(Kind == Register && "Invalid type access!"); 597 return Reg.RegNum; 598 } 599 600 StringRef getSysReg() const { 601 assert(Kind == SystemRegister && "Invalid access!"); 602 return StringRef(SysReg.Data, SysReg.Length); 603 } 604 605 const MCExpr *getImm() const { 606 assert(Kind == Immediate && "Invalid type access!"); 607 return Imm.Val; 608 } 609 610 StringRef getToken() const { 611 assert(Kind == Token && "Invalid type access!"); 612 return Tok; 613 } 614 615 void print(raw_ostream &OS) const override { 616 switch (Kind) { 617 case Immediate: 618 OS << *getImm(); 619 break; 620 case Register: 621 OS << "<register x"; 622 OS << getReg() << ">"; 623 break; 624 case Token: 625 OS << "'" << getToken() << "'"; 626 break; 627 case SystemRegister: 628 OS << "<sysreg: " << getSysReg() << '>'; 629 break; 630 } 631 } 632 633 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 634 bool IsRV64) { 635 auto Op = make_unique<RISCVOperand>(Token); 636 Op->Tok = Str; 637 Op->StartLoc = S; 638 Op->EndLoc = S; 639 Op->IsRV64 = IsRV64; 640 return Op; 641 } 642 643 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 644 SMLoc E, bool IsRV64) { 645 auto Op = make_unique<RISCVOperand>(Register); 646 Op->Reg.RegNum = RegNo; 647 Op->StartLoc = S; 648 Op->EndLoc = E; 649 Op->IsRV64 = IsRV64; 650 return Op; 651 } 652 653 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 654 SMLoc E, bool IsRV64) { 655 auto Op = make_unique<RISCVOperand>(Immediate); 656 Op->Imm.Val = Val; 657 Op->StartLoc = S; 658 Op->EndLoc = E; 659 Op->IsRV64 = IsRV64; 660 return Op; 661 } 662 663 static std::unique_ptr<RISCVOperand> 664 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 665 auto Op = make_unique<RISCVOperand>(SystemRegister); 666 Op->SysReg.Data = Str.data(); 667 Op->SysReg.Length = Str.size(); 668 Op->SysReg.Encoding = Encoding; 669 Op->StartLoc = S; 670 Op->IsRV64 = IsRV64; 671 return Op; 672 } 673 674 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 675 assert(Expr && "Expr shouldn't be null!"); 676 int64_t Imm = 0; 677 RISCVMCExpr::VariantKind VK; 678 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 679 680 if (IsConstant) 681 Inst.addOperand(MCOperand::createImm(Imm)); 682 else 683 Inst.addOperand(MCOperand::createExpr(Expr)); 684 } 685 686 // Used by the TableGen Code 687 void addRegOperands(MCInst &Inst, unsigned N) const { 688 assert(N == 1 && "Invalid number of operands!"); 689 Inst.addOperand(MCOperand::createReg(getReg())); 690 } 691 692 void addImmOperands(MCInst &Inst, unsigned N) const { 693 assert(N == 1 && "Invalid number of operands!"); 694 addExpr(Inst, getImm()); 695 } 696 697 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 698 assert(N == 1 && "Invalid number of operands!"); 699 // isFenceArg has validated the operand, meaning this cast is safe 700 auto SE = cast<MCSymbolRefExpr>(getImm()); 701 702 unsigned Imm = 0; 703 for (char c : SE->getSymbol().getName()) { 704 switch (c) { 705 default: 706 llvm_unreachable("FenceArg must contain only [iorw]"); 707 case 'i': Imm |= RISCVFenceField::I; break; 708 case 'o': Imm |= RISCVFenceField::O; break; 709 case 'r': Imm |= RISCVFenceField::R; break; 710 case 'w': Imm |= RISCVFenceField::W; break; 711 } 712 } 713 Inst.addOperand(MCOperand::createImm(Imm)); 714 } 715 716 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 717 assert(N == 1 && "Invalid number of operands!"); 718 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 719 } 720 721 // Returns the rounding mode represented by this RISCVOperand. Should only 722 // be called after checking isFRMArg. 723 RISCVFPRndMode::RoundingMode getRoundingMode() const { 724 // isFRMArg has validated the operand, meaning this cast is safe. 725 auto SE = cast<MCSymbolRefExpr>(getImm()); 726 RISCVFPRndMode::RoundingMode FRM = 727 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 728 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 729 return FRM; 730 } 731 732 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 733 assert(N == 1 && "Invalid number of operands!"); 734 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 735 } 736 }; 737 } // end anonymous namespace. 738 739 #define GET_REGISTER_MATCHER 740 #define GET_MATCHER_IMPLEMENTATION 741 #include "RISCVGenAsmMatcher.inc" 742 743 // Return the matching FPR64 register for the given FPR32. 744 // FIXME: Ideally this function could be removed in favour of using 745 // information from TableGen. 746 unsigned convertFPR32ToFPR64(unsigned Reg) { 747 switch (Reg) { 748 default: 749 llvm_unreachable("Not a recognised FPR32 register"); 750 case RISCV::F0_32: return RISCV::F0_64; 751 case RISCV::F1_32: return RISCV::F1_64; 752 case RISCV::F2_32: return RISCV::F2_64; 753 case RISCV::F3_32: return RISCV::F3_64; 754 case RISCV::F4_32: return RISCV::F4_64; 755 case RISCV::F5_32: return RISCV::F5_64; 756 case RISCV::F6_32: return RISCV::F6_64; 757 case RISCV::F7_32: return RISCV::F7_64; 758 case RISCV::F8_32: return RISCV::F8_64; 759 case RISCV::F9_32: return RISCV::F9_64; 760 case RISCV::F10_32: return RISCV::F10_64; 761 case RISCV::F11_32: return RISCV::F11_64; 762 case RISCV::F12_32: return RISCV::F12_64; 763 case RISCV::F13_32: return RISCV::F13_64; 764 case RISCV::F14_32: return RISCV::F14_64; 765 case RISCV::F15_32: return RISCV::F15_64; 766 case RISCV::F16_32: return RISCV::F16_64; 767 case RISCV::F17_32: return RISCV::F17_64; 768 case RISCV::F18_32: return RISCV::F18_64; 769 case RISCV::F19_32: return RISCV::F19_64; 770 case RISCV::F20_32: return RISCV::F20_64; 771 case RISCV::F21_32: return RISCV::F21_64; 772 case RISCV::F22_32: return RISCV::F22_64; 773 case RISCV::F23_32: return RISCV::F23_64; 774 case RISCV::F24_32: return RISCV::F24_64; 775 case RISCV::F25_32: return RISCV::F25_64; 776 case RISCV::F26_32: return RISCV::F26_64; 777 case RISCV::F27_32: return RISCV::F27_64; 778 case RISCV::F28_32: return RISCV::F28_64; 779 case RISCV::F29_32: return RISCV::F29_64; 780 case RISCV::F30_32: return RISCV::F30_64; 781 case RISCV::F31_32: return RISCV::F31_64; 782 } 783 } 784 785 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 786 unsigned Kind) { 787 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 788 if (!Op.isReg()) 789 return Match_InvalidOperand; 790 791 unsigned Reg = Op.getReg(); 792 bool IsRegFPR32 = 793 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 794 bool IsRegFPR32C = 795 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 796 797 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 798 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 799 if ((IsRegFPR32 && Kind == MCK_FPR64) || 800 (IsRegFPR32C && Kind == MCK_FPR64C)) { 801 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 802 return Match_Success; 803 } 804 return Match_InvalidOperand; 805 } 806 807 bool RISCVAsmParser::generateImmOutOfRangeError( 808 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 809 Twine Msg = "immediate must be an integer in the range") { 810 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 811 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 812 } 813 814 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 815 OperandVector &Operands, 816 MCStreamer &Out, 817 uint64_t &ErrorInfo, 818 bool MatchingInlineAsm) { 819 MCInst Inst; 820 821 auto Result = 822 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 823 switch (Result) { 824 default: 825 break; 826 case Match_Success: 827 return processInstruction(Inst, IDLoc, Operands, Out); 828 case Match_MissingFeature: 829 return Error(IDLoc, "instruction use requires an option to be enabled"); 830 case Match_MnemonicFail: 831 return Error(IDLoc, "unrecognized instruction mnemonic"); 832 case Match_InvalidOperand: { 833 SMLoc ErrorLoc = IDLoc; 834 if (ErrorInfo != ~0U) { 835 if (ErrorInfo >= Operands.size()) 836 return Error(ErrorLoc, "too few operands for instruction"); 837 838 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 839 if (ErrorLoc == SMLoc()) 840 ErrorLoc = IDLoc; 841 } 842 return Error(ErrorLoc, "invalid operand for instruction"); 843 } 844 } 845 846 // Handle the case when the error message is of specific type 847 // other than the generic Match_InvalidOperand, and the 848 // corresponding operand is missing. 849 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 850 SMLoc ErrorLoc = IDLoc; 851 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 852 return Error(ErrorLoc, "too few operands for instruction"); 853 } 854 855 switch(Result) { 856 default: 857 break; 858 case Match_InvalidImmXLenLI: 859 if (isRV64()) { 860 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 861 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 862 } 863 return generateImmOutOfRangeError(Operands, ErrorInfo, 864 std::numeric_limits<int32_t>::min(), 865 std::numeric_limits<uint32_t>::max()); 866 case Match_InvalidUImmLog2XLen: 867 if (isRV64()) 868 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 869 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 870 case Match_InvalidUImmLog2XLenNonZero: 871 if (isRV64()) 872 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 873 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 874 case Match_InvalidUImm5: 875 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 876 case Match_InvalidSImm6: 877 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 878 (1 << 5) - 1); 879 case Match_InvalidSImm6NonZero: 880 return generateImmOutOfRangeError( 881 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 882 "immediate must be non-zero in the range"); 883 case Match_InvalidCLUIImm: 884 return generateImmOutOfRangeError( 885 Operands, ErrorInfo, 1, (1 << 5) - 1, 886 "immediate must be in [0xfffe0, 0xfffff] or"); 887 case Match_InvalidUImm7Lsb00: 888 return generateImmOutOfRangeError( 889 Operands, ErrorInfo, 0, (1 << 7) - 4, 890 "immediate must be a multiple of 4 bytes in the range"); 891 case Match_InvalidUImm8Lsb00: 892 return generateImmOutOfRangeError( 893 Operands, ErrorInfo, 0, (1 << 8) - 4, 894 "immediate must be a multiple of 4 bytes in the range"); 895 case Match_InvalidUImm8Lsb000: 896 return generateImmOutOfRangeError( 897 Operands, ErrorInfo, 0, (1 << 8) - 8, 898 "immediate must be a multiple of 8 bytes in the range"); 899 case Match_InvalidSImm9Lsb0: 900 return generateImmOutOfRangeError( 901 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 902 "immediate must be a multiple of 2 bytes in the range"); 903 case Match_InvalidUImm9Lsb000: 904 return generateImmOutOfRangeError( 905 Operands, ErrorInfo, 0, (1 << 9) - 8, 906 "immediate must be a multiple of 8 bytes in the range"); 907 case Match_InvalidUImm10Lsb00NonZero: 908 return generateImmOutOfRangeError( 909 Operands, ErrorInfo, 4, (1 << 10) - 4, 910 "immediate must be a multiple of 4 bytes in the range"); 911 case Match_InvalidSImm10Lsb0000NonZero: 912 return generateImmOutOfRangeError( 913 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 914 "immediate must be a multiple of 16 bytes and non-zero in the range"); 915 case Match_InvalidSImm12: 916 return generateImmOutOfRangeError( 917 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 918 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 919 "integer in the range"); 920 case Match_InvalidSImm12Lsb0: 921 return generateImmOutOfRangeError( 922 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 923 "immediate must be a multiple of 2 bytes in the range"); 924 case Match_InvalidSImm13Lsb0: 925 return generateImmOutOfRangeError( 926 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 927 "immediate must be a multiple of 2 bytes in the range"); 928 case Match_InvalidUImm20LUI: 929 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 930 "operand must be a symbol with " 931 "%hi/%tprel_hi modifier or an integer in " 932 "the range"); 933 case Match_InvalidUImm20AUIPC: 934 return generateImmOutOfRangeError( 935 Operands, ErrorInfo, 0, (1 << 20) - 1, 936 "operand must be a symbol with a " 937 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 938 "an integer in the range"); 939 case Match_InvalidSImm21Lsb0JAL: 940 return generateImmOutOfRangeError( 941 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 942 "immediate must be a multiple of 2 bytes in the range"); 943 case Match_InvalidCSRSystemRegister: { 944 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 945 "operand must be a valid system register " 946 "name or an integer in the range"); 947 } 948 case Match_InvalidFenceArg: { 949 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 950 return Error( 951 ErrorLoc, 952 "operand must be formed of letters selected in-order from 'iorw'"); 953 } 954 case Match_InvalidFRMArg: { 955 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 956 return Error( 957 ErrorLoc, 958 "operand must be a valid floating point rounding mode mnemonic"); 959 } 960 case Match_InvalidBareSymbol: { 961 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 962 return Error(ErrorLoc, "operand must be a bare symbol name"); 963 } 964 case Match_InvalidCallSymbol: { 965 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 966 return Error(ErrorLoc, "operand must be a bare symbol name"); 967 } 968 case Match_InvalidTPRelAddSymbol: { 969 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 970 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 971 } 972 } 973 974 llvm_unreachable("Unknown match type detected!"); 975 } 976 977 // Attempts to match Name as a register (either using the default name or 978 // alternative ABI names), setting RegNo to the matching register. Upon 979 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 980 // x16-x31 will be rejected. 981 static bool matchRegisterNameHelper(bool IsRV32E, unsigned &RegNo, 982 StringRef Name) { 983 RegNo = MatchRegisterName(Name); 984 if (RegNo == 0) 985 RegNo = MatchRegisterAltName(Name); 986 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 987 RegNo = 0; 988 return RegNo == 0; 989 } 990 991 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 992 SMLoc &EndLoc) { 993 const AsmToken &Tok = getParser().getTok(); 994 StartLoc = Tok.getLoc(); 995 EndLoc = Tok.getEndLoc(); 996 RegNo = 0; 997 StringRef Name = getLexer().getTok().getIdentifier(); 998 999 if (matchRegisterNameHelper(isRV32E(), RegNo, Name)) 1000 return Error(StartLoc, "invalid register name"); 1001 1002 getParser().Lex(); // Eat identifier token. 1003 return false; 1004 } 1005 1006 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1007 bool AllowParens) { 1008 SMLoc FirstS = getLoc(); 1009 bool HadParens = false; 1010 AsmToken LParen; 1011 1012 // If this is an LParen and a parenthesised register name is allowed, parse it 1013 // atomically. 1014 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1015 AsmToken Buf[2]; 1016 size_t ReadCount = getLexer().peekTokens(Buf); 1017 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1018 HadParens = true; 1019 LParen = getParser().getTok(); 1020 getParser().Lex(); // Eat '(' 1021 } 1022 } 1023 1024 switch (getLexer().getKind()) { 1025 default: 1026 if (HadParens) 1027 getLexer().UnLex(LParen); 1028 return MatchOperand_NoMatch; 1029 case AsmToken::Identifier: 1030 StringRef Name = getLexer().getTok().getIdentifier(); 1031 unsigned RegNo; 1032 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1033 1034 if (RegNo == 0) { 1035 if (HadParens) 1036 getLexer().UnLex(LParen); 1037 return MatchOperand_NoMatch; 1038 } 1039 if (HadParens) 1040 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1041 SMLoc S = getLoc(); 1042 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1043 getLexer().Lex(); 1044 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1045 } 1046 1047 if (HadParens) { 1048 getParser().Lex(); // Eat ')' 1049 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1050 } 1051 1052 return MatchOperand_Success; 1053 } 1054 1055 OperandMatchResultTy 1056 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1057 SMLoc S = getLoc(); 1058 const MCExpr *Res; 1059 1060 switch (getLexer().getKind()) { 1061 default: 1062 return MatchOperand_NoMatch; 1063 case AsmToken::LParen: 1064 case AsmToken::Minus: 1065 case AsmToken::Plus: 1066 case AsmToken::Exclaim: 1067 case AsmToken::Tilde: 1068 case AsmToken::Integer: 1069 case AsmToken::String: { 1070 if (getParser().parseExpression(Res)) 1071 return MatchOperand_ParseFail; 1072 1073 auto *CE = dyn_cast<MCConstantExpr>(Res); 1074 if (CE) { 1075 int64_t Imm = CE->getValue(); 1076 if (isUInt<12>(Imm)) { 1077 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1078 // Accept an immediate representing a named or un-named Sys Reg 1079 // if the range is valid, regardless of the required features. 1080 Operands.push_back(RISCVOperand::createSysReg( 1081 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1082 return MatchOperand_Success; 1083 } 1084 } 1085 1086 Twine Msg = "immediate must be an integer in the range"; 1087 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1088 return MatchOperand_ParseFail; 1089 } 1090 case AsmToken::Identifier: { 1091 StringRef Identifier; 1092 if (getParser().parseIdentifier(Identifier)) 1093 return MatchOperand_ParseFail; 1094 1095 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1096 // Accept a named Sys Reg if the required features are present. 1097 if (SysReg) { 1098 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1099 Error(S, "system register use requires an option to be enabled"); 1100 return MatchOperand_ParseFail; 1101 } 1102 Operands.push_back(RISCVOperand::createSysReg( 1103 Identifier, S, SysReg->Encoding, isRV64())); 1104 return MatchOperand_Success; 1105 } 1106 1107 Twine Msg = "operand must be a valid system register name " 1108 "or an integer in the range"; 1109 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1110 return MatchOperand_ParseFail; 1111 } 1112 case AsmToken::Percent: { 1113 // Discard operand with modifier. 1114 Twine Msg = "immediate must be an integer in the range"; 1115 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1116 return MatchOperand_ParseFail; 1117 } 1118 } 1119 1120 return MatchOperand_NoMatch; 1121 } 1122 1123 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1124 SMLoc S = getLoc(); 1125 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1126 const MCExpr *Res; 1127 1128 switch (getLexer().getKind()) { 1129 default: 1130 return MatchOperand_NoMatch; 1131 case AsmToken::LParen: 1132 case AsmToken::Dot: 1133 case AsmToken::Minus: 1134 case AsmToken::Plus: 1135 case AsmToken::Exclaim: 1136 case AsmToken::Tilde: 1137 case AsmToken::Integer: 1138 case AsmToken::String: 1139 case AsmToken::Identifier: 1140 if (getParser().parseExpression(Res)) 1141 return MatchOperand_ParseFail; 1142 break; 1143 case AsmToken::Percent: 1144 return parseOperandWithModifier(Operands); 1145 } 1146 1147 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1148 return MatchOperand_Success; 1149 } 1150 1151 OperandMatchResultTy 1152 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1153 SMLoc S = getLoc(); 1154 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1155 1156 if (getLexer().getKind() != AsmToken::Percent) { 1157 Error(getLoc(), "expected '%' for operand modifier"); 1158 return MatchOperand_ParseFail; 1159 } 1160 1161 getParser().Lex(); // Eat '%' 1162 1163 if (getLexer().getKind() != AsmToken::Identifier) { 1164 Error(getLoc(), "expected valid identifier for operand modifier"); 1165 return MatchOperand_ParseFail; 1166 } 1167 StringRef Identifier = getParser().getTok().getIdentifier(); 1168 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1169 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1170 Error(getLoc(), "unrecognized operand modifier"); 1171 return MatchOperand_ParseFail; 1172 } 1173 1174 getParser().Lex(); // Eat the identifier 1175 if (getLexer().getKind() != AsmToken::LParen) { 1176 Error(getLoc(), "expected '('"); 1177 return MatchOperand_ParseFail; 1178 } 1179 getParser().Lex(); // Eat '(' 1180 1181 const MCExpr *SubExpr; 1182 if (getParser().parseParenExpression(SubExpr, E)) { 1183 return MatchOperand_ParseFail; 1184 } 1185 1186 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1187 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1188 return MatchOperand_Success; 1189 } 1190 1191 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1192 SMLoc S = getLoc(); 1193 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1194 const MCExpr *Res; 1195 1196 if (getLexer().getKind() != AsmToken::Identifier) 1197 return MatchOperand_NoMatch; 1198 1199 StringRef Identifier; 1200 AsmToken Tok = getLexer().getTok(); 1201 1202 if (getParser().parseIdentifier(Identifier)) 1203 return MatchOperand_ParseFail; 1204 1205 if (Identifier.consume_back("@plt")) { 1206 Error(getLoc(), "'@plt' operand not valid for instruction"); 1207 return MatchOperand_ParseFail; 1208 } 1209 1210 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1211 1212 if (Sym->isVariable()) { 1213 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1214 if (!isa<MCSymbolRefExpr>(V)) { 1215 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1216 return MatchOperand_NoMatch; 1217 } 1218 Res = V; 1219 } else 1220 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1221 1222 MCBinaryExpr::Opcode Opcode; 1223 switch (getLexer().getKind()) { 1224 default: 1225 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1226 return MatchOperand_Success; 1227 case AsmToken::Plus: 1228 Opcode = MCBinaryExpr::Add; 1229 break; 1230 case AsmToken::Minus: 1231 Opcode = MCBinaryExpr::Sub; 1232 break; 1233 } 1234 1235 const MCExpr *Expr; 1236 if (getParser().parseExpression(Expr)) 1237 return MatchOperand_ParseFail; 1238 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1239 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1240 return MatchOperand_Success; 1241 } 1242 1243 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1244 SMLoc S = getLoc(); 1245 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1246 const MCExpr *Res; 1247 1248 if (getLexer().getKind() != AsmToken::Identifier) 1249 return MatchOperand_NoMatch; 1250 1251 // Avoid parsing the register in `call rd, foo` as a call symbol. 1252 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1253 return MatchOperand_NoMatch; 1254 1255 StringRef Identifier; 1256 if (getParser().parseIdentifier(Identifier)) 1257 return MatchOperand_ParseFail; 1258 1259 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1260 if (Identifier.consume_back("@plt")) 1261 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1262 1263 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1264 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1265 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1266 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1267 return MatchOperand_Success; 1268 } 1269 1270 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1271 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1272 // both being acceptable forms. When parsing `jal ra, foo` this function 1273 // will be called for the `ra` register operand in an attempt to match the 1274 // single-operand alias. parseJALOffset must fail for this case. It would 1275 // seem logical to try parse the operand using parseImmediate and return 1276 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1277 // the second form rather than the first). We can't do this as there's no 1278 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1279 // is an identifier and is followed by a comma. 1280 if (getLexer().is(AsmToken::Identifier) && 1281 getLexer().peekTok().is(AsmToken::Comma)) 1282 return MatchOperand_NoMatch; 1283 1284 return parseImmediate(Operands); 1285 } 1286 1287 OperandMatchResultTy 1288 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1289 if (getLexer().isNot(AsmToken::LParen)) { 1290 Error(getLoc(), "expected '('"); 1291 return MatchOperand_ParseFail; 1292 } 1293 1294 getParser().Lex(); // Eat '(' 1295 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1296 1297 if (parseRegister(Operands) != MatchOperand_Success) { 1298 Error(getLoc(), "expected register"); 1299 return MatchOperand_ParseFail; 1300 } 1301 1302 if (getLexer().isNot(AsmToken::RParen)) { 1303 Error(getLoc(), "expected ')'"); 1304 return MatchOperand_ParseFail; 1305 } 1306 1307 getParser().Lex(); // Eat ')' 1308 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1309 1310 return MatchOperand_Success; 1311 } 1312 1313 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1314 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1315 // as one of their register operands, such as `(a0)`. This just denotes that 1316 // the register (in this case `a0`) contains a memory address. 1317 // 1318 // Normally, we would be able to parse these by putting the parens into the 1319 // instruction string. However, GNU as also accepts a zero-offset memory 1320 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1321 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1322 // do not accept an immediate operand, and we do not want to add a "dummy" 1323 // operand that is silently dropped. 1324 // 1325 // Instead, we use this custom parser. This will: allow (and discard) an 1326 // offset if it is zero; require (and discard) parentheses; and add only the 1327 // parsed register operand to `Operands`. 1328 // 1329 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1330 // will only print the register surrounded by parentheses (which GNU as also 1331 // uses as its canonical representation for these operands). 1332 std::unique_ptr<RISCVOperand> OptionalImmOp; 1333 1334 if (getLexer().isNot(AsmToken::LParen)) { 1335 // Parse an Integer token. We do not accept arbritrary constant expressions 1336 // in the offset field (because they may include parens, which complicates 1337 // parsing a lot). 1338 int64_t ImmVal; 1339 SMLoc ImmStart = getLoc(); 1340 if (getParser().parseIntToken(ImmVal, 1341 "expected '(' or optional integer offset")) 1342 return MatchOperand_ParseFail; 1343 1344 // Create a RISCVOperand for checking later (so the error messages are 1345 // nicer), but we don't add it to Operands. 1346 SMLoc ImmEnd = getLoc(); 1347 OptionalImmOp = 1348 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1349 ImmStart, ImmEnd, isRV64()); 1350 } 1351 1352 if (getLexer().isNot(AsmToken::LParen)) { 1353 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1354 : "expected '(' or optional integer offset"); 1355 return MatchOperand_ParseFail; 1356 } 1357 getParser().Lex(); // Eat '(' 1358 1359 if (parseRegister(Operands) != MatchOperand_Success) { 1360 Error(getLoc(), "expected register"); 1361 return MatchOperand_ParseFail; 1362 } 1363 1364 if (getLexer().isNot(AsmToken::RParen)) { 1365 Error(getLoc(), "expected ')'"); 1366 return MatchOperand_ParseFail; 1367 } 1368 getParser().Lex(); // Eat ')' 1369 1370 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1371 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1372 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1373 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1374 return MatchOperand_ParseFail; 1375 } 1376 1377 return MatchOperand_Success; 1378 } 1379 1380 /// Looks at a token type and creates the relevant operand from this 1381 /// information, adding to Operands. If operand was parsed, returns false, else 1382 /// true. 1383 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1384 // Check if the current operand has a custom associated parser, if so, try to 1385 // custom parse the operand, or fallback to the general approach. 1386 OperandMatchResultTy Result = 1387 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1388 if (Result == MatchOperand_Success) 1389 return false; 1390 if (Result == MatchOperand_ParseFail) 1391 return true; 1392 1393 // Attempt to parse token as a register. 1394 if (parseRegister(Operands, true) == MatchOperand_Success) 1395 return false; 1396 1397 // Attempt to parse token as an immediate 1398 if (parseImmediate(Operands) == MatchOperand_Success) { 1399 // Parse memory base register if present 1400 if (getLexer().is(AsmToken::LParen)) 1401 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1402 return false; 1403 } 1404 1405 // Finally we have exhausted all options and must declare defeat. 1406 Error(getLoc(), "unknown operand"); 1407 return true; 1408 } 1409 1410 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1411 StringRef Name, SMLoc NameLoc, 1412 OperandVector &Operands) { 1413 // Ensure that if the instruction occurs when relaxation is enabled, 1414 // relocations are forced for the file. Ideally this would be done when there 1415 // is enough information to reliably determine if the instruction itself may 1416 // cause relaxations. Unfortunately instruction processing stage occurs in the 1417 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1418 // for the entire file. 1419 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1420 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1421 if (Assembler != nullptr) { 1422 RISCVAsmBackend &MAB = 1423 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1424 MAB.setForceRelocs(); 1425 } 1426 } 1427 1428 // First operand is token for instruction 1429 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1430 1431 // If there are no more operands, then finish 1432 if (getLexer().is(AsmToken::EndOfStatement)) 1433 return false; 1434 1435 // Parse first operand 1436 if (parseOperand(Operands, Name)) 1437 return true; 1438 1439 // Parse until end of statement, consuming commas between operands 1440 unsigned OperandIdx = 1; 1441 while (getLexer().is(AsmToken::Comma)) { 1442 // Consume comma token 1443 getLexer().Lex(); 1444 1445 // Parse next operand 1446 if (parseOperand(Operands, Name)) 1447 return true; 1448 1449 ++OperandIdx; 1450 } 1451 1452 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1453 SMLoc Loc = getLexer().getLoc(); 1454 getParser().eatToEndOfStatement(); 1455 return Error(Loc, "unexpected token"); 1456 } 1457 1458 getParser().Lex(); // Consume the EndOfStatement. 1459 return false; 1460 } 1461 1462 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1463 RISCVMCExpr::VariantKind &Kind, 1464 int64_t &Addend) { 1465 Kind = RISCVMCExpr::VK_RISCV_None; 1466 Addend = 0; 1467 1468 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1469 Kind = RE->getKind(); 1470 Expr = RE->getSubExpr(); 1471 } 1472 1473 // It's a simple symbol reference or constant with no addend. 1474 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1475 return true; 1476 1477 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1478 if (!BE) 1479 return false; 1480 1481 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1482 return false; 1483 1484 if (BE->getOpcode() != MCBinaryExpr::Add && 1485 BE->getOpcode() != MCBinaryExpr::Sub) 1486 return false; 1487 1488 // We are able to support the subtraction of two symbol references 1489 if (BE->getOpcode() == MCBinaryExpr::Sub && 1490 isa<MCSymbolRefExpr>(BE->getRHS())) 1491 return true; 1492 1493 // See if the addend is a constant, otherwise there's more going 1494 // on here than we can deal with. 1495 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1496 if (!AddendExpr) 1497 return false; 1498 1499 Addend = AddendExpr->getValue(); 1500 if (BE->getOpcode() == MCBinaryExpr::Sub) 1501 Addend = -Addend; 1502 1503 // It's some symbol reference + a constant addend 1504 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1505 } 1506 1507 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1508 // This returns false if this function recognizes the directive 1509 // regardless of whether it is successfully handles or reports an 1510 // error. Otherwise it returns true to give the generic parser a 1511 // chance at recognizing it. 1512 StringRef IDVal = DirectiveID.getString(); 1513 1514 if (IDVal == ".option") 1515 return parseDirectiveOption(); 1516 1517 return true; 1518 } 1519 1520 bool RISCVAsmParser::parseDirectiveOption() { 1521 MCAsmParser &Parser = getParser(); 1522 // Get the option token. 1523 AsmToken Tok = Parser.getTok(); 1524 // At the moment only identifiers are supported. 1525 if (Tok.isNot(AsmToken::Identifier)) 1526 return Error(Parser.getTok().getLoc(), 1527 "unexpected token, expected identifier"); 1528 1529 StringRef Option = Tok.getIdentifier(); 1530 1531 if (Option == "push") { 1532 getTargetStreamer().emitDirectiveOptionPush(); 1533 1534 Parser.Lex(); 1535 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1536 return Error(Parser.getTok().getLoc(), 1537 "unexpected token, expected end of statement"); 1538 1539 pushFeatureBits(); 1540 return false; 1541 } 1542 1543 if (Option == "pop") { 1544 SMLoc StartLoc = Parser.getTok().getLoc(); 1545 getTargetStreamer().emitDirectiveOptionPop(); 1546 1547 Parser.Lex(); 1548 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1549 return Error(Parser.getTok().getLoc(), 1550 "unexpected token, expected end of statement"); 1551 1552 if (popFeatureBits()) 1553 return Error(StartLoc, ".option pop with no .option push"); 1554 1555 return false; 1556 } 1557 1558 if (Option == "rvc") { 1559 getTargetStreamer().emitDirectiveOptionRVC(); 1560 1561 Parser.Lex(); 1562 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1563 return Error(Parser.getTok().getLoc(), 1564 "unexpected token, expected end of statement"); 1565 1566 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1567 return false; 1568 } 1569 1570 if (Option == "norvc") { 1571 getTargetStreamer().emitDirectiveOptionNoRVC(); 1572 1573 Parser.Lex(); 1574 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1575 return Error(Parser.getTok().getLoc(), 1576 "unexpected token, expected end of statement"); 1577 1578 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1579 return false; 1580 } 1581 1582 if (Option == "relax") { 1583 getTargetStreamer().emitDirectiveOptionRelax(); 1584 1585 Parser.Lex(); 1586 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1587 return Error(Parser.getTok().getLoc(), 1588 "unexpected token, expected end of statement"); 1589 1590 setFeatureBits(RISCV::FeatureRelax, "relax"); 1591 return false; 1592 } 1593 1594 if (Option == "norelax") { 1595 getTargetStreamer().emitDirectiveOptionNoRelax(); 1596 1597 Parser.Lex(); 1598 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1599 return Error(Parser.getTok().getLoc(), 1600 "unexpected token, expected end of statement"); 1601 1602 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1603 return false; 1604 } 1605 1606 // Unknown option. 1607 Warning(Parser.getTok().getLoc(), 1608 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1609 "'norelax'"); 1610 Parser.eatToEndOfStatement(); 1611 return false; 1612 } 1613 1614 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1615 MCInst CInst; 1616 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1617 CInst.setLoc(Inst.getLoc()); 1618 S.EmitInstruction((Res ? CInst : Inst), getSTI()); 1619 } 1620 1621 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value, 1622 MCStreamer &Out) { 1623 RISCVMatInt::InstSeq Seq; 1624 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 1625 1626 unsigned SrcReg = RISCV::X0; 1627 for (RISCVMatInt::Inst &Inst : Seq) { 1628 if (Inst.Opc == RISCV::LUI) { 1629 emitToStreamer( 1630 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 1631 } else { 1632 emitToStreamer( 1633 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 1634 Inst.Imm)); 1635 } 1636 1637 // Only the first instruction has X0 as its source. 1638 SrcReg = DestReg; 1639 } 1640 } 1641 1642 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 1643 const MCExpr *Symbol, 1644 RISCVMCExpr::VariantKind VKHi, 1645 unsigned SecondOpcode, SMLoc IDLoc, 1646 MCStreamer &Out) { 1647 // A pair of instructions for PC-relative addressing; expands to 1648 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 1649 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 1650 MCContext &Ctx = getContext(); 1651 1652 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1653 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1654 Out.EmitLabel(TmpLabel); 1655 1656 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 1657 emitToStreamer( 1658 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 1659 1660 const MCExpr *RefToLinkTmpLabel = 1661 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1662 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1663 1664 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 1665 .addOperand(DestReg) 1666 .addOperand(TmpReg) 1667 .addExpr(RefToLinkTmpLabel)); 1668 } 1669 1670 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1671 MCStreamer &Out) { 1672 // The load local address pseudo-instruction "lla" is used in PC-relative 1673 // addressing of local symbols: 1674 // lla rdest, symbol 1675 // expands to 1676 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1677 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1678 MCOperand DestReg = Inst.getOperand(0); 1679 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1680 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1681 RISCV::ADDI, IDLoc, Out); 1682 } 1683 1684 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 1685 MCStreamer &Out) { 1686 // The load address pseudo-instruction "la" is used in PC-relative and 1687 // GOT-indirect addressing of global symbols: 1688 // la rdest, symbol 1689 // expands to either (for non-PIC) 1690 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1691 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1692 // or (for PIC) 1693 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 1694 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1695 MCOperand DestReg = Inst.getOperand(0); 1696 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1697 unsigned SecondOpcode; 1698 RISCVMCExpr::VariantKind VKHi; 1699 // FIXME: Should check .option (no)pic when implemented 1700 if (getContext().getObjectFileInfo()->isPositionIndependent()) { 1701 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1702 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 1703 } else { 1704 SecondOpcode = RISCV::ADDI; 1705 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 1706 } 1707 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 1708 } 1709 1710 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 1711 MCStreamer &Out) { 1712 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 1713 // initial-exec TLS model addressing of global symbols: 1714 // la.tls.ie rdest, symbol 1715 // expands to 1716 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 1717 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1718 MCOperand DestReg = Inst.getOperand(0); 1719 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1720 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1721 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 1722 SecondOpcode, IDLoc, Out); 1723 } 1724 1725 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 1726 MCStreamer &Out) { 1727 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 1728 // global-dynamic TLS model addressing of global symbols: 1729 // la.tls.gd rdest, symbol 1730 // expands to 1731 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 1732 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1733 MCOperand DestReg = Inst.getOperand(0); 1734 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1735 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 1736 RISCV::ADDI, IDLoc, Out); 1737 } 1738 1739 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 1740 SMLoc IDLoc, MCStreamer &Out, 1741 bool HasTmpReg) { 1742 // The load/store pseudo-instruction does a pc-relative load with 1743 // a symbol. 1744 // 1745 // The expansion looks like this 1746 // 1747 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 1748 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 1749 MCOperand DestReg = Inst.getOperand(0); 1750 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 1751 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 1752 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 1753 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 1754 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1755 Opcode, IDLoc, Out); 1756 } 1757 1758 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 1759 OperandVector &Operands) { 1760 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 1761 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 1762 if (Inst.getOperand(2).getReg() != RISCV::X4) { 1763 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 1764 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 1765 "%tprel_add modifier"); 1766 } 1767 1768 return false; 1769 } 1770 1771 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1772 OperandVector &Operands, 1773 MCStreamer &Out) { 1774 Inst.setLoc(IDLoc); 1775 1776 switch (Inst.getOpcode()) { 1777 default: 1778 break; 1779 case RISCV::PseudoLI: { 1780 unsigned Reg = Inst.getOperand(0).getReg(); 1781 const MCOperand &Op1 = Inst.getOperand(1); 1782 if (Op1.isExpr()) { 1783 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 1784 // Just convert to an addi. This allows compatibility with gas. 1785 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1786 .addReg(Reg) 1787 .addReg(RISCV::X0) 1788 .addExpr(Op1.getExpr())); 1789 return false; 1790 } 1791 int64_t Imm = Inst.getOperand(1).getImm(); 1792 // On RV32 the immediate here can either be a signed or an unsigned 1793 // 32-bit number. Sign extension has to be performed to ensure that Imm 1794 // represents the expected signed 64-bit number. 1795 if (!isRV64()) 1796 Imm = SignExtend64<32>(Imm); 1797 emitLoadImm(Reg, Imm, Out); 1798 return false; 1799 } 1800 case RISCV::PseudoLLA: 1801 emitLoadLocalAddress(Inst, IDLoc, Out); 1802 return false; 1803 case RISCV::PseudoLA: 1804 emitLoadAddress(Inst, IDLoc, Out); 1805 return false; 1806 case RISCV::PseudoLA_TLS_IE: 1807 emitLoadTLSIEAddress(Inst, IDLoc, Out); 1808 return false; 1809 case RISCV::PseudoLA_TLS_GD: 1810 emitLoadTLSGDAddress(Inst, IDLoc, Out); 1811 return false; 1812 case RISCV::PseudoLB: 1813 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 1814 return false; 1815 case RISCV::PseudoLBU: 1816 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 1817 return false; 1818 case RISCV::PseudoLH: 1819 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 1820 return false; 1821 case RISCV::PseudoLHU: 1822 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 1823 return false; 1824 case RISCV::PseudoLW: 1825 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 1826 return false; 1827 case RISCV::PseudoLWU: 1828 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 1829 return false; 1830 case RISCV::PseudoLD: 1831 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 1832 return false; 1833 case RISCV::PseudoFLW: 1834 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 1835 return false; 1836 case RISCV::PseudoFLD: 1837 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 1838 return false; 1839 case RISCV::PseudoSB: 1840 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 1841 return false; 1842 case RISCV::PseudoSH: 1843 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 1844 return false; 1845 case RISCV::PseudoSW: 1846 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 1847 return false; 1848 case RISCV::PseudoSD: 1849 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 1850 return false; 1851 case RISCV::PseudoFSW: 1852 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 1853 return false; 1854 case RISCV::PseudoFSD: 1855 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 1856 return false; 1857 case RISCV::PseudoAddTPRel: 1858 if (checkPseudoAddTPRel(Inst, Operands)) 1859 return true; 1860 break; 1861 } 1862 1863 emitToStreamer(Out, Inst); 1864 return false; 1865 } 1866 1867 extern "C" void LLVMInitializeRISCVAsmParser() { 1868 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 1869 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 1870 } 1871