Skip to content
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

Add support for emitting load/store pair instructions #30

Merged
merged 1 commit into from
May 24, 2024
Merged
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
10 changes: 10 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
72 changes: 72 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,78 @@ class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
let Inst{6-0} = opcode.Value;
}

//===----------------------------------------------------------------------===//
// MIPS custom instruction formats
//===----------------------------------------------------------------------===//

// Load double pair format.
class LDPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
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<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
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<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
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<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
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
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
165 changes: 153 additions & 12 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<XLenVT, [{return isShiftedUInt<5, 2>(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<XLenVT, [{return isShiftedUInt<4, 3>(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<XLenVT, [{return isShiftedUInt<6, 2>(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<XLenVT, [{return isShiftedUInt<5, 3>(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<OtherVT>,
ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(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<XLenVT, [{return isShiftedUInt<6, 3>(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<XLenVT,
[{return isShiftedUInt<8, 2>(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<XLenVT,
[{return (Imm != 0) && isShiftedInt<6, 4>(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<XLenVT>,
ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(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<XLenVT, [{
Expand Down Expand Up @@ -1999,27 +2140,27 @@ def : Pat<(select (XLenVT GPR:$rs2), (XLenVT GPR:$rs1), (XLenVT GPR:$rs3)),
//===----------------------------------------------------------------------===//

let Predicates = [UsesLoadStorePairs], hasSideEffects = 0 in {
def LWP : Pseudo<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7:$imm7), [],
"lwp", "$rd1, $rd2, ${imm7}(${rs1})">,
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;
}
Expand Down
Loading