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 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); 378 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None; 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 // Return the matching FPR64 register for the given FPR32. 745 // FIXME: Ideally this function could be removed in favour of using 746 // information from TableGen. 747 Register convertFPR32ToFPR64(Register Reg) { 748 switch (Reg) { 749 default: 750 llvm_unreachable("Not a recognised FPR32 register"); 751 case RISCV::F0_32: return RISCV::F0_64; 752 case RISCV::F1_32: return RISCV::F1_64; 753 case RISCV::F2_32: return RISCV::F2_64; 754 case RISCV::F3_32: return RISCV::F3_64; 755 case RISCV::F4_32: return RISCV::F4_64; 756 case RISCV::F5_32: return RISCV::F5_64; 757 case RISCV::F6_32: return RISCV::F6_64; 758 case RISCV::F7_32: return RISCV::F7_64; 759 case RISCV::F8_32: return RISCV::F8_64; 760 case RISCV::F9_32: return RISCV::F9_64; 761 case RISCV::F10_32: return RISCV::F10_64; 762 case RISCV::F11_32: return RISCV::F11_64; 763 case RISCV::F12_32: return RISCV::F12_64; 764 case RISCV::F13_32: return RISCV::F13_64; 765 case RISCV::F14_32: return RISCV::F14_64; 766 case RISCV::F15_32: return RISCV::F15_64; 767 case RISCV::F16_32: return RISCV::F16_64; 768 case RISCV::F17_32: return RISCV::F17_64; 769 case RISCV::F18_32: return RISCV::F18_64; 770 case RISCV::F19_32: return RISCV::F19_64; 771 case RISCV::F20_32: return RISCV::F20_64; 772 case RISCV::F21_32: return RISCV::F21_64; 773 case RISCV::F22_32: return RISCV::F22_64; 774 case RISCV::F23_32: return RISCV::F23_64; 775 case RISCV::F24_32: return RISCV::F24_64; 776 case RISCV::F25_32: return RISCV::F25_64; 777 case RISCV::F26_32: return RISCV::F26_64; 778 case RISCV::F27_32: return RISCV::F27_64; 779 case RISCV::F28_32: return RISCV::F28_64; 780 case RISCV::F29_32: return RISCV::F29_64; 781 case RISCV::F30_32: return RISCV::F30_64; 782 case RISCV::F31_32: return RISCV::F31_64; 783 } 784 } 785 786 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 787 unsigned Kind) { 788 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 789 if (!Op.isReg()) 790 return Match_InvalidOperand; 791 792 Register Reg = Op.getReg(); 793 bool IsRegFPR32 = 794 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 795 bool IsRegFPR32C = 796 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 797 798 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 799 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 800 if ((IsRegFPR32 && Kind == MCK_FPR64) || 801 (IsRegFPR32C && Kind == MCK_FPR64C)) { 802 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 803 return Match_Success; 804 } 805 return Match_InvalidOperand; 806 } 807 808 bool RISCVAsmParser::generateImmOutOfRangeError( 809 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 810 Twine Msg = "immediate must be an integer in the range") { 811 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 812 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 813 } 814 815 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 816 OperandVector &Operands, 817 MCStreamer &Out, 818 uint64_t &ErrorInfo, 819 bool MatchingInlineAsm) { 820 MCInst Inst; 821 822 auto Result = 823 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 824 switch (Result) { 825 default: 826 break; 827 case Match_Success: 828 return processInstruction(Inst, IDLoc, Operands, Out); 829 case Match_MissingFeature: 830 return Error(IDLoc, "instruction use requires an option to be enabled"); 831 case Match_MnemonicFail: 832 return Error(IDLoc, "unrecognized instruction mnemonic"); 833 case Match_InvalidOperand: { 834 SMLoc ErrorLoc = IDLoc; 835 if (ErrorInfo != ~0U) { 836 if (ErrorInfo >= Operands.size()) 837 return Error(ErrorLoc, "too few operands for instruction"); 838 839 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 840 if (ErrorLoc == SMLoc()) 841 ErrorLoc = IDLoc; 842 } 843 return Error(ErrorLoc, "invalid operand for instruction"); 844 } 845 } 846 847 // Handle the case when the error message is of specific type 848 // other than the generic Match_InvalidOperand, and the 849 // corresponding operand is missing. 850 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 851 SMLoc ErrorLoc = IDLoc; 852 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 853 return Error(ErrorLoc, "too few operands for instruction"); 854 } 855 856 switch(Result) { 857 default: 858 break; 859 case Match_InvalidImmXLenLI: 860 if (isRV64()) { 861 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 862 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 863 } 864 return generateImmOutOfRangeError(Operands, ErrorInfo, 865 std::numeric_limits<int32_t>::min(), 866 std::numeric_limits<uint32_t>::max()); 867 case Match_InvalidUImmLog2XLen: 868 if (isRV64()) 869 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 870 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 871 case Match_InvalidUImmLog2XLenNonZero: 872 if (isRV64()) 873 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 874 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 875 case Match_InvalidUImm5: 876 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 877 case Match_InvalidSImm6: 878 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 879 (1 << 5) - 1); 880 case Match_InvalidSImm6NonZero: 881 return generateImmOutOfRangeError( 882 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 883 "immediate must be non-zero in the range"); 884 case Match_InvalidCLUIImm: 885 return generateImmOutOfRangeError( 886 Operands, ErrorInfo, 1, (1 << 5) - 1, 887 "immediate must be in [0xfffe0, 0xfffff] or"); 888 case Match_InvalidUImm7Lsb00: 889 return generateImmOutOfRangeError( 890 Operands, ErrorInfo, 0, (1 << 7) - 4, 891 "immediate must be a multiple of 4 bytes in the range"); 892 case Match_InvalidUImm8Lsb00: 893 return generateImmOutOfRangeError( 894 Operands, ErrorInfo, 0, (1 << 8) - 4, 895 "immediate must be a multiple of 4 bytes in the range"); 896 case Match_InvalidUImm8Lsb000: 897 return generateImmOutOfRangeError( 898 Operands, ErrorInfo, 0, (1 << 8) - 8, 899 "immediate must be a multiple of 8 bytes in the range"); 900 case Match_InvalidSImm9Lsb0: 901 return generateImmOutOfRangeError( 902 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 903 "immediate must be a multiple of 2 bytes in the range"); 904 case Match_InvalidUImm9Lsb000: 905 return generateImmOutOfRangeError( 906 Operands, ErrorInfo, 0, (1 << 9) - 8, 907 "immediate must be a multiple of 8 bytes in the range"); 908 case Match_InvalidUImm10Lsb00NonZero: 909 return generateImmOutOfRangeError( 910 Operands, ErrorInfo, 4, (1 << 10) - 4, 911 "immediate must be a multiple of 4 bytes in the range"); 912 case Match_InvalidSImm10Lsb0000NonZero: 913 return generateImmOutOfRangeError( 914 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 915 "immediate must be a multiple of 16 bytes and non-zero in the range"); 916 case Match_InvalidSImm12: 917 return generateImmOutOfRangeError( 918 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 919 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 920 "integer in the range"); 921 case Match_InvalidSImm12Lsb0: 922 return generateImmOutOfRangeError( 923 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 924 "immediate must be a multiple of 2 bytes in the range"); 925 case Match_InvalidSImm13Lsb0: 926 return generateImmOutOfRangeError( 927 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 928 "immediate must be a multiple of 2 bytes in the range"); 929 case Match_InvalidUImm20LUI: 930 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 931 "operand must be a symbol with " 932 "%hi/%tprel_hi modifier or an integer in " 933 "the range"); 934 case Match_InvalidUImm20AUIPC: 935 return generateImmOutOfRangeError( 936 Operands, ErrorInfo, 0, (1 << 20) - 1, 937 "operand must be a symbol with a " 938 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 939 "an integer in the range"); 940 case Match_InvalidSImm21Lsb0JAL: 941 return generateImmOutOfRangeError( 942 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 943 "immediate must be a multiple of 2 bytes in the range"); 944 case Match_InvalidCSRSystemRegister: { 945 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 946 "operand must be a valid system register " 947 "name or an integer in the range"); 948 } 949 case Match_InvalidFenceArg: { 950 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 951 return Error( 952 ErrorLoc, 953 "operand must be formed of letters selected in-order from 'iorw'"); 954 } 955 case Match_InvalidFRMArg: { 956 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 957 return Error( 958 ErrorLoc, 959 "operand must be a valid floating point rounding mode mnemonic"); 960 } 961 case Match_InvalidBareSymbol: { 962 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 963 return Error(ErrorLoc, "operand must be a bare symbol name"); 964 } 965 case Match_InvalidCallSymbol: { 966 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 967 return Error(ErrorLoc, "operand must be a bare symbol name"); 968 } 969 case Match_InvalidTPRelAddSymbol: { 970 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 971 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 972 } 973 } 974 975 llvm_unreachable("Unknown match type detected!"); 976 } 977 978 // Attempts to match Name as a register (either using the default name or 979 // alternative ABI names), setting RegNo to the matching register. Upon 980 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 981 // x16-x31 will be rejected. 982 static bool matchRegisterNameHelper(bool IsRV32E, Register &RegNo, 983 StringRef Name) { 984 RegNo = MatchRegisterName(Name); 985 if (RegNo == 0) 986 RegNo = MatchRegisterAltName(Name); 987 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 988 RegNo = 0; 989 return RegNo == 0; 990 } 991 992 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 993 SMLoc &EndLoc) { 994 const AsmToken &Tok = getParser().getTok(); 995 StartLoc = Tok.getLoc(); 996 EndLoc = Tok.getEndLoc(); 997 RegNo = 0; 998 StringRef Name = getLexer().getTok().getIdentifier(); 999 1000 if (matchRegisterNameHelper(isRV32E(), (Register&)RegNo, Name)) 1001 return Error(StartLoc, "invalid register name"); 1002 1003 getParser().Lex(); // Eat identifier token. 1004 return false; 1005 } 1006 1007 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1008 bool AllowParens) { 1009 SMLoc FirstS = getLoc(); 1010 bool HadParens = false; 1011 AsmToken LParen; 1012 1013 // If this is an LParen and a parenthesised register name is allowed, parse it 1014 // atomically. 1015 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1016 AsmToken Buf[2]; 1017 size_t ReadCount = getLexer().peekTokens(Buf); 1018 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1019 HadParens = true; 1020 LParen = getParser().getTok(); 1021 getParser().Lex(); // Eat '(' 1022 } 1023 } 1024 1025 switch (getLexer().getKind()) { 1026 default: 1027 if (HadParens) 1028 getLexer().UnLex(LParen); 1029 return MatchOperand_NoMatch; 1030 case AsmToken::Identifier: 1031 StringRef Name = getLexer().getTok().getIdentifier(); 1032 Register RegNo; 1033 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1034 1035 if (RegNo == 0) { 1036 if (HadParens) 1037 getLexer().UnLex(LParen); 1038 return MatchOperand_NoMatch; 1039 } 1040 if (HadParens) 1041 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1042 SMLoc S = getLoc(); 1043 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1044 getLexer().Lex(); 1045 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1046 } 1047 1048 if (HadParens) { 1049 getParser().Lex(); // Eat ')' 1050 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1051 } 1052 1053 return MatchOperand_Success; 1054 } 1055 1056 OperandMatchResultTy 1057 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1058 SMLoc S = getLoc(); 1059 const MCExpr *Res; 1060 1061 switch (getLexer().getKind()) { 1062 default: 1063 return MatchOperand_NoMatch; 1064 case AsmToken::LParen: 1065 case AsmToken::Minus: 1066 case AsmToken::Plus: 1067 case AsmToken::Exclaim: 1068 case AsmToken::Tilde: 1069 case AsmToken::Integer: 1070 case AsmToken::String: { 1071 if (getParser().parseExpression(Res)) 1072 return MatchOperand_ParseFail; 1073 1074 auto *CE = dyn_cast<MCConstantExpr>(Res); 1075 if (CE) { 1076 int64_t Imm = CE->getValue(); 1077 if (isUInt<12>(Imm)) { 1078 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1079 // Accept an immediate representing a named or un-named Sys Reg 1080 // if the range is valid, regardless of the required features. 1081 Operands.push_back(RISCVOperand::createSysReg( 1082 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1083 return MatchOperand_Success; 1084 } 1085 } 1086 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 case AsmToken::Identifier: { 1092 StringRef Identifier; 1093 if (getParser().parseIdentifier(Identifier)) 1094 return MatchOperand_ParseFail; 1095 1096 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1097 // Accept a named Sys Reg if the required features are present. 1098 if (SysReg) { 1099 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1100 Error(S, "system register use requires an option to be enabled"); 1101 return MatchOperand_ParseFail; 1102 } 1103 Operands.push_back(RISCVOperand::createSysReg( 1104 Identifier, S, SysReg->Encoding, isRV64())); 1105 return MatchOperand_Success; 1106 } 1107 1108 Twine Msg = "operand must be a valid system register name " 1109 "or an integer in the range"; 1110 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1111 return MatchOperand_ParseFail; 1112 } 1113 case AsmToken::Percent: { 1114 // Discard operand with modifier. 1115 Twine Msg = "immediate must be an integer in the range"; 1116 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1117 return MatchOperand_ParseFail; 1118 } 1119 } 1120 1121 return MatchOperand_NoMatch; 1122 } 1123 1124 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1125 SMLoc S = getLoc(); 1126 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1127 const MCExpr *Res; 1128 1129 switch (getLexer().getKind()) { 1130 default: 1131 return MatchOperand_NoMatch; 1132 case AsmToken::LParen: 1133 case AsmToken::Dot: 1134 case AsmToken::Minus: 1135 case AsmToken::Plus: 1136 case AsmToken::Exclaim: 1137 case AsmToken::Tilde: 1138 case AsmToken::Integer: 1139 case AsmToken::String: 1140 case AsmToken::Identifier: 1141 if (getParser().parseExpression(Res)) 1142 return MatchOperand_ParseFail; 1143 break; 1144 case AsmToken::Percent: 1145 return parseOperandWithModifier(Operands); 1146 } 1147 1148 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1149 return MatchOperand_Success; 1150 } 1151 1152 OperandMatchResultTy 1153 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1154 SMLoc S = getLoc(); 1155 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1156 1157 if (getLexer().getKind() != AsmToken::Percent) { 1158 Error(getLoc(), "expected '%' for operand modifier"); 1159 return MatchOperand_ParseFail; 1160 } 1161 1162 getParser().Lex(); // Eat '%' 1163 1164 if (getLexer().getKind() != AsmToken::Identifier) { 1165 Error(getLoc(), "expected valid identifier for operand modifier"); 1166 return MatchOperand_ParseFail; 1167 } 1168 StringRef Identifier = getParser().getTok().getIdentifier(); 1169 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1170 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1171 Error(getLoc(), "unrecognized operand modifier"); 1172 return MatchOperand_ParseFail; 1173 } 1174 1175 getParser().Lex(); // Eat the identifier 1176 if (getLexer().getKind() != AsmToken::LParen) { 1177 Error(getLoc(), "expected '('"); 1178 return MatchOperand_ParseFail; 1179 } 1180 getParser().Lex(); // Eat '(' 1181 1182 const MCExpr *SubExpr; 1183 if (getParser().parseParenExpression(SubExpr, E)) { 1184 return MatchOperand_ParseFail; 1185 } 1186 1187 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1188 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1189 return MatchOperand_Success; 1190 } 1191 1192 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1193 SMLoc S = getLoc(); 1194 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1195 const MCExpr *Res; 1196 1197 if (getLexer().getKind() != AsmToken::Identifier) 1198 return MatchOperand_NoMatch; 1199 1200 StringRef Identifier; 1201 AsmToken Tok = getLexer().getTok(); 1202 1203 if (getParser().parseIdentifier(Identifier)) 1204 return MatchOperand_ParseFail; 1205 1206 if (Identifier.consume_back("@plt")) { 1207 Error(getLoc(), "'@plt' operand not valid for instruction"); 1208 return MatchOperand_ParseFail; 1209 } 1210 1211 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1212 1213 if (Sym->isVariable()) { 1214 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1215 if (!isa<MCSymbolRefExpr>(V)) { 1216 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1217 return MatchOperand_NoMatch; 1218 } 1219 Res = V; 1220 } else 1221 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1222 1223 MCBinaryExpr::Opcode Opcode; 1224 switch (getLexer().getKind()) { 1225 default: 1226 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1227 return MatchOperand_Success; 1228 case AsmToken::Plus: 1229 Opcode = MCBinaryExpr::Add; 1230 break; 1231 case AsmToken::Minus: 1232 Opcode = MCBinaryExpr::Sub; 1233 break; 1234 } 1235 1236 const MCExpr *Expr; 1237 if (getParser().parseExpression(Expr)) 1238 return MatchOperand_ParseFail; 1239 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1240 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1241 return MatchOperand_Success; 1242 } 1243 1244 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1245 SMLoc S = getLoc(); 1246 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1247 const MCExpr *Res; 1248 1249 if (getLexer().getKind() != AsmToken::Identifier) 1250 return MatchOperand_NoMatch; 1251 1252 // Avoid parsing the register in `call rd, foo` as a call symbol. 1253 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1254 return MatchOperand_NoMatch; 1255 1256 StringRef Identifier; 1257 if (getParser().parseIdentifier(Identifier)) 1258 return MatchOperand_ParseFail; 1259 1260 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1261 if (Identifier.consume_back("@plt")) 1262 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1263 1264 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1265 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1266 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1267 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1268 return MatchOperand_Success; 1269 } 1270 1271 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1272 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1273 // both being acceptable forms. When parsing `jal ra, foo` this function 1274 // will be called for the `ra` register operand in an attempt to match the 1275 // single-operand alias. parseJALOffset must fail for this case. It would 1276 // seem logical to try parse the operand using parseImmediate and return 1277 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1278 // the second form rather than the first). We can't do this as there's no 1279 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1280 // is an identifier and is followed by a comma. 1281 if (getLexer().is(AsmToken::Identifier) && 1282 getLexer().peekTok().is(AsmToken::Comma)) 1283 return MatchOperand_NoMatch; 1284 1285 return parseImmediate(Operands); 1286 } 1287 1288 OperandMatchResultTy 1289 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1290 if (getLexer().isNot(AsmToken::LParen)) { 1291 Error(getLoc(), "expected '('"); 1292 return MatchOperand_ParseFail; 1293 } 1294 1295 getParser().Lex(); // Eat '(' 1296 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1297 1298 if (parseRegister(Operands) != MatchOperand_Success) { 1299 Error(getLoc(), "expected register"); 1300 return MatchOperand_ParseFail; 1301 } 1302 1303 if (getLexer().isNot(AsmToken::RParen)) { 1304 Error(getLoc(), "expected ')'"); 1305 return MatchOperand_ParseFail; 1306 } 1307 1308 getParser().Lex(); // Eat ')' 1309 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1310 1311 return MatchOperand_Success; 1312 } 1313 1314 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1315 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1316 // as one of their register operands, such as `(a0)`. This just denotes that 1317 // the register (in this case `a0`) contains a memory address. 1318 // 1319 // Normally, we would be able to parse these by putting the parens into the 1320 // instruction string. However, GNU as also accepts a zero-offset memory 1321 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1322 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1323 // do not accept an immediate operand, and we do not want to add a "dummy" 1324 // operand that is silently dropped. 1325 // 1326 // Instead, we use this custom parser. This will: allow (and discard) an 1327 // offset if it is zero; require (and discard) parentheses; and add only the 1328 // parsed register operand to `Operands`. 1329 // 1330 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1331 // will only print the register surrounded by parentheses (which GNU as also 1332 // uses as its canonical representation for these operands). 1333 std::unique_ptr<RISCVOperand> OptionalImmOp; 1334 1335 if (getLexer().isNot(AsmToken::LParen)) { 1336 // Parse an Integer token. We do not accept arbritrary constant expressions 1337 // in the offset field (because they may include parens, which complicates 1338 // parsing a lot). 1339 int64_t ImmVal; 1340 SMLoc ImmStart = getLoc(); 1341 if (getParser().parseIntToken(ImmVal, 1342 "expected '(' or optional integer offset")) 1343 return MatchOperand_ParseFail; 1344 1345 // Create a RISCVOperand for checking later (so the error messages are 1346 // nicer), but we don't add it to Operands. 1347 SMLoc ImmEnd = getLoc(); 1348 OptionalImmOp = 1349 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1350 ImmStart, ImmEnd, isRV64()); 1351 } 1352 1353 if (getLexer().isNot(AsmToken::LParen)) { 1354 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1355 : "expected '(' or optional integer offset"); 1356 return MatchOperand_ParseFail; 1357 } 1358 getParser().Lex(); // Eat '(' 1359 1360 if (parseRegister(Operands) != MatchOperand_Success) { 1361 Error(getLoc(), "expected register"); 1362 return MatchOperand_ParseFail; 1363 } 1364 1365 if (getLexer().isNot(AsmToken::RParen)) { 1366 Error(getLoc(), "expected ')'"); 1367 return MatchOperand_ParseFail; 1368 } 1369 getParser().Lex(); // Eat ')' 1370 1371 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1372 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1373 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1374 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1375 return MatchOperand_ParseFail; 1376 } 1377 1378 return MatchOperand_Success; 1379 } 1380 1381 /// Looks at a token type and creates the relevant operand from this 1382 /// information, adding to Operands. If operand was parsed, returns false, else 1383 /// true. 1384 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1385 // Check if the current operand has a custom associated parser, if so, try to 1386 // custom parse the operand, or fallback to the general approach. 1387 OperandMatchResultTy Result = 1388 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1389 if (Result == MatchOperand_Success) 1390 return false; 1391 if (Result == MatchOperand_ParseFail) 1392 return true; 1393 1394 // Attempt to parse token as a register. 1395 if (parseRegister(Operands, true) == MatchOperand_Success) 1396 return false; 1397 1398 // Attempt to parse token as an immediate 1399 if (parseImmediate(Operands) == MatchOperand_Success) { 1400 // Parse memory base register if present 1401 if (getLexer().is(AsmToken::LParen)) 1402 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1403 return false; 1404 } 1405 1406 // Finally we have exhausted all options and must declare defeat. 1407 Error(getLoc(), "unknown operand"); 1408 return true; 1409 } 1410 1411 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1412 StringRef Name, SMLoc NameLoc, 1413 OperandVector &Operands) { 1414 // Ensure that if the instruction occurs when relaxation is enabled, 1415 // relocations are forced for the file. Ideally this would be done when there 1416 // is enough information to reliably determine if the instruction itself may 1417 // cause relaxations. Unfortunately instruction processing stage occurs in the 1418 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1419 // for the entire file. 1420 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1421 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1422 if (Assembler != nullptr) { 1423 RISCVAsmBackend &MAB = 1424 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1425 MAB.setForceRelocs(); 1426 } 1427 } 1428 1429 // First operand is token for instruction 1430 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1431 1432 // If there are no more operands, then finish 1433 if (getLexer().is(AsmToken::EndOfStatement)) 1434 return false; 1435 1436 // Parse first operand 1437 if (parseOperand(Operands, Name)) 1438 return true; 1439 1440 // Parse until end of statement, consuming commas between operands 1441 unsigned OperandIdx = 1; 1442 while (getLexer().is(AsmToken::Comma)) { 1443 // Consume comma token 1444 getLexer().Lex(); 1445 1446 // Parse next operand 1447 if (parseOperand(Operands, Name)) 1448 return true; 1449 1450 ++OperandIdx; 1451 } 1452 1453 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1454 SMLoc Loc = getLexer().getLoc(); 1455 getParser().eatToEndOfStatement(); 1456 return Error(Loc, "unexpected token"); 1457 } 1458 1459 getParser().Lex(); // Consume the EndOfStatement. 1460 return false; 1461 } 1462 1463 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1464 RISCVMCExpr::VariantKind &Kind, 1465 int64_t &Addend) { 1466 Kind = RISCVMCExpr::VK_RISCV_None; 1467 Addend = 0; 1468 1469 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1470 Kind = RE->getKind(); 1471 Expr = RE->getSubExpr(); 1472 } 1473 1474 // It's a simple symbol reference or constant with no addend. 1475 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1476 return true; 1477 1478 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1479 if (!BE) 1480 return false; 1481 1482 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1483 return false; 1484 1485 if (BE->getOpcode() != MCBinaryExpr::Add && 1486 BE->getOpcode() != MCBinaryExpr::Sub) 1487 return false; 1488 1489 // We are able to support the subtraction of two symbol references 1490 if (BE->getOpcode() == MCBinaryExpr::Sub && 1491 isa<MCSymbolRefExpr>(BE->getRHS())) 1492 return true; 1493 1494 // See if the addend is a constant, otherwise there's more going 1495 // on here than we can deal with. 1496 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1497 if (!AddendExpr) 1498 return false; 1499 1500 Addend = AddendExpr->getValue(); 1501 if (BE->getOpcode() == MCBinaryExpr::Sub) 1502 Addend = -Addend; 1503 1504 // It's some symbol reference + a constant addend 1505 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1506 } 1507 1508 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1509 // This returns false if this function recognizes the directive 1510 // regardless of whether it is successfully handles or reports an 1511 // error. Otherwise it returns true to give the generic parser a 1512 // chance at recognizing it. 1513 StringRef IDVal = DirectiveID.getString(); 1514 1515 if (IDVal == ".option") 1516 return parseDirectiveOption(); 1517 1518 return true; 1519 } 1520 1521 bool RISCVAsmParser::parseDirectiveOption() { 1522 MCAsmParser &Parser = getParser(); 1523 // Get the option token. 1524 AsmToken Tok = Parser.getTok(); 1525 // At the moment only identifiers are supported. 1526 if (Tok.isNot(AsmToken::Identifier)) 1527 return Error(Parser.getTok().getLoc(), 1528 "unexpected token, expected identifier"); 1529 1530 StringRef Option = Tok.getIdentifier(); 1531 1532 if (Option == "push") { 1533 getTargetStreamer().emitDirectiveOptionPush(); 1534 1535 Parser.Lex(); 1536 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1537 return Error(Parser.getTok().getLoc(), 1538 "unexpected token, expected end of statement"); 1539 1540 pushFeatureBits(); 1541 return false; 1542 } 1543 1544 if (Option == "pop") { 1545 SMLoc StartLoc = Parser.getTok().getLoc(); 1546 getTargetStreamer().emitDirectiveOptionPop(); 1547 1548 Parser.Lex(); 1549 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1550 return Error(Parser.getTok().getLoc(), 1551 "unexpected token, expected end of statement"); 1552 1553 if (popFeatureBits()) 1554 return Error(StartLoc, ".option pop with no .option push"); 1555 1556 return false; 1557 } 1558 1559 if (Option == "rvc") { 1560 getTargetStreamer().emitDirectiveOptionRVC(); 1561 1562 Parser.Lex(); 1563 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1564 return Error(Parser.getTok().getLoc(), 1565 "unexpected token, expected end of statement"); 1566 1567 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1568 return false; 1569 } 1570 1571 if (Option == "norvc") { 1572 getTargetStreamer().emitDirectiveOptionNoRVC(); 1573 1574 Parser.Lex(); 1575 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1576 return Error(Parser.getTok().getLoc(), 1577 "unexpected token, expected end of statement"); 1578 1579 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1580 return false; 1581 } 1582 1583 if (Option == "relax") { 1584 getTargetStreamer().emitDirectiveOptionRelax(); 1585 1586 Parser.Lex(); 1587 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1588 return Error(Parser.getTok().getLoc(), 1589 "unexpected token, expected end of statement"); 1590 1591 setFeatureBits(RISCV::FeatureRelax, "relax"); 1592 return false; 1593 } 1594 1595 if (Option == "norelax") { 1596 getTargetStreamer().emitDirectiveOptionNoRelax(); 1597 1598 Parser.Lex(); 1599 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1600 return Error(Parser.getTok().getLoc(), 1601 "unexpected token, expected end of statement"); 1602 1603 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1604 return false; 1605 } 1606 1607 // Unknown option. 1608 Warning(Parser.getTok().getLoc(), 1609 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1610 "'norelax'"); 1611 Parser.eatToEndOfStatement(); 1612 return false; 1613 } 1614 1615 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1616 MCInst CInst; 1617 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1618 CInst.setLoc(Inst.getLoc()); 1619 S.EmitInstruction((Res ? CInst : Inst), getSTI()); 1620 } 1621 1622 void RISCVAsmParser::emitLoadImm(Register DestReg, int64_t Value, 1623 MCStreamer &Out) { 1624 RISCVMatInt::InstSeq Seq; 1625 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 1626 1627 Register SrcReg = RISCV::X0; 1628 for (RISCVMatInt::Inst &Inst : Seq) { 1629 if (Inst.Opc == RISCV::LUI) { 1630 emitToStreamer( 1631 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 1632 } else { 1633 emitToStreamer( 1634 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 1635 Inst.Imm)); 1636 } 1637 1638 // Only the first instruction has X0 as its source. 1639 SrcReg = DestReg; 1640 } 1641 } 1642 1643 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 1644 const MCExpr *Symbol, 1645 RISCVMCExpr::VariantKind VKHi, 1646 unsigned SecondOpcode, SMLoc IDLoc, 1647 MCStreamer &Out) { 1648 // A pair of instructions for PC-relative addressing; expands to 1649 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 1650 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 1651 MCContext &Ctx = getContext(); 1652 1653 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1654 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1655 Out.EmitLabel(TmpLabel); 1656 1657 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 1658 emitToStreamer( 1659 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 1660 1661 const MCExpr *RefToLinkTmpLabel = 1662 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1663 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1664 1665 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 1666 .addOperand(DestReg) 1667 .addOperand(TmpReg) 1668 .addExpr(RefToLinkTmpLabel)); 1669 } 1670 1671 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1672 MCStreamer &Out) { 1673 // The load local address pseudo-instruction "lla" is used in PC-relative 1674 // addressing of local symbols: 1675 // lla rdest, symbol 1676 // expands to 1677 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1678 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1679 MCOperand DestReg = Inst.getOperand(0); 1680 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1681 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1682 RISCV::ADDI, IDLoc, Out); 1683 } 1684 1685 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 1686 MCStreamer &Out) { 1687 // The load address pseudo-instruction "la" is used in PC-relative and 1688 // GOT-indirect addressing of global symbols: 1689 // la rdest, symbol 1690 // expands to either (for non-PIC) 1691 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1692 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1693 // or (for PIC) 1694 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 1695 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1696 MCOperand DestReg = Inst.getOperand(0); 1697 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1698 unsigned SecondOpcode; 1699 RISCVMCExpr::VariantKind VKHi; 1700 // FIXME: Should check .option (no)pic when implemented 1701 if (getContext().getObjectFileInfo()->isPositionIndependent()) { 1702 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1703 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 1704 } else { 1705 SecondOpcode = RISCV::ADDI; 1706 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 1707 } 1708 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 1709 } 1710 1711 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 1712 MCStreamer &Out) { 1713 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 1714 // initial-exec TLS model addressing of global symbols: 1715 // la.tls.ie rdest, symbol 1716 // expands to 1717 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 1718 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1719 MCOperand DestReg = Inst.getOperand(0); 1720 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1721 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1722 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 1723 SecondOpcode, IDLoc, Out); 1724 } 1725 1726 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 1727 MCStreamer &Out) { 1728 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 1729 // global-dynamic TLS model addressing of global symbols: 1730 // la.tls.gd rdest, symbol 1731 // expands to 1732 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 1733 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1734 MCOperand DestReg = Inst.getOperand(0); 1735 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1736 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 1737 RISCV::ADDI, IDLoc, Out); 1738 } 1739 1740 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 1741 SMLoc IDLoc, MCStreamer &Out, 1742 bool HasTmpReg) { 1743 // The load/store pseudo-instruction does a pc-relative load with 1744 // a symbol. 1745 // 1746 // The expansion looks like this 1747 // 1748 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 1749 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 1750 MCOperand DestReg = Inst.getOperand(0); 1751 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 1752 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 1753 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 1754 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 1755 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1756 Opcode, IDLoc, Out); 1757 } 1758 1759 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 1760 OperandVector &Operands) { 1761 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 1762 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 1763 if (Inst.getOperand(2).getReg() != RISCV::X4) { 1764 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 1765 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 1766 "%tprel_add modifier"); 1767 } 1768 1769 return false; 1770 } 1771 1772 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1773 OperandVector &Operands, 1774 MCStreamer &Out) { 1775 Inst.setLoc(IDLoc); 1776 1777 switch (Inst.getOpcode()) { 1778 default: 1779 break; 1780 case RISCV::PseudoLI: { 1781 Register Reg = Inst.getOperand(0).getReg(); 1782 const MCOperand &Op1 = Inst.getOperand(1); 1783 if (Op1.isExpr()) { 1784 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 1785 // Just convert to an addi. This allows compatibility with gas. 1786 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1787 .addReg(Reg) 1788 .addReg(RISCV::X0) 1789 .addExpr(Op1.getExpr())); 1790 return false; 1791 } 1792 int64_t Imm = Inst.getOperand(1).getImm(); 1793 // On RV32 the immediate here can either be a signed or an unsigned 1794 // 32-bit number. Sign extension has to be performed to ensure that Imm 1795 // represents the expected signed 64-bit number. 1796 if (!isRV64()) 1797 Imm = SignExtend64<32>(Imm); 1798 emitLoadImm(Reg, Imm, Out); 1799 return false; 1800 } 1801 case RISCV::PseudoLLA: 1802 emitLoadLocalAddress(Inst, IDLoc, Out); 1803 return false; 1804 case RISCV::PseudoLA: 1805 emitLoadAddress(Inst, IDLoc, Out); 1806 return false; 1807 case RISCV::PseudoLA_TLS_IE: 1808 emitLoadTLSIEAddress(Inst, IDLoc, Out); 1809 return false; 1810 case RISCV::PseudoLA_TLS_GD: 1811 emitLoadTLSGDAddress(Inst, IDLoc, Out); 1812 return false; 1813 case RISCV::PseudoLB: 1814 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 1815 return false; 1816 case RISCV::PseudoLBU: 1817 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 1818 return false; 1819 case RISCV::PseudoLH: 1820 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 1821 return false; 1822 case RISCV::PseudoLHU: 1823 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 1824 return false; 1825 case RISCV::PseudoLW: 1826 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 1827 return false; 1828 case RISCV::PseudoLWU: 1829 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 1830 return false; 1831 case RISCV::PseudoLD: 1832 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 1833 return false; 1834 case RISCV::PseudoFLW: 1835 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 1836 return false; 1837 case RISCV::PseudoFLD: 1838 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 1839 return false; 1840 case RISCV::PseudoSB: 1841 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 1842 return false; 1843 case RISCV::PseudoSH: 1844 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 1845 return false; 1846 case RISCV::PseudoSW: 1847 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 1848 return false; 1849 case RISCV::PseudoSD: 1850 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 1851 return false; 1852 case RISCV::PseudoFSW: 1853 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 1854 return false; 1855 case RISCV::PseudoFSD: 1856 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 1857 return false; 1858 case RISCV::PseudoAddTPRel: 1859 if (checkPseudoAddTPRel(Inst, Operands)) 1860 return true; 1861 break; 1862 } 1863 1864 emitToStreamer(Out, Inst); 1865 return false; 1866 } 1867 1868 extern "C" void LLVMInitializeRISCVAsmParser() { 1869 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 1870 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 1871 } 1872