Finish chapter 15

This commit is contained in:
shylie 2025-10-16 12:26:11 -04:00
parent ecee5141a5
commit ddf3a97f70
24 changed files with 958 additions and 56 deletions

View File

@ -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

View 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

View File

@ -1,6 +1,7 @@
include "llvm/Target/Target.td"
include "FootRegisterInfo.td"
include "FootCallingConvention.td"
include "FootInstrInfo.td"
def : ProcessorModel<"generic", NoSchedModel, /*Features=*/[]>;

View 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());
}

View File

@ -0,0 +1,6 @@
#include "FootCallingConvention.h"
#include "MCTargetDesc/FootMCTargetDesc.h"
using namespace llvm;
#include "FootGenCallingConv.inc"

View 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

View 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)>;

View 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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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>;
}

View File

@ -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]>;

View File

@ -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;
};

View File

@ -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)>;
}

View File

@ -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) {}

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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"

View File

@ -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);
}

View File

@ -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"

View File

@ -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