Skip to content

Commit

Permalink
[SOL] Create PQR instruction class (#81)
Browse files Browse the repository at this point in the history
* Create PQR instruction class
  • Loading branch information
LucasSte committed Aug 19, 2024
1 parent 1372dcd commit f97cc35
Show file tree
Hide file tree
Showing 13 changed files with 477 additions and 110 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class SBFDisassembler : public MCDisassembler {
SBF_STX = 0x3,
SBF_ALU = 0x4,
SBF_JMP = 0x5,
SBF_PQR = 0x6,
SBF_ALU64 = 0x7
};

Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,16 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,
if (VT == MVT::i32 && !STI.getHasAlu32())
continue;

if (Subtarget->isSolana() && !STI.getHasSdiv()) {
if (Subtarget->isSolana() && !STI.getHasPqrClass()) {
setOperationAction(ISD::SDIV, VT, Expand);
setOperationAction(ISD::SREM, VT, Expand);
setOperationAction(ISD::UREM, VT, Expand);
setOperationAction(ISD::MULHU, VT, Expand);
setOperationAction(ISD::MULHS, VT, Expand);
}

setOperationAction(ISD::SDIVREM, VT, Expand);
setOperationAction(ISD::UDIVREM, VT, Expand);
setOperationAction(ISD::SREM, VT, Expand);
setOperationAction(ISD::UREM, VT, Expand);
setOperationAction(ISD::MULHU, VT, Expand);
setOperationAction(ISD::MULHS, VT, Expand);
setOperationAction(ISD::UMUL_LOHI, VT, Expand);
setOperationAction(ISD::SMUL_LOHI, VT, Expand);
setOperationAction(ISD::ROTR, VT, Expand);
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/SBF/SBFInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def SBF_ST : SBFOpClass<0x2>;
def SBF_STX : SBFOpClass<0x3>;
def SBF_ALU : SBFOpClass<0x4>;
def SBF_JMP : SBFOpClass<0x5>;
def SBF_PQR : SBFOpClass<0x6>;
def SBF_ALU64 : SBFOpClass<0x7>;

class SBFSrcType<bits<1> val> {
Expand Down Expand Up @@ -45,6 +46,14 @@ def SBF_END : SBFArithOp<0xd>;
def SBF_SDIV : SBFArithOp<0xe>;
def SBF_HOR : SBFArithOp<0xf>;

def PQR_UHMUL : SBFArithOp<0x2>;
def PQR_UDIV : SBFArithOp<0x4>;
def PQR_UREM : SBFArithOp<0x6>;
def PQR_LMUL : SBFArithOp<0x8>;
def PQR_SHMUL : SBFArithOp<0xa>;
def PQR_SDIV : SBFArithOp<0xc>;
def PQR_SREM : SBFArithOp<0xe>;

def SBF_XCHG : SBFArithOp<0xe>;
def SBF_CMPXCHG : SBFArithOp<0xf>;

Expand Down
115 changes: 78 additions & 37 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def SBFRevSub : Predicate<"Subtarget->getReverseSubImm()">;
def SBFNoRevSub : Predicate<"!Subtarget->getReverseSubImm()">;
def SBFCallxSrc : Predicate<"Subtarget->getCallXRegSrc()">, AssemblerPredicate<(all_of FeatureCallxRegSrc)>;
def NoSBFCallxSrc : Predicate<"!Subtarget->getCallXRegSrc()">;
def SBFPqrInstr : Predicate<"Subtarget->getHasPqrClass()">;
def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">;

def brtarget : Operand<OtherVT> {
let PrintMethod = "printBrTargetOperand";
Expand Down Expand Up @@ -136,10 +138,13 @@ def SBF_CC_LEU : PatLeaf<(i64 imm),
// +----------------+--------+--------------------+
// (MSB) (LSB)
class TYPE_ALU_JMP<bits<4> op, bits<1> srctype,
dag outs, dag ins, string asmstr, list<dag> pattern>
dag outs, dag ins, string asmstr, list<dag> pattern,
bit IsPqr64 = 0>
: InstSBF<outs, ins, asmstr, pattern> {

let Inst{63-60} = op;
// In the PQR class, instructions that deal with 64-bit registers have a different OpCode.
// To obtain it, we add one to its base value.
let Inst{63-60} = !if(IsPqr64, !add(op, 1), op);
let Inst{59} = srctype;
}

Expand Down Expand Up @@ -211,9 +216,11 @@ defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE>;
}

// ALU instructions
class ALU_RI<SBFOpClass Class, SBFArithOp Opc,
dag outs, dag ins, string asmstr, list<dag> pattern>
: TYPE_ALU_JMP<Opc.Value, SBF_K.Value, outs, ins, asmstr, pattern> {
class MATH_RI<SBFOpClass Class, SBFArithOp Opc,
dag outs, dag ins, string asmstr,
list<dag> pattern, bit isPqr64 = 0>
: TYPE_ALU_JMP<Opc.Value, SBF_K.Value, outs, ins,
asmstr, pattern, isPqr64> {
bits<4> dst;
bits<32> imm;

Expand All @@ -222,9 +229,11 @@ class ALU_RI<SBFOpClass Class, SBFArithOp Opc,
let SBFClass = Class;
}

class ALU_RR<SBFOpClass Class, SBFArithOp Opc,
dag outs, dag ins, string asmstr, list<dag> pattern>
: TYPE_ALU_JMP<Opc.Value, SBF_X.Value, outs, ins, asmstr, pattern> {
class MATH_RR<SBFOpClass Class, SBFArithOp Opc,
dag outs, dag ins, string asmstr,
list<dag> pattern, bit isPqr64 = 0>
: TYPE_ALU_JMP<Opc.Value, SBF_X.Value, outs, ins,
asmstr, pattern, isPqr64> {
bits<4> dst;
bits<4> src;

Expand All @@ -233,25 +242,14 @@ class ALU_RR<SBFOpClass Class, SBFArithOp Opc,
let SBFClass = Class;
}

multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode, bit UseImmPat = 1> {
def _rr : ALU_RR<SBF_ALU64, Opc,
(outs GPR:$dst),
(ins GPR:$src2, GPR:$src),
Mnemonic # "64 $dst, $src",
[(set GPR:$dst, (OpNode i64:$src2, i64:$src))]>;
def _ri : ALU_RI<SBF_ALU64, Opc,
(outs GPR:$dst),
(ins GPR:$src2, i64imm:$imm),
Mnemonic # "64 $dst, $imm",
!if(UseImmPat,
[(set GPR:$dst,
(OpNode GPR:$src2, i64immSExt32:$imm))], [])>;
def _rr_32 : ALU_RR<SBF_ALU, Opc,
multiclass MATH_32<SBFArithOp Opc, string Mnemonic,
SBFOpClass Class, SDNode OpNode, bit UseImmPat = 1> {
def _rr_32 : MATH_RR<Class, Opc,
(outs GPR32:$dst),
(ins GPR32:$src2, GPR32:$src),
Mnemonic # "32 $dst, $src",
[(set GPR32:$dst, (OpNode i32:$src2, i32:$src))]>;
def _ri_32 : ALU_RI<SBF_ALU, Opc,
def _ri_32 : MATH_RI<Class, Opc,
(outs GPR32:$dst),
(ins GPR32:$src2, i32imm:$imm),
Mnemonic # "32 $dst, $imm",
Expand All @@ -260,6 +258,40 @@ multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode, bit UseImmPat = 1
(OpNode GPR32:$src2, i32immSExt32:$imm))], [])>;
}

multiclass MATH_64<SBFArithOp Opc, string Mnemonic,
SBFOpClass Class, SDNode OpNode, bit UseImmPat = 1> {

defvar isPqr64 = !if(!eq(Class, SBF_PQR), 1, 0);

def _rr : MATH_RR<Class, Opc,
(outs GPR:$dst),
(ins GPR:$src2, GPR:$src),
Mnemonic # "64 $dst, $src",
[(set GPR:$dst, (OpNode i64:$src2, i64:$src))],
isPqr64>;

def _ri : MATH_RI<Class, Opc,
(outs GPR:$dst),
(ins GPR:$src2, i64imm:$imm),
Mnemonic # "64 $dst, $imm",
!if(UseImmPat,
[(set GPR:$dst,
(OpNode GPR:$src2, i64immSExt32:$imm))], []),
isPqr64>;
}

multiclass ALU<SBFArithOp Opc, string Mnemonic,
SDNode OpNode, bit UseImmPat = 1> {
defm "" : MATH_64<Opc, Mnemonic, SBF_ALU64, OpNode, UseImmPat>;

defm "" : MATH_32<Opc, Mnemonic, SBF_ALU, OpNode, UseImmPat>;
}

multiclass PQR<SBFArithOp Opc, string Mnemonic, SDNode OpNode> {
defm "" : MATH_64<Opc, Mnemonic, SBF_PQR, OpNode>;
defm "" : MATH_32<Opc, Mnemonic, SBF_PQR, OpNode>;
}

let Constraints = "$dst = $src2" in {
let isAsCheapAsAMove = 1 in {
defm ADD : ALU<SBF_ADD, "add", add>;
Expand All @@ -272,13 +304,13 @@ let Constraints = "$dst = $src2" in {
defm SRA : ALU<SBF_ARSH, "arsh", sra>;

let Predicates = [SBFNoLddw] in {
def HOR : ALU_RI<SBF_ALU64, SBF_HOR,
def HOR : MATH_RI<SBF_ALU64, SBF_HOR,
(outs GPR:$dst),
(ins GPR:$src2, i32imm:$imm),
"hor64 $dst, $imm",
[]>;
let DecoderNamespace = "SBFv2" in {
def HOR_addr : ALU_RI<SBF_ALU64, SBF_HOR,
def HOR_addr : MATH_RI<SBF_ALU64, SBF_HOR,
(outs GPR:$dst),
(ins GPR:$src2, u64imm:$imm),
"hor64 $dst, $imm",
Expand All @@ -288,11 +320,20 @@ let Constraints = "$dst = $src2" in {
}
}

defm MUL : ALU<SBF_MUL, "mul", mul>;
defm DIV : ALU<SBF_DIV, "div", udiv>;

let Predicates = [SBFSubtargetSolana] in {
defm SDIV : ALU<SBF_SDIV, "sdiv", sdiv>;
let Predicates = [SBFNoPqrInstr] in {
defm MUL : ALU<SBF_MUL, "mul", mul>;
defm DIV : ALU<SBF_DIV, "div", udiv>;
}

let Predicates = [SBFPqrInstr] in {
defm UHMUL : MATH_64<PQR_UHMUL, "uhmul", SBF_PQR, mulhu>;
defm UDIV : PQR<PQR_UDIV, "udiv", udiv>;
defm UREM : PQR<PQR_UREM, "urem", urem>;
defm LMUL : PQR<PQR_LMUL, "lmul", mul>;
defm SHMUL : MATH_64<PQR_SHMUL, "shmul", SBF_PQR, mulhs>;
defm SDIV_pqr : PQR<PQR_SDIV, "sdiv", sdiv>;
defm SREM : PQR<PQR_SREM, "srem", srem>;
}
}

Expand Down Expand Up @@ -355,22 +396,22 @@ class LD_IMM64<bits<4> Pseudo, string Mnemonic>

let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def LD_imm64 : LD_IMM64<0, "lddw">, Requires<[SBFHasLddw]>;
def MOV_rr : ALU_RR<SBF_ALU64, SBF_MOV,
def MOV_rr : MATH_RR<SBF_ALU64, SBF_MOV,
(outs GPR:$dst),
(ins GPR:$src),
"mov64 $dst, $src",
[]>;
def MOV_ri : ALU_RI<SBF_ALU64, SBF_MOV,
def MOV_ri : MATH_RI<SBF_ALU64, SBF_MOV,
(outs GPR:$dst),
(ins i64imm:$imm),
"mov64 $dst, $imm",
[(set GPR:$dst, (i64 i64immSExt32:$imm))]>;
def MOV_rr_32 : ALU_RR<SBF_ALU, SBF_MOV,
def MOV_rr_32 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov32 $dst, $src",
[]>;
def MOV_ri_32 : ALU_RI<SBF_ALU, SBF_MOV,
def MOV_ri_32 : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins i32imm:$imm),
"mov32 $dst, $imm",
Expand Down Expand Up @@ -468,7 +509,7 @@ let isCodeGenOnly = 1 in {
"$dst = core_alu32_mem($opcode, $src, $offset)",
[]>;
let Constraints = "$dst = $src" in {
def CORE_SHIFT : ALU_RR<SBF_ALU64, SBF_LSH,
def CORE_SHIFT : MATH_RR<SBF_ALU64, SBF_LSH,
(outs GPR:$dst),
(ins u64imm:$opcode, GPR:$src, u64imm:$offset),
"$dst = core_shift($opcode, $src, $offset)",
Expand Down Expand Up @@ -896,16 +937,16 @@ let Constraints = "$dst = $src" in {
}

let isCodeGenOnly = 1 in {
def MOV_32_64 : ALU_RR<SBF_ALU, SBF_MOV,
def MOV_32_64 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins GPR32:$src),
"mov32 $dst, $src", []>;
def MOV_32_64_addr : ALU_RI<SBF_ALU, SBF_MOV,
def MOV_32_64_addr : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins u64imm:$imm),
"mov32 $dst, $imm", []>, Requires<[SBFNoLddw]>;
}

let DecoderNamespace = "SBFv2", Predicates = [SBFNoLddw] in {
def MOV_32_64_imm : ALU_RI<SBF_ALU, SBF_MOV,
def MOV_32_64_imm : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins i32imm:$imm),
"mov32 $dst, $imm", []>;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SBF/SBFSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) {
IsSolana = true;
HasJmpExt = false;
HasAlu32 = false;
HasSdiv = false;
UseDwarfRIS = false;

// SBFv2 features
Expand All @@ -47,6 +46,7 @@ void SBFSubtarget::initializeEnvironment(const Triple &TT) {
ReverseSubImm = false;
NoLddw = false;
CallxRegSrc = false;
HasPqrClass = false;
}

void SBFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/SBF/SBFSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// Relocate FK_Data_8 fixups as R_SBF_64_ABS64
bool UseRelocAbs64;

// whether the cpu supports native SBF_SDIV
bool HasSdiv;

// Not used for anything, just set by the static-syscalls marker feature.
bool HasStaticSyscalls;

Expand All @@ -81,6 +78,9 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// Whether to encode destination register in Callx's src field
bool CallxRegSrc;

// Whether we have the PQR instruction class
bool HasPqrClass;

public:
// This constructor initializes the data members to match that
// of the specified triple.
Expand All @@ -97,12 +97,12 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
bool getHasJmpExt() const { return HasJmpExt; }
bool getHasAlu32() const { return HasAlu32; }
bool getHasDynamicFrames() const { return HasDynamicFrames; }
bool getHasSdiv() const { return HasSdiv; }
bool getUseDwarfRIS() const { return UseDwarfRIS; }
bool getDisableNeg() const { return DisableNeg; }
bool getReverseSubImm() const { return ReverseSubImm; }
bool getNoLddw() const { return NoLddw; }
bool getCallXRegSrc() const { return CallxRegSrc; }
bool getHasPqrClass() const { return HasPqrClass; }

const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SBFFrameLowering *getFrameLowering() const override {
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/SBF/SBFTargetFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ def FeatureSolana : SubtargetFeature<"solana", "IsSolana", "true",
def FeatureDynamicFrames : SubtargetFeature<"dynamic-frames", "HasDynamicFrames", "true",
"Enable dynamic frames">;

def FeatureSdiv : SubtargetFeature<"sdiv", "HasSdiv", "true",
"Enable native SBF_SDIV support">;

def FeatureRelocAbs64 : SubtargetFeature<"reloc-abs64", "UseRelocAbs64", "true",
"Fix 64bit data relocations">;

Expand All @@ -46,6 +43,9 @@ def FeatureDisableLddw : SubtargetFeature<"no-lddw", "NoLddw", "true",
def FeatureCallxRegSrc : SubtargetFeature<"callx-reg-src", "CallxRegSrc", "true",
"Encode Callx destination register in the src field">;

def FeaturePqrInstr : SubtargetFeature<"pqr-instr", "HasPqrClass", "true",
"Enable the PQR instruction class">;

class Proc<string Name, list<SubtargetFeature> Features>
: Processor<Name, NoItineraries, Features>;

Expand All @@ -54,5 +54,6 @@ def : Proc<"v1", []>;
def : Proc<"v2", []>;
def : Proc<"v3", []>;
def : Proc<"probe", []>;
def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv, FeatureRelocAbs64, FeatureStaticSyscalls,
FeatureDisableNeg, FeatureReverseSubImm, FeatureDisableLddw, FeatureCallxRegSrc]>;
def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureRelocAbs64, FeatureStaticSyscalls,
FeatureDisableNeg, FeatureReverseSubImm, FeatureDisableLddw, FeatureCallxRegSrc,
FeaturePqrInstr]>;
Loading

0 comments on commit f97cc35

Please sign in to comment.