Compare commits

...

2 Commits

Author SHA1 Message Date
ecee5141a5 Begin backend implementation 2025-09-23 09:54:35 -04:00
644ff9745e Add foot target skeleton 2025-08-25 11:25:44 -04:00
41 changed files with 1202 additions and 0 deletions

View File

@ -103,6 +103,7 @@ add_clang_library(clangBasic
Targets/BPF.cpp Targets/BPF.cpp
Targets/CSKY.cpp Targets/CSKY.cpp
Targets/DirectX.cpp Targets/DirectX.cpp
Targets/Foot.cpp
Targets/Hexagon.cpp Targets/Hexagon.cpp
Targets/Lanai.cpp Targets/Lanai.cpp
Targets/LoongArch.cpp Targets/LoongArch.cpp

View File

@ -21,6 +21,7 @@
#include "Targets/BPF.h" #include "Targets/BPF.h"
#include "Targets/CSKY.h" #include "Targets/CSKY.h"
#include "Targets/DirectX.h" #include "Targets/DirectX.h"
#include "Targets/Foot.h"
#include "Targets/Hexagon.h" #include "Targets/Hexagon.h"
#include "Targets/Lanai.h" #include "Targets/Lanai.h"
#include "Targets/LoongArch.h" #include "Targets/LoongArch.h"
@ -122,6 +123,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::xcore: case llvm::Triple::xcore:
return std::make_unique<XCoreTargetInfo>(Triple, Opts); return std::make_unique<XCoreTargetInfo>(Triple, Opts);
case llvm::Triple::foot:
return std::make_unique<FootTargetInfo>(Triple, Opts);
case llvm::Triple::hexagon: case llvm::Triple::hexagon:
if (os == llvm::Triple::Linux && if (os == llvm::Triple::Linux &&
Triple.getEnvironment() == llvm::Triple::Musl) Triple.getEnvironment() == llvm::Triple::Musl)

View File

@ -0,0 +1,57 @@
#include "Foot.h"
#include "clang/Basic/MacroBuilder.h"
static const char* FootDataLayoutStr =
"e-"
"p:16:32-"
"n8:16:32-"
"i64:64:64-i32:32:32-i16:16:32-"
"f32:32:32-"
"v32:32:32";
namespace clang {
namespace targets {
FootTargetInfo::FootTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
resetDataLayout(FootDataLayoutStr);
}
void FootTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const
{
Builder.defineMacro("__foot__");
}
SmallVector<Builtin::InfosShard> FootTargetInfo::getTargetBuiltins() const
{
return {};
}
TargetInfo::BuiltinVaListKind FootTargetInfo::getBuiltinVaListKind() const
{
return BuiltinVaListKind::VoidPtrBuiltinVaList;
}
bool FootTargetInfo::validateAsmConstraint(const char *&Name, ConstraintInfo &info) const
{
return true;
}
std::string_view FootTargetInfo::getClobbers() const
{
return "";
}
ArrayRef<const char *> FootTargetInfo::getGCCRegNames() const
{
return {};
}
ArrayRef<TargetInfo::GCCRegAlias> FootTargetInfo::getGCCRegAliases() const
{
return {};
}
} // namespace targets
} // namespace clang

View File

@ -0,0 +1,27 @@
#ifndef CLANG_LIB_BASIC_TARGETS_FOOT_FOOT_H
#define CLANG_LIB_BASIC_TARGETS_FOOT_FOOT_H
#include "clang/Basic/TargetInfo.h"
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY FootTargetInfo : public TargetInfo
{
public:
FootTargetInfo(const llvm::Triple &Triple, const TargetOptions &);
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override;
SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
BuiltinVaListKind getBuiltinVaListKind() const override;
bool validateAsmConstraint(const char *&Name, ConstraintInfo &info) const override;
std::string_view getClobbers() const override;
protected:
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<GCCRegAlias> getGCCRegAliases() const override;
};
} // namespace targets
} // namespace clang
#endif // CLANG_LIB_BASIC_TARGETS_FOOT_FOOT_H

View File

@ -533,6 +533,7 @@ set(LLVM_ALL_TARGETS
ARM ARM
AVR AVR
BPF BPF
Foot
Hexagon Hexagon
Lanai Lanai
LoongArch LoongArch

View File

@ -60,6 +60,7 @@ public:
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
csky, // CSKY: csky csky, // CSKY: csky
dxil, // DXIL 32-bit DirectX bytecode dxil, // DXIL 32-bit DirectX bytecode
foot, // foot: foot
hexagon, // Hexagon: hexagon hexagon, // Hexagon: hexagon
loongarch32, // LoongArch (32-bit): loongarch32 loongarch32, // LoongArch (32-bit): loongarch32
loongarch64, // LoongArch (64-bit): loongarch64 loongarch64, // LoongArch (64-bit): loongarch64

View File

@ -0,0 +1,16 @@
add_llvm_component_library(LLVMFootAsmParser
FootAsmParser.cpp
LINK_COMPONENTS
FootDesc
FootInfo
CodeGenTypes
MC
MCParser
Support
TargetParser
ADD_TO_COMPONENT
Foot
)

View File

@ -0,0 +1,333 @@
#include "MCTargetDesc/FootInstPrinter.h"
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "TargetInfo/FootTargetInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Casting.h"
using namespace llvm;
namespace {
class FootAsmParser : public MCTargetAsmParser {
private:
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override;
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) override;
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) override;
bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands, MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) override;
#define GET_ASSEMBLER_HEADER
#include "FootGenAsmMatcher.inc"
ParseStatus parseImmediate(OperandVector &Operands);
ParseStatus parseRegister(OperandVector &Operands);
public:
FootAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
const MCInstrInfo &MII, const MCTargetOptions &Options)
: MCTargetAsmParser(Options, STI, MII) {
MCAsmParserExtension::Initialize(Parser);
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
}
};
class FootOperand : public MCParsedAsmOperand {
private:
SMLoc StartLoc, EndLoc;
enum KindTy {
k_Immediate,
k_Register,
k_Token
} Kind;
struct TokOp {
const char *Data;
unsigned Length;
};
struct RegOp {
unsigned RegNum;
int ElementWidth;
};
struct ImmOp {
const MCExpr *Val;
};
union {
struct TokOp Tok;
struct RegOp Reg;
struct ImmOp Imm;
};
public:
FootOperand(KindTy K) : Kind(K) {}
FootOperand(const FootOperand &o) : MCParsedAsmOperand() {
StartLoc = o.StartLoc;
EndLoc = o.EndLoc;
Kind = o.Kind;
switch (Kind) {
case k_Token:
Tok = o.Tok;
break;
case k_Immediate:
Imm = o.Imm;
break;
case k_Register:
Reg = o.Reg;
break;
}
}
void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;
static std::unique_ptr<FootOperand> createToken(StringRef Str, SMLoc S) {
auto Op = std::make_unique<FootOperand>(k_Token);
Op->StartLoc = S;
Op->EndLoc = S;
Op->Tok.Data = Str.data();
Op->Tok.Length = Str.size();
return Op;
}
static std::unique_ptr<FootOperand> createReg(unsigned RegNo, SMLoc S,
SMLoc E) {
auto Op = std::make_unique<FootOperand>(k_Register);
Op->Reg.RegNum = RegNo;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static std::unique_ptr<FootOperand> createImm(const MCExpr *Val, SMLoc S,
SMLoc E) {
auto Op = std::make_unique<FootOperand>(k_Immediate);
Op->Imm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
Inst.addOperand(MCOperand::createImm(CE->getValue()));
}
else {
Inst.addOperand(MCOperand::createExpr(Expr));
}
}
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getReg()));
}
void addImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getImm());
}
StringRef getToken() const {
assert(Kind == k_Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
}
SMLoc getStartLoc() const override { return StartLoc; }
SMLoc getEndLoc() const override { return EndLoc; }
bool isToken() const override { return Kind == k_Token; }
bool isImm() const override { return Kind == k_Immediate; }
bool isMem() const override { return false; }
bool isReg() const override { return Kind == k_Register; }
MCRegister getReg() const override {
assert(Kind == k_Register && "Invalid access!");
return Reg.RegNum;
}
const MCExpr *getImm() const {
assert(Kind == k_Immediate && "Invalid access!");
return Imm.Val;
}
};
} // namespace
#define GET_REGISTER_MATCHER
#include "FootGenAsmMatcher.inc"
void FootOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
switch (Kind) {
case k_Immediate:
MAI.printExpr(OS, *getImm());
break;
case k_Token:
OS << "'" << getToken() << "'";
break;
case k_Register:
OS << "<register " << getReg() << ">";
break;
}
}
ParseStatus FootAsmParser::parseImmediate(OperandVector &Operands) {
switch (getLexer().getKind()) {
default:
return ParseStatus::NoMatch;
case llvm::AsmToken::LParen:
case llvm::AsmToken::Minus:
case llvm::AsmToken::Plus:
case llvm::AsmToken::Integer:
case llvm::AsmToken::String:
case llvm::AsmToken::Identifier:
break;
}
const MCExpr *IdVal;
SMLoc S = getLoc();
if (getParser().parseExpression(IdVal)) {
return ParseStatus::Failure;
}
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
Operands.push_back(FootOperand::createImm(IdVal, S, E));
return ParseStatus::Success;
}
ParseStatus FootAsmParser::parseRegister(OperandVector &Operands) {
SMLoc S = getLoc();
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
switch (getLexer().getKind()) {
default:
return ParseStatus::NoMatch;
case llvm::AsmToken::Identifier:
StringRef Name = getLexer().getTok().getIdentifier();
unsigned RegNo = MatchRegisterName(Name);
if (RegNo == 0) {
return ParseStatus::NoMatch;
}
getLexer().Lex();
Operands.push_back(FootOperand::createReg(RegNo, S, E));
}
return ParseStatus::Success;
}
bool FootAsmParser::parseInstruction(ParseInstructionInfo &Info,
StringRef Name, SMLoc NameLoc,
OperandVector &Operands) {
Operands.push_back(FootOperand::createToken(Name, NameLoc));
while (!getLexer().is(AsmToken::EndOfStatement)) {
// try to parse register first
if (parseRegister(Operands).isSuccess()) {
continue;
}
// skip commas
if (getLexer().is(AsmToken::Comma)) {
getLexer().Lex();
continue;
}
if (parseImmediate(Operands).isSuccess()) {
continue;
}
SMLoc Loc = getLexer().getLoc();
return Error(Loc, "unexpected token");
}
// no errors
getParser().Lex();
return false;
}
bool FootAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) {
if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess()) {
return Error(StartLoc, "invalid register name");
}
return false;
}
ParseStatus FootAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) {
const AsmToken &Tok = getParser().getTok();
StartLoc = Tok.getLoc();
EndLoc = Tok.getEndLoc();
Reg = Foot::NoRegister;
StringRef Name = getLexer().getTok().getIdentifier();
if (!MatchRegisterName(Name)) {
// skip unknown identifier
getParser().Lex();
return ParseStatus::Success;
}
return ParseStatus::NoMatch;
}
bool FootAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
MCInst Inst;
SMLoc ErrorLoc;
FeatureBitset MissingFeatures;
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm)) {
default:
break;
case Match_Success:
Inst.setLoc(IDLoc);
Out.emitInstruction(Inst, getSTI());
return false;
case Match_MissingFeature:
return Error(IDLoc, "instruction use requires an option to be enabled");
case Match_MnemonicFail:
return Error(IDLoc, "unrecognized instruction mnemonic");
case Match_InvalidOperand:
ErrorLoc = IDLoc;
if (ErrorInfo != ~0u) {
if (ErrorInfo >= Operands.size()) {
return Error(ErrorLoc, "too few operands for instruction");
}
ErrorLoc = ((FootOperand&)*Operands[ErrorInfo]).getStartLoc();
if (ErrorLoc == SMLoc()) {
ErrorLoc = IDLoc;
}
}
return Error(ErrorLoc, "invalid operand for instruction");
}
llvm_unreachable("unknown match type detected");
}
extern "C" LLVM_C_ABI void LLVMInitializeFootAsmParser() {
RegisterMCAsmParser<FootAsmParser> Z(getTheFootTarget());
}
#define GET_MATCHER_IMPLEMENTATION
#include "FootGenAsmMatcher.inc"

View File

@ -0,0 +1,44 @@
add_llvm_component_group(Foot)
set(LLVM_TARGET_DEFINITIONS Foot.td)
tablegen(LLVM FootGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM FootGenRegisterInfo.inc -gen-register-info)
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)
add_public_tablegen_target(FootCommonTableGen)
add_llvm_target(FootCodeGen
FootFrameLowering.cpp
FootInstrInfo.cpp
FootISelLowering.cpp
FootSubtarget.cpp
FootTargetMachine.cpp
FootTargetObjectFile.cpp
FootRegisterInfo.cpp
LINK_COMPONENTS
FootDesc
FootInfo
Analysis
CodeGen
Core
MC
Passes
SelectionDAG
Support
Target
TargetParser
TransformUtils
ADD_TO_COMPONENT
Foot
)
add_subdirectory(AsmParser)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)

View File

@ -0,0 +1,12 @@
include "llvm/Target/Target.td"
include "FootRegisterInfo.td"
include "FootInstrInfo.td"
def : ProcessorModel<"generic", NoSchedModel, /*Features=*/[]>;
def FootInstrInfo : InstrInfo;
def Foot : Target {
let InstructionSet = FootInstrInfo;
}

View File

@ -0,0 +1,13 @@
#include "FootFrameLowering.h"
using namespace llvm;
bool FootFrameLowering::hasFPImpl(const MachineFunction& MF) const {
return false;
}
void FootFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}
void FootFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}

View File

@ -0,0 +1,24 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTFRAMELOWERING_H
#define LLVM_LIB_TARGET_FOOT_FOOTFRAMELOWERING_H
#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
class FootSubtarget;
class FootFrameLowering : public TargetFrameLowering {
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
public:
FootFrameLowering(const FootSubtarget &Sti)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8), 0) {}
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTFRAMELOWERING_H

View File

@ -0,0 +1,18 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H
#define LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H
#include "llvm/CodeGen/TargetLowering.h"
namespace llvm {
class FootSubtarget;
class FootTargetMachine;
class FootTargetLowering : public TargetLowering {
public:
explicit FootTargetLowering(const TargetMachine &TM);
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H

View File

@ -0,0 +1,23 @@
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;
bits<32> Inst;
bits<3> Condition;
bits<1> Repeat;
bits<1> Vect1;
bits<2> DstAddrMode;
bits<5> dst;
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;
}

View File

@ -0,0 +1,8 @@
#include "FootInstrInfo.h"
#define GET_INSTRINFO_CTOR_DTOR
#include "FootGenInstrInfo.inc"
using namespace llvm;
FootInstrInfo::FootInstrInfo() : FootGenInstrInfo() {}

View File

@ -0,0 +1,19 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTINSTRINFO_H
#define LLVM_LIB_TARGET_FOOT_FOOTINSTRINFO_H
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "FootGenInstrInfo.inc"
namespace llvm {
class FootInstrInfo : public FootGenInstrInfo {
public:
FootInstrInfo();
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTINSTRINFO_H

View File

@ -0,0 +1,11 @@
include "FootInstrFormats.td"
def CNST : FootInstruction<"CNST", "$dst, $imm", 0b0000, (outs GP32:$dst), (ins i16imm:$imm)> {
bits<16> imm;
let Inst{15-0} = imm;
let Condition = 0b000;
let Repeat = 0b0;
let Vect1 = 0b0;
let DstAddrMode = 0b01;
}

View File

@ -0,0 +1,34 @@
#include "FootRegisterInfo.h"
#include "FootFrameLowering.h"
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#define GET_REGINFO_TARGET_DESC
#include "FootGenRegisterInfo.inc"
using namespace llvm;
FootRegisterInfo::FootRegisterInfo() : FootGenRegisterInfo(Foot::RRA) {}
const MCPhysReg *FootRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return nullptr;
}
BitVector FootRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved{ getNumRegs() };
return Reserved;
}
bool FootRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
return false;
}
Register FootRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return Register();
}

View File

@ -0,0 +1,27 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
#define LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
#include "llvm/CodeGen/TargetRegisterInfo.h"
#define GET_REGINFO_HEADER
#include "FootGenRegisterInfo.inc"
namespace llvm {
struct FootRegisterInfo : public FootGenRegisterInfo {
FootRegisterInfo();
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
unsigned FIOperandNum,
RegScavenger *RS = nullptr) const override;
Register getFrameRegister(const MachineFunction &MF) const override;
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H

View File

@ -0,0 +1,45 @@
let Namespace = "Foot" in {
class FootRegister<bits<16> enc, string name>
: Register<name> {
let HWEncoding = enc;
let SubRegs = [];
let CoveredBySubRegs = false;
}
def R0 : FootRegister<0, "r0">;
def R1 : FootRegister<1, "r1">;
def R2 : FootRegister<2, "r2">;
def R3 : FootRegister<3, "r3">;
def R4 : FootRegister<4, "r4">;
def R5 : FootRegister<5, "r5">;
def R6 : FootRegister<6, "r6">;
def R7 : FootRegister<7, "r7">;
def R8 : FootRegister<8, "r8">;
def R9 : FootRegister<9, "r9">;
def R10 : FootRegister<10, "r10">;
def R11 : FootRegister<11, "r11">;
def R12 : FootRegister<12, "r12">;
def R13 : FootRegister<13, "r13">;
def R14 : FootRegister<14, "r14">;
def R15 : FootRegister<15, "r15">;
def R16 : FootRegister<16, "r16">;
def R17 : FootRegister<17, "r17">;
def R18 : FootRegister<18, "r18">;
def R19 : FootRegister<19, "r19">;
def R20 : FootRegister<20, "r20">;
def R21 : FootRegister<21, "r21">;
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 R28 : FootRegister<28, "r28">;
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)>;
}

View File

@ -0,0 +1,18 @@
#include "FootSubtarget.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
#define DEBUG_TYPE "foot-subtarget"
#define GET_SUBTARGET_TARGET_DESC
#define GET_SUBTARGET_CTOR
#include "FootGenSubtargetInfo.inc"
void FootSubtarget::anchor() {}
FootSubtarget::FootSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
const TargetMachine &TM)
: FootGenSubtargetInfo(TT, CPU, "", FS), TLInfo(TM) {}

View File

@ -0,0 +1,34 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H
#define LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H
#include "FootISelLowering.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#define GET_SUBTARGETINFO_HEADER
#include "FootGenSubtargetInfo.inc"
namespace llvm {
class TargetMachine;
class Triple;
class FootSubtarget : public FootGenSubtargetInfo {
virtual void anchor();
FootTargetLowering TLInfo;
public:
FootSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
const TargetMachine &TM);
const FootTargetLowering *getTargetLowering() const override {
return &TLInfo;
}
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H

View File

@ -0,0 +1,54 @@
#include "FootTargetMachine.h"
#include "TargetInfo/FootTargetInfo.h"
#include "FootTargetObjectFile.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
static const char* FootDataLayoutStr =
"e-"
"p:16:32-"
"n8:16:32-"
"i64:64:64-i32:32:32-i16:16:32-"
"f32:32:32-"
"v32:32:32";
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)
: CodeGenTargetMachineImpl(T, FootDataLayoutStr, TT, CPU, FS, Options, RM ? *RM : Reloc::Static, CM ? *CM : CodeModel::Small, OL) {
initAsmInfo();
}
FootTargetMachine::~FootTargetMachine() = default;
TargetPassConfig *FootTargetMachine::createPassConfig(PassManagerBase &PM) {
return new FootPassConfig(*this, PM);
}
TargetLoweringObjectFile *FootTargetMachine::getObjFileLowering() const {
static FootTargetObjectFileELF TLOF;
return &TLOF;
}
FootPassConfig::FootPassConfig(TargetMachine &TM, PassManagerBase &PM) :
TargetPassConfig(TM, PM) {}
void FootPassConfig::addIRPasses() {
TargetPassConfig::addIRPasses();
}
bool FootPassConfig::addInstSelector() {
return false;
}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootTarget()
{
RegisterTargetMachine<FootTargetMachine> X(getTheFootTarget());
}

View File

@ -0,0 +1,34 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
#define LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
namespace llvm {
class FootTargetMachine : public CodeGenTargetMachineImpl {
public:
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);
~FootTargetMachine() override;
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
TargetLoweringObjectFile *getObjFileLowering() const override;
};
class FootPassConfig : public TargetPassConfig {
public:
FootPassConfig(TargetMachine &TM, PassManagerBase &PM);
void addIRPasses() override;
bool addInstSelector() override;
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H

View File

@ -0,0 +1,5 @@
#include "FootTargetObjectFile.h"
using namespace llvm;
FootTargetObjectFileELF::FootTargetObjectFileELF() {}

View File

@ -0,0 +1,15 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTTARGETOBJECTFILE_H
#define LLVM_LIB_TARGET_FOOT_FOOTTARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
class FootTargetObjectFileELF : public TargetLoweringObjectFileELF {
public:
FootTargetObjectFileELF();
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTTARGETOBJECTFILE_H

View File

@ -0,0 +1,12 @@
add_llvm_component_library(LLVMFootDesc
FootMCTargetDesc.cpp
FootAsmInfo.cpp
FootMCCodeEmitter.cpp
FootInstPrinter.cpp
LINK_COMPONENTS
Support
ADD_TO_COMPONENT
Foot
)

View File

@ -0,0 +1,6 @@
#include "FootAsmInfo.h"
using namespace llvm;
FootMCAsmInfoELF::FootMCAsmInfoELF() :
MCAsmInfoELF() {}

View File

@ -0,0 +1,15 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTASMINFO_H
#define LLVM_LIB_TARGET_FOOT_FOOTASMINFO_H
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
class FootMCAsmInfoELF : public MCAsmInfoELF {
public:
explicit FootMCAsmInfoELF();
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTASMINFO_H

View File

@ -0,0 +1,55 @@
#include "FootInstPrinter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
#define GET_INSTRUCTION_NAME
#define PRINT_ALIAS_INSTR
#include "FootGenAsmWriter.inc"
FootInstPrinter::FootInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
void FootInstPrinter::printInst(const MCInst *MI, uint64_t Address,
StringRef Annot, const MCSubtargetInfo &STI,
raw_ostream &O) {
if (!PrintAliases || !printAliasInstr(MI, Address, O)) {
printInstruction(MI, Address, O);
}
printAnnotation(O, Annot);
}
void FootInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
unsigned Reg = Op.getReg();
printRegName(O, Reg);
}
else if (Op.isImm()) {
printImm(MI, OpNo, O);
}
else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
MAI.printExpr(O, *Op.getExpr());
}
}
void FootInstPrinter::printImm(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
markup(O, Markup::Immediate) << "#" << formatImm(Op.getImm());
}
void FootInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {
markup(O, Markup::Register) << getRegisterName(Reg);
}

View File

@ -0,0 +1,32 @@
#ifndef LLVM_LIB_TARGET_FOOT_FOOTINSTPRINTER_H
#define LLVM_LIB_TARGET_FOOT_FOOTINSTPRINTER_H
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInstPrinter.h"
namespace llvm {
class FootInstPrinter : public MCInstPrinter {
private:
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printRegName(raw_ostream &OS, MCRegister Reg) override;
public:
FootInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI);
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &O) override;
std::pair<const char *, uint64_t> getMnemonic(const MCInst &MI) const override;
virtual void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(MCRegister Reg);
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_FOOTINSTPRINTER_H

View File

@ -0,0 +1,64 @@
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/EndianStream.h"
#include <cstdint>
using namespace llvm;
#define DEBUG_TYPE "mccodeemitter"
namespace {
class FootMCCodeEmitter : public MCCodeEmitter {
MCContext &MCCtxt;
public:
FootMCCodeEmitter(MCContext &MCCtxt) : MCCodeEmitter(), MCCtxt(MCCtxt) {}
~FootMCCodeEmitter() override = default;
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
};
} // namespace
MCCodeEmitter *llvm::createFootMCCodeEmitter(const MCInstrInfo &MCII,
MCContext &MCCtxt) {
return new FootMCCodeEmitter(MCCtxt);
}
unsigned FootMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
if (MO.isReg()) {
return MCCtxt.getRegisterInfo()->getEncodingValue(MO.getReg());
}
assert(MO.isImm() && "Unsupported operand type");
return static_cast<unsigned>(MO.getImm());
}
void FootMCCodeEmitter::encodeInstruction(const MCInst &MI,
SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
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);
}
#include "FootGenAsmEmitter.inc"

View File

@ -0,0 +1,63 @@
#include "FootMCTargetDesc.h"
#include "FootAsmInfo.h"
#include "FootInstPrinter.h"
#include "TargetInfo/FootTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
#define GET_SUBTARGETINFO_MC_DESC
#include "FootGenSubtargetInfo.inc"
#define GET_REGINFO_MC_DESC
#include "FootGenRegisterInfo.inc"
#define GET_INSTRINFO_MC_DESC
#include "FootGenInstrInfo.inc"
using namespace llvm;
static MCSubtargetInfo *createFootSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
return createFootMCSubtargetInfoImpl(TT, CPU, CPU, FS);
}
static MCInstrInfo *createFootInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitFootMCInstrInfo(X);
return X;
}
static MCRegisterInfo *createFootRegisterInfo(const Triple &Triple) {
MCRegisterInfo *X = new MCRegisterInfo();
InitFootMCRegisterInfo(X, Foot::RRA);
return X;
}
static MCAsmInfo *createFootMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TheTriple,
const MCTargetOptions &Options) {
return new FootMCAsmInfoELF();
}
static MCInstPrinter *createFootMCInstPrinter(const Triple &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
if (SyntaxVariant == 0) {
return new FootInstPrinter(MAI, MII, MRI);
}
return nullptr;
}
extern "C" LLVM_C_ABI void LLVMInitializeFootTargetMC() {
Target &TheTarget = getTheFootTarget();
TargetRegistry::RegisterMCSubtargetInfo(TheTarget, createFootSubtargetInfo);
TargetRegistry::RegisterMCInstrInfo(TheTarget, createFootInstrInfo);
TargetRegistry::RegisterMCRegInfo(TheTarget, createFootRegisterInfo);
TargetRegistry::RegisterMCInstPrinter(TheTarget, createFootMCInstPrinter);
RegisterMCAsmInfoFn X(TheTarget, createFootMCAsmInfo);
}

View File

@ -0,0 +1,27 @@
#ifndef LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
#define LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
#include "llvm/MC/MCInstrInfo.h"
#include <cstdint>
namespace llvm {
class MCContext;
class MCCodeEmitter;
MCCodeEmitter *createFootMCCodeEmitter(const MCInstrInfo &MII,
MCContext &MCCtxt);
} // namespace llvm
#define GET_SUBTARGETINFO_ENUM
#include "FootGenSubtargetInfo.inc"
#define GET_REGINFO_ENUM
#include "FootGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "FootGenInstrInfo.inc"
#endif // LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H

View File

@ -0,0 +1,10 @@
add_llvm_component_library(LLVMFootInfo
FootTargetInfo.cpp
LINK_COMPONENTS
Support
MC
ADD_TO_COMPONENT
Foot
)

View File

@ -0,0 +1,16 @@
#include "FootTargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootTargetInfo() {
RegisterTarget<Triple::foot, /*HasJIT=*/ false> X(
getTheFootTarget(), /*Name=*/"foot",
/*Desc=*/"Foot target",
/*BackendName=*/"Foot"
);
}
Target &llvm::getTheFootTarget() {
static Target TheFootTarget;
return TheFootTarget;
}

View File

@ -0,0 +1,12 @@
#ifndef LLVM_LIB_TARGET_FOOT_TARGETINFO_FOOTTARGETINFO_H
#define LLVM_LIB_TARGET_FOOT_TARGETINFO_FOOTTARGETINFO_H
namespace llvm {
class Target;
Target &getTheFootTarget();
} // namespace llvm
#endif // LLVM_LIB_TARGET_FOOT_TARGETINFO_FOOTTARGETINFO_H

View File

@ -39,6 +39,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case bpfel: return "bpfel"; case bpfel: return "bpfel";
case csky: return "csky"; case csky: return "csky";
case dxil: return "dxil"; case dxil: return "dxil";
case foot: return "foot";
case hexagon: return "hexagon"; case hexagon: return "hexagon";
case hsail64: return "hsail64"; case hsail64: return "hsail64";
case hsail: return "hsail"; case hsail: return "hsail";
@ -198,6 +199,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case mips64: case mips64:
case mips64el: return "mips"; case mips64el: return "mips";
case foot: return "foot";
case hexagon: return "hexagon"; case hexagon: return "hexagon";
case amdgcn: return "amdgcn"; case amdgcn: return "amdgcn";
@ -464,6 +467,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("riscv64", riscv64) .Case("riscv64", riscv64)
.Case("riscv32be", riscv32be) .Case("riscv32be", riscv32be)
.Case("riscv64be", riscv64be) .Case("riscv64be", riscv64be)
.Case("foot", foot)
.Case("hexagon", hexagon) .Case("hexagon", hexagon)
.Case("sparc", sparc) .Case("sparc", sparc)
.Case("sparcel", sparcel) .Case("sparcel", sparcel)
@ -611,6 +615,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("riscv64", Triple::riscv64) .Case("riscv64", Triple::riscv64)
.Case("riscv32be", Triple::riscv32be) .Case("riscv32be", Triple::riscv32be)
.Case("riscv64be", Triple::riscv64be) .Case("riscv64be", Triple::riscv64be)
.Case("foot", Triple::foot)
.Case("hexagon", Triple::hexagon) .Case("hexagon", Triple::hexagon)
.Cases("s390x", "systemz", Triple::systemz) .Cases("s390x", "systemz", Triple::systemz)
.Case("sparc", Triple::sparc) .Case("sparc", Triple::sparc)
@ -940,6 +945,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::aarch64: case Triple::aarch64:
case Triple::aarch64_32: case Triple::aarch64_32:
case Triple::arm: case Triple::arm:
case Triple::foot:
case Triple::thumb: case Triple::thumb:
case Triple::x86: case Triple::x86:
case Triple::x86_64: case Triple::x86_64:
@ -1681,6 +1687,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
return 0; return 0;
case llvm::Triple::avr: case llvm::Triple::avr:
case llvm::Triple::foot:
case llvm::Triple::msp430: case llvm::Triple::msp430:
return 16; return 16;
@ -1801,6 +1808,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::armeb: case Triple::armeb:
case Triple::csky: case Triple::csky:
case Triple::dxil: case Triple::dxil:
case Triple::foot:
case Triple::hexagon: case Triple::hexagon:
case Triple::hsail: case Triple::hsail:
case Triple::kalimba: case Triple::kalimba:
@ -1871,6 +1879,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::avr: case Triple::avr:
case Triple::csky: case Triple::csky:
case Triple::dxil: case Triple::dxil:
case Triple::foot:
case Triple::hexagon: case Triple::hexagon:
case Triple::kalimba: case Triple::kalimba:
case Triple::lanai: case Triple::lanai:
@ -1958,6 +1967,7 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::amdil: case Triple::amdil:
case Triple::avr: case Triple::avr:
case Triple::dxil: case Triple::dxil:
case Triple::foot:
case Triple::hexagon: case Triple::hexagon:
case Triple::hsail64: case Triple::hsail64:
case Triple::hsail: case Triple::hsail:
@ -2071,6 +2081,7 @@ bool Triple::isLittleEndian() const {
case Triple::bpfel: case Triple::bpfel:
case Triple::csky: case Triple::csky:
case Triple::dxil: case Triple::dxil:
case Triple::foot:
case Triple::hexagon: case Triple::hexagon:
case Triple::hsail64: case Triple::hsail64:
case Triple::hsail: case Triple::hsail:

1
llvm/test/MC/Foot/CNST.s Normal file
View File

@ -0,0 +1 @@
CNST r0, 8