From 0a88c79b7eb5495f6ff8d424196dd37c0baa41d7 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Mon, 31 Mar 2025 13:30:47 +0800 Subject: [PATCH] [RISCV] Add relocation support for XAndesperf branch and gp-related instructions --- .../ELFRelocs/RISCV_nonstandard.def | 11 ++ .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 36 ++---- .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 18 +++ .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 17 ++- .../MCTargetDesc/RISCVELFObjectWriter.cpp | 2 + .../RISCV/MCTargetDesc/RISCVFixupKinds.h | 4 + .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 18 +++ llvm/lib/Target/RISCV/RISCVInstrFormats.td | 103 ++++++++++-------- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 17 ++- llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 66 +++++------ llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 5 - llvm/test/MC/RISCV/custom_reloc.s | 13 +++ .../MC/RISCV/xandesperf-fixups-diagnostics.s | 13 +++ llvm/test/MC/RISCV/xandesperf-fixups.s | 33 ++++++ llvm/test/MC/RISCV/xandesperf-relocation.s | 66 +++++++++++ .../MC/RISCV/xandesperf-rv64-relocation.s | 26 +++++ 16 files changed, 330 insertions(+), 118 deletions(-) create mode 100644 llvm/test/MC/RISCV/xandesperf-fixups-diagnostics.s create mode 100644 llvm/test/MC/RISCV/xandesperf-fixups.s create mode 100644 llvm/test/MC/RISCV/xandesperf-relocation.s create mode 100644 llvm/test/MC/RISCV/xandesperf-rv64-relocation.s diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def index 7ae3d3f205772..7437533d5041b 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def @@ -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) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 9bc4734815364..fa11268bec835 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -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(Op). - template bool isBareSimmNLsb0() const { + // modifiers and isShiftedInt(Op). + template bool isBareSimmNLsbK() const { if (!isImm()) return false; int64_t Imm; if (evaluateConstantImm(getImm(), Imm)) - return isShiftedInt(fixImmediateForRV32(Imm, isRV64Imm())); + return isShiftedInt(fixImmediateForRV32(Imm, isRV64Imm())); RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None; return RISCVAsmParser::classifySymbolRef(getImm(), VK) && @@ -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; @@ -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); }); } @@ -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"); @@ -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"); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index d8cfeb07e52b6..43a93e64aee6e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -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"); @@ -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; + } } } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 6ef94fb5e93da..545bfea66ea8f 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -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, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index 35e75489794f7..ed6bbc9fa9a6a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -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; } } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index 80fbed8d10f99..0bdb35e2c573b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -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 diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 7486618782e6c..dec98e1028124 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -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; } } diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index 8d56637d8b281..fd125e6f4bdbe 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -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 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 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 val> { @@ -190,42 +199,42 @@ class RVInstCommon 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 @@ -233,7 +242,7 @@ class RVInstCommon 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 : ImmAsmOperand<"U", width, suffix> { } +class BareSImmNAsmOperand + : ImmAsmOperand<"BareS", width, ""> { + let PredicateMethod = "isBareSimmN<" # width # ">"; +} + class BareSImmNLsb0AsmOperand : ImmAsmOperand<"BareS", width, "Lsb0"> { - let PredicateMethod = "isBareSimmNLsb0<" # width # ">"; + let PredicateMethod = "isBareSimmNLsbK<" # width # ", 1>"; +} + +class BareSImmNLsb00AsmOperand + : ImmAsmOperand<"BareS", width, "Lsb00"> { + let PredicateMethod = "isBareSimmNLsbK<" # width # ", 2>"; +} + +class BareSImmNLsb000AsmOperand + : ImmAsmOperand<"BareS", width, "Lsb000"> { + let PredicateMethod = "isBareSimmNLsbK<" # width # ", 3>"; } class RISCVOp : Operand { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td index 2ec768435259c..60fbeff5ab116 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td @@ -15,40 +15,40 @@ //===----------------------------------------------------------------------===// // A 11-bit signed immediate where the least significant bit is zero. -def simm11_lsb0 : Operand { - let ParserMatchClass = SImmAsmOperand<11, "Lsb0">; +def bare_simm11_lsb0 : Operand { + let ParserMatchClass = BareSImmNLsb0AsmOperand<11>; let PrintMethod = "printBranchOperand"; let EncoderMethod = "getImmOpValueAsrN<1>"; let DecoderMethod = "decodeSImmOperandAndLslN<11, 1>"; let MCOperandPredicate = [{ int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedInt<10, 1>(Imm); + if (MCOp.evaluateAsConstantImm(Imm)) + return isShiftedInt<10, 1>(Imm); + return MCOp.isBareSymbolRef(); }]; let OperandType = "OPERAND_PCREL"; } -def simm18 : Operand { - let ParserMatchClass = SImmAsmOperand<18>; +def bare_simm18 : Operand { + let ParserMatchClass = BareSImmNAsmOperand<18>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<18>"; } -def simm18_lsb0 : Operand { - let ParserMatchClass = SImmAsmOperand<18, "Lsb0">; +def bare_simm18_lsb0 : Operand { + let ParserMatchClass = BareSImmNLsb0AsmOperand<18>; let EncoderMethod = "getImmOpValueAsrN<1>"; let DecoderMethod = "decodeSImmOperandAndLslN<18, 1>"; } -def simm19_lsb00 : Operand { - let ParserMatchClass = SImmAsmOperand<19, "Lsb00">; +def bare_simm19_lsb00 : Operand { + let ParserMatchClass = BareSImmNLsb00AsmOperand<19>; let EncoderMethod = "getImmOpValueAsrN<2>"; let DecoderMethod = "decodeSImmOperandAndLslN<19, 2>"; } -def simm20_lsb000 : Operand { - let ParserMatchClass = SImmAsmOperand<20, "Lsb000">; +def bare_simm20_lsb000 : Operand { + let ParserMatchClass = BareSImmNLsb000AsmOperand<20>; let EncoderMethod = "getImmOpValueAsrN<3>"; let DecoderMethod = "decodeSImmOperandAndLslN<20, 3>"; } @@ -58,8 +58,8 @@ def simm20_lsb000 : Operand { //===----------------------------------------------------------------------===// class NDSRVInstBB - : RVInst<(outs), (ins GPR:$rs1, uimmlog2xlen:$cimm, simm11_lsb0:$imm10), - opcodestr, "$rs1, $cimm, $imm10", [], InstFormatOther>, + : RVInst<(outs), (ins GPR:$rs1, uimmlog2xlen:$cimm, bare_simm11_lsb0:$imm10), + opcodestr, "$rs1, $cimm, $imm10", [], InstFormatNDS_BRANCH_10>, Sched<[WriteJmp, ReadIALU]> { bits<10> imm10; bits<5> rs1; @@ -82,8 +82,8 @@ class NDSRVInstBB } class NDSRVInstBC funct3, string opcodestr> - : RVInst<(outs), (ins GPR:$rs1, uimm7:$cimm, simm11_lsb0:$imm10), - opcodestr, "$rs1, $cimm, $imm10", [], InstFormatOther>, + : RVInst<(outs), (ins GPR:$rs1, uimm7:$cimm, bare_simm11_lsb0:$imm10), + opcodestr, "$rs1, $cimm, $imm10", [], InstFormatNDS_BRANCH_10>, Sched<[WriteJmp, ReadIALU]> { bits<10> imm10; bits<5> rs1; @@ -137,8 +137,8 @@ class NDSRVInstRR funct7, string opcodestr> // GP: ADDI, LB, LBU class NDSRVInstLBGP funct2, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm18:$imm18), - opcodestr, "$rd, ${imm18}", [], InstFormatOther> { + : RVInst<(outs GPR:$rd), (ins bare_simm18:$imm18), + opcodestr, "$rd, ${imm18}", [], InstFormatNDS_GPREL_18S0_I> { bits<18> imm18; bits<5> rd; @@ -158,8 +158,8 @@ class NDSRVInstLBGP funct2, string opcodestr> // GP: LH, LHU class NDSRVInstLHGP funct3, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm18_lsb0:$imm17), - opcodestr, "$rd, ${imm17}", [], InstFormatOther> { + : RVInst<(outs GPR:$rd), (ins bare_simm18_lsb0:$imm17), + opcodestr, "$rd, ${imm17}", [], InstFormatNDS_GPREL_17S1_I> { bits<17> imm17; bits<5> rd; @@ -178,8 +178,8 @@ class NDSRVInstLHGP funct3, string opcodestr> // GP: LW, LWU class NDSRVInstLWGP funct3, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm19_lsb00:$imm17), - opcodestr, "$rd, ${imm17}", [], InstFormatOther> { + : RVInst<(outs GPR:$rd), (ins bare_simm19_lsb00:$imm17), + opcodestr, "$rd, ${imm17}", [], InstFormatNDS_GPREL_17S2_I> { bits<17> imm17; bits<5> rd; @@ -199,8 +199,8 @@ class NDSRVInstLWGP funct3, string opcodestr> // GP: LD class NDSRVInstLDGP funct3, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm20_lsb000:$imm17), - opcodestr, "$rd, ${imm17}", [], InstFormatOther> { + : RVInst<(outs GPR:$rd), (ins bare_simm20_lsb000:$imm17), + opcodestr, "$rd, ${imm17}", [], InstFormatNDS_GPREL_17S3_I> { bits<17> imm17; bits<5> rd; @@ -220,8 +220,8 @@ class NDSRVInstLDGP funct3, string opcodestr> // GP: SB class NDSRVInstSBGP funct2, string opcodestr> - : RVInst<(outs), (ins GPR:$rs2, simm18:$imm18), - opcodestr, "$rs2, ${imm18}", [], InstFormatOther> { + : RVInst<(outs), (ins GPR:$rs2, bare_simm18:$imm18), + opcodestr, "$rs2, ${imm18}", [], InstFormatNDS_GPREL_18S0_S> { bits<18> imm18; bits<5> rs2; @@ -242,8 +242,8 @@ class NDSRVInstSBGP funct2, string opcodestr> // GP: SH class NDSRVInstSHGP funct3, string opcodestr> - : RVInst<(outs), (ins GPR:$rs2, simm18_lsb0:$imm17), - opcodestr, "$rs2, ${imm17}", [], InstFormatOther> { + : RVInst<(outs), (ins GPR:$rs2, bare_simm18_lsb0:$imm17), + opcodestr, "$rs2, ${imm17}", [], InstFormatNDS_GPREL_17S1_S> { bits<17> imm17; bits<5> rs2; @@ -263,8 +263,8 @@ class NDSRVInstSHGP funct3, string opcodestr> // GP: SW class NDSRVInstSWGP funct3, string opcodestr> - : RVInst<(outs), (ins GPR:$rs2, simm19_lsb00:$imm17), - opcodestr, "$rs2, ${imm17}", [], InstFormatOther> { + : RVInst<(outs), (ins GPR:$rs2, bare_simm19_lsb00:$imm17), + opcodestr, "$rs2, ${imm17}", [], InstFormatNDS_GPREL_17S2_S> { bits<17> imm17; bits<5> rs2; @@ -285,8 +285,8 @@ class NDSRVInstSWGP funct3, string opcodestr> // GP: SD class NDSRVInstSDGP funct3, string opcodestr> - : RVInst<(outs), (ins GPR:$rs2, simm20_lsb000:$imm17), - opcodestr, "$rs2, ${imm17}", [], InstFormatOther> { + : RVInst<(outs), (ins GPR:$rs2, bare_simm20_lsb000:$imm17), + opcodestr, "$rs2, ${imm17}", [], InstFormatNDS_GPREL_17S3_S> { bits<17> imm17; bits<5> rs2; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 52bd893c881e8..31b88b1ffe8af 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -124,11 +124,6 @@ def simm26_nosimm12 : ImmLeaf(Imm) && !isInt<26>(Imm);}]>; -class BareSImmNAsmOperand - : ImmAsmOperand<"BareS", width, ""> { - let PredicateMethod = "isBareSimmN<" # width # ">"; -} - // 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no // sign-/zero-extension. This is represented internally as a signed 32-bit value. def bare_simm32 : RISCVOp { diff --git a/llvm/test/MC/RISCV/custom_reloc.s b/llvm/test/MC/RISCV/custom_reloc.s index cdb819467875f..a68f71063ea92 100644 --- a/llvm/test/MC/RISCV/custom_reloc.s +++ b/llvm/test/MC/RISCV/custom_reloc.s @@ -48,6 +48,19 @@ # CHECK-OBJ-NEXT: R_RISCV_VENDOR QUALCOMM # CHECK-OBJ-NEXT: R_RISCV_CUSTOM192 my_bar+0x2 + .reloc ., R_RISCV_VENDOR, ANDES + .reloc ., R_RISCV_NDS_BRANCH_10, my_bar + 2 + addi a1, a1, 0 + # CHECK-ASM: [[L3:.L[^:]+]]: + # CHECK-ASM-NEXT: .reloc [[L3]], R_RISCV_VENDOR, ANDES + # CHECK-ASM-NEXT: [[L4:.L[^:]+]]: + # CHECK-ASM-NEXT: .reloc [[L4]], R_RISCV_NDS_BRANCH_10, my_bar+2 + # CHECK-ASM-NEXT: mv a1, a1 + + # CHECK-OBJ: addi a1, a1, 0 + # CHECK-OBJ-NEXT: R_RISCV_VENDOR ANDES + # CHECK-OBJ-NEXT: R_RISCV_CUSTOM241 my_bar+0x2 + nop # CHECK-ASM: nop # CHECK-OBJ: addi zero, zero, 0x0 diff --git a/llvm/test/MC/RISCV/xandesperf-fixups-diagnostics.s b/llvm/test/MC/RISCV/xandesperf-fixups-diagnostics.s new file mode 100644 index 0000000000000..e52f8129129d7 --- /dev/null +++ b/llvm/test/MC/RISCV/xandesperf-fixups-diagnostics.s @@ -0,0 +1,13 @@ +# RUN: not llvm-mc -triple riscv32 -filetype obj -mattr=+xandesperf < %s -o /dev/null 2>&1 | FileCheck %s + + nds.bbc t0, 7, far_distant # CHECK: :[[@LINE]]:3: error: fixup value out of range + nds.bbc t0, 7, unaligned # CHECK: :[[@LINE]]:3: error: fixup value must be 2-byte aligned + + .byte 0 +unaligned: + .byte 0 + .byte 0 + .byte 0 + + .space 1<<10 +far_distant: diff --git a/llvm/test/MC/RISCV/xandesperf-fixups.s b/llvm/test/MC/RISCV/xandesperf-fixups.s new file mode 100644 index 0000000000000..f2e41aca3a067 --- /dev/null +++ b/llvm/test/MC/RISCV/xandesperf-fixups.s @@ -0,0 +1,33 @@ +# RUN: llvm-mc -triple riscv32 -mattr=+xandesperf -M no-aliases < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=CHECK-FIXUP %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xandesperf < %s \ +# RUN: | llvm-objdump --mattr=+xandesperf --no-print-imm-hex -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INSTR %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xandesperf %s \ +# RUN: | llvm-readobj -r - | FileCheck %s -check-prefix=CHECK-REL + +.LBB0: + +.fill 1000 + +nds.bbc t0, 7, .LBB0 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_riscv_nds_branch_10 +# CHECK-INSTR: nds.bbc t0, 7, 0 + +nds.bbs t0, 7, .LBB1 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_riscv_nds_branch_10 +# CHECK-INSTR: nds.bbs t0, 7, 0x7e0 + +nds.beqc t0, 7, .LBB0 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_riscv_nds_branch_10 +# CHECK-INSTR: nds.beqc t0, 7, 0 + +nds.bnec t0, 7, .LBB1 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_riscv_nds_branch_10 +# CHECK-INSTR: nds.bnec t0, 7, 0x7e0 + +.fill 1000 + +.LBB1: + +# CHECK-REL-NOT: R_RISCV diff --git a/llvm/test/MC/RISCV/xandesperf-relocation.s b/llvm/test/MC/RISCV/xandesperf-relocation.s new file mode 100644 index 0000000000000..1b5b41fcc0c3c --- /dev/null +++ b/llvm/test/MC/RISCV/xandesperf-relocation.s @@ -0,0 +1,66 @@ +# RUN: llvm-mc -triple riscv32 -mattr=+xandesperf -M no-aliases < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=INSTR %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xandesperf < %s \ +# RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s + +# Check prefixes: +# RELOC - Check the relocation in the object. +# INSTR - Check the instruction is handled properly by the ASMPrinter + +.long foo +# RELOC: R_RISCV_32 foo + +.quad foo +# RELOC: R_RISCV_64 foo + +nds.bbc t0, 7, foo +# RELOC: R_RISCV_CUSTOM241 +# INSTR: nds.bbc t0, 7, foo + +nds.bbs t0, 7, foo +# RELOC: R_RISCV_CUSTOM241 +# INSTR: nds.bbs t0, 7, foo + +nds.beqc t0, 7, foo +# RELOC: R_RISCV_CUSTOM241 +# INSTR: nds.beqc t0, 7, foo + +nds.bnec t0, 7, foo +# RELOC: R_RISCV_CUSTOM241 +# INSTR: nds.bnec t0, 7, foo + +nds.addigp t0, foo +# RELOC: R_RISCV_CUSTOM246 +# INSTR: nds.addigp t0, foo + +nds.lbgp t0, foo +# RELOC: R_RISCV_CUSTOM246 +# INSTR: nds.lbgp t0, foo + +nds.lbugp t0, foo +# RELOC: R_RISCV_CUSTOM246 +# INSTR: nds.lbugp t0, foo + +nds.lhgp t0, foo +# RELOC: R_RISCV_CUSTOM247 +# INSTR: nds.lhgp t0, foo + +nds.lhugp t0, foo +# RELOC: R_RISCV_CUSTOM247 +# INSTR: nds.lhugp t0, foo + +nds.lwgp t0, foo +# RELOC: R_RISCV_CUSTOM248 +# INSTR: nds.lwgp t0, foo + +nds.sbgp t0, foo +# RELOC: R_RISCV_CUSTOM250 +# INSTR: nds.sbgp t0, foo + +nds.shgp t0, foo +# RELOC: R_RISCV_CUSTOM251 +# INSTR: nds.shgp t0, foo + +nds.swgp t0, foo +# RELOC: R_RISCV_CUSTOM252 +# INSTR: nds.swgp t0, foo diff --git a/llvm/test/MC/RISCV/xandesperf-rv64-relocation.s b/llvm/test/MC/RISCV/xandesperf-rv64-relocation.s new file mode 100644 index 0000000000000..5bb4b553f6c3d --- /dev/null +++ b/llvm/test/MC/RISCV/xandesperf-rv64-relocation.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple riscv64 -mattr=+xandesperf -M no-aliases < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=INSTR %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xandesperf < %s \ +# RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s + +# Check prefixes: +# RELOC - Check the relocation in the object. +# INSTR - Check the instruction is handled properly by the ASMPrinter + +.long foo +# RELOC: R_RISCV_32 foo + +.quad foo +# RELOC: R_RISCV_64 foo + +nds.lwugp t0, foo +# RELOC: R_RISCV_CUSTOM248 +# INSTR: nds.lwugp t0, foo + +nds.ldgp t0, foo +# RELOC: R_RISCV_CUSTOM249 +# INSTR: nds.ldgp t0, foo + +nds.sdgp t0, foo +# RELOC: R_RISCV_CUSTOM253 +# INSTR: nds.sdgp t0, foo