Skip to content

Commit

Permalink
Attempt 1
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Dec 11, 2024
1 parent f082558 commit a956e94
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 42 deletions.
12 changes: 12 additions & 0 deletions llvm/lib/Target/SBF/SBFInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ def SBF_JMP : SBFOpClass<0x5>;
def SBF_PQR : SBFOpClass<0x6>;
def SBF_ALU64 : SBFOpClass<0x7>;

def SBF_ST_V2 : SBFOpClass<0x4>;
def SBF_LD_V2 : SBFOpClass<0x7>;

class SBFSrcType<bits<1> val> {
bits<1> Value = val;
}
Expand Down Expand Up @@ -92,6 +95,15 @@ def SBF_H : SBFWidthModifer<0x1>;
def SBF_B : SBFWidthModifer<0x2>;
def SBF_DW : SBFWidthModifer<0x3>;

class SBFSizeModifier<bits<4> val> {
bits<4> Value = val;
}

def SBF_B_V2 : SBFSizeModifier<0x2>;
def SBF_H_V2 : SBFSizeModifier<0x3>;
def SBF_W_V2 : SBFSizeModifier<0x8>;
def SBF_DW_V2 : SBFSizeModifier<0x9>;

class SBFModeModifer<bits<3> val> {
bits<3> Value = val;
}
Expand Down
24 changes: 14 additions & 10 deletions llvm/lib/Target/SBF/SBFInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ using namespace llvm;
SBFInstrInfo::SBFInstrInfo()
: SBFGenInstrInfo(SBF::ADJCALLSTACKDOWN, SBF::ADJCALLSTACKUP) {}

void SBFInstrInfo::setHasExplicitSignExt(bool HasExplicitSext) {
void SBFInstrInfo::initializeTargetFeatures(bool HasExplicitSext, bool NewMemEncoding) {
this->HasExplicitSignExt = HasExplicitSext;
this->NewMemEncoding = NewMemEncoding;
}

void SBFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Expand Down Expand Up @@ -60,24 +61,27 @@ void SBFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
DebugLoc dl = MI->getDebugLoc();
unsigned LdOpc, StOpc;

#define STORE_SWITCH(X) \
StOpc = NewMemEncoding ? SBF::ST##X##_V2 : SBF::ST##X##_V1;

unsigned BytesPerOp = std::min(static_cast<unsigned>(Alignment), 8u);
switch (Alignment) {
case 1:
LdOpc = SBF::LDB;
StOpc = SBF::STB;
STORE_SWITCH(B)
break;
case 2:
LdOpc = SBF::LDH;
StOpc = SBF::STH;
STORE_SWITCH(H)
break;
case 4:
LdOpc = SBF::LDW;
StOpc = SBF::STW;
STORE_SWITCH(W)
break;
case 8:
case 16:
LdOpc = SBF::LDD;
StOpc = SBF::STD;
STORE_SWITCH(D)
break;
default:
llvm_unreachable("unsupported memcpy alignment");
Expand Down Expand Up @@ -105,19 +109,19 @@ void SBFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
if (BytesLeft < 2) {
Offset = CopyLen - 1;
LdOpc = SBF::LDB;
StOpc = SBF::STB;
STORE_SWITCH(B)
} else if (BytesLeft <= 2) {
Offset = CopyLen - 2;
LdOpc = SBF::LDH;
StOpc = SBF::STH;
STORE_SWITCH(H)
} else if (BytesLeft <= 4) {
Offset = CopyLen - 4;
LdOpc = SBF::LDW;
StOpc = SBF::STW;
STORE_SWITCH(W)
} else if (BytesLeft <= 8) {
Offset = CopyLen - 8;
LdOpc = SBF::LDD;
StOpc = SBF::STD;
STORE_SWITCH(D)
} else {
llvm_unreachable("There cannot be more than 8 bytes left");
}
Expand Down Expand Up @@ -154,7 +158,7 @@ void SBFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
DL = I->getDebugLoc();

if (RC == &SBF::GPRRegClass)
BuildMI(MBB, I, DL, get(SBF::STD))
BuildMI(MBB, I, DL, get(NewMemEncoding ? SBF::STD_V2 : SBF::STD_V1))
.addReg(SrcReg, getKillRegState(IsKill))
.addFrameIndex(FI)
.addImm(0);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ class SBFInstrInfo : public SBFGenInstrInfo {
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
void setHasExplicitSignExt(bool HasExplicitSext);
void initializeTargetFeatures(bool HasExplicitSext, bool NewMemEncoding);

private:
void expandMEMCPY(MachineBasicBlock::iterator) const;
bool HasExplicitSignExt;
bool NewMemEncoding;
};
}

Expand Down
150 changes: 128 additions & 22 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">;
def SBFHasStoreImm : Predicate<"Subtarget->getHasStoreImm()">;
def SBFExplicitSignExt : Predicate<"Subtarget->getHasExplicitSignExt()">;
def SBFNoExplicitSignExt : Predicate<"!Subtarget->getHasExplicitSignExt()">;
def SBFNewMemEncoding : Predicate<"Subtarget->getNewMemEncoding()">;
def SBFOldMemEncoding : Predicate<"!Subtarget->getNewMemEncoding()">;

def brtarget : Operand<OtherVT> {
let PrintMethod = "printBrTargetOperand";
Expand Down Expand Up @@ -173,6 +175,22 @@ class TYPE_LD_ST<bits<3> mode, bits<2> size,
let Inst{60-59} = size;
}

//For load and store instructions in SBFv2 the 8-bit 'code' field is divided as:
//
// +--------+---------------+-------------------+
// | 4 bits | 1 bit | 3 bits |
// | size | source type | instruction class |
// +--------+---------------+-------------------+
// (MSB) (LSB)
class TYPE_LD_ST_V2<bits<4> size, bits<1> srctype,
dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSBF<outs, ins, asmstr, pattern> {

let Inst{63-60} = size;
let Inst{59} = srctype;
}


// jump instructions
class JMP_RR<SBFJumpOp Opc, string Mnemonic, PatLeaf Cond>
: TYPE_ALU_JMP<Opc.Value, SBF_X.Value,
Expand Down Expand Up @@ -474,7 +492,7 @@ def LD_pseudo
}

// STORE instructions
class STORE<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
class STORE_V1<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST<SBF_MEM.Value, SizeOp.Value,
(outs),
(ins GPR:$src, MEMri:$addr),
Expand All @@ -489,17 +507,40 @@ class STORE<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
let SBFClass = SBF_STX;
}

class STOREi64<SBFWidthModifer Opc, string Mnemonic, PatFrag OpNode>
: STORE<Opc, Mnemonic, [(OpNode GPR:$src, ADDRri:$addr)]>;
class STORE_V2<SBFSizeModifier SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST_V2<SizeOp.Value, SBF_X.Value,
(outs),
(ins GPR:$src, MEMri:$addr),
Mnemonic # " [$addr], $src",
Pattern> {
bits<4> src;
bits<20> addr;

let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = src;
let Inst{47-32} = addr{15-0}; // offset
let SBFClass = SBF_ST_V2;
}

multiclass STOREi64<SBFWidthModifer SizeV1, SBFSizeModifier SizeV2,
string Mnemonic, PatFrag OpNode> {
def _V1 : STORE_V1<SizeV1, Mnemonic, [(OpNode GPR:$src, ADDRri:$addr)]>,
Requires<[SBFOldMemEncoding]>;

let DecoderNamespace = "SBFv2" in {
def _V2 : STORE_V2<SizeV2, Mnemonic, [(OpNode GPR:$src, ADDRri:$addr)]>,
Requires<[SBFNewMemEncoding]>;
}
}

let Predicates = [SBFNoALU32] in {
def STW : STOREi64<SBF_W, "stxw", truncstorei32>;
def STH : STOREi64<SBF_H, "stxh", truncstorei16>;
def STB : STOREi64<SBF_B, "stxb", truncstorei8>;
defm STW : STOREi64<SBF_W, SBF_W_V2, "stxw", truncstorei32>;
defm STH : STOREi64<SBF_H, SBF_H_V2, "stxh", truncstorei16>;
defm STB : STOREi64<SBF_B, SBF_B_V2, "stxb", truncstorei8>;
}
def STD : STOREi64<SBF_DW, "stxdw", store>;
defm STD : STOREi64<SBF_DW, SBF_DW_V2, "stxdw", store>;

class STORE_imm<SBFWidthModifer SizeOp,
class STORE_imm_V1<SBFWidthModifer SizeOp,
string Mnemonic, dag Pattern>
: TYPE_LD_ST<SBF_MEM.Value, SizeOp.Value,
(outs),
Expand All @@ -514,6 +555,32 @@ class STORE_imm<SBFWidthModifer SizeOp,
let SBFClass = SBF_ST;
}

class STORE_imm_V2<SBFSizeModifier SizeOp,
string Mnemonic, dag Pattern>
: TYPE_LD_ST_V2<SizeOp.Value, SBF_K.Value,
(outs),
(ins i64imm:$imm, MEMri:$addr),
Mnemonic # " [$addr], $imm",
[Pattern]> {
bits<20> addr;
bits<32> imm;
let Inst{51-48} = addr{19-16}; // base reg
let Inst{47-32} = addr{15-0}; // offset
let Inst{31-0} = imm;
let SBFClass = SBF_ST_V2;
}

multiclass STORE_imm<SBFWidthModifer SizeV1, SBFSizeModifier SizeV2,
string Mnemonic, dag Pattern> {
def _V1 : STORE_imm_V1<SizeV1, Mnemonic, Pattern>,
Requires<[SBFOldMemEncoding]>;

let DecoderNamespace = "SBFv2" in {
def _V2 : STORE_imm_V2<SizeV2, Mnemonic, Pattern>,
Requires<[SBFNewMemEncoding]>;
}
}

// Opcode (SBF_ST | SBF_MEM | SBF_DW) implies sign extension for
// value stored to memory:
// - it is fine to generate such write when immediate is -1
Expand All @@ -527,19 +594,34 @@ class STORE_imm<SBFWidthModifer SizeOp,
//
// For SBF_{B,H,W} the size of value stored matches size of the immediate.
let Predicates = [SBFHasStoreImm] in {
def STD_imm : STORE_imm<SBF_DW, "stdw", (store (i64 i64immSExt32:$imm), ADDRri:$addr)>;
def STW_imm : STORE_imm<SBF_W, "stw", (truncstorei32 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
def STH_imm : STORE_imm<SBF_H, "sth", (truncstorei16 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
def STB_imm : STORE_imm<SBF_B, "stb", (truncstorei8 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
defm STD_imm : STORE_imm<SBF_DW, SBF_DW_V2, "stdw",
(store (i64 i64immSExt32:$imm), ADDRri:$addr)>;
defm STW_imm : STORE_imm<SBF_W, SBF_W_V2, "stw",
(truncstorei32 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
defm STH_imm : STORE_imm<SBF_H, SBF_H_V2, "sth",
(truncstorei16 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
defm STB_imm : STORE_imm<SBF_B, SBF_B_V2, "stb",
(truncstorei8 (i64 i64immZExt32:$imm), ADDRri:$addr)>;
}



let Predicates = [SBFHasALU32, SBFHasStoreImm, SBFOldMemEncoding] in {
def : Pat<(store (i32 imm:$src), ADDRri:$dst),
(STW_imm_V1 (imm_to_i64 $src), ADDRri:$dst)>;
def : Pat<(truncstorei16 (i32 imm:$src), ADDRri:$dst),
(STH_imm_V1 (imm_to_i64 imm:$src), ADDRri:$dst)>;
def : Pat<(truncstorei8 (i32 imm:$src), ADDRri:$dst),
(STB_imm_V1 (imm_to_i64 imm:$src), ADDRri:$dst)>;
}

let Predicates = [SBFHasALU32, SBFHasStoreImm] in {
let Predicates = [SBFHasALU32, SBFHasStoreImm, SBFNewMemEncoding] in {
def : Pat<(store (i32 imm:$src), ADDRri:$dst),
(STW_imm (imm_to_i64 $src), ADDRri:$dst)>;
(STW_imm_V2 (imm_to_i64 $src), ADDRri:$dst)>;
def : Pat<(truncstorei16 (i32 imm:$src), ADDRri:$dst),
(STH_imm (imm_to_i64 imm:$src), ADDRri:$dst)>;
(STH_imm_V2 (imm_to_i64 imm:$src), ADDRri:$dst)>;
def : Pat<(truncstorei8 (i32 imm:$src), ADDRri:$dst),
(STB_imm (imm_to_i64 imm:$src), ADDRri:$dst)>;
(STB_imm_V2 (imm_to_i64 imm:$src), ADDRri:$dst)>;
}

// LOAD instructions
Expand Down Expand Up @@ -1078,7 +1160,7 @@ def : Pat<(i64 (anyext GPR32:$src)),
def : Pat<(i64 (anyext GPR32:$src)),
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>, Requires<[SBFNoExplicitSignExt]>;

class STORE32<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
class STORE32_V1<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST<SBF_MEM.Value, SizeOp.Value,
(outs),
(ins GPR32:$src, MEMri:$addr),
Expand All @@ -1093,13 +1175,37 @@ class STORE32<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
let SBFClass = SBF_STX;
}

class STOREi32<SBFWidthModifer Opc, string Mnemonic, PatFrag OpNode>
: STORE32<Opc, Mnemonic, [(OpNode GPR32:$src, ADDRri:$addr)]>;
class STORE32_V2<SBFSizeModifier SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST_V2<SizeOp.Value,
SBF_X.Value,
(outs),
(ins GPR32:$src, MEMri:$addr),
Mnemonic # " [$addr], $src",
Pattern> {
bits<4> src;
bits<20> addr;

let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = src;
let Inst{47-32} = addr{15-0}; // offset
let SBFClass = SBF_ST_V2;
}

multiclass STOREi32<SBFWidthModifer SizeV1, SBFSizeModifier SizeV2,
string Mnemonic, PatFrag OpNode> {
def _V1 : STORE32_V1<SizeV1, Mnemonic, [(OpNode GPR32:$src, ADDRri:$addr)]>,
Requires<[SBFOldMemEncoding]>;

let DecoderNamespace = "SBFALU32V2" in {
def _V2 : STORE32_V2<SizeV2, Mnemonic, [(OpNode GPR32:$src, ADDRri:$addr)]>,
Requires<[SBFNewMemEncoding]>;
}
}

let Predicates = [SBFHasALU32], DecoderNamespace = "SBFALU32" in {
def STW32 : STOREi32<SBF_W, "stxw", store>;
def STH32 : STOREi32<SBF_H, "stxh", truncstorei16>;
def STB32 : STOREi32<SBF_B, "stxb", truncstorei8>;
defm STW32 : STOREi32<SBF_W, SBF_W_V2, "stxw", store>;
defm STH32 : STOREi32<SBF_H, SBF_H_V2, "stxh", truncstorei16>;
defm STB32 : STOREi32<SBF_B, SBF_B_V2, "stxb", truncstorei8>;
}

class LOAD32<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
Expand Down
29 changes: 21 additions & 8 deletions llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,28 @@ void SBFMISimplifyPatchable::initialize(MachineFunction &MFParm) {
LLVM_DEBUG(dbgs() << "*** SBF simplify patchable insts pass ***\n\n");
}

static bool isST(unsigned Opcode) {
return Opcode == SBF::STB_imm || Opcode == SBF::STH_imm ||
Opcode == SBF::STW_imm || Opcode == SBF::STD_imm;
static bool isST(unsigned Opcode, bool NewEncoding) {
if (NewEncoding) {
return Opcode == SBF::STB_imm_V2 || Opcode == SBF::STH_imm_V2 ||
Opcode == SBF::STW_imm_V2 || Opcode == SBF::STD_imm_V2;
}

return Opcode == SBF::STB_imm_V1 || Opcode == SBF::STH_imm_V1 ||
Opcode == SBF::STW_imm_V1 || Opcode == SBF::STD_imm_V1;
}

static bool isSTX32(unsigned Opcode) {
return Opcode == SBF::STB32 || Opcode == SBF::STH32 || Opcode == SBF::STW32;
}

static bool isSTX64(unsigned Opcode) {
return Opcode == SBF::STB || Opcode == SBF::STH || Opcode == SBF::STW ||
Opcode == SBF::STD;
static bool isSTX64(unsigned Opcode, bool NewEncoding) {
if (NewEncoding) {
return Opcode == SBF::STB_V2 || Opcode == SBF::STH_V2 ||
Opcode == SBF::STW_V2 ||Opcode == SBF::STD_V2;
}

return Opcode == SBF::STB_V1 || Opcode == SBF::STH_V1 || Opcode == SBF::STW_V1 ||
Opcode == SBF::STD_V1;
}

static bool isLDX32(unsigned Opcode) {
Expand All @@ -127,6 +137,8 @@ void SBFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI,
const MachineOperand *BaseOp = (RelocOp == Op1) ? Op2 : Op1;

// Go through all uses of %1 as in %1 = ADD_rr %2, %3
const SBFSubtarget& SubTarget = MF->getSubtarget<SBFSubtarget>();
bool NewMemEncoding = SubTarget.getNewMemEncoding();
const MachineOperand Op0 = Inst->getOperand(0);
for (MachineOperand &MO :
llvm::make_early_inc_range(MRI->use_operands(Op0.getReg()))) {
Expand All @@ -141,7 +153,8 @@ void SBFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI,
COREOp = SBF::CORE_LD64;
else if (isLDX32(Opcode))
COREOp = SBF::CORE_LD32;
else if (isSTX64(Opcode) || isSTX32(Opcode) || isST(Opcode))
else if (isSTX64(Opcode, NewMemEncoding) || isSTX32(Opcode)
|| isST(Opcode, NewMemEncoding))
COREOp = SBF::CORE_ST;
else
continue;
Expand All @@ -154,7 +167,7 @@ void SBFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI,
// Reject the form:
// %1 = ADD_rr %2, %3
// *(type *)(%2 + 0) = %1
if (isSTX64(Opcode) || isSTX32(Opcode)) {
if (isSTX64(Opcode, NewMemEncoding) || isSTX32(Opcode)) {
const MachineOperand &Opnd = DefInst->getOperand(0);
if (Opnd.isReg() && Opnd.getReg() == MO.getReg())
continue;
Expand Down
Loading

0 comments on commit a956e94

Please sign in to comment.