First working version?

This commit is contained in:
shylie 2025-10-21 18:25:06 -04:00
parent d2159076c8
commit a8b079fdd0
20 changed files with 424 additions and 115 deletions

View File

@ -341,6 +341,7 @@ LLVM_ABI void initializeWindowsSecureHotPatchingPass(PassRegistry &);
LLVM_ABI void initializeWinEHPreparePass(PassRegistry &);
LLVM_ABI void initializeWriteBitcodePassPass(PassRegistry &);
LLVM_ABI void initializeXRayInstrumentationLegacyPass(PassRegistry &);
LLVM_ABI void initializeFootRemovePseudoInstructionsPass(PassRegistry &);
} // end namespace llvm

View File

@ -24,6 +24,7 @@ add_llvm_target(FootCodeGen
FootRegisterInfo.cpp
FootAsmPrinter.cpp
FootDAGToDAGISel.cpp
FootRemovePseudoInstructions.cpp
LINK_COMPONENTS
FootDesc

View File

@ -9,6 +9,7 @@ namespace llvm {
void initializeFootDAGToDAGISelLegacyPass(PassRegistry &);
Pass *createFootISelDAG(FootTargetMachine &TM);
Pass *createFootRemovePseudoInstructionsPassForLegacyPM();
} // namespace llvm

View File

@ -1,7 +1,9 @@
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "TargetInfo/FootTargetInfo.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
@ -25,25 +27,48 @@ public:
bool FootAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCO) {
switch (MO.getType()) {
case MachineOperand::MO_Register:
if (MO.isImplicit())
return false;
MCO.createReg(MO.getReg());
MCO = MCOperand::createReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
MCO = MCOperand::createImm(MO.getImm());
break;
case MachineOperand::MO_CImmediate:
llvm_unreachable("cimm not yet implemented");
case MachineOperand::MO_FPImmediate:
llvm_unreachable("fpimm not yet implemented");
case MachineOperand::MO_MachineBasicBlock:
llvm_unreachable("machine basic block not yet implemented");
case MachineOperand::MO_FrameIndex:
llvm_unreachable("frame index not yet implemented");
case MachineOperand::MO_ConstantPoolIndex:
llvm_unreachable("constant pool index not yet implemented");
case MachineOperand::MO_TargetIndex:
llvm_unreachable("target index not yet implemented");
case MachineOperand::MO_JumpTableIndex:
llvm_unreachable("jump table index not yet implemented");
case MachineOperand::MO_ExternalSymbol:
llvm_unreachable("external symbol not yet implemented");
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_BlockAddress:
llvm_unreachable("block address not yet implemented");
case MachineOperand::MO_RegisterMask:
return false;
case MachineOperand::MO_MachineBasicBlock:
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
case MachineOperand::MO_RegisterLiveOut:
llvm_unreachable("register live out not yet implemented");
case MachineOperand::MO_Metadata:
llvm_unreachable("metadata not yet implemented");
case MachineOperand::MO_MCSymbol:
case MachineOperand::MO_JumpTableIndex:
case MachineOperand::MO_ConstantPoolIndex:
case MachineOperand::MO_BlockAddress:
llvm_unreachable("not yet implemented");
default:
llvm_unreachable("unknown operand type");
llvm_unreachable("mc symbol not yet implemented");
case MachineOperand::MO_CFIIndex:
llvm_unreachable("cfi index not yet implemented");
case MachineOperand::MO_IntrinsicID:
llvm_unreachable("intrinsic id not yet implemented");
case MachineOperand::MO_Predicate:
llvm_unreachable("predicate not yet implemented");
case MachineOperand::MO_ShuffleMask:
llvm_unreachable("shuffle mask not yet implemented");
case MachineOperand::MO_DbgInstrRef:
llvm_unreachable("debug instr ref not yet implemented");
}
return true;
}
@ -62,6 +87,8 @@ MCInst FootAsmPrinter::machineInstrToMCInst(const MachineInstr &MI) {
}
void FootAsmPrinter::emitInstruction(const MachineInstr *MI) {
Foot_MC::verifyInstructionPredicates(MI->getOpcode(), getSubtargetInfo().getFeatureBits());
MCInst TmpInst = machineInstrToMCInst(*MI);
EmitToStreamer(*OutStreamer, TmpInst);
}

View File

@ -6,14 +6,29 @@
using namespace llvm;
namespace {
enum FootAddrModes {
FOOT_ADDRMODE_M = 0,
FOOT_ADDRMODE_D = 1,
FOOT_ADDRMODE_I = 2,
FOOT_ADDRMODE_A = 3,
FOOT_ADDRMODE_COUNT = 4
};
} // namespace
class FootDAGToDAGISel : public SelectionDAGISel {
public:
explicit FootDAGToDAGISel(TargetMachine &TM) : SelectionDAGISel(TM) {}
private:
void SelectStore(SDNode *N, SDLoc &DL);
void SelectAdd(SDNode *N, SDLoc &DL);
void SelectReturnGlue(SDNode *N, SDLoc &DL);
void SelectLoad(SDNode *N, SDLoc &Loc);
void SelectStore(SDNode *N, SDLoc &Loc);
void SelectAdd(SDNode *N, SDLoc &Loc);
void SelectSub(SDNode *N, SDLoc &Loc);
void SelectConstant(SDNode *N, SDLoc &Loc);
void SelectCall(SDNode *N, SDLoc &Loc);
void Select(SDNode *N) override;
#include "FootGenDAGISel.inc"
@ -24,14 +39,32 @@ public:
static char ID;
FootDAGToDAGISelLegacy(FootTargetMachine &TM)
: SelectionDAGISelLegacy(ID, std::make_unique<FootDAGToDAGISel>(TM)) {}
StringRef getPassName() const override { return "FootDAGToDAGISelLegacy"; }
};
void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &DL) {
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
void FootDAGToDAGISel::SelectLoad(SDNode *N, SDLoc &Loc) {
LoadSDNode *LN = cast<LoadSDNode>(N);
SDValue Addr = LN->getBasePtr();
SDValue Chain = LN->getChain();
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Addr)) {
Addr = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
}
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Ops[] = { Addr, Zero, Chain };
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_D_I_M_A, Loc, {MVT::i32, MVT::Other}, Ops);
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectStore(SDNode *N, SDLoc &DL) {
void FootDAGToDAGISel::SelectStore(SDNode *N, SDLoc &Loc) {
StoreSDNode *SN = cast<StoreSDNode>(N);
SDValue Val = SN->getValue();
SDValue Addr = SN->getBasePtr();
@ -41,38 +74,130 @@ void FootDAGToDAGISel::SelectStore(SDNode *N, SDLoc &DL) {
Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Addr)) {
Addr = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), DL, MVT::i32);
Addr = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
}
SDNode *NewNode;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val)) {
SDValue Imm = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i32);
SDValue RegOp = CurDAG->getRegister(Foot::R27, MVT::i32);
SDValue Ops[] = { Addr, Imm, Chain };
NewNode = CurDAG->getMachineNode(Foot::CNST_I_A, DL, MVT::Other, Ops);
SDValue CopyOps[] = { Addr, Chain };
SDNode* CopyNode = CurDAG->getMachineNode(Foot::CNST_D_A_R, Loc, MVT::i32, CopyOps);
SDNode *Store;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val)) {
SDValue Imm = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
SDValue Ops[] = { Imm };
Store = CurDAG->getMachineNode(Foot::CNST_I_A, Loc, MVT::i32, Ops);
}
else {
SDValue Zero = CurDAG->getRegister(Foot::R0, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Ops[] = { Addr, Val, Zero, Chain };
NewNode = CurDAG->getMachineNode(Foot::BWOR_I_D_M_A, DL, MVT::Other, Ops);
SDValue Ops[] = { Val, Zero };
Store = CurDAG->getMachineNode(Foot::BWOR_I_D_M_A, Loc, MVT::i32, Ops);
}
SDValue FakeStoreOps[] = { SDValue(Store, 0) };
SDNode* FakeStore = CurDAG->getMachineNode(Foot::PSEUDO_STORE, Loc, MVT::Other, FakeStoreOps);
ReplaceNode(N, FakeStore);
}
void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) {
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
int LHS_AddrMode = FOOT_ADDRMODE_D;
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(LHS)) {
LHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
LHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(LHS)) {
LHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
LHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(LHS)) {
LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
LHS_AddrMode = FOOT_ADDRMODE_M;
}
int RHS_AddrMode = FOOT_ADDRMODE_D;
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(RHS)) {
RHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
RHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(RHS)) {
RHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
RHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS)) {
RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
RHS_AddrMode = FOOT_ADDRMODE_M;
}
unsigned Opc = Foot::ADDI_D_D_D_A;
switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) {
case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M:
Opc = Foot::ADDI_D_D_M_A;
break;
case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I:
Opc = Foot::ADDI_D_D_I_A;
break;
case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D:
Opc = Foot::ADDI_D_M_D_A;
break;
case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I:
Opc = Foot::ADDI_D_M_I_A;
break;
case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D:
Opc = Foot::ADDI_D_I_D_A;
break;
case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M:
Opc = Foot::ADDI_D_I_M_A;
break;
case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I:
Opc = Foot::ADDI_D_I_I_A;
break;
}
SDValue Ops[] = { LHS, RHS };
SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops);
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectReturnGlue(SDNode *N, SDLoc &DL) {
void FootDAGToDAGISel::SelectSub(SDNode *N, SDLoc &Loc) {
llvm_unreachable("not yet implemented");
}
void FootDAGToDAGISel::SelectConstant(SDNode *N, SDLoc &Loc) {
ConstantSDNode *CN = cast<ConstantSDNode>(N);
if (CN->getSExtValue() > 0xFFFF) {
report_fatal_error(">16-bit constants not yet supported");
}
SDValue Val = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Val);
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectCall(SDNode *N, SDLoc &Loc) {
SDValue Chain = N->getOperand(0);
SDValue RetVal = N->getOperand(1);
SDValue R0Val = CurDAG->getCopyToReg(Chain, DL, Foot::R0, RetVal);
SDValue RRA = CurDAG->getRegister(Foot::RRA, MVT::i32);
SDValue RPC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(1, Loc, MVT::i32);
SDValue RetAddr = CurDAG->getTargetFrameIndex(0, MVT::i32);
SDValue Ops[] = { RPC, Zero, Chain };
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getRegister(Foot::R0, MVT::i32);
SDValue Ops[] = { PC, RetAddr, Zero, R0Val.getOperand(1) };
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_D_I_M_A, DL, MVT::Other, Ops);
SDNode *Jump = CurDAG->getMachineNode(Foot::ADDI_D_D_M_A, Loc, MVT::i32, Ops);
SDNode *NewNode = CurDAG->getMachineNode(Foot::PSEUDO_CALL, Loc, {MVT::Other, MVT::Glue}, SDValue(Jump, 0));
ReplaceNode(N, NewNode);
}
@ -85,18 +210,24 @@ void FootDAGToDAGISel::Select(SDNode *N) {
SDLoc DL(N);
switch (N->getOpcode()) {
case ISD::ADD:
SelectAdd(N, DL);
case ISD::LOAD:
SelectLoad(N, DL);
break;
case ISD::STORE:
SelectStore(N, DL);
break;
case FootISD::RETURN_GLUE:
SelectReturnGlue(N, DL);
case ISD::ADD:
SelectAdd(N, DL);
break;
case ISD::SUB:
SelectSub(N, DL);
break;
case ISD::Constant:
SelectConstant(N, DL);
break;
case FootISD::CALL:
SelectCall(N, DL);
break;
default:
SelectCode(N);
break;

View File

@ -1,4 +1,5 @@
#include "FootFrameLowering.h"
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@ -14,51 +15,64 @@ bool FootFrameLowering::hasFPImpl(const MachineFunction& MF) const {
void FootFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
int FrameIndex = MFI.CreateFixedObject(4, 4, true);
unsigned NumBytes = MFI.getStackSize();
if (NumBytes > 0) {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
if (NumBytes < (1 << 5)) {
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A))
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A), Foot::RSP)
.addReg(Foot::RSP)
.addReg(Foot::RSP)
.addReg(NumBytes);
.addImm(NumBytes);
}
else {
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A))
.addReg(Foot::RSP)
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A), Foot::RSP)
.addReg(Foot::RSP)
.addReg(Foot::R27);
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A))
.addReg(Foot::R27)
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A), Foot::R27)
.addImm(NumBytes);
}
}
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::BWOR_I_D_M_A))
.addFrameIndex(FrameIndex)
.addReg(Foot::RRA)
.addImm(0);
}
void FootFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
unsigned NumBytes = MFI.getStackSize();
if (NumBytes > 0) {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
if (NumBytes < (1 << 5)) {
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A))
BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A), Foot::RSP)
.addReg(Foot::RSP)
.addReg(Foot::RSP)
.addReg(NumBytes);
.addImm(NumBytes);
}
else {
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A))
.addReg(Foot::RSP)
BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A), Foot::RSP)
.addReg(Foot::RSP)
.addReg(Foot::R27);
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A))
.addReg(Foot::R27)
BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), TII->get(Foot::CNST_D_A), Foot::R27)
.addImm(NumBytes);
}
}
const auto& I = MBB.getFirstTerminator();
BuildMI(MBB, I, I->getDebugLoc(), TII->get(Foot::BWOR_D_I_M_A))
.addReg(Foot::RPC)
.addFrameIndex(-1)
.addImm(0);
MBB.erase(I);
}
MachineBasicBlock::iterator FootFrameLowering::eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
@ -79,3 +93,19 @@ MachineBasicBlock::iterator FootFrameLowering::eliminateCallFramePseudoInstr(Mac
return MBB.erase(MI);
}
StackOffset FootFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FrameIndex,
Register &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
int Offset = MFI.getObjectSize(FrameIndex) + getOffsetOfLocalArea() +
MFI.getStackSize();
if (hasFP(MF)) {
llvm_unreachable("foot has no frame pointer");
}
FrameReg = Foot::RSP;
return StackOffset::getFixed(Offset);
}

View File

@ -21,6 +21,9 @@ public:
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FrameIndex,
Register &FrameReg) const override;
};
} // namespace llvm

View File

@ -62,8 +62,6 @@ const char *FootTargetLowering::getTargetNodeName(unsigned Opcode) const {
break;
case FootISD::CALL:
return "FootISD::CALL";
case FootISD::RETURN_GLUE:
return "FootISD::RETURN_GLUE";
}
return nullptr;
}
@ -74,6 +72,9 @@ SDValue FootTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
MFI.CreateFixedObject(4, 0, true);
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
CCInfo.AnalyzeFormalArguments(Ins, CC_Foot_Common);
@ -147,16 +148,14 @@ SDValue FootTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
// guarantee that all emitted copies are 'stuck together'
Glue = Chain.getValue(1);
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
if (Glue.getNode()) {
if (Glue) {
RetOps.push_back(Glue);
}
return DAG.getNode(FootISD::RETURN_GLUE, DL, MVT::Other, RetOps);
}
return DAG.getNode(FootISD::RETURN_GLUE, DL, MVT::Other, RetOps);
SDNode *NewNode = DAG.getMachineNode(Foot::PSEUDO_RET, DL, MVT::Other, RetOps);
return SDValue(NewNode, 0);
}
SDValue FootTargetLowering::LowerCall(CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const {

View File

@ -9,8 +9,7 @@ namespace FootISD {
enum NodeType : unsigned {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
CALL,
RETURN_GLUE
CALL
};
} // namespace FootISD

View File

@ -3,6 +3,7 @@
#include "MCTargetDesc/FootMCTargetDesc.h"
#define GET_INSTRINFO_CTOR_DTOR
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "FootGenInstrInfo.inc"
#include "llvm/CodeGen/MachineFrameInfo.h"
@ -25,13 +26,12 @@ void FootInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
unsigned Opc = Foot::ADDI_I_D_M_A;
unsigned Opc = Foot::BWOR_I_D_M_A;
MFI.setStackID(FrameIndex, TargetStackID::Default);
BuildMI(MBB, MI, DebugLoc(), get(Opc))
.addReg(SrcReg, getKillRegState(IsKill))
.addFrameIndex(FrameIndex)
// this needs some refactoring. this is technically an immediate for this format
.addReg(0)
.addReg(SrcReg, getKillRegState(IsKill))
.addImm(0)
.addMemOperand(MMO);
}
@ -49,12 +49,22 @@ void FootInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
unsigned Opc = Foot::ADDI_D_I_M_A;
unsigned Opc = Foot::BWOR_D_I_M_A;
MFI.setStackID(FrameIndex, TargetStackID::Default);
BuildMI(MBB, MI, DebugLoc(), get(Opc))
.addReg(DestReg)
.addFrameIndex(FrameIndex)
// this needs some refactoring. this is technically an immediate for this format
.addReg(0)
.addImm(0)
.addMemOperand(MMO);
}
void FootInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const DebugLoc &DL,
Register DestReg, Register SrcReg, bool KillSrc,
bool RenamableDest,
bool RenamableSrc) const {
BuildMI(MBB, MI, MI->getDebugLoc(), get(Foot::BWOR_D_D_M_A))
.addReg(DestReg, RegState::Define | getRenamableRegState(RenamableDest))
.addReg(SrcReg, getKillRegState(KillSrc) | getRenamableRegState(RenamableSrc))
.addImm(0);
}

View File

@ -27,6 +27,12 @@ public:
const TargetRegisterInfo *TRI,
Register VReg,
MachineInstr::MIFlag Flags) const override;
void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const DebugLoc& DL,
Register DestReg, Register SrcReg, bool KillSrc,
bool RenamableDest,
bool RenamableSrc) const override;
};
} // namespace llvm

View File

@ -1,15 +1,26 @@
include "FootInstrFormats.td"
def Footcall : SDNode<"FootISD::CALL",
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def Footcallseq_start : SDNode<"ISD::CALLSEQ_START",
SDCallSeqStart<[SDTCisVT<0, i32>,
SDTCisVT<0, i32>]>,
[SDNPHasChain, SDNPOutGlue]>;
def Footcallseq_end : SDNode<"ISD::CALLSEQ_END",
SDCallSeqStart<[SDTCisVT<0, i32>,
SDTCisVT<0, i32>]>,
[SDNPHasChain, SDNPOutGlue]>;
let mayLoad = 1, mayStore = 1, hasSideEffects = 1 in {
defm CNST_M : FootInstructionA<"CNST.m", "$dst, $imm", 0b0000, 0b00, (outs GP32:$dst), (ins i16imm:$imm)>;
defm CNST_D : FootInstructionA<"CNST.d", "$dst, $imm", 0b0000, 0b01, (outs GP32:$dst), (ins i16imm:$imm)>;
defm CNST_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs GP32:$dst), (ins i16imm:$imm)>;
defm CNST_A : FootInstructionA<"CNST.a", "$dst, $imm", 0b0000, 0b11, (outs GP32:$dst), (ins i16imm:$imm)>;
defm PC_CNST_M : FootInstructionA<"CNST.m", "$dst, $imm", 0b0000, 0b00, (outs PC32:$dst), (ins i16imm:$imm)>;
defm PC_CNST_D : FootInstructionA<"CNST.d", "$dst, $imm", 0b0000, 0b01, (outs PC32:$dst), (ins i16imm:$imm)>;
defm PC_CNST_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs PC32:$dst), (ins i16imm:$imm)>;
defm PC_CNST_A : FootInstructionA<"CNST.a", "$dst, $imm", 0b0000, 0b11, (outs PC32:$dst), (ins i16imm:$imm)>;
defm CMPR : FootInstructionB<"CMPR", 0b00000000>;
defm BWNG : FootInstructionB<"BWNG", 0b00000001>;
defm ARNG : FootInstructionB<"ARNG", 0b00000010>;
@ -27,20 +38,42 @@ defm SUBT : FootInstructionC<"SUBT", 0b1010, (outs GP32:$dst), (ins GP32:$a, GP3
defm MULT : FootInstructionC<"MULT", 0b1011, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
defm DIVI : FootInstructionC<"DIVI", 0b1100, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
defm MODU : FootInstructionC<"MODU", 0b1101, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
}
def Footreturnglue : SDNode<"FootISD::RETURN_GLUE", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
let OutOperandList = (outs),
InOperandList = (ins),
isReturn = 1,
isTerminator = 1,
isBarrier = 1,
Namespace = "Foot" in {
def PSEUDO_RET : StandardPseudoInstruction;
}
def Footcall : SDNode<"FootISD::CALL",
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
let OutOperandList = (outs),
InOperandList = (ins GP32:$a),
isCall = 1,
isCodeGenOnly = 1,
Uses = [RSP],
Namespace = "Foot" in {
def PSEUDO_CALL : StandardPseudoInstruction;
}
def Footcallseq_start : SDNode<"ISD::CALLSEQ_START",
SDCallSeqStart<[SDTCisVT<0, i32>,
SDTCisVT<0, i32>]>,
[SDNPHasChain, SDNPOutGlue]>;
let OutOperandList = (outs),
InOperandList = (ins GP32:$a),
mayStore = 1,
isCodeGenOnly = 1,
Namespace = "Foot" in {
def PSEUDO_STORE : StandardPseudoInstruction;
}
def Footcallseq_end : SDNode<"ISD::CALLSEQ_END",
SDCallSeqStart<[SDTCisVT<0, i32>,
SDTCisVT<0, i32>]>,
[SDNPHasChain, SDNPOutGlue]>;
let Defs = [RSP], Uses = [RSP],
isCodeGenOnly = 1, Namespace = "Foot",
OutOperandList = (outs),
InOperandList = (ins i32imm:$amt1, i32imm:$amt2) in {
def ADJCALLSTACKDOWN : StandardPseudoInstruction {
let Pattern = [(Footcallseq_start timm:$amt1, timm:$amt2)];
}
def ADJCALLSTACKUP : StandardPseudoInstruction {
let Pattern = [(Footcallseq_end timm:$amt1, timm:$amt2)];
}
}

View File

@ -0,0 +1,15 @@
#ifndef MODULE_PASS
#define MODULE_PASS(NAME, CREATE_PASS)
#endif
#undef MODULE_PASS
#ifndef FUNCTION_PASS
#define FUNCTION_PASS(NAME, CREATE_PASS)
#endif
#undef FUNCTION_PASS
#ifndef MACHINE_FUNCTION_PASS
#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS)
#endif
MACHINE_FUNCTION_PASS("foot-remove-pseudo-instructions", FootRemovePseudoInstructionsNewPass())
#undef MACHINE_FUNCTION_PASS

View File

@ -1,11 +1,12 @@
#include "FootRegisterInfo.h"
#include "FootFrameLowering.h"
#include "FootRegisterInfo.h"
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#define GET_REGINFO_TARGET_DESC
@ -13,18 +14,15 @@
using namespace llvm;
namespace {
MCPhysReg CSR_SaveList[] = {
0
};
} // namespace
FootRegisterInfo::FootRegisterInfo() : FootGenRegisterInfo(Foot::RRA) {}
const MCPhysReg *FootRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_SaveList;
return CSR_Foot_Common_SaveList;
}
const uint32_t *FootRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const {
return CSR_Foot_Common_RegMask;
}
BitVector FootRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
@ -35,7 +33,6 @@ BitVector FootRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
bool FootRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
/*
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
@ -48,14 +45,17 @@ bool FootRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int64_t Offset = MFI.getObjectOffset(Index);
// adjust to account for stack pointer adjusted before load/store
Offset += MFI.getStackSize();
assert(FIOperandNum == 1 && "Stack argument is expected to be the second"
"operand for both loads and stores");
switch (MI.getOpcode()) {
case Foot::ADDI_D_D_D_A:
case Foot::SUBT_D_D_D_A:
Register DestReg = Foot::R27;
if (FIOperandNum == 1) {
DestReg = Foot::R26;
}
*/
BuildMI(MBB, MI, DebugLoc(), TII.get(Foot::ADDI_D_D_M_A), DestReg)
.addReg(Foot::RSP)
.addImm(Offset);
FIOp.ChangeToRegister(DestReg, false);
return false;
}

View File

@ -12,6 +12,8 @@ struct FootRegisterInfo : public FootGenRegisterInfo {
FootRegisterInfo();
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;

View File

@ -33,8 +33,8 @@ def R22 : FootRegister<22, "r22">;
def R23 : FootRegister<23, "r23">;
def R24 : FootRegister<24, "r24">;
def R25 : FootRegister<25, "r25">;
def R26 : FootRegister<26, "r26">;
def R27 : FootRegister<27, "r27">;
def R26 : FootRegister<26, "r26">; /* used by compiler */
def R27 : FootRegister<27, "r27">; /* used by compiler */
def RSP : FootRegister<28, "rsp">; /* stack pointer */
def RRA : FootRegister<29, "rra">; /* return address */
def RLC : FootRegister<30, "rlc">; /* loop counter */

View File

@ -0,0 +1,46 @@
#include "Foot.h"
#include "llvm/Pass.h"
#include "llvm/InitializePasses.h"
#define DEBUG_TYPE "foot-remove-pseudo-instructions"
using namespace llvm;
namespace {
class FootRemovePseudoInstructions : public MachineFunctionPass {
public:
static char ID;
FootRemovePseudoInstructions() : MachineFunctionPass(ID) {}
bool runOnMachineFunction(MachineFunction &MF) override {
LLVM_DEBUG(dbgs() << "Removing Foot pseudo-instructions from " << MF.getName() << "\n");
bool MadeChanges = false;
for (auto &MBB : MF) {
for (auto MI = MBB.begin(); MI != MBB.end();) {
if (MI->isPseudo()) {
MI = MBB.erase(MI);
MadeChanges = true;
continue;
}
++MI;
}
}
return MadeChanges;
}
};
} // namespace
char FootRemovePseudoInstructions::ID = 0;
INITIALIZE_PASS(FootRemovePseudoInstructions, DEBUG_TYPE, "Foot remove pseudo-instructions", false, false)
Pass *llvm::createFootRemovePseudoInstructionsPassForLegacyPM() {
return new FootRemovePseudoInstructions();
}

View File

@ -66,6 +66,10 @@ void FootPassConfig::addIRPasses() {
TargetPassConfig::addIRPasses();
}
void FootPassConfig::addPreEmitPass() {
addPass(createFootRemovePseudoInstructionsPassForLegacyPM());
}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootTarget()
{
RegisterTargetMachine<FootTargetMachine> X(getTheFootTarget());

View File

@ -35,6 +35,7 @@ public:
bool addInstSelector() override;
void addIRPasses() override;
void addPreEmitPass() override;
};
} // namespace llvm

View File

@ -15,12 +15,12 @@ using namespace llvm;
#include "FootGenAsmWriter.inc"
FootInstPrinter::FootInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI)
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
void FootInstPrinter::printInst(const MCInst *MI, uint64_t Address,
StringRef Annot, const MCSubtargetInfo &STI,
raw_ostream &O) {
StringRef Annot, const MCSubtargetInfo &STI,
raw_ostream &O) {
if (!PrintAliases || !printAliasInstr(MI, Address, O)) {
printInstruction(MI, Address, O);
}
@ -29,7 +29,7 @@ void FootInstPrinter::printInst(const MCInst *MI, uint64_t Address,
}
void FootInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
unsigned Reg = Op.getReg();
@ -44,7 +44,7 @@ void FootInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
void FootInstPrinter::printImm(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
markup(O, Markup::Immediate) << "#" << formatImm(Op.getImm());
}