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