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