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