Skip to content

Commit

Permalink
[SOL] New encoding for memory instructions (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte authored Dec 16, 2024
1 parent b70bb3f commit dda6181
Show file tree
Hide file tree
Showing 22 changed files with 713 additions and 130 deletions.
26 changes: 20 additions & 6 deletions llvm/lib/Target/SBF/BTFDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include <optional>
#include "SBFSubtarget.h"

using namespace llvm;
using namespace BTFX;
Expand Down Expand Up @@ -1309,6 +1310,15 @@ void BTFDebug::processGlobalValue(const MachineOperand &MO) {
}
}

static bool isCoreLoadOrStore(unsigned OpCode, bool NewMemEncoding) {
if (NewMemEncoding)
return OpCode == SBF::CORE_LD64_V2 || OpCode == SBF::CORE_LD32_V2 ||
OpCode == SBF::CORE_ST_V2;

return OpCode == SBF::CORE_LD64_V1 || OpCode == SBF::CORE_LD32_V1 ||
OpCode == SBF::CORE_ST_V1;
}

void BTFDebug::beginInstruction(const MachineInstr *MI) {
DebugHandlerBase::beginInstruction(MI);

Expand All @@ -1329,6 +1339,10 @@ void BTFDebug::beginInstruction(const MachineInstr *MI) {
return;
}

bool NewMemEncoding = MI->getParent()
->getParent()
->getSubtarget<SBFSubtarget>()
.getNewMemEncoding();
if (MI->getOpcode() == SBF::LD_imm64) {
// If the insn is "r2 = LD_imm64 @<an AmaAttr global>",
// add this insn into the .BTF.ext FieldReloc subsection.
Expand All @@ -1345,9 +1359,7 @@ void BTFDebug::beginInstruction(const MachineInstr *MI) {
// If the insn is "r2 = LD_imm64 @<an TypeIdAttr global>",
// The LD_imm64 result will be replaced with a btf type id.
processGlobalValue(MI->getOperand(1));
} else if (MI->getOpcode() == SBF::CORE_LD64 ||
MI->getOpcode() == SBF::CORE_LD32 ||
MI->getOpcode() == SBF::CORE_ST ||
} else if (isCoreLoadOrStore(MI->getOpcode(), NewMemEncoding) ||
MI->getOpcode() == SBF::CORE_SHIFT) {
// relocation insn is a load, store or shift insn.
processGlobalValue(MI->getOperand(3));
Expand Down Expand Up @@ -1496,6 +1508,10 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {

/// Emit proper patchable instructions.
bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
bool NewMemEncoding = MI->getParent()
->getParent()
->getSubtarget<SBFSubtarget>()
.getNewMemEncoding();
if (MI->getOpcode() == SBF::LD_imm64) {
const MachineOperand &MO = MI->getOperand(1);
if (MO.isGlobal()) {
Expand Down Expand Up @@ -1525,9 +1541,7 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
return true;
}
}
} else if (MI->getOpcode() == SBF::CORE_LD64 ||
MI->getOpcode() == SBF::CORE_LD32 ||
MI->getOpcode() == SBF::CORE_ST ||
} else if (isCoreLoadOrStore(MI->getOpcode(), NewMemEncoding) ||
MI->getOpcode() == SBF::CORE_SHIFT) {
const MachineOperand &MO = MI->getOperand(3);
if (MO.isGlobal()) {
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class SBFDisassembler : public MCDisassembler {
uint8_t getInstSize(uint64_t Inst) const { return (Inst >> 59) & 0x3; };
uint8_t getInstMode(uint64_t Inst) const { return (Inst >> 61) & 0x7; };
bool isMov32(uint64_t Inst) const { return (Inst >> 56) == 0xb4; }
bool isNewMem(uint64_t Inst) const;
};

} // end anonymous namespace
Expand Down Expand Up @@ -158,6 +159,18 @@ static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
return MCDisassembler::Success;
}

bool SBFDisassembler::isNewMem(uint64_t Inst) const {
uint8_t OpCode = Inst >> 56;

uint8_t LSB = OpCode & 0xf;
if (LSB != 0x7 && LSB != 0xc && LSB != 0xf)
return false;

uint8_t MSB = OpCode >> 4;

return MSB == 0x2 || MSB == 0x3 || MSB == 0x8 || MSB == 0x9;
}

DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
Expand All @@ -183,6 +196,16 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
STI.hasFeature(SBF::FeatureDisableLddw))
Result =
decodeInstruction(DecoderTableSBFv264, Instr, Insn, Address, this, STI);
else if (isNewMem(Insn) && (Insn >> 60) != 0x9 &&
STI.hasFeature(SBF::FeatureNewMemEncoding) &&
STI.hasFeature(SBF::ALU32))
Result =
decodeInstruction(DecoderTableSBFALU32MEMv264,
Instr, Insn, Address, this, STI);
else if (isNewMem(Insn) && STI.hasFeature(SBF::FeatureNewMemEncoding))
Result =
decodeInstruction(DecoderTableSBFv264,
Instr, Insn, Address, this, STI);
else
Result =
decodeInstruction(DecoderTableSBF64, Instr, Insn, Address, this, STI);
Expand Down
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_LD_V2 : SBFOpClass<0x4>;
def SBF_ST_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
45 changes: 24 additions & 21 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,24 @@ void SBFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
DebugLoc dl = MI->getDebugLoc();
unsigned LdOpc, StOpc;

#define MEM_SWITCH(X) \
LdOpc = NewMemEncoding ? SBF::LD##X##_V2 : SBF::LD##X##_V1; \
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;
MEM_SWITCH(B)
break;
case 2:
LdOpc = SBF::LDH;
StOpc = SBF::STH;
MEM_SWITCH(H)
break;
case 4:
LdOpc = SBF::LDW;
StOpc = SBF::STW;
MEM_SWITCH(W)
break;
case 8:
case 16:
LdOpc = SBF::LDD;
StOpc = SBF::STD;
MEM_SWITCH(D)
break;
default:
llvm_unreachable("unsupported memcpy alignment");
Expand All @@ -104,20 +105,16 @@ void SBFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {

if (BytesLeft < 2) {
Offset = CopyLen - 1;
LdOpc = SBF::LDB;
StOpc = SBF::STB;
MEM_SWITCH(B)
} else if (BytesLeft <= 2) {
Offset = CopyLen - 2;
LdOpc = SBF::LDH;
StOpc = SBF::STH;
MEM_SWITCH(H)
} else if (BytesLeft <= 4) {
Offset = CopyLen - 4;
LdOpc = SBF::LDW;
StOpc = SBF::STW;
MEM_SWITCH(W)
} else if (BytesLeft <= 8) {
Offset = CopyLen - 8;
LdOpc = SBF::LDD;
StOpc = SBF::STD;
MEM_SWITCH(D)
} else {
llvm_unreachable("There cannot be more than 8 bytes left");
}
Expand Down Expand Up @@ -154,12 +151,14 @@ 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);
else if (RC == &SBF::GPR32RegClass)
BuildMI(MBB, I, DL, get(SBF::STW32))
BuildMI(MBB, I, DL, get(NewMemEncoding ?
SBF::STW32_V2 : SBF::STW32_V1))
.addReg(SrcReg, getKillRegState(IsKill))
.addFrameIndex(FI)
.addImm(0);
Expand All @@ -178,9 +177,13 @@ void SBFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
DL = I->getDebugLoc();

if (RC == &SBF::GPRRegClass)
BuildMI(MBB, I, DL, get(SBF::LDD), DestReg).addFrameIndex(FI).addImm(0);
BuildMI(MBB, I, DL, get(NewMemEncoding ?
SBF::LDD_V2 : SBF::LDD_V1),
DestReg).addFrameIndex(FI).addImm(0);
else if (RC == &SBF::GPR32RegClass)
BuildMI(MBB, I, DL, get(SBF::LDW32), DestReg).addFrameIndex(FI).addImm(0);
BuildMI(MBB, I, DL, get(NewMemEncoding ?
SBF::LDW32_V2 : SBF::LDW32_V1),
DestReg).addFrameIndex(FI).addImm(0);
else
llvm_unreachable("Can't load this register from stack slot");
}
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
Loading

0 comments on commit dda6181

Please sign in to comment.