Skip to content

Commit 347384f

Browse files
committed
[RISCV] Add relocation support for XAndesperf branch and gp-related instructions
1 parent 7e6c1bd commit 347384f

16 files changed

+330
-118
lines changed

llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,14 @@ ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_ABS20_U, 192)
2626
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_BRANCH, 193)
2727
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_32, 194)
2828
ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_CALL_PLT, 195)
29+
30+
// Andes Nonstandard Relocations
31+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_BRANCH_10, 241)
32+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_18S0_I, 246)
33+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S1_I, 247)
34+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S2_I, 248)
35+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S3_I, 249)
36+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_18S0_S, 250)
37+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S1_S, 251)
38+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S2_S, 252)
39+
ELF_RISCV_NONSTANDARD_RELOC(ANDES, R_RISCV_NDS_GPREL_17S3_S, 253)

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -534,14 +534,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
534534
}
535535

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

542542
int64_t Imm;
543543
if (evaluateConstantImm(getImm(), Imm))
544-
return isShiftedInt<N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
544+
return isShiftedInt<N - K, K>(fixImmediateForRV32(Imm, isRV64Imm()));
545545

546546
RISCV::Specifier VK = RISCV::S_None;
547547
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
@@ -857,10 +857,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
857857
return SignExtend64<32>(Imm);
858858
}
859859

860-
bool isSImm11Lsb0() const {
861-
return isSImmPred([](int64_t Imm) { return isShiftedInt<10, 1>(Imm); });
862-
}
863-
864860
bool isSImm12() const {
865861
if (!isImm())
866862
return false;
@@ -951,22 +947,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
951947
[](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
952948
}
953949

954-
bool isSImm18() const {
955-
return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); });
956-
}
957-
958-
bool isSImm18Lsb0() const {
959-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 1>(Imm); });
960-
}
961-
962-
bool isSImm19Lsb00() const {
963-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 2>(Imm); });
964-
}
965-
966-
bool isSImm20Lsb000() const {
967-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 3>(Imm); });
968-
}
969-
970950
bool isSImm32Lsb0() const {
971951
return isSImmPred([](int64_t Imm) { return isShiftedInt<31, 1>(Imm); });
972952
}
@@ -1547,7 +1527,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15471527
case Match_InvalidSImm11:
15481528
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
15491529
(1 << 10) - 1);
1550-
case Match_InvalidSImm11Lsb0:
1530+
case Match_InvalidBareSImm11Lsb0:
15511531
return generateImmOutOfRangeError(
15521532
Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
15531533
"immediate must be a multiple of 2 bytes in the range");
@@ -1623,18 +1603,18 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16231603
(1 << 4),
16241604
"immediate must be in the range");
16251605
}
1626-
case Match_InvalidSImm18:
1606+
case Match_InvalidBareSImm18:
16271607
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
16281608
(1 << 17) - 1);
1629-
case Match_InvalidSImm18Lsb0:
1609+
case Match_InvalidBareSImm18Lsb0:
16301610
return generateImmOutOfRangeError(
16311611
Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
16321612
"immediate must be a multiple of 2 bytes in the range");
1633-
case Match_InvalidSImm19Lsb00:
1613+
case Match_InvalidBareSImm19Lsb00:
16341614
return generateImmOutOfRangeError(
16351615
Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
16361616
"immediate must be a multiple of 4 bytes in the range");
1637-
case Match_InvalidSImm20Lsb000:
1617+
case Match_InvalidBareSImm20Lsb000:
16381618
return generateImmOutOfRangeError(
16391619
Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
16401620
"immediate must be a multiple of 8 bytes in the range");

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
8686
{"fixup_riscv_qc_e_32", 16, 32, 0},
8787
{"fixup_riscv_qc_abs20_u", 12, 20, 0},
8888
{"fixup_riscv_qc_e_call_plt", 0, 48, MCFixupKindInfo::FKF_IsPCRel},
89+
90+
// Andes fixups
91+
{"fixup_riscv_nds_branch_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
8992
};
9093
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
9194
"Not all fixup kinds added to Infos array");
@@ -567,6 +570,21 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
567570
(Bit15_13 << 17) | (Bit4_1 << 8) | (Bit11 << 7);
568571
return Value;
569572
}
573+
case RISCV::fixup_riscv_nds_branch_10: {
574+
if (!isInt<11>(Value))
575+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
576+
if (Value & 0x1)
577+
Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
578+
// Need to extract imm[10], imm[9:5], imm[4:1] from the 11-bit Value.
579+
unsigned Sbit = (Value >> 10) & 0x1;
580+
unsigned Hi5 = (Value >> 5) & 0x1f;
581+
unsigned Lo4 = (Value >> 1) & 0xf;
582+
// Inst{31} = Sbit;
583+
// Inst{29-25} = Hi5;
584+
// Inst{11-8} = Lo4;
585+
Value = (Sbit << 31) | (Hi5 << 25) | (Lo4 << 8);
586+
return Value;
587+
}
570588
}
571589
}
572590

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,21 @@ enum {
5656
InstFormatQC_EB = 24,
5757
InstFormatQC_EJ = 25,
5858
InstFormatQC_ES = 26,
59-
InstFormatOther = 31,
60-
61-
InstFormatMask = 31,
59+
InstFormatNDS_BRANCH_10 = 27,
60+
InstFormatNDS_GPREL_18S0_I = 28,
61+
InstFormatNDS_GPREL_17S1_I = 29,
62+
InstFormatNDS_GPREL_17S2_I = 30,
63+
InstFormatNDS_GPREL_17S3_I = 31,
64+
InstFormatNDS_GPREL_18S0_S = 32,
65+
InstFormatNDS_GPREL_17S1_S = 33,
66+
InstFormatNDS_GPREL_17S2_S = 34,
67+
InstFormatNDS_GPREL_17S3_S = 35,
68+
InstFormatOther = 63,
69+
70+
InstFormatMask = 63,
6271
InstFormatShift = 0,
6372

64-
ConstraintShift = InstFormatShift + 5,
73+
ConstraintShift = InstFormatShift + 6,
6574
VS2Constraint = 0b001 << ConstraintShift,
6675
VS1Constraint = 0b010 << ConstraintShift,
6776
VMConstraint = 0b100 << ConstraintShift,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ unsigned RISCVELFObjectWriter::getRelocType(const MCFixup &Fixup,
103103
return ELF::R_RISCV_QC_E_BRANCH;
104104
case RISCV::fixup_riscv_qc_e_call_plt:
105105
return ELF::R_RISCV_QC_E_CALL_PLT;
106+
case RISCV::fixup_riscv_nds_branch_10:
107+
return ELF::R_RISCV_NDS_BRANCH_10;
106108
}
107109
}
108110

llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ enum Fixups {
5656
// 32-bit fixup for symbol references in the 48-bit qc.j/qc.jal instructions
5757
fixup_riscv_qc_e_call_plt,
5858

59+
// Andes specific fixups
60+
// 10-bit fixup for symbol references in the xandesperf branch instruction
61+
fixup_riscv_nds_branch_10,
62+
5963
// Used as a sentinel, must be the last
6064
fixup_riscv_invalid,
6165
NumTargetFixupKinds = fixup_riscv_invalid - FirstTargetFixupKind

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,24 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
647647
} else if (MIFrm == RISCVII::InstFormatQC_EJ) {
648648
FixupKind = RISCV::fixup_riscv_qc_e_call_plt;
649649
RelaxCandidate = true;
650+
} else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
651+
FixupKind = RISCV::fixup_riscv_nds_branch_10;
652+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_I) {
653+
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_I;
654+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_I) {
655+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_I;
656+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_I) {
657+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_I;
658+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_I) {
659+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_I;
660+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_S) {
661+
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_S;
662+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_S) {
663+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_S;
664+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_S) {
665+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_S;
666+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_S) {
667+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_S;
650668
}
651669
}
652670

llvm/lib/Target/RISCV/RISCVInstrFormats.td

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,46 @@
2727
// Format specifies the encoding used by the instruction. This is used by
2828
// RISCVMCCodeEmitter to determine which form of fixup to use. These
2929
// definitions must be kept in-sync with RISCVBaseInfo.h.
30-
class InstFormat<bits<5> val> {
31-
bits<5> Value = val;
32-
}
33-
def InstFormatPseudo : InstFormat<0>;
34-
def InstFormatR : InstFormat<1>;
35-
def InstFormatR4 : InstFormat<2>;
36-
def InstFormatI : InstFormat<3>;
37-
def InstFormatS : InstFormat<4>;
38-
def InstFormatB : InstFormat<5>;
39-
def InstFormatU : InstFormat<6>;
40-
def InstFormatJ : InstFormat<7>;
41-
def InstFormatCR : InstFormat<8>;
42-
def InstFormatCI : InstFormat<9>;
43-
def InstFormatCSS : InstFormat<10>;
44-
def InstFormatCIW : InstFormat<11>;
45-
def InstFormatCL : InstFormat<12>;
46-
def InstFormatCS : InstFormat<13>;
47-
def InstFormatCA : InstFormat<14>;
48-
def InstFormatCB : InstFormat<15>;
49-
def InstFormatCJ : InstFormat<16>;
50-
def InstFormatCU : InstFormat<17>;
51-
def InstFormatCLB : InstFormat<18>;
52-
def InstFormatCLH : InstFormat<19>;
53-
def InstFormatCSB : InstFormat<20>;
54-
def InstFormatCSH : InstFormat<21>;
55-
def InstFormatQC_EAI : InstFormat<22>;
56-
def InstFormatQC_EI : InstFormat<23>;
57-
def InstFormatQC_EB : InstFormat<24>;
58-
def InstFormatQC_EJ : InstFormat<25>;
59-
def InstFormatQC_ES : InstFormat<26>;
60-
def InstFormatOther : InstFormat<31>;
30+
class InstFormat<bits<6> val> {
31+
bits<6> Value = val;
32+
}
33+
def InstFormatPseudo : InstFormat<0>;
34+
def InstFormatR : InstFormat<1>;
35+
def InstFormatR4 : InstFormat<2>;
36+
def InstFormatI : InstFormat<3>;
37+
def InstFormatS : InstFormat<4>;
38+
def InstFormatB : InstFormat<5>;
39+
def InstFormatU : InstFormat<6>;
40+
def InstFormatJ : InstFormat<7>;
41+
def InstFormatCR : InstFormat<8>;
42+
def InstFormatCI : InstFormat<9>;
43+
def InstFormatCSS : InstFormat<10>;
44+
def InstFormatCIW : InstFormat<11>;
45+
def InstFormatCL : InstFormat<12>;
46+
def InstFormatCS : InstFormat<13>;
47+
def InstFormatCA : InstFormat<14>;
48+
def InstFormatCB : InstFormat<15>;
49+
def InstFormatCJ : InstFormat<16>;
50+
def InstFormatCU : InstFormat<17>;
51+
def InstFormatCLB : InstFormat<18>;
52+
def InstFormatCLH : InstFormat<19>;
53+
def InstFormatCSB : InstFormat<20>;
54+
def InstFormatCSH : InstFormat<21>;
55+
def InstFormatQC_EAI : InstFormat<22>;
56+
def InstFormatQC_EI : InstFormat<23>;
57+
def InstFormatQC_EB : InstFormat<24>;
58+
def InstFormatQC_EJ : InstFormat<25>;
59+
def InstFormatQC_ES : InstFormat<26>;
60+
def InstFormatNDS_BRANCH_10 : InstFormat<27>;
61+
def InstFormatNDS_GPREL_18S0_I : InstFormat<28>;
62+
def InstFormatNDS_GPREL_17S1_I : InstFormat<29>;
63+
def InstFormatNDS_GPREL_17S2_I : InstFormat<30>;
64+
def InstFormatNDS_GPREL_17S3_I : InstFormat<31>;
65+
def InstFormatNDS_GPREL_18S0_S : InstFormat<32>;
66+
def InstFormatNDS_GPREL_17S1_S : InstFormat<33>;
67+
def InstFormatNDS_GPREL_17S2_S : InstFormat<34>;
68+
def InstFormatNDS_GPREL_17S3_S : InstFormat<35>;
69+
def InstFormatOther : InstFormat<63>;
6170

6271

6372
class RISCVVConstraint<bits<3> val> {
@@ -192,50 +201,50 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
192201
let AsmString = opcodestr # !if(!empty(argstr), "", "\t" # argstr);
193202
let Pattern = pattern;
194203

195-
let TSFlags{4-0} = format.Value;
204+
let TSFlags{5-0} = format.Value;
196205

197206
// Defaults
198207
RISCVVConstraint RVVConstraint = NoConstraint;
199-
let TSFlags{7-5} = RVVConstraint.Value;
208+
let TSFlags{8-6} = RVVConstraint.Value;
200209

201210
bits<3> VLMul = 0;
202-
let TSFlags{10-8} = VLMul;
211+
let TSFlags{11-9} = VLMul;
203212

204213
bit IsTiedPseudo = 0;
205-
let TSFlags{11} = IsTiedPseudo;
214+
let TSFlags{12} = IsTiedPseudo;
206215

207216
bit HasSEWOp = 0;
208-
let TSFlags{12} = HasSEWOp;
217+
let TSFlags{13} = HasSEWOp;
209218

210219
bit HasVLOp = 0;
211-
let TSFlags{13} = HasVLOp;
220+
let TSFlags{14} = HasVLOp;
212221

213222
bit HasVecPolicyOp = 0;
214-
let TSFlags{14} = HasVecPolicyOp;
223+
let TSFlags{15} = HasVecPolicyOp;
215224

216225
bit IsRVVWideningReduction = 0;
217-
let TSFlags{15} = IsRVVWideningReduction;
226+
let TSFlags{16} = IsRVVWideningReduction;
218227

219228
bit UsesMaskPolicy = 0;
220-
let TSFlags{16} = UsesMaskPolicy;
229+
let TSFlags{17} = UsesMaskPolicy;
221230

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

229238
bit HasRoundModeOp = 0;
230-
let TSFlags{18} = HasRoundModeOp;
239+
let TSFlags{19} = HasRoundModeOp;
231240

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

240249
// Indicates whether these instructions can partially overlap between source
241250
// registers and destination registers according to the vector spec.
@@ -244,19 +253,19 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
244253
// 2 -> narrowing case
245254
// 3 -> widening case
246255
bits<2> TargetOverlapConstraintType = 0;
247-
let TSFlags{21-20} = TargetOverlapConstraintType;
256+
let TSFlags{22-21} = TargetOverlapConstraintType;
248257

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

257266
// Indicates the EEW of a vector instruction's destination operand.
258267
EEW DestEEW = EEWSEWx1;
259-
let TSFlags{25-24} = DestEEW.Value;
268+
let TSFlags{26-25} = DestEEW.Value;
260269
}
261270

262271
class RVInst<dag outs, dag ins, string opcodestr, string argstr,

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,24 @@ class UImmAsmOperand<int width, string suffix = "">
227227
: ImmAsmOperand<"U", width, suffix> {
228228
}
229229

230+
class BareSImmNAsmOperand<int width>
231+
: ImmAsmOperand<"BareS", width, ""> {
232+
let PredicateMethod = "isBareSimmN<" # width # ">";
233+
}
234+
230235
class BareSImmNLsb0AsmOperand<int width>
231236
: ImmAsmOperand<"BareS", width, "Lsb0"> {
232-
let PredicateMethod = "isBareSimmNLsb0<" # width # ">";
237+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 1>";
238+
}
239+
240+
class BareSImmNLsb00AsmOperand<int width>
241+
: ImmAsmOperand<"BareS", width, "Lsb00"> {
242+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 2>";
243+
}
244+
245+
class BareSImmNLsb000AsmOperand<int width>
246+
: ImmAsmOperand<"BareS", width, "Lsb000"> {
247+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 3>";
233248
}
234249

235250
class RISCVOp<ValueType vt = XLenVT> : Operand<vt> {

0 commit comments

Comments
 (0)