From ae9e3dd4fa46b2cc684ce839c2bb7de832dd47a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jovan=20Dmitrovi=C4=87?= Date: Fri, 24 May 2024 10:59:18 +0200 Subject: [PATCH] Add support for emitting load/store pair instructions In order to support this, immediate operands with LSBs that are equal to zero are moved from the C extension InstrInfo. --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 10 ++ .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 + llvm/lib/Target/RISCV/RISCVInstrFormats.td | 72 ++++++++ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 + llvm/lib/Target/RISCV/RISCVInstrInfo.td | 165 ++++++++++++++++-- llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 125 ------------- 6 files changed, 239 insertions(+), 137 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 3f4a73ad89bf..fb983578d55f 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -814,6 +814,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_None; } + bool isUImm7Lsb000() const { + if (!isImm()) + return false; + int64_t Imm; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isShiftedUInt<4, 3>(Imm) && + VK == RISCVMCExpr::VK_RISCV_None; + } + bool isUImm8Lsb00() const { if (!isImm()) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index aa641bc866aa..a4c9391965a1 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -272,6 +272,7 @@ enum OperandType : unsigned { OPERAND_UIMM6, OPERAND_UIMM7, OPERAND_UIMM7_LSB00, + OPERAND_UIMM7_LSB000, OPERAND_UIMM8_LSB00, OPERAND_UIMM8, OPERAND_UIMM8_LSB000, diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index a5c8524d05cb..ff9bfaee839b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -469,6 +469,78 @@ class RVInstJ + : RVInst { + bits<7> imm7; + bits<5> rs1; + bits<5> rd1; + bits<5> rd2; + + let Inst{31-27} = rd2; + let Inst{26-23} = imm7{6-3}; + let Inst{22-20} = 0b000; + let Inst{19-15} = rs1; + let Inst{14-12} = 0b100; + let Inst{11-7} = rd1; + let Inst{6-0} = 0b0001011; +} + +// Load word pair format. +class LWPFormat + : RVInst { + bits<7> imm7; + bits<5> rs1; + bits<5> rd1; + bits<5> rd2; + + let Inst{31-27} = rd2; + let Inst{26-22} = imm7{6-2}; + let Inst{21-20} = 0b01; + let Inst{19-15} = rs1; + let Inst{14-12} = 0b100; + let Inst{11-7} = rd1; + let Inst{6-0} = 0b0001011; +} + +// Store double pair format. +class SDPFormat + : RVInst { + bits<7> imm7; + bits<5> rs3; + bits<5> rs2; + bits<5> rs1; + + let Inst{31-27} = rs3; + let Inst{26-25} = imm7{6-5}; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = 0b101; + let Inst{11-10} = imm7{4-3}; + let Inst{9-0} = 0b0000001011; +} + +// Store word pair format. +class SWPFormat + : RVInst { + bits<7> imm7; + bits<5> rs3; + bits<5> rs2; + bits<5> rs1; + + let Inst{31-27} = rs3; + let Inst{26-25} = imm7{6-5}; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = 0b101; + let Inst{11-9} = imm7{4-2}; + let Inst{8-0} = 0b010001011; +} + //===----------------------------------------------------------------------===// // Instruction classes for .insn directives //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 5709d43977d6..ff3d13f3bb5d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2095,6 +2095,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_UIMM7_LSB00: Ok = isShiftedUInt<5, 2>(Imm); break; + case RISCVOp::OPERAND_UIMM7_LSB000: + Ok = isShiftedUInt<4, 3>(Imm); + break; case RISCVOp::OPERAND_UIMM8_LSB00: Ok = isShiftedUInt<6, 2>(Imm); break; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 7a1393d073c4..946098730640 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -240,6 +240,147 @@ def simm12 : RISCVSImmLeafOp<12> { }]; } +// A 7-bit unsigned immediate where the least significant two bits are zero. +def uimm7_lsb00 : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<7>"; + let OperandType = "OPERAND_UIMM7_LSB00"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<5, 2>(Imm); + }]; +} + +// A 7-bit unsigned immediate where the least significant three bits are zero. +def uimm7_lsb000 : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<7, "Lsb000">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<7>"; + let OperandType = "OPERAND_UIMM7_LSB000"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<4, 3>(Imm); + }]; +} + +// A 8-bit unsigned immediate where the least significant two bits are zero. +def uimm8_lsb00 : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<8>"; + let OperandType = "OPERAND_UIMM8_LSB00"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<6, 2>(Imm); + }]; +} + +// A 8-bit unsigned immediate where the least significant three bits are zero. +def uimm8_lsb000 : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<8>"; + let OperandType = "OPERAND_UIMM8_LSB000"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<5, 3>(Imm); + }]; +} + +// A 9-bit signed immediate where the least significant bit is zero. +def simm9_lsb0 : Operand, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; + let PrintMethod = "printBranchOperand"; + let EncoderMethod = "getImmOpValueAsr1"; + let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; + let MCOperandPredicate = [{ + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return isShiftedInt<8, 1>(Imm); + return MCOp.isBareSymbolRef(); + + }]; + let OperandType = "OPERAND_PCREL"; +} + +// A 9-bit unsigned immediate where the least significant three bits are zero. +def uimm9_lsb000 : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<9>"; + let OperandType = "OPERAND_UIMM9_LSB000"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<6, 3>(Imm); + }]; +} + +// A 10-bit unsigned immediate where the least significant two bits are zero +// and the immediate can't be zero. +def uimm10_lsb00nonzero : RISCVOp, + ImmLeaf(Imm) && (Imm != 0);}]> { + let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmNonZeroOperand<10>"; + let OperandType = "OPERAND_UIMM10_LSB00_NONZERO"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedUInt<8, 2>(Imm) && (Imm != 0); + }]; +} + +// A 10-bit signed immediate where the least significant four bits are zero. +def simm10_lsb0000nonzero : RISCVOp, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeSImmNonZeroOperand<10>"; + let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedInt<6, 4>(Imm) && (Imm != 0); + }]; +} + +// A 12-bit signed immediate where the least significant bit is zero. +def simm12_lsb0 : Operand, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; + let PrintMethod = "printBranchOperand"; + let EncoderMethod = "getImmOpValueAsr1"; + let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; + let MCOperandPredicate = [{ + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return isShiftedInt<11, 1>(Imm); + return MCOp.isBareSymbolRef(); + }]; + let OperandType = "OPERAND_PCREL"; +} + // A 12-bit signed immediate which cannot fit in 6-bit signed immediate, // but even negative value fit in 12-bit. def simm12_no6 : ImmLeaf, - Sched<[WriteLDW, WriteLDW, ReadMemBase]> { +def LWP : LWPFormat<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7_lsb00:$imm7), + "lwp", "$rd1, $rd2, ${imm7}(${rs1})">, + Sched<[WriteLDW, WriteLDW, ReadMemBase]> { let mayLoad = 1; let mayStore = 0; } -def LDP : Pseudo<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7:$imm7), [], - "ldp", "$rd1, $rd2, ${imm7}(${rs1})">, - Sched<[WriteLDD, WriteLDD, ReadMemBase]> { +def LDP : LDPFormat<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7_lsb000:$imm7), + "ldp", "$rd1, $rd2, ${imm7}(${rs1})">, + Sched<[WriteLDD, WriteLDD, ReadMemBase]> { let mayLoad = 1; let mayStore = 0; } -def SWP : Pseudo<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7:$imm7), [], - "swp", "$rs2, $rs3, ${imm7}(${rs1})">, - Sched<[WriteSTW, ReadStoreData, ReadStoreData, ReadMemBase]> { +def SWP : SWPFormat<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7_lsb00:$imm7), + "swp", "$rs2, $rs3, ${imm7}(${rs1})">, + Sched<[WriteSTW, ReadStoreData, ReadStoreData, ReadMemBase]> { let mayLoad = 0; let mayStore = 1; } -def SDP : Pseudo<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7:$imm7), [], - "sdp", "$rs2, $rs3, ${imm7}(${rs1})">, - Sched<[WriteSTD, ReadStoreData, ReadStoreData, ReadMemBase]> { +def SDP : SDPFormat<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7_lsb000:$imm7), + "sdp", "$rs2, $rs3, ${imm7}(${rs1})">, + Sched<[WriteSTD, ReadStoreData, ReadStoreData, ReadMemBase]> { let mayLoad = 0; let mayStore = 1; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index 18d38348f721..619f4beca8e5 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -95,131 +95,6 @@ def c_lui_imm : RISCVOp, }]; } -// A 7-bit unsigned immediate where the least significant two bits are zero. -def uimm7_lsb00 : RISCVOp, - ImmLeaf(Imm);}]> { - let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<7>"; - let OperandType = "OPERAND_UIMM7_LSB00"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedUInt<5, 2>(Imm); - }]; -} - -// A 8-bit unsigned immediate where the least significant two bits are zero. -def uimm8_lsb00 : RISCVOp, - ImmLeaf(Imm);}]> { - let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<8>"; - let OperandType = "OPERAND_UIMM8_LSB00"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedUInt<6, 2>(Imm); - }]; -} - -// A 8-bit unsigned immediate where the least significant three bits are zero. -def uimm8_lsb000 : RISCVOp, - ImmLeaf(Imm);}]> { - let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<8>"; - let OperandType = "OPERAND_UIMM8_LSB000"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedUInt<5, 3>(Imm); - }]; -} - -// A 9-bit signed immediate where the least significant bit is zero. -def simm9_lsb0 : Operand, - ImmLeaf(Imm);}]> { - let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; - let PrintMethod = "printBranchOperand"; - let EncoderMethod = "getImmOpValueAsr1"; - let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; - let MCOperandPredicate = [{ - int64_t Imm; - if (MCOp.evaluateAsConstantImm(Imm)) - return isShiftedInt<8, 1>(Imm); - return MCOp.isBareSymbolRef(); - - }]; - let OperandType = "OPERAND_PCREL"; -} - -// A 9-bit unsigned immediate where the least significant three bits are zero. -def uimm9_lsb000 : RISCVOp, - ImmLeaf(Imm);}]> { - let ParserMatchClass = UImmAsmOperand<9, "Lsb000">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<9>"; - let OperandType = "OPERAND_UIMM9_LSB000"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedUInt<6, 3>(Imm); - }]; -} - -// A 10-bit unsigned immediate where the least significant two bits are zero -// and the immediate can't be zero. -def uimm10_lsb00nonzero : RISCVOp, - ImmLeaf(Imm) && (Imm != 0);}]> { - let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmNonZeroOperand<10>"; - let OperandType = "OPERAND_UIMM10_LSB00_NONZERO"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedUInt<8, 2>(Imm) && (Imm != 0); - }]; -} - -// A 10-bit signed immediate where the least significant four bits are zero. -def simm10_lsb0000nonzero : RISCVOp, - ImmLeaf(Imm);}]> { - let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; - let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeSImmNonZeroOperand<10>"; - let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO"; - let MCOperandPredicate = [{ - int64_t Imm; - if (!MCOp.evaluateAsConstantImm(Imm)) - return false; - return isShiftedInt<6, 4>(Imm) && (Imm != 0); - }]; -} - -// A 12-bit signed immediate where the least significant bit is zero. -def simm12_lsb0 : Operand, - ImmLeaf(Imm);}]> { - let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; - let PrintMethod = "printBranchOperand"; - let EncoderMethod = "getImmOpValueAsr1"; - let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; - let MCOperandPredicate = [{ - int64_t Imm; - if (MCOp.evaluateAsConstantImm(Imm)) - return isShiftedInt<11, 1>(Imm); - return MCOp.isBareSymbolRef(); - }]; - let OperandType = "OPERAND_PCREL"; -} def InsnCDirectiveOpcode : AsmOperandClass { let Name = "InsnCDirectiveOpcode";