Finish chapter 15
This commit is contained in:
parent
ecee5141a5
commit
ddf3a97f70
@ -8,10 +8,13 @@ tablegen(LLVM FootGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM FootGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM FootGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM FootGenAsmEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM FootGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM FootGenDAGISel.inc -gen-dag-isel)
|
||||
|
||||
add_public_tablegen_target(FootCommonTableGen)
|
||||
|
||||
add_llvm_target(FootCodeGen
|
||||
FootCallingConvention.cpp
|
||||
FootFrameLowering.cpp
|
||||
FootInstrInfo.cpp
|
||||
FootISelLowering.cpp
|
||||
@ -19,6 +22,8 @@ add_llvm_target(FootCodeGen
|
||||
FootTargetMachine.cpp
|
||||
FootTargetObjectFile.cpp
|
||||
FootRegisterInfo.cpp
|
||||
FootAsmPrinter.cpp
|
||||
FootDAGToDAGISel.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
FootDesc
|
||||
|
||||
15
llvm/lib/Target/Foot/Foot.h
Normal file
15
llvm/lib/Target/Foot/Foot.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOT_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOT_H
|
||||
|
||||
#include "FootTargetMachine.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/PassRegistry.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
void initializeFootDAGToDAGISelLegacyPass(PassRegistry &);
|
||||
Pass *createFootISelDAG(FootTargetMachine &TM);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOT_H
|
||||
@ -1,6 +1,7 @@
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
include "FootRegisterInfo.td"
|
||||
include "FootCallingConvention.td"
|
||||
include "FootInstrInfo.td"
|
||||
|
||||
def : ProcessorModel<"generic", NoSchedModel, /*Features=*/[]>;
|
||||
|
||||
71
llvm/lib/Target/Foot/FootAsmPrinter.cpp
Normal file
71
llvm/lib/Target/Foot/FootAsmPrinter.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
class FootAsmPrinter : public AsmPrinter {
|
||||
public:
|
||||
explicit FootAsmPrinter(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> Streamer) :
|
||||
AsmPrinter(TM, std::move(Streamer)) {}
|
||||
|
||||
MCInst machineInstrToMCInst(const MachineInstr &MI);
|
||||
bool lowerOperand(const MachineOperand &MO, MCOperand &MCO);
|
||||
|
||||
void emitInstruction(const MachineInstr *MI) override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool FootAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCO) {
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
if (MO.isImplicit())
|
||||
return false;
|
||||
MCO.createReg(MO.getReg());
|
||||
break;
|
||||
case MachineOperand::MO_Immediate:
|
||||
MCO = MCOperand::createImm(MO.getImm());
|
||||
break;
|
||||
case MachineOperand::MO_RegisterMask:
|
||||
return false;
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
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");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MCInst FootAsmPrinter::machineInstrToMCInst(const MachineInstr &MI) {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(MI.getOpcode());
|
||||
for (const MachineOperand &MO : MI.operands()) {
|
||||
MCOperand MCOp;
|
||||
if (lowerOperand(MO, MCOp)) {
|
||||
TmpInst.addOperand(MCOp);
|
||||
}
|
||||
}
|
||||
|
||||
return TmpInst;
|
||||
}
|
||||
|
||||
void FootAsmPrinter::emitInstruction(const MachineInstr *MI) {
|
||||
MCInst TmpInst = machineInstrToMCInst(*MI);
|
||||
EmitToStreamer(*OutStreamer, TmpInst);
|
||||
}
|
||||
|
||||
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootAsmPrinter() {
|
||||
RegisterAsmPrinter<FootAsmPrinter> Tmp(getTheFootTarget());
|
||||
}
|
||||
6
llvm/lib/Target/Foot/FootCallingConvention.cpp
Normal file
6
llvm/lib/Target/Foot/FootCallingConvention.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "FootCallingConvention.h"
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#include "FootGenCallingConv.inc"
|
||||
16
llvm/lib/Target/Foot/FootCallingConvention.h
Normal file
16
llvm/lib/Target/Foot/FootCallingConvention.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOTCALLINGCONVENTION_H
|
||||
#define LLVM_LIB_TARGET_FOOTCALLINGCONVENTION_H
|
||||
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
|
||||
namespace llvm {
|
||||
bool CC_Foot_Common(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
Type *OrigTy, CCState &State);
|
||||
|
||||
bool RetCC_Foot_Common(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
Type *OrigTy, CCState &State);
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOTCALLINGCONVENTION_H
|
||||
13
llvm/lib/Target/Foot/FootCallingConvention.td
Normal file
13
llvm/lib/Target/Foot/FootCallingConvention.td
Normal file
@ -0,0 +1,13 @@
|
||||
defvar Foot_Common = [
|
||||
CCIfType<[i8, i16], CCBitConvertToType<i32>>,
|
||||
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3, R4, R5, R6, R7]>>,
|
||||
CCAssignToStack<4, 4>
|
||||
];
|
||||
|
||||
let Entry = 1 in
|
||||
def CC_Foot_Common : CallingConv<Foot_Common>;
|
||||
|
||||
let Entry = 1 in
|
||||
def RetCC_Foot_Common : CallingConv<Foot_Common>;
|
||||
|
||||
def CSR_Foot_Common : CalleeSavedRegs<(add)>;
|
||||
35
llvm/lib/Target/Foot/FootDAGToDAGISel.cpp
Normal file
35
llvm/lib/Target/Foot/FootDAGToDAGISel.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "Foot.h"
|
||||
#include "FootTargetMachine.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
class FootDAGToDAGISel : public SelectionDAGISel {
|
||||
public:
|
||||
explicit FootDAGToDAGISel(TargetMachine &TM) : SelectionDAGISel(TM) {}
|
||||
|
||||
private:
|
||||
void Select(SDNode *N) override;
|
||||
#include "FootGenDAGISel.inc"
|
||||
};
|
||||
|
||||
class FootDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
|
||||
public:
|
||||
static char ID;
|
||||
FootDAGToDAGISelLegacy(FootTargetMachine &TM)
|
||||
: SelectionDAGISelLegacy(ID, std::make_unique<FootDAGToDAGISel>(TM)) {}
|
||||
};
|
||||
|
||||
void FootDAGToDAGISel::Select(SDNode *N) {
|
||||
if (N->isMachineOpcode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SelectCode(N);
|
||||
}
|
||||
|
||||
char FootDAGToDAGISelLegacy::ID = 0;
|
||||
|
||||
Pass *llvm::createFootISelDAG(FootTargetMachine &TM) {
|
||||
return new FootDAGToDAGISelLegacy(TM);
|
||||
}
|
||||
@ -1,4 +1,9 @@
|
||||
#include "FootFrameLowering.h"
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -7,7 +12,70 @@ bool FootFrameLowering::hasFPImpl(const MachineFunction& MF) const {
|
||||
}
|
||||
|
||||
void FootFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {}
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
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))
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(NumBytes);
|
||||
}
|
||||
else {
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A))
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::R27);
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A))
|
||||
.addReg(Foot::R27)
|
||||
.addImm(NumBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FootFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {}
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
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))
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(NumBytes);
|
||||
}
|
||||
else {
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A))
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::R27);
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A))
|
||||
.addReg(Foot::R27)
|
||||
.addImm(NumBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock::iterator FootFrameLowering::eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const {
|
||||
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
||||
unsigned Opc = MI->getOpcode();
|
||||
|
||||
assert(hasReservedCallFrame(MF) && "Foot doesn't have an FP register");
|
||||
|
||||
if (Opc != TII->getCallFrameSetupOpcode() &&
|
||||
Opc != TII->getCallFrameDestroyOpcode()) {
|
||||
report_fatal_error("Unexpected frame psuedo instruction");
|
||||
}
|
||||
|
||||
if (MI->getOperand(1).getImm() != 0) {
|
||||
report_fatal_error("callee pop count not supported");
|
||||
}
|
||||
|
||||
return MBB.erase(MI);
|
||||
}
|
||||
|
||||
@ -17,6 +17,10 @@ public:
|
||||
|
||||
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
||||
|
||||
MachineBasicBlock::iterator
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -0,0 +1,279 @@
|
||||
#include "FootCallingConvention.h"
|
||||
#include "FootISelLowering.h"
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "FootSubtarget.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
FootTargetLowering::FootTargetLowering(const TargetMachine &TM,
|
||||
const FootSubtarget &STI)
|
||||
: TargetLowering(TM), Subtarget(STI) {
|
||||
addRegisterClass(MVT::i32, &Foot::GP32RegClass);
|
||||
addRegisterClass(MVT::v2i16, &Foot::GP32RegClass);
|
||||
addRegisterClass(MVT::v4i8, &Foot::GP32RegClass);
|
||||
|
||||
computeRegisterProperties(Subtarget.getRegisterInfo());
|
||||
}
|
||||
|
||||
const char *FootTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
case FootISD::FIRST_NUMBER:
|
||||
break;
|
||||
case FootISD::CALL:
|
||||
return "FootISD::CALL";
|
||||
case FootISD::RETURN_GLUE:
|
||||
return "FootISD::RETURN_GLUE";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
|
||||
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_Foot_Common);
|
||||
for (size_t I = 0; I < ArgLocs.size(); ++I) {
|
||||
auto &VA = ArgLocs[I];
|
||||
SDValue ArgValue;
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
if (VA.getLocInfo() != CCValAssign::Full) {
|
||||
report_fatal_error("non-full passing, not yet implemented");
|
||||
}
|
||||
|
||||
EVT RegVT = VA.getLocVT();
|
||||
// no special logic for selecting register class
|
||||
// just don't use one of the hardware-reserved registers
|
||||
// (which aren't part of GP32RegClass anyway)
|
||||
const TargetRegisterClass *DstRC = &Foot::GP32RegClass;
|
||||
Register VReg = RegInfo.createVirtualRegister(DstRC);
|
||||
RegInfo.addLiveIn(VA.getLocReg(), VReg);
|
||||
ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
|
||||
}
|
||||
else {
|
||||
assert(VA.isMemLoc() && "CCValAssign is neither reg nor mem");
|
||||
|
||||
unsigned ArgOffset = VA.getLocMemOffset();
|
||||
|
||||
if (VA.getLocInfo() != CCValAssign::Full) {
|
||||
report_fatal_error("only values are supported directly in the stack");
|
||||
}
|
||||
|
||||
unsigned ArgSize = VA.getValVT().getSizeInBits() / 8;
|
||||
int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, true);
|
||||
|
||||
SDValue FrameIdxNode = DAG.getFrameIndex(FrameIndex, getPointerTy(DAG.getDataLayout()));
|
||||
MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
|
||||
|
||||
ISD::LoadExtType ExtType = ISD::NON_EXTLOAD;
|
||||
MVT MemVT = VA.getValVT();
|
||||
|
||||
ArgValue = DAG.getExtLoad(ExtType, DL, VA.getLocVT(), Chain, FrameIdxNode, PtrInfo, MemVT);
|
||||
}
|
||||
|
||||
InVals.push_back(ArgValue);
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
|
||||
SelectionDAG &DAG) const {
|
||||
SmallVector<CCValAssign> RetValLocs;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
|
||||
CCState CCInfo(CallConv, IsVarArg, MF, RetValLocs, *DAG.getContext());
|
||||
|
||||
CCInfo.AnalyzeReturn(Outs, RetCC_Foot_Common);
|
||||
|
||||
SDValue Glue;
|
||||
SmallVector<SDValue> RetOps(1, Chain);
|
||||
|
||||
for (size_t I = 0, E = RetValLocs.size(); I != E; ++I) {
|
||||
CCValAssign &VA = RetValLocs[I];
|
||||
|
||||
assert(VA.isRegLoc() && "stack return not yet implemented");
|
||||
assert(VA.getLocInfo() == CCValAssign::Full &&
|
||||
"extension/truncation of any sort is not yet implemented");
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[I], Glue);
|
||||
|
||||
// guarantee that all emitted copies are 'stuck together'
|
||||
Glue = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
|
||||
if (Glue.getNode()) {
|
||||
RetOps.push_back(Glue);
|
||||
}
|
||||
|
||||
return DAG.getNode(FootISD::RETURN_GLUE, DL, MVT::Other, RetOps);
|
||||
}
|
||||
|
||||
return DAG.getNode(FootISD::RETURN_GLUE, DL, MVT::Other, RetOps);
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerCall(CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const {
|
||||
SelectionDAG &DAG = CLI.DAG;
|
||||
SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
|
||||
SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
|
||||
SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
|
||||
|
||||
SDValue Chain = CLI.Chain;
|
||||
SDValue Callee = CLI.Callee;
|
||||
CallingConv::ID CallConv = CLI.CallConv;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
SDLoc &DL = CLI.DL;
|
||||
|
||||
// Tail-call optimization is not supported yet
|
||||
CLI.IsTailCall = false;
|
||||
|
||||
if (CLI.IsVarArg) {
|
||||
report_fatal_error("Var args not yet implemented");
|
||||
}
|
||||
bool IsVarArg = false;
|
||||
|
||||
switch (CallConv) {
|
||||
default:
|
||||
report_fatal_error("unsupported callling convention: " + Twine(CallConv));
|
||||
case CallingConv::Fast:
|
||||
case CallingConv::C:
|
||||
break;
|
||||
}
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
|
||||
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_Foot_Common);
|
||||
|
||||
unsigned NumBytes = CCInfo.getStackSize();
|
||||
|
||||
for (const ISD::OutputArg &Out : Outs) {
|
||||
ISD::ArgFlagsTy OutFlags = Out.Flags;
|
||||
if (OutFlags.isByVal()) {
|
||||
report_fatal_error("Unsupported attribute");
|
||||
}
|
||||
}
|
||||
|
||||
SDValue InGlue;
|
||||
|
||||
auto PtrVT = getPointerTy(MF.getDataLayout());
|
||||
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
|
||||
|
||||
SDValue StackPtr = DAG.getCopyFromReg(Chain, DL, Foot::RSP, getPointerTy(DAG.getDataLayout()));
|
||||
|
||||
SmallVector<std::pair<Register, SDValue>> RegsToPass;
|
||||
SmallVector<SDValue, 8> MemOpChains;
|
||||
|
||||
for (size_t I = 0, E = ArgLocs.size(); I != E; ++I) {
|
||||
CCValAssign &VA = ArgLocs[I];
|
||||
SDValue &Arg = OutVals[I];
|
||||
|
||||
if (VA.getLocInfo() != CCValAssign::Full) {
|
||||
report_fatal_error("extensions not yet implemented: " + Twine(VA.getLocInfo()));
|
||||
}
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
RegsToPass.emplace_back(VA.getLocReg(), Arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(VA.isMemLoc() && "Expected stack argument");
|
||||
|
||||
SDValue DstAddr;
|
||||
MachinePointerInfo DstInfo;
|
||||
|
||||
unsigned OpSize = VA.getValVT().getSizeInBits();
|
||||
// round up to nearest byte count
|
||||
OpSize = (OpSize + 7) / 8;
|
||||
unsigned LocMemOffset = VA.getLocMemOffset();
|
||||
SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, DL);
|
||||
// pointer arithmetic
|
||||
DstAddr = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
|
||||
DstInfo = MachinePointerInfo::getStack(MF, LocMemOffset);
|
||||
|
||||
SDValue Store = DAG.getStore(Chain, DL, Arg, DstAddr, DstInfo);
|
||||
}
|
||||
|
||||
if (!MemOpChains.empty()) {
|
||||
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
|
||||
}
|
||||
|
||||
for (auto& RegToPass : RegsToPass) {
|
||||
Chain = DAG.getCopyToReg(Chain, DL, RegToPass.first, RegToPass.second, InGlue);
|
||||
InGlue = Chain.getValue(1);
|
||||
}
|
||||
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT, G->getOffset(), 0);
|
||||
}
|
||||
else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
||||
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
|
||||
}
|
||||
else {
|
||||
report_fatal_error("Other calls not supported");
|
||||
}
|
||||
|
||||
SmallVector<SDValue, 8> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(Callee);
|
||||
|
||||
for (auto &Reg : RegsToPass) {
|
||||
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
|
||||
}
|
||||
|
||||
const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
|
||||
const uint32_t *Mask = TRI.getCallPreservedMask(MF, CallConv);
|
||||
|
||||
assert(Mask && "Missing call preserved mask for calling convention");
|
||||
Ops.push_back(DAG.getRegisterMask(Mask));
|
||||
|
||||
if (InGlue.getNode()) {
|
||||
Ops.push_back(InGlue);
|
||||
}
|
||||
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||
Chain = DAG.getNode(FootISD::CALL, DL, NodeTys, Ops);
|
||||
InGlue = Chain.getValue(1);
|
||||
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
|
||||
|
||||
Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
|
||||
InGlue = Chain.getValue(1);
|
||||
|
||||
SmallVector<CCValAssign, 16> RetValLocs;
|
||||
CCState CCRetInfo(CallConv, IsVarArg, MF, RetValLocs, *DAG.getContext());
|
||||
|
||||
CCRetInfo.AnalyzeCallResult(Ins, RetCC_Foot_Common);
|
||||
|
||||
for (size_t I = 0, E = RetValLocs.size(); I != E; ++I) {
|
||||
CCValAssign &VA = RetValLocs[I];
|
||||
assert(VA.isRegLoc() && "stack return not yet implemented");
|
||||
assert(VA.getLocInf() == CCValAssign::Full && "extension/truncation not yet implemented");
|
||||
|
||||
Chain = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getValVT(), InGlue)
|
||||
.getValue(1);
|
||||
|
||||
InGlue = Chain.getValue(2);
|
||||
InVals.push_back(Chain.getValue(0));
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
bool FootTargetLowering::CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
|
||||
const Type *RetTy) const {
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
|
||||
MF.getFunction().getContext());
|
||||
|
||||
return !IsVarArg && CCInfo.CheckReturn(Outs, RetCC_Foot_Common);
|
||||
}
|
||||
@ -5,12 +5,41 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace FootISD {
|
||||
|
||||
enum NodeType : unsigned {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
CALL,
|
||||
RETURN_GLUE
|
||||
};
|
||||
|
||||
} // namespace FootISD
|
||||
|
||||
class FootSubtarget;
|
||||
class FootTargetMachine;
|
||||
|
||||
class FootTargetLowering : public TargetLowering {
|
||||
const FootSubtarget &Subtarget;
|
||||
public:
|
||||
explicit FootTargetLowering(const TargetMachine &TM);
|
||||
explicit FootTargetLowering(const TargetMachine &TM,
|
||||
const FootSubtarget &STI);
|
||||
|
||||
const char *getTargetNodeName(unsigned Opcode) const override;
|
||||
|
||||
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
|
||||
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const override;
|
||||
|
||||
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
|
||||
SelectionDAG &DAG) const override;
|
||||
|
||||
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const override;
|
||||
|
||||
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
LLVMContext &Context, const Type *RetTy) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -1,23 +1,315 @@
|
||||
class FootInstruction<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
dag oops = (outs), dag iops = (ins)>
|
||||
: Instruction<> {
|
||||
let Namespace = "Foot";
|
||||
let AsmString = !strconcat(asm, "\t", operands);
|
||||
let OutOperandList = oops;
|
||||
let InOperandList = iops;
|
||||
class _FootInstructionA<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> dstmode, bits<1> repeat,
|
||||
dag oops = (outs), dag iops = (ins)>
|
||||
: Instruction<> {
|
||||
let Namespace = "Foot";
|
||||
let AsmString = !strconcat(asm, "\t", operands);
|
||||
let OutOperandList = oops;
|
||||
let InOperandList = iops;
|
||||
|
||||
bits<32> Inst;
|
||||
bits<3> Condition;
|
||||
bits<1> Repeat;
|
||||
bits<1> Vect1;
|
||||
bits<2> DstAddrMode;
|
||||
bits<5> dst;
|
||||
bits<32> Inst;
|
||||
bits<3> Condition;
|
||||
bits<5> dst;
|
||||
bits<16> imm;
|
||||
|
||||
let Inst{31-29} = Condition;
|
||||
let Inst{28} = Repeat;
|
||||
let Inst{27-24} = opcode;
|
||||
let Inst{23} = Vect1;
|
||||
let Inst{22-21} = DstAddrMode;
|
||||
let Inst{20-16} = dst;
|
||||
let Inst{31-29} = Condition;
|
||||
let Inst{28} = repeat;
|
||||
let Inst{27-24} = opcode;
|
||||
let Inst{23} = 0b0;
|
||||
let Inst{22-21} = dstmode;
|
||||
let Inst{20-16} = dst;
|
||||
let Inst{15-0} = imm;
|
||||
}
|
||||
|
||||
multiclass FootInstructionA<string asm, string operands,
|
||||
bits<4> opcode, bits<2> dstmode,
|
||||
dag oops = (outs), dag iops = (ins)> {
|
||||
def _A : _FootInstructionA<asm, operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L : _FootInstructionA<!strconcat(asm, ".l"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE : _FootInstructionA<!strconcat(asm, ".le"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E : _FootInstructionA<!strconcat(asm, ".e"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE : _FootInstructionA<!strconcat(asm, ".ge"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G : _FootInstructionA<!strconcat(asm, ".g"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE : _FootInstructionA<!strconcat(asm, ".ne"), operands, opcode, dstmode, 0b0, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
|
||||
def _A_R : _FootInstructionA<asm, operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L_R : _FootInstructionA<!strconcat(asm, ".l"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE_R : _FootInstructionA<!strconcat(asm, ".le"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E_R : _FootInstructionA<!strconcat(asm, ".e"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE_R : _FootInstructionA<!strconcat(asm, ".ge"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G_R : _FootInstructionA<!strconcat(asm, ".g"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE_R : _FootInstructionA<!strconcat(asm, ".ne"), operands, opcode, dstmode, 0b1, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
}
|
||||
|
||||
class _FootInstructionB<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> dstmode, bits<2> amode,
|
||||
bits<8> opcode2, bits<1> repeat,
|
||||
dag oops = (outs), dag iops = (ins)>
|
||||
: Instruction<> {
|
||||
let Namespace = "Foot";
|
||||
let AsmString = !strconcat(asm, "\t", operands);
|
||||
let OutOperandList = oops;
|
||||
let InOperandList = iops;
|
||||
|
||||
bits<32> Inst;
|
||||
bits<3> Condition;
|
||||
bits<2> Vect;
|
||||
bits<5> dst;
|
||||
bits<5> a;
|
||||
|
||||
let Inst{31-29} = Condition;
|
||||
let Inst{28} = repeat;
|
||||
let Inst{27-24} = opcode;
|
||||
let Inst{23} = Vect{1};
|
||||
let Inst{22-21} = dstmode;
|
||||
let Inst{20-16} = dst;
|
||||
let Inst{15-8} = opcode2;
|
||||
let Inst{7} = Vect{0};
|
||||
let Inst{6-5} = amode;
|
||||
let Inst{4-0} = a;
|
||||
|
||||
let Vect = 0b00;
|
||||
}
|
||||
|
||||
multiclass _mFootInstructionB<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> dstmode, bits<2> amode,
|
||||
bits<8> opcode2,
|
||||
dag oops = (outs), dag iops = (ins)> {
|
||||
def _A : _FootInstructionB<asm, operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L : _FootInstructionB<!strconcat(asm, ".l"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE : _FootInstructionB<!strconcat(asm, ".le"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E : _FootInstructionB<!strconcat(asm, ".e"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE : _FootInstructionB<!strconcat(asm, ".ge"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G : _FootInstructionB<!strconcat(asm, ".g"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE : _FootInstructionB<!strconcat(asm, ".ne"), operands, opcode, dstmode, amode, opcode2, 0b0, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
|
||||
def _A_R : _FootInstructionB<asm, operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L_R : _FootInstructionB<!strconcat(asm, ".l"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE_R : _FootInstructionB<!strconcat(asm, ".le"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E_R : _FootInstructionB<!strconcat(asm, ".e"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE_R : _FootInstructionB<!strconcat(asm, ".ge"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G_R : _FootInstructionB<!strconcat(asm, ".g"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE_R : _FootInstructionB<!strconcat(asm, ".ne"), operands, opcode, dstmode, amode, opcode2, 0b1, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
}
|
||||
|
||||
multiclass FootInstructionB<string asm, bits<8> opcode2> {
|
||||
defm _M_M : _mFootInstructionB<!strconcat(asm, ".m.m"), "$dst, $a", 0b0001, 0b00, 0b00, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _M_D : _mFootInstructionB<!strconcat(asm, ".m.d"), "$dst, $a", 0b0001, 0b00, 0b01, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _M_I : _mFootInstructionB<!strconcat(asm, ".m.i"), "$dst, $a", 0b0001, 0b00, 0b10, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _M_A : _mFootInstructionB<!strconcat(asm, ".m.a"), "$dst, $a", 0b0001, 0b00, 0b11, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _D_M : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b00, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _D_D : _mFootInstructionB<!strconcat(asm, ".d.d"), "$dst, $a", 0b0001, 0b01, 0b01, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _D_I : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b10, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _D_A : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b11, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _I_M : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b00, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _I_D : _mFootInstructionB<!strconcat(asm, ".i.d"), "$dst, $a", 0b0001, 0b10, 0b01, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _I_I : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b10, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _I_A : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b11, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _A_M : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b00, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _A_D : _mFootInstructionB<!strconcat(asm, ".a.d"), "$dst, $a", 0b0001, 0b11, 0b01, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _A_I : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b10, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm _A_A : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b11, opcode2, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
}
|
||||
|
||||
class _FootInstructionC<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> dstmode, bits<2> amode,
|
||||
bits<2> bmode, bits<1> repeat,
|
||||
dag oops = (outs), dag iops = (ins)>
|
||||
: Instruction<> {
|
||||
let Namespace = "Foot";
|
||||
let AsmString = !strconcat(asm, "\t", operands);
|
||||
let OutOperandList = oops;
|
||||
let InOperandList = iops;
|
||||
|
||||
bits<32> Inst;
|
||||
bits<3> Condition;
|
||||
bits<2> Vect;
|
||||
bits<5> dst;
|
||||
bits<5> a;
|
||||
bits<5> b;
|
||||
|
||||
let Inst{31-29} = Condition;
|
||||
let Inst{28} = repeat;
|
||||
let Inst{27-24} = opcode;
|
||||
let Inst{23} = Vect{1};
|
||||
let Inst{22-21} = dstmode;
|
||||
let Inst{20-16} = dst;
|
||||
let Inst{15} = 0b0;
|
||||
let Inst{14-13} = bmode;
|
||||
let Inst{12-8} = b;
|
||||
let Inst{7} = Vect{0};
|
||||
let Inst{6-5} = amode;
|
||||
let Inst{4-0} = a;
|
||||
|
||||
let Vect = 0b00;
|
||||
}
|
||||
|
||||
multiclass _mmmFootInstructionC<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> dstmode, bits<2> amode,
|
||||
bits<2> bmode,
|
||||
dag oops = (outs), dag iops = (ins)> {
|
||||
def _A : _FootInstructionC<asm, operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L : _FootInstructionC<!strconcat(asm, ".l"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE : _FootInstructionC<!strconcat(asm, ".le"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E : _FootInstructionC<!strconcat(asm, ".e"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE : _FootInstructionC<!strconcat(asm, ".ge"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G : _FootInstructionC<!strconcat(asm, ".g"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE : _FootInstructionC<!strconcat(asm, ".ne"), operands, opcode, dstmode, amode, bmode, 0b0, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
|
||||
def _A_R : _FootInstructionC<asm, operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b000;
|
||||
}
|
||||
|
||||
def _L_R : _FootInstructionC<!strconcat(asm, ".l"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b001;
|
||||
}
|
||||
|
||||
def _LE_R : _FootInstructionC<!strconcat(asm, ".le"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b010;
|
||||
}
|
||||
|
||||
def _E_R : _FootInstructionC<!strconcat(asm, ".e"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b011;
|
||||
}
|
||||
|
||||
def _GE_R : _FootInstructionC<!strconcat(asm, ".ge"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b100;
|
||||
}
|
||||
|
||||
def _G_R : _FootInstructionC<!strconcat(asm, ".g"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b101;
|
||||
}
|
||||
|
||||
def _NE_R : _FootInstructionC<!strconcat(asm, ".ne"), operands, opcode, dstmode, amode, bmode, 0b1, oops, iops> {
|
||||
let Condition = 0b110;
|
||||
}
|
||||
}
|
||||
|
||||
multiclass _mmFootInstructionC<string asm, string operands,
|
||||
bits<4> opcode,
|
||||
bits<2> amode, bits<2> bmode> {
|
||||
defm _M : _mmmFootInstructionC<!strconcat(asm, ".m"), operands, opcode, 0b00, amode, bmode, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm _D : _mmmFootInstructionC<!strconcat(asm, ".d"), operands, opcode, 0b01, amode, bmode, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm _I : _mmmFootInstructionC<!strconcat(asm, ".i"), operands, opcode, 0b10, amode, bmode, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm _A : _mmmFootInstructionC<!strconcat(asm, ".a"), operands, opcode, 0b11, amode, bmode, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
}
|
||||
|
||||
multiclass _mFootInstructionC<string asm, string operands,
|
||||
bits<4> opcode, bits<2> bmode> {
|
||||
defm _M : _mmFootInstructionC<!strconcat(asm, ".m"), operands, opcode, 0b00, bmode>;
|
||||
defm _D : _mmFootInstructionC<!strconcat(asm, ".d"), operands, opcode, 0b01, bmode>;
|
||||
defm _I : _mmFootInstructionC<!strconcat(asm, ".i"), operands, opcode, 0b10, bmode>;
|
||||
defm _A : _mmFootInstructionC<!strconcat(asm, ".a"), operands, opcode, 0b11, bmode>;
|
||||
}
|
||||
|
||||
multiclass FootInstructionC<string asm, bits<4> opcode> {
|
||||
defm _M : _mFootInstructionC<!strconcat(asm, ".m"), "$dst, $a, $b", opcode, 0b00>;
|
||||
defm _D : _mFootInstructionC<!strconcat(asm, ".d"), "$dst, $a, $b", opcode, 0b01>;
|
||||
defm _I : _mFootInstructionC<!strconcat(asm, ".i"), "$dst, $a, $b", opcode, 0b10>;
|
||||
defm _A : _mFootInstructionC<!strconcat(asm, ".a"), "$dst, $a, $b", opcode, 0b11>;
|
||||
}
|
||||
|
||||
@ -1,11 +1,41 @@
|
||||
include "FootInstrFormats.td"
|
||||
|
||||
def CNST : FootInstruction<"CNST", "$dst, $imm", 0b0000, (outs GP32:$dst), (ins i16imm:$imm)> {
|
||||
bits<16> imm;
|
||||
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)>;
|
||||
|
||||
let Inst{15-0} = imm;
|
||||
let Condition = 0b000;
|
||||
let Repeat = 0b0;
|
||||
let Vect1 = 0b0;
|
||||
let DstAddrMode = 0b01;
|
||||
}
|
||||
defm CMPR : FootInstructionB<"CMPR", 0b00000000>;
|
||||
defm BWNG : FootInstructionB<"BWNG", 0b00000001>;
|
||||
defm ARNG : FootInstructionB<"ARNG", 0b00000010>;
|
||||
defm LONG : FootInstructionB<"LONG", 0b00000011>;
|
||||
defm CONF : FootInstructionB<"CONF", 0b00000100>;
|
||||
|
||||
defm BWOR : FootInstructionC<"BWOR", 0b0010>;
|
||||
defm BAND : FootInstructionC<"BAND", 0b0011>;
|
||||
defm BXOR : FootInstructionC<"BXOR", 0b0100>;
|
||||
defm SRSH : FootInstructionC<"SRSH", 0b0110>;
|
||||
defm ZLSH : FootInstructionC<"ZLSH", 0b0111>;
|
||||
defm CLSH : FootInstructionC<"CLSH", 0b1000>;
|
||||
defm ADDI : FootInstructionC<"ADDI", 0b1001>;
|
||||
defm SUBT : FootInstructionC<"SUBT", 0b1010>;
|
||||
defm MULT : FootInstructionC<"MULT", 0b1011>;
|
||||
defm DIVI : FootInstructionC<"DIVI", 0b1100>;
|
||||
defm MODU : FootInstructionC<"MODU", 0b1101>;
|
||||
|
||||
def Footreturnglue : SDNode<"Foot::RETURN_GLUE", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
|
||||
|
||||
def Footcall : SDNode<"Foot::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]>;
|
||||
|
||||
@ -16,8 +16,8 @@ struct FootRegisterInfo : public FootGenRegisterInfo {
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const override;
|
||||
|
||||
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
|
||||
unsigned FIOperandNum,
|
||||
RegScavenger *RS = nullptr) const override;
|
||||
unsigned FIOperandNum,
|
||||
RegScavenger *RS = nullptr) const override;
|
||||
|
||||
Register getFrameRegister(const MachineFunction &MF) const override;
|
||||
};
|
||||
|
||||
@ -35,11 +35,11 @@ def R24 : FootRegister<24, "r24">;
|
||||
def R25 : FootRegister<25, "r25">;
|
||||
def R26 : FootRegister<26, "r26">;
|
||||
def R27 : FootRegister<27, "r27">;
|
||||
def R28 : FootRegister<28, "r28">;
|
||||
def RSP : FootRegister<28, "rsp">; /* stack pointer */
|
||||
def RRA : FootRegister<29, "rra">; /* return address */
|
||||
def RLC : FootRegister<30, "rlc">; /* loop counter */
|
||||
def RPC : FootRegister<31, "rpc">; /* program counter */
|
||||
|
||||
def GP32 : RegisterClass<"Foot", [i32], 32, (sequence "R%u", 0, 28)>;
|
||||
def GP32 : RegisterClass<"Foot", [i32], 32, (sequence "R%u", 0, 27)>;
|
||||
|
||||
}
|
||||
|
||||
@ -11,8 +11,8 @@ using namespace llvm;
|
||||
#define GET_SUBTARGET_CTOR
|
||||
#include "FootGenSubtargetInfo.inc"
|
||||
|
||||
// Pin the vtable to this file.
|
||||
void FootSubtarget::anchor() {}
|
||||
|
||||
FootSubtarget::FootSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
const TargetMachine &TM)
|
||||
: FootGenSubtargetInfo(TT, CPU, "", FS), TLInfo(TM) {}
|
||||
FootSubtarget::FootSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const TargetMachine &TM)
|
||||
: FootGenSubtargetInfo(TT, CPU, "", FS), FrameLowering(*this), TLInfo(TM, *this) {}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H
|
||||
|
||||
#include "FootFrameLowering.h"
|
||||
#include "FootISelLowering.h"
|
||||
#include "FootInstrInfo.h"
|
||||
#include "FootRegisterInfo.h"
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
|
||||
#define GET_SUBTARGETINFO_HEADER
|
||||
@ -16,17 +20,37 @@ class Triple;
|
||||
|
||||
class FootSubtarget : public FootGenSubtargetInfo {
|
||||
virtual void anchor();
|
||||
FootFrameLowering FrameLowering;
|
||||
FootInstrInfo InstrInfo;
|
||||
FootRegisterInfo RegisterInfo;
|
||||
FootTargetLowering TLInfo;
|
||||
SelectionDAGTargetInfo SDTgtInfo;
|
||||
|
||||
public:
|
||||
FootSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
const TargetMachine &TM);
|
||||
const TargetMachine &TM);
|
||||
|
||||
const FootInstrInfo *getInstrInfo() const override {
|
||||
return &InstrInfo;
|
||||
}
|
||||
|
||||
const FootFrameLowering *getFrameLowering() const override {
|
||||
return &FrameLowering;
|
||||
}
|
||||
|
||||
const FootRegisterInfo *getRegisterInfo() const override {
|
||||
return &RegisterInfo;
|
||||
}
|
||||
|
||||
const FootTargetLowering *getTargetLowering() const override {
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
|
||||
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
|
||||
return &SDTgtInfo;
|
||||
}
|
||||
|
||||
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#include "Foot.h"
|
||||
#include "FootTargetMachine.h"
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
#include "FootTargetObjectFile.h"
|
||||
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -15,12 +17,12 @@ static const char* FootDataLayoutStr =
|
||||
using namespace llvm;
|
||||
|
||||
FootTargetMachine::FootTargetMachine(const Target &T, const Triple &TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options,
|
||||
std::optional<Reloc::Model> RM,
|
||||
std::optional<CodeModel::Model> CM,
|
||||
CodeGenOptLevel OL,
|
||||
bool JIT)
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options,
|
||||
std::optional<Reloc::Model> RM,
|
||||
std::optional<CodeModel::Model> CM,
|
||||
CodeGenOptLevel OL,
|
||||
bool JIT)
|
||||
: CodeGenTargetMachineImpl(T, FootDataLayoutStr, TT, CPU, FS, Options, RM ? *RM : Reloc::Static, CM ? *CM : CodeModel::Small, OL) {
|
||||
initAsmInfo();
|
||||
}
|
||||
@ -40,12 +42,13 @@ TargetLoweringObjectFile *FootTargetMachine::getObjFileLowering() const {
|
||||
FootPassConfig::FootPassConfig(TargetMachine &TM, PassManagerBase &PM) :
|
||||
TargetPassConfig(TM, PM) {}
|
||||
|
||||
void FootPassConfig::addIRPasses() {
|
||||
TargetPassConfig::addIRPasses();
|
||||
bool FootPassConfig::addInstSelector() {
|
||||
addPass(createFootISelDAG(getFootTargetMachine()));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FootPassConfig::addInstSelector() {
|
||||
return false;
|
||||
void FootPassConfig::addIRPasses() {
|
||||
TargetPassConfig::addIRPasses();
|
||||
}
|
||||
|
||||
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootTarget()
|
||||
|
||||
@ -25,8 +25,12 @@ class FootPassConfig : public TargetPassConfig {
|
||||
public:
|
||||
FootPassConfig(TargetMachine &TM, PassManagerBase &PM);
|
||||
|
||||
void addIRPasses() override;
|
||||
FootTargetMachine &getFootTargetMachine() const {
|
||||
return getTM<FootTargetMachine>();
|
||||
}
|
||||
|
||||
bool addInstSelector() override;
|
||||
void addIRPasses() override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -58,7 +58,7 @@ void FootMCCodeEmitter::encodeInstruction(const MCInst &MI,
|
||||
uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||
assert(((Encoding & 0xffffffff00000000) == 0) &&
|
||||
"Only the first 32 bits should be set");
|
||||
support::endian::write<uint32_t>(CB, Encoding, llvm::endianness::little);
|
||||
support::endian::write<uint32_t>(CB, Encoding, llvm::endianness::little);
|
||||
}
|
||||
|
||||
#include "FootGenAsmEmitter.inc"
|
||||
|
||||
@ -59,5 +59,6 @@ extern "C" LLVM_C_ABI void LLVMInitializeFootTargetMC() {
|
||||
TargetRegistry::RegisterMCInstrInfo(TheTarget, createFootInstrInfo);
|
||||
TargetRegistry::RegisterMCRegInfo(TheTarget, createFootRegisterInfo);
|
||||
TargetRegistry::RegisterMCInstPrinter(TheTarget, createFootMCInstPrinter);
|
||||
TargetRegistry::RegisterMCCodeEmitter(TheTarget, createFootMCCodeEmitter);
|
||||
RegisterMCAsmInfoFn X(TheTarget, createFootMCAsmInfo);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
|
||||
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
@ -14,12 +15,12 @@ MCCodeEmitter *createFootMCCodeEmitter(const MCInstrInfo &MII,
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "FootGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "FootGenRegisterInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "FootGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#define GET_INSTRINFO_MC_HELPER_DECLS
|
||||
#include "FootGenInstrInfo.inc"
|
||||
|
||||
@ -1 +1,6 @@
|
||||
CNST r0, 8
|
||||
// RUN: llvm-mc -triple=foot %s -o - | FileCheck %s
|
||||
// RUN: llvm-mc -triple=foot %s -o - --show-encoding | FileCheck --check-prefix=ENCODING %s
|
||||
//
|
||||
// CHECK: CNST.d r0, #8
|
||||
// ENCODING: [0x08,0x00,0x20,0x00]
|
||||
CNST.d r0, 8
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user