Skip to content

Commit 0a88c79

Browse files
committed
[RISCV] Add relocation support for XAndesperf branch and gp-related instructions
1 parent cf17ee1 commit 0a88c79

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_JUMP_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
@@ -533,14 +533,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
533533
}
534534

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

541541
int64_t Imm;
542542
if (evaluateConstantImm(getImm(), Imm))
543-
return isShiftedInt<N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
543+
return isShiftedInt<N - K, K>(fixImmediateForRV32(Imm, isRV64Imm()));
544544

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

855-
bool isSImm11Lsb0() const {
856-
return isSImmPred([](int64_t Imm) { return isShiftedInt<10, 1>(Imm); });
857-
}
858-
859855
bool isSImm12() const {
860856
if (!isImm())
861857
return false;
@@ -948,22 +944,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
948944
[](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
949945
}
950946

951-
bool isSImm18() const {
952-
return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); });
953-
}
954-
955-
bool isSImm18Lsb0() const {
956-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 1>(Imm); });
957-
}
958-
959-
bool isSImm19Lsb00() const {
960-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 2>(Imm); });
961-
}
962-
963-
bool isSImm20Lsb000() const {
964-
return isSImmPred([](int64_t Imm) { return isShiftedInt<17, 3>(Imm); });
965-
}
966-
967947
bool isSImm32Lsb0() const {
968948
return isSImmPred([](int64_t Imm) { return isShiftedInt<31, 1>(Imm); });
969949
}
@@ -1535,7 +1515,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15351515
case Match_InvalidSImm11:
15361516
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
15371517
(1 << 10) - 1);
1538-
case Match_InvalidSImm11Lsb0:
1518+
case Match_InvalidBareSImm11Lsb0:
15391519
return generateImmOutOfRangeError(
15401520
Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
15411521
"immediate must be a multiple of 2 bytes in the range");
@@ -1611,18 +1591,18 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16111591
(1 << 4),
16121592
"immediate must be in the range");
16131593
}
1614-
case Match_InvalidSImm18:
1594+
case Match_InvalidBareSImm18:
16151595
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
16161596
(1 << 17) - 1);
1617-
case Match_InvalidSImm18Lsb0:
1597+
case Match_InvalidBareSImm18Lsb0:
16181598
return generateImmOutOfRangeError(
16191599
Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
16201600
"immediate must be a multiple of 2 bytes in the range");
1621-
case Match_InvalidSImm19Lsb00:
1601+
case Match_InvalidBareSImm19Lsb00:
16221602
return generateImmOutOfRangeError(
16231603
Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
16241604
"immediate must be a multiple of 4 bytes in the range");
1625-
case Match_InvalidSImm20Lsb000:
1605+
case Match_InvalidBareSImm20Lsb000:
16261606
return generateImmOutOfRangeError(
16271607
Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
16281608
"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
@@ -88,6 +88,9 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
8888
{"fixup_riscv_qc_e_32", 16, 32, 0},
8989
{"fixup_riscv_qc_abs20_u", 12, 20, 0},
9090
{"fixup_riscv_qc_e_jump_plt", 0, 48, MCFixupKindInfo::FKF_IsPCRel},
91+
92+
// Andes fixups
93+
{"fixup_riscv_nds_branch_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
9194
};
9295
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
9396
"Not all fixup kinds added to Infos array");
@@ -568,6 +571,21 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
568571
(Bit15_13 << 17) | (Bit4_1 << 8) | (Bit11 << 7);
569572
return Value;
570573
}
574+
case RISCV::fixup_riscv_nds_branch_10: {
575+
if (!isInt<11>(Value))
576+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
577+
if (Value & 0x1)
578+
Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
579+
// Need to extract imm[10], imm[9:5], imm[4:1] from the 11-bit Value.
580+
unsigned Sbit = (Value >> 10) & 0x1;
581+
unsigned Hi5 = (Value >> 5) & 0x1f;
582+
unsigned Lo4 = (Value >> 1) & 0xf;
583+
// Inst{31} = Sbit;
584+
// Inst{29-25} = Hi5;
585+
// Inst{11-8} = Lo4;
586+
Value = (Sbit << 31) | (Hi5 << 25) | (Lo4 << 8);
587+
return Value;
588+
}
571589
}
572590
}
573591

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
@@ -108,6 +108,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
108108
return ELF::R_RISCV_QC_E_BRANCH;
109109
case RISCV::fixup_riscv_qc_e_jump_plt:
110110
return ELF::R_RISCV_QC_E_JUMP_PLT;
111+
case RISCV::fixup_riscv_nds_branch_10:
112+
return ELF::R_RISCV_NDS_BRANCH_10;
111113
}
112114
}
113115

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_jump_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
@@ -677,6 +677,24 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
677677
FixupKind = RISCV::fixup_riscv_qc_e_32;
678678
} else if (MIFrm == RISCVII::InstFormatQC_EJ) {
679679
FixupKind = RISCV::fixup_riscv_qc_e_jump_plt;
680+
} else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
681+
FixupKind = RISCV::fixup_riscv_nds_branch_10;
682+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_I) {
683+
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_I;
684+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_I) {
685+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_I;
686+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_I) {
687+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_I;
688+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_I) {
689+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_I;
690+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_18S0_S) {
691+
FixupKind = ELF::R_RISCV_NDS_GPREL_18S0_S;
692+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S1_S) {
693+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S1_S;
694+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S2_S) {
695+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S2_S;
696+
} else if (MIFrm == RISCVII::InstFormatNDS_GPREL_17S3_S) {
697+
FixupKind = ELF::R_RISCV_NDS_GPREL_17S3_S;
680698
}
681699
}
682700

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> {
@@ -190,50 +199,50 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
190199
let AsmString = opcodestr # !if(!empty(argstr), "", "\t" # argstr);
191200
let Pattern = pattern;
192201

193-
let TSFlags{4-0} = format.Value;
202+
let TSFlags{5-0} = format.Value;
194203

195204
// Defaults
196205
RISCVVConstraint RVVConstraint = NoConstraint;
197-
let TSFlags{7-5} = RVVConstraint.Value;
206+
let TSFlags{8-6} = RVVConstraint.Value;
198207

199208
bits<3> VLMul = 0;
200-
let TSFlags{10-8} = VLMul;
209+
let TSFlags{11-9} = VLMul;
201210

202211
bit IsTiedPseudo = 0;
203-
let TSFlags{11} = IsTiedPseudo;
212+
let TSFlags{12} = IsTiedPseudo;
204213

205214
bit HasSEWOp = 0;
206-
let TSFlags{12} = HasSEWOp;
215+
let TSFlags{13} = HasSEWOp;
207216

208217
bit HasVLOp = 0;
209-
let TSFlags{13} = HasVLOp;
218+
let TSFlags{14} = HasVLOp;
210219

211220
bit HasVecPolicyOp = 0;
212-
let TSFlags{14} = HasVecPolicyOp;
221+
let TSFlags{15} = HasVecPolicyOp;
213222

214223
bit IsRVVWideningReduction = 0;
215-
let TSFlags{15} = IsRVVWideningReduction;
224+
let TSFlags{16} = IsRVVWideningReduction;
216225

217226
bit UsesMaskPolicy = 0;
218-
let TSFlags{16} = UsesMaskPolicy;
227+
let TSFlags{17} = UsesMaskPolicy;
219228

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

227236
bit HasRoundModeOp = 0;
228-
let TSFlags{18} = HasRoundModeOp;
237+
let TSFlags{19} = HasRoundModeOp;
229238

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

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

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

255264
// Indicates the EEW of a vector instruction's destination operand.
256265
EEW DestEEW = EEWSEWx1;
257-
let TSFlags{25-24} = DestEEW.Value;
266+
let TSFlags{26-25} = DestEEW.Value;
258267
}
259268

260269
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
@@ -161,9 +161,24 @@ class UImmAsmOperand<int width, string suffix = "">
161161
: ImmAsmOperand<"U", width, suffix> {
162162
}
163163

164+
class BareSImmNAsmOperand<int width>
165+
: ImmAsmOperand<"BareS", width, ""> {
166+
let PredicateMethod = "isBareSimmN<" # width # ">";
167+
}
168+
164169
class BareSImmNLsb0AsmOperand<int width>
165170
: ImmAsmOperand<"BareS", width, "Lsb0"> {
166-
let PredicateMethod = "isBareSimmNLsb0<" # width # ">";
171+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 1>";
172+
}
173+
174+
class BareSImmNLsb00AsmOperand<int width>
175+
: ImmAsmOperand<"BareS", width, "Lsb00"> {
176+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 2>";
177+
}
178+
179+
class BareSImmNLsb000AsmOperand<int width>
180+
: ImmAsmOperand<"BareS", width, "Lsb000"> {
181+
let PredicateMethod = "isBareSimmNLsbK<" # width # ", 3>";
167182
}
168183

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

0 commit comments

Comments
 (0)