Skip to content

[RISCV] Add symbol parsing support for XAndesPerf branch and gp-related instructions #137748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,14 @@ ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_ABS20_U, 192)
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_BRANCH, 193)
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_32, 194)
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_JUMP_PLT, 195)

// Andes Nonstandard Relocations
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_BRANCH_10, 241)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_18S0_I, 246)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S1_I, 247)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S2_I, 248)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S3_I, 249)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_18S0_S, 250)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S1_S, 251)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S2_S, 252)
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S3_S, 253)
Comment on lines +30 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there non-llvm documentation for these relocations and the instructions/formats they apply to?

Separately, I am thinking of refactoring this file as with these changes, ELD (an external user) will break: https://github.com/qualcomm/eld/blob/b3197fa1e54b470d36d8bdff7a10b469287caa3a/lib/Target/RISCV/RISCVRelocationInternal.h#L70 - this is because I didn't do a good job originally to predict this, rather than a problem you have caused with these changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will ask our guys to release such a document for these relocations.

36 changes: 8 additions & 28 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,14 +533,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
}

// True if operand is a symbol with no modifiers, or a constant with no
// modifiers and isShiftedInt<N-1, 1>(Op).
template <int N> bool isBareSimmNLsb0() const {
// modifiers and isShiftedInt<N-K, K>(Op).
template <int N, int K> bool isBareSimmNLsbK() const {
if (!isImm())
return false;

int64_t Imm;
if (evaluateConstantImm(getImm(), Imm))
return isShiftedInt<N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
return isShiftedInt<N - K, K>(fixImmediateForRV32(Imm, isRV64Imm()));

RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
Expand Down Expand Up @@ -852,10 +852,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return SignExtend64<32>(Imm);
}

bool isSImm11Lsb0() const {
return isSImmPred([](int64_t Imm) { return isShiftedInt<10, 1>(Imm); });
}

bool isSImm12() const {
if (!isImm())
return false;
Expand Down Expand Up @@ -948,22 +944,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
[](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
}

bool isSImm18() const {
return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); });
}

bool isSImm18Lsb0() const {
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 1>(Imm); });
}

bool isSImm19Lsb00() const {
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 2>(Imm); });
}

bool isSImm20Lsb000() const {
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 3>(Imm); });
}

bool isSImm32Lsb0() const {
return isSImmPred([](int64_t Imm) { return isShiftedInt<31, 1>(Imm); });
}
Expand Down Expand Up @@ -1535,7 +1515,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
(1 << 10) - 1);
case Match_InvalidSImm11Lsb0:
case Match_InvalidBareSImm11Lsb0:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
"immediate must be a multiple of 2 bytes in the range");
Expand Down Expand Up @@ -1611,18 +1591,18 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
(1 << 4),
"immediate must be in the range");
}
case Match_InvalidSImm18:
case Match_InvalidBareSImm18:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
(1 << 17) - 1);
case Match_InvalidSImm18Lsb0:
case Match_InvalidBareSImm18Lsb0:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
"immediate must be a multiple of 2 bytes in the range");
case Match_InvalidSImm19Lsb00:
case Match_InvalidBareSImm19Lsb00:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
"immediate must be a multiple of 4 bytes in the range");
case Match_InvalidSImm20Lsb000:
case Match_InvalidBareSImm20Lsb000:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
"immediate must be a multiple of 8 bytes in the range");
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_riscv_qc_e_32", 16, 32, 0},
{"fixup_riscv_qc_abs20_u", 12, 20, 0},
{"fixup_riscv_qc_e_jump_plt", 0, 48, MCFixupKindInfo::FKF_IsPCRel},

// Andes fixups
{"fixup_riscv_nds_branch_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
};
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
"Not all fixup kinds added to Infos array");
Expand Down Expand Up @@ -568,6 +571,21 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
(Bit15_13 << 17) | (Bit4_1 << 8) | (Bit11 << 7);
return Value;
}
case RISCV::fixup_riscv_nds_branch_10: {
if (!isInt<11>(Value))
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
if (Value & 0x1)
Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
// Need to extract imm[10], imm[9:5], imm[4:1] from the 11-bit Value.
unsigned Sbit = (Value >> 10) & 0x1;
unsigned Hi5 = (Value >> 5) & 0x1f;
unsigned Lo4 = (Value >> 1) & 0xf;
// Inst{31} = Sbit;
// Inst{29-25} = Hi5;
// Inst{11-8} = Lo4;
Value = (Sbit << 31) | (Hi5 << 25) | (Lo4 << 8);
return Value;
}
}
}

Expand Down
17 changes: 13 additions & 4 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,21 @@ enum {
InstFormatQC_EB = 24,
InstFormatQC_EJ = 25,
InstFormatQC_ES = 26,
InstFormatOther = 31,

InstFormatMask = 31,
InstFormatNDS_BRANCH_10 = 27,
InstFormatNDS_GPREL_18S0_I = 28,
InstFormatNDS_GPREL_17S1_I = 29,
InstFormatNDS_GPREL_17S2_I = 30,
InstFormatNDS_GPREL_17S3_I = 31,
InstFormatNDS_GPREL_18S0_S = 32,
InstFormatNDS_GPREL_17S1_S = 33,
InstFormatNDS_GPREL_17S2_S = 34,
InstFormatNDS_GPREL_17S3_S = 35,
InstFormatOther = 63,

InstFormatMask = 63,
InstFormatShift = 0,

ConstraintShift = InstFormatShift + 5,
ConstraintShift = InstFormatShift + 6,
VS2Constraint = 0b001 << ConstraintShift,
VS1Constraint = 0b010 << ConstraintShift,
VMConstraint = 0b100 << ConstraintShift,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_RISCV_QC_E_BRANCH;
case RISCV::fixup_riscv_qc_e_jump_plt:
return ELF::R_RISCV_QC_E_JUMP_PLT;
case RISCV::fixup_riscv_nds_branch_10:
return ELF::R_RISCV_NDS_BRANCH_10;
}
}

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ enum Fixups {
// 32-bit fixup for symbol references in the 48-bit qc.j/qc.jal instructions
fixup_riscv_qc_e_jump_plt,

// Andes specific fixups
// 10-bit fixup for symbol references in the xandesperf branch instruction
fixup_riscv_nds_branch_10,

// Used as a sentinel, must be the last
fixup_riscv_invalid,
NumTargetFixupKinds = fixup_riscv_invalid - FirstTargetFixupKind
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,24 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
FixupKind = RISCV::fixup_riscv_qc_e_32;
} else if (MIFrm == RISCVII::InstFormatQC_EJ) {
FixupKind = RISCV::fixup_riscv_qc_e_jump_plt;
} else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
FixupKind = RISCV::fixup_riscv_nds_branch_10;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_I) {
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_I;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_I) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_I;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_I) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_I;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_I) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_I;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_S) {
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_S;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_S) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_S;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_S) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_S;
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_S) {
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_S;
}
}

Expand Down
103 changes: 56 additions & 47 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,46 @@
// Format specifies the encoding used by the instruction. This is used by
// RISCVMCCodeEmitter to determine which form of fixup to use. These
// definitions must be kept in-sync with RISCVBaseInfo.h.
class InstFormat<bits<5> val> {
bits<5> Value = val;
}
def InstFormatPseudo : InstFormat<0>;
def InstFormatR : InstFormat<1>;
def InstFormatR4 : InstFormat<2>;
def InstFormatI : InstFormat<3>;
def InstFormatS : InstFormat<4>;
def InstFormatB : InstFormat<5>;
def InstFormatU : InstFormat<6>;
def InstFormatJ : InstFormat<7>;
def InstFormatCR : InstFormat<8>;
def InstFormatCI : InstFormat<9>;
def InstFormatCSS : InstFormat<10>;
def InstFormatCIW : InstFormat<11>;
def InstFormatCL : InstFormat<12>;
def InstFormatCS : InstFormat<13>;
def InstFormatCA : InstFormat<14>;
def InstFormatCB : InstFormat<15>;
def InstFormatCJ : InstFormat<16>;
def InstFormatCU : InstFormat<17>;
def InstFormatCLB : InstFormat<18>;
def InstFormatCLH : InstFormat<19>;
def InstFormatCSB : InstFormat<20>;
def InstFormatCSH : InstFormat<21>;
def InstFormatQC_EAI : InstFormat<22>;
def InstFormatQC_EI : InstFormat<23>;
def InstFormatQC_EB : InstFormat<24>;
def InstFormatQC_EJ : InstFormat<25>;
def InstFormatQC_ES : InstFormat<26>;
def InstFormatOther : InstFormat<31>;
class InstFormat<bits<6> val> {
bits<6> Value = val;
}
def InstFormatPseudo : InstFormat<0>;
def InstFormatR : InstFormat<1>;
def InstFormatR4 : InstFormat<2>;
def InstFormatI : InstFormat<3>;
def InstFormatS : InstFormat<4>;
def InstFormatB : InstFormat<5>;
def InstFormatU : InstFormat<6>;
def InstFormatJ : InstFormat<7>;
def InstFormatCR : InstFormat<8>;
def InstFormatCI : InstFormat<9>;
def InstFormatCSS : InstFormat<10>;
def InstFormatCIW : InstFormat<11>;
def InstFormatCL : InstFormat<12>;
def InstFormatCS : InstFormat<13>;
def InstFormatCA : InstFormat<14>;
def InstFormatCB : InstFormat<15>;
def InstFormatCJ : InstFormat<16>;
def InstFormatCU : InstFormat<17>;
def InstFormatCLB : InstFormat<18>;
def InstFormatCLH : InstFormat<19>;
def InstFormatCSB : InstFormat<20>;
def InstFormatCSH : InstFormat<21>;
def InstFormatQC_EAI : InstFormat<22>;
def InstFormatQC_EI : InstFormat<23>;
def InstFormatQC_EB : InstFormat<24>;
def InstFormatQC_EJ : InstFormat<25>;
def InstFormatQC_ES : InstFormat<26>;
def InstFormatNDS_BRANCH_10 : InstFormat<27>;
def InstFormatNDS_GPREL_18S0_I : InstFormat<28>;
def InstFormatNDS_GPREL_17S1_I : InstFormat<29>;
def InstFormatNDS_GPREL_17S2_I : InstFormat<30>;
def InstFormatNDS_GPREL_17S3_I : InstFormat<31>;
def InstFormatNDS_GPREL_18S0_S : InstFormat<32>;
def InstFormatNDS_GPREL_17S1_S : InstFormat<33>;
def InstFormatNDS_GPREL_17S2_S : InstFormat<34>;
def InstFormatNDS_GPREL_17S3_S : InstFormat<35>;
def InstFormatOther : InstFormat<63>;


class RISCVVConstraint<bits<3> val> {
Expand Down Expand Up @@ -190,50 +199,50 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
let AsmString = opcodestr # !if(!empty(argstr), "", "\t" # argstr);
let Pattern = pattern;

let TSFlags{4-0} = format.Value;
let TSFlags{5-0} = format.Value;

// Defaults
RISCVVConstraint RVVConstraint = NoConstraint;
let TSFlags{7-5} = RVVConstraint.Value;
let TSFlags{8-6} = RVVConstraint.Value;

bits<3> VLMul = 0;
let TSFlags{10-8} = VLMul;
let TSFlags{11-9} = VLMul;

bit IsTiedPseudo = 0;
let TSFlags{11} = IsTiedPseudo;
let TSFlags{12} = IsTiedPseudo;

bit HasSEWOp = 0;
let TSFlags{12} = HasSEWOp;
let TSFlags{13} = HasSEWOp;

bit HasVLOp = 0;
let TSFlags{13} = HasVLOp;
let TSFlags{14} = HasVLOp;

bit HasVecPolicyOp = 0;
let TSFlags{14} = HasVecPolicyOp;
let TSFlags{15} = HasVecPolicyOp;

bit IsRVVWideningReduction = 0;
let TSFlags{15} = IsRVVWideningReduction;
let TSFlags{16} = IsRVVWideningReduction;

bit UsesMaskPolicy = 0;
let TSFlags{16} = UsesMaskPolicy;
let TSFlags{17} = UsesMaskPolicy;

// Indicates that the result can be considered sign extended from bit 31. Some
// instructions with this flag aren't W instructions, but are either sign
// extended from a smaller size, always outputs a small integer, or put zeros
// in bits 63:31. Used by the SExtWRemoval pass.
bit IsSignExtendingOpW = 0;
let TSFlags{17} = IsSignExtendingOpW;
let TSFlags{18} = IsSignExtendingOpW;

bit HasRoundModeOp = 0;
let TSFlags{18} = HasRoundModeOp;
let TSFlags{19} = HasRoundModeOp;

// This is only valid when HasRoundModeOp is set to 1. HasRoundModeOp is set
// to 1 for vector fixed-point or floating-point intrinsics. This bit is
// processed under pass 'RISCVInsertReadWriteCSR' pass to distinguish between
// fixed-point / floating-point instructions and emit appropriate read/write
// to the correct CSR.
bit UsesVXRM = 0;
let TSFlags{19} = UsesVXRM;
let TSFlags{20} = UsesVXRM;

// Indicates whether these instructions can partially overlap between source
// registers and destination registers according to the vector spec.
Expand All @@ -242,19 +251,19 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
// 2 -> narrowing case
// 3 -> widening case
bits<2> TargetOverlapConstraintType = 0;
let TSFlags{21-20} = TargetOverlapConstraintType;
let TSFlags{22-21} = TargetOverlapConstraintType;

// Most vector instructions are elementwise, but some may depend on the value
// of VL (e.g. vslide1down.vx), and others may depend on the VL and mask
// (e.g. vredsum.vs, viota.m). Mark these instructions so that peepholes avoid
// changing their VL and/or mask.
EltDeps ElementsDependOn = EltDepsNone;
let TSFlags{22} = ElementsDependOn.VL;
let TSFlags{23} = ElementsDependOn.Mask;
let TSFlags{23} = ElementsDependOn.VL;
let TSFlags{24} = ElementsDependOn.Mask;

// Indicates the EEW of a vector instruction's destination operand.
EEW DestEEW = EEWSEWx1;
let TSFlags{25-24} = DestEEW.Value;
let TSFlags{26-25} = DestEEW.Value;
}

class RVInst<dag outs, dag ins, string opcodestr, string argstr,
Expand Down
17 changes: 16 additions & 1 deletion llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,24 @@ class UImmAsmOperand<int width, string suffix = "">
: ImmAsmOperand<"U", width, suffix> {
}

class BareSImmNAsmOperand<int width>
: ImmAsmOperand<"BareS", width, ""> {
let PredicateMethod = "isBareSimmN<" # width # ">";
}

class BareSImmNLsb0AsmOperand<int width>
: ImmAsmOperand<"BareS", width, "Lsb0"> {
let PredicateMethod = "isBareSimmNLsb0<" # width # ">";
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 1>";
}

class BareSImmNLsb00AsmOperand<int width>
: ImmAsmOperand<"BareS", width, "Lsb00"> {
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 2>";
}

class BareSImmNLsb000AsmOperand<int width>
: ImmAsmOperand<"BareS", width, "Lsb000"> {
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 3>";
}

class RISCVOp<ValueType vt = XLenVT> : Operand<vt> {
Expand Down
Loading
Loading