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