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

[SOL] New encoding for memory instructions #118

Merged
merged 1 commit into from
Dec 16, 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
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
Loading