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