@@ -169,6 +169,12 @@ class RISCVAsmParser : public MCTargetAsmParser {
169169 // 'add' is an overloaded mnemonic.
170170 bool checkPseudoAddTPRel (MCInst &Inst, OperandVector &Operands);
171171
172+ // Checks that a PseudoTLSDESCCall is using x5/t0 in its output operand.
173+ // Enforcing this using a restricted register class for the output
174+ // operand of PseudoTLSDESCCall results in a poor diagnostic due to the fact
175+ // 'jalr' is an overloaded mnemonic.
176+ bool checkPseudoTLSDESCCall (MCInst &Inst, OperandVector &Operands);
177+
172178 // Check instruction constraints.
173179 bool validateInstruction (MCInst &Inst, OperandVector &Operands);
174180
@@ -549,6 +555,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
549555 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
550556 }
551557
558+ bool isTLSDESCCallSymbol () const {
559+ int64_t Imm;
560+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
561+ // Must be of 'immediate' type but not a constant.
562+ if (!isImm () || evaluateConstantImm (getImm (), Imm, VK))
563+ return false ;
564+ return RISCVAsmParser::classifySymbolRef (getImm (), VK) &&
565+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_CALL;
566+ }
567+
552568 bool isCSRSystemRegister () const { return isSystemRegister (); }
553569
554570 bool isVTypeImm (unsigned N) const {
@@ -601,7 +617,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
601617 if (!isImm ())
602618 return false ;
603619 bool IsConstantImm = evaluateConstantImm (getImm (), Imm, VK);
604- if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
620+ if (VK == RISCVMCExpr::VK_RISCV_LO ||
621+ VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
622+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
623+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO)
605624 return true ;
606625 // Given only Imm, ensuring that the actually specified constant is either
607626 // a signed or unsigned 64-bit number is unfortunately impossible.
@@ -854,7 +873,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
854873 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
855874 VK == RISCVMCExpr::VK_RISCV_LO ||
856875 VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
857- VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
876+ VK == RISCVMCExpr::VK_RISCV_TPREL_LO ||
877+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
878+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO);
858879 }
859880
860881 bool isSImm12Lsb0 () const { return isBareSimmNLsb0<12 >(); }
@@ -911,14 +932,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
911932 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
912933 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
913934 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
914- VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
915- } else {
916- return isUInt<20 >(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
917- VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
918- VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
919- VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
920- VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
935+ VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
936+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
921937 }
938+
939+ return isUInt<20 >(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
940+ VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
941+ VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
942+ VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
943+ VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
944+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
922945 }
923946
924947 bool isSImm21Lsb0JAL () const { return isBareSimmNLsb0<21 >(); }
@@ -1556,6 +1579,11 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15561579 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
15571580 return Error (ErrorLoc, " operand must be a symbol with %tprel_add modifier" );
15581581 }
1582+ case Match_InvalidTLSDESCCallSymbol: {
1583+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
1584+ return Error (ErrorLoc,
1585+ " operand must be a symbol with %tlsdesc_call modifier" );
1586+ }
15591587 case Match_InvalidRTZArg: {
15601588 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
15611589 return Error (ErrorLoc, " operand must be 'rtz' floating-point rounding mode" );
@@ -3324,6 +3352,19 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
33243352 return false ;
33253353}
33263354
3355+ bool RISCVAsmParser::checkPseudoTLSDESCCall (MCInst &Inst,
3356+ OperandVector &Operands) {
3357+ assert (Inst.getOpcode () == RISCV::PseudoTLSDESCCall && " Invalid instruction" );
3358+ assert (Inst.getOperand (0 ).isReg () && " Unexpected operand kind" );
3359+ if (Inst.getOperand (0 ).getReg () != RISCV::X5) {
3360+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3 ]).getStartLoc ();
3361+ return Error (ErrorLoc, " the output operand must be t0/x5 when using "
3362+ " %tlsdesc_call modifier" );
3363+ }
3364+
3365+ return false ;
3366+ }
3367+
33273368std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp () const {
33283369 return RISCVOperand::createReg (RISCV::NoRegister, llvm::SMLoc (),
33293370 llvm::SMLoc ());
@@ -3559,6 +3600,10 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
35593600 if (checkPseudoAddTPRel (Inst, Operands))
35603601 return true ;
35613602 break ;
3603+ case RISCV::PseudoTLSDESCCall:
3604+ if (checkPseudoTLSDESCCall (Inst, Operands))
3605+ return true ;
3606+ break ;
35623607 case RISCV::PseudoSEXT_B:
35633608 emitPseudoExtend (Inst, /* SignExtend=*/ true , /* Width=*/ 8 , IDLoc, Out);
35643609 return false ;
0 commit comments