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