@@ -169,6 +169,12 @@ class RISCVAsmParser : public MCTargetAsmParser {
169
169
// 'add' is an overloaded mnemonic.
170
170
bool checkPseudoAddTPRel (MCInst &Inst, OperandVector &Operands);
171
171
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
+
172
178
// Check instruction constraints.
173
179
bool validateInstruction (MCInst &Inst, OperandVector &Operands);
174
180
@@ -549,6 +555,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
549
555
VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
550
556
}
551
557
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
+
552
568
bool isCSRSystemRegister () const { return isSystemRegister (); }
553
569
554
570
bool isVTypeImm (unsigned N) const {
@@ -601,7 +617,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
601
617
if (!isImm ())
602
618
return false ;
603
619
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)
605
624
return true ;
606
625
// Given only Imm, ensuring that the actually specified constant is either
607
626
// a signed or unsigned 64-bit number is unfortunately impossible.
@@ -854,7 +873,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
854
873
return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
855
874
VK == RISCVMCExpr::VK_RISCV_LO ||
856
875
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);
858
879
}
859
880
860
881
bool isSImm12Lsb0 () const { return isBareSimmNLsb0<12 >(); }
@@ -911,14 +932,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
911
932
return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
912
933
VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
913
934
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);
921
937
}
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);
922
945
}
923
946
924
947
bool isSImm21Lsb0JAL () const { return isBareSimmNLsb0<21 >(); }
@@ -1556,6 +1579,11 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1556
1579
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
1557
1580
return Error (ErrorLoc, " operand must be a symbol with %tprel_add modifier" );
1558
1581
}
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
+ }
1559
1587
case Match_InvalidRTZArg: {
1560
1588
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
1561
1589
return Error (ErrorLoc, " operand must be 'rtz' floating-point rounding mode" );
@@ -3324,6 +3352,19 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3324
3352
return false ;
3325
3353
}
3326
3354
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
+
3327
3368
std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp () const {
3328
3369
return RISCVOperand::createReg (RISCV::NoRegister, llvm::SMLoc (),
3329
3370
llvm::SMLoc ());
@@ -3559,6 +3600,10 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3559
3600
if (checkPseudoAddTPRel (Inst, Operands))
3560
3601
return true ;
3561
3602
break ;
3603
+ case RISCV::PseudoTLSDESCCall:
3604
+ if (checkPseudoTLSDESCCall (Inst, Operands))
3605
+ return true ;
3606
+ break ;
3562
3607
case RISCV::PseudoSEXT_B:
3563
3608
emitPseudoExtend (Inst, /* SignExtend=*/ true , /* Width=*/ 8 , IDLoc, Out);
3564
3609
return false ;
0 commit comments