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

Create PQR instruction class #81

Merged
merged 2 commits into from
Jan 18, 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
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
Loading