Compare commits
18 Commits
main
...
foot-backe
| Author | SHA1 | Date | |
|---|---|---|---|
| bbea044c7d | |||
| 5aceff62cb | |||
| b62191afce | |||
| 10d1aa1358 | |||
| 4d1125e9f7 | |||
| 3ebb39e016 | |||
| 56524948c5 | |||
| 6e5ef10cc0 | |||
| 1927db30f9 | |||
| 429540e1c6 | |||
| 85073c9006 | |||
| 12cdefd2b9 | |||
| 77be592768 | |||
| a8b079fdd0 | |||
| d2159076c8 | |||
| ddf3a97f70 | |||
| ecee5141a5 | |||
| 644ff9745e |
@ -103,6 +103,7 @@ add_clang_library(clangBasic
|
||||
Targets/BPF.cpp
|
||||
Targets/CSKY.cpp
|
||||
Targets/DirectX.cpp
|
||||
Targets/Foot.cpp
|
||||
Targets/Hexagon.cpp
|
||||
Targets/Lanai.cpp
|
||||
Targets/LoongArch.cpp
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "Targets/BPF.h"
|
||||
#include "Targets/CSKY.h"
|
||||
#include "Targets/DirectX.h"
|
||||
#include "Targets/Foot.h"
|
||||
#include "Targets/Hexagon.h"
|
||||
#include "Targets/Lanai.h"
|
||||
#include "Targets/LoongArch.h"
|
||||
@ -122,6 +123,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
|
||||
case llvm::Triple::xcore:
|
||||
return std::make_unique<XCoreTargetInfo>(Triple, Opts);
|
||||
|
||||
case llvm::Triple::foot:
|
||||
return std::make_unique<FootTargetInfo>(Triple, Opts);
|
||||
|
||||
case llvm::Triple::hexagon:
|
||||
if (os == llvm::Triple::Linux &&
|
||||
Triple.getEnvironment() == llvm::Triple::Musl)
|
||||
|
||||
57
clang/lib/Basic/Targets/Foot.cpp
Normal file
57
clang/lib/Basic/Targets/Foot.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "Foot.h"
|
||||
|
||||
#include "clang/Basic/MacroBuilder.h"
|
||||
|
||||
static const char* FootDataLayoutStr =
|
||||
"e-"
|
||||
"p:32: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
|
||||
27
clang/lib/Basic/Targets/Foot.h
Normal file
27
clang/lib/Basic/Targets/Foot.h
Normal 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
|
||||
64
lld/ELF/Arch/Foot.cpp
Normal file
64
lld/ELF/Arch/Foot.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
//===-- Foot.cpp -------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===-------------------------------------------------------------------===//
|
||||
|
||||
#include "InputFiles.h"
|
||||
#include "OutputSections.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
#include "Thunks.h"
|
||||
#include "lld/Common/ErrorHandler.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/Support/ELFAttributes.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
using namespace llvm::support::endian;
|
||||
using namespace llvm::ELF;
|
||||
using namespace lld;
|
||||
using namespace lld::elf;
|
||||
|
||||
namespace {
|
||||
class Foot final : public TargetInfo {
|
||||
public:
|
||||
Foot(Ctx &);
|
||||
RelExpr getRelExpr(RelType type, const Symbol &s,
|
||||
const uint8_t *loc) const override;
|
||||
void relocate(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const override;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Foot::Foot(Ctx &ctx) : TargetInfo(ctx) {
|
||||
defaultImageBase = 0;
|
||||
}
|
||||
|
||||
RelExpr Foot::getRelExpr(RelType type, const Symbol &s,
|
||||
const uint8_t *loc) const {
|
||||
return R_ABS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Foot::relocate(uint8_t *loc, const Relocation &rel,
|
||||
uint64_t val) const {
|
||||
switch (rel.type) {
|
||||
case R_FOOT_CNST16:
|
||||
checkUInt(ctx, loc, val, 16, rel);
|
||||
write16le(loc, val / 4); // foot is 32-bit addressable
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown relocation type");
|
||||
}
|
||||
}
|
||||
|
||||
void lld::elf::setFootTargetInfo(Ctx &ctx) {
|
||||
ctx.target.reset(new Foot(ctx));
|
||||
}
|
||||
@ -24,6 +24,7 @@ add_lld_library(lldELF
|
||||
Arch/AMDGPU.cpp
|
||||
Arch/ARM.cpp
|
||||
Arch/AVR.cpp
|
||||
Arch/Foot.cpp
|
||||
Arch/Hexagon.cpp
|
||||
Arch/LoongArch.cpp
|
||||
Arch/Mips.cpp
|
||||
|
||||
@ -82,6 +82,8 @@ void elf::setTarget(Ctx &ctx) {
|
||||
return setSystemZTargetInfo(ctx);
|
||||
case EM_X86_64:
|
||||
return setX86_64TargetInfo(ctx);
|
||||
case EM_FOOT:
|
||||
return setFootTargetInfo(ctx);
|
||||
default:
|
||||
Fatal(ctx) << "unsupported e_machine value: " << ctx.arg.emachine;
|
||||
}
|
||||
|
||||
@ -198,6 +198,7 @@ void setSPARCV9TargetInfo(Ctx &);
|
||||
void setSystemZTargetInfo(Ctx &);
|
||||
void setX86TargetInfo(Ctx &);
|
||||
void setX86_64TargetInfo(Ctx &);
|
||||
void setFootTargetInfo(Ctx &);
|
||||
|
||||
struct ErrorPlace {
|
||||
InputSectionBase *isec;
|
||||
|
||||
@ -533,6 +533,7 @@ set(LLVM_ALL_TARGETS
|
||||
ARM
|
||||
AVR
|
||||
BPF
|
||||
Foot
|
||||
Hexagon
|
||||
Lanai
|
||||
LoongArch
|
||||
|
||||
@ -325,6 +325,7 @@ enum {
|
||||
EM_VE = 251, // NEC SX-Aurora VE
|
||||
EM_CSKY = 252, // C-SKY 32-bit processor
|
||||
EM_LOONGARCH = 258, // LoongArch
|
||||
EM_FOOT = 259, // Foot
|
||||
};
|
||||
|
||||
// Object file classes.
|
||||
@ -1090,6 +1091,11 @@ enum {
|
||||
#include "ELFRelocs/Xtensa.def"
|
||||
};
|
||||
|
||||
// ELF Relocation types for Foot
|
||||
enum {
|
||||
#include "ELFRelocs/Foot.def"
|
||||
};
|
||||
|
||||
#undef ELF_RELOC
|
||||
|
||||
// Section header.
|
||||
|
||||
8
llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def
Normal file
8
llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef ELF_RELOC
|
||||
#error "ELF_RELOC must be defined"
|
||||
#endif
|
||||
|
||||
ELF_RELOC(R_FOOT_CNST16, 1)
|
||||
ELF_RELOC(R_FOOT_32, 2)
|
||||
ELF_RELOC(R_FOOT_64, 3)
|
||||
@ -341,6 +341,7 @@ LLVM_ABI void initializeWindowsSecureHotPatchingPass(PassRegistry &);
|
||||
LLVM_ABI void initializeWinEHPreparePass(PassRegistry &);
|
||||
LLVM_ABI void initializeWriteBitcodePassPass(PassRegistry &);
|
||||
LLVM_ABI void initializeXRayInstrumentationLegacyPass(PassRegistry &);
|
||||
LLVM_ABI void initializeFootRemovePseudoInstructionsPass(PassRegistry &);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@ -294,8 +294,8 @@ private:
|
||||
protected:
|
||||
ELFFile<ELFT> EF;
|
||||
|
||||
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
|
||||
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
|
||||
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
|
||||
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
|
||||
const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
|
||||
|
||||
// Hold CREL relocations for SectionRef::relocations().
|
||||
@ -677,8 +677,7 @@ uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint16_t ELFObjectFile<ELFT>::getEMachine() const {
|
||||
template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEMachine() const {
|
||||
return EF.getHeader().e_machine;
|
||||
}
|
||||
|
||||
@ -1278,13 +1277,11 @@ section_iterator ELFObjectFile<ELFT>::section_end() const {
|
||||
return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
|
||||
template <class ELFT> uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
|
||||
return ELFT::Is64Bits ? 8 : 4;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
|
||||
template <class ELFT> StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
|
||||
constexpr bool IsLittleEndian = ELFT::Endianness == llvm::endianness::little;
|
||||
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
|
||||
case ELF::ELFCLASS32:
|
||||
@ -1324,6 +1321,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
|
||||
return "elf32-loongarch";
|
||||
case ELF::EM_XTENSA:
|
||||
return "elf32-xtensa";
|
||||
case ELF::EM_FOOT:
|
||||
return "elf32-foot";
|
||||
default:
|
||||
return "elf32-unknown";
|
||||
}
|
||||
@ -1457,6 +1456,9 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
|
||||
case ELF::EM_XTENSA:
|
||||
return Triple::xtensa;
|
||||
|
||||
case ELF::EM_FOOT:
|
||||
return Triple::foot;
|
||||
|
||||
default:
|
||||
return Triple::UnknownArch;
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ public:
|
||||
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
|
||||
csky, // CSKY: csky
|
||||
dxil, // DXIL 32-bit DirectX bytecode
|
||||
foot, // foot: foot
|
||||
hexagon, // Hexagon: hexagon
|
||||
loongarch32, // LoongArch (32-bit): loongarch32
|
||||
loongarch64, // LoongArch (64-bit): loongarch64
|
||||
|
||||
@ -183,6 +183,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_FOOT:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/Foot.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
16
llvm/lib/Target/Foot/AsmParser/CMakeLists.txt
Normal file
16
llvm/lib/Target/Foot/AsmParser/CMakeLists.txt
Normal 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
|
||||
)
|
||||
333
llvm/lib/Target/Foot/AsmParser/FootAsmParser.cpp
Normal file
333
llvm/lib/Target/Foot/AsmParser/FootAsmParser.cpp
Normal 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"
|
||||
52
llvm/lib/Target/Foot/CMakeLists.txt
Normal file
52
llvm/lib/Target/Foot/CMakeLists.txt
Normal file
@ -0,0 +1,52 @@
|
||||
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)
|
||||
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
|
||||
FootSubtarget.cpp
|
||||
FootTargetMachine.cpp
|
||||
FootTargetObjectFile.cpp
|
||||
FootRegisterInfo.cpp
|
||||
FootAsmPrinter.cpp
|
||||
FootISelDAGToDAG.cpp
|
||||
FootRemovePseudoInstructions.cpp
|
||||
FootMachineFunctionInfo.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
FootDesc
|
||||
FootInfo
|
||||
|
||||
AsmPrinter
|
||||
Analysis
|
||||
CodeGen
|
||||
Core
|
||||
MC
|
||||
Passes
|
||||
SelectionDAG
|
||||
Support
|
||||
Target
|
||||
TargetParser
|
||||
TransformUtils
|
||||
|
||||
ADD_TO_COMPONENT
|
||||
Foot
|
||||
)
|
||||
|
||||
add_subdirectory(AsmParser)
|
||||
add_subdirectory(MCTargetDesc)
|
||||
add_subdirectory(TargetInfo)
|
||||
16
llvm/lib/Target/Foot/Foot.h
Normal file
16
llvm/lib/Target/Foot/Foot.h
Normal file
@ -0,0 +1,16 @@
|
||||
#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);
|
||||
Pass *createFootRemovePseudoInstructionsPassForLegacyPM();
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOT_H
|
||||
13
llvm/lib/Target/Foot/Foot.td
Normal file
13
llvm/lib/Target/Foot/Foot.td
Normal file
@ -0,0 +1,13 @@
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
include "FootRegisterInfo.td"
|
||||
include "FootCallingConvention.td"
|
||||
include "FootInstrInfo.td"
|
||||
|
||||
def : ProcessorModel<"generic", NoSchedModel, /*Features=*/[]>;
|
||||
|
||||
def FootInstrInfo : InstrInfo;
|
||||
|
||||
def Foot : Target {
|
||||
let InstructionSet = FootInstrInfo;
|
||||
}
|
||||
139
llvm/lib/Target/Foot/FootAsmPrinter.cpp
Normal file
139
llvm/lib/Target/Foot/FootAsmPrinter.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Target/TargetMachine.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;
|
||||
void emitFunctionBodyStart() override;
|
||||
|
||||
StringRef getPassName() const override { return "FootAsmPrinter"; }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool FootAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCO) {
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
MCO = MCOperand::createReg(MO.getReg());
|
||||
break;
|
||||
case MachineOperand::MO_Immediate:
|
||||
MCO = MCOperand::createImm(MO.getImm());
|
||||
break;
|
||||
case MachineOperand::MO_CImmediate:
|
||||
llvm_unreachable("cimm not yet implemented");
|
||||
case MachineOperand::MO_FPImmediate:
|
||||
llvm_unreachable("fpimm not yet implemented");
|
||||
case MachineOperand::MO_MachineBasicBlock: {
|
||||
MachineBasicBlock *MBB = MO.getMBB();
|
||||
MCSymbol *Label = MBB->getSymbol();
|
||||
MCO = MCOperand::createExpr(MCSymbolRefExpr::create(Label, OutContext));
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_FrameIndex:
|
||||
llvm_unreachable("frame index not yet implemented");
|
||||
case MachineOperand::MO_ConstantPoolIndex: {
|
||||
unsigned Index = MO.getIndex();
|
||||
MCSymbol *Sym = GetCPISymbol(Index);
|
||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, OutContext);
|
||||
MCO = MCOperand::createExpr(Expr);
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_TargetIndex:
|
||||
llvm_unreachable("target index not yet implemented");
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
llvm_unreachable("jump table index not yet implemented");
|
||||
case MachineOperand::MO_ExternalSymbol: {
|
||||
StringRef Name = MO.getSymbolName();
|
||||
MCSymbol *Sym = OutContext.getOrCreateSymbol(Name);
|
||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, OutContext);
|
||||
MCO = MCOperand::createExpr(Expr);
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_GlobalAddress: {
|
||||
const GlobalValue *GV = MO.getGlobal();
|
||||
MCSymbol *Sym = getSymbol(GV);
|
||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, OutContext);
|
||||
MCO = MCOperand::createExpr(Expr);
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_BlockAddress: {
|
||||
MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
|
||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, OutContext);
|
||||
MCO = MCOperand::createExpr(Expr);
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_RegisterMask:
|
||||
return false;
|
||||
case MachineOperand::MO_RegisterLiveOut:
|
||||
llvm_unreachable("register live out not yet implemented");
|
||||
case MachineOperand::MO_Metadata:
|
||||
llvm_unreachable("metadata not yet implemented");
|
||||
case MachineOperand::MO_MCSymbol:
|
||||
llvm_unreachable("mc symbol not yet implemented");
|
||||
case MachineOperand::MO_CFIIndex:
|
||||
llvm_unreachable("cfi index not yet implemented");
|
||||
case MachineOperand::MO_IntrinsicID:
|
||||
llvm_unreachable("intrinsic id not yet implemented");
|
||||
case MachineOperand::MO_Predicate:
|
||||
llvm_unreachable("predicate not yet implemented");
|
||||
case MachineOperand::MO_ShuffleMask:
|
||||
llvm_unreachable("shuffle mask not yet implemented");
|
||||
case MachineOperand::MO_DbgInstrRef:
|
||||
llvm_unreachable("debug instr ref not yet implemented");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
Foot_MC::verifyInstructionPredicates(MI->getOpcode(),
|
||||
getSubtargetInfo().getFeatureBits());
|
||||
|
||||
MCInst TmpInst = machineInstrToMCInst(*MI);
|
||||
EmitToStreamer(*OutStreamer, TmpInst);
|
||||
}
|
||||
|
||||
void FootAsmPrinter::emitFunctionBodyStart() {
|
||||
for (const auto &CFI : MF->getFrameInstructions()) {
|
||||
emitCFIInstruction(CFI);
|
||||
}
|
||||
}
|
||||
|
||||
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)>;
|
||||
150
llvm/lib/Target/Foot/FootFrameLowering.cpp
Normal file
150
llvm/lib/Target/Foot/FootFrameLowering.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include "FootFrameLowering.h"
|
||||
|
||||
#include "FootMachineFunctionInfo.h"
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool FootFrameLowering::hasFPImpl(const MachineFunction &MF) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FootFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
||||
|
||||
int FI = MF.getInfo<FootMachineFunctionInfo>()->getReturnAddressFrameIndex();
|
||||
|
||||
unsigned int CFIIndex =
|
||||
MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
|
||||
nullptr, MF.getRegInfo().getTargetRegisterInfo()->getDwarfRegNum(
|
||||
Foot::RSP, true)));
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(TargetOpcode::CFI_INSTRUCTION))
|
||||
.addCFIIndex(CFIIndex);
|
||||
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::BWOR_I_D_M_A))
|
||||
.addFrameIndex(FI)
|
||||
.addReg(Foot::RRA)
|
||||
.addImm(0);
|
||||
unsigned int RRADwarfRegNum =
|
||||
MF.getRegInfo().getTargetRegisterInfo()->getDwarfRegNum(Foot::RRA, false);
|
||||
int Offset = MFI.getObjectOffset(FI);
|
||||
CFIIndex = MF.addFrameInst(
|
||||
MCCFIInstruction::createOffset(nullptr, RRADwarfRegNum, Offset));
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(TargetOpcode::CFI_INSTRUCTION))
|
||||
.addCFIIndex(CFIIndex);
|
||||
|
||||
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_M_A),
|
||||
Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addImm(NumBytes);
|
||||
} else {
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A),
|
||||
Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::R27);
|
||||
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A), Foot::R27)
|
||||
.addImm(NumBytes);
|
||||
}
|
||||
|
||||
CFIIndex = MF.addFrameInst(
|
||||
MCCFIInstruction::createAdjustCfaOffset(nullptr, NumBytes));
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(TargetOpcode::CFI_INSTRUCTION))
|
||||
.addCFIIndex(CFIIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void FootFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
||||
|
||||
unsigned NumBytes = MFI.getStackSize();
|
||||
|
||||
int FI = MF.getInfo<FootMachineFunctionInfo>()->getReturnAddressFrameIndex();
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(Foot::BWOR_D_I_M_A))
|
||||
.addReg(Foot::RRA)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
|
||||
if (NumBytes > 0) {
|
||||
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
||||
if (NumBytes < (1 << 5)) {
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(Foot::ADDI_D_D_M_A), Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addImm(NumBytes);
|
||||
} else {
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(Foot::ADDI_D_D_D_A), Foot::RSP)
|
||||
.addReg(Foot::RSP)
|
||||
.addReg(Foot::R27);
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(Foot::CNST_D_A), Foot::R27)
|
||||
.addImm(NumBytes);
|
||||
}
|
||||
|
||||
unsigned int CFIIndex =
|
||||
MF.addFrameInst(MCCFIInstruction::createAdjustCfaOffset(nullptr, 0));
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
||||
TII->get(TargetOpcode::CFI_INSTRUCTION))
|
||||
.addCFIIndex(CFIIndex);
|
||||
}
|
||||
|
||||
const auto &I = MBB.getFirstTerminator();
|
||||
BuildMI(MBB, MBB.getFirstTerminator(), I->getDebugLoc(),
|
||||
TII->get(Foot::COPY_D_D_A))
|
||||
.addReg(Foot::RPC)
|
||||
.addReg(Foot::RRA);
|
||||
|
||||
MBB.erase(I);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void FootFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
BitVector &SavedRegs,
|
||||
RegScavenger *RS) const {
|
||||
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
|
||||
|
||||
SavedRegs.set(Foot::RSP);
|
||||
SavedRegs.set(Foot::RRA);
|
||||
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
|
||||
int RetAddrFI = MFI.CreateStackObject(4, Align(4), false);
|
||||
|
||||
MF.getInfo<FootMachineFunctionInfo>()->setReturnAddressFrameIndex(RetAddrFI);
|
||||
}
|
||||
31
llvm/lib/Target/Foot/FootFrameLowering.h
Normal file
31
llvm/lib/Target/Foot/FootFrameLowering.h
Normal file
@ -0,0 +1,31 @@
|
||||
#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;
|
||||
|
||||
MachineBasicBlock::iterator
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const override;
|
||||
|
||||
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||
RegScavenger *RS) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTFRAMELOWERING_H
|
||||
1054
llvm/lib/Target/Foot/FootISelDAGToDAG.cpp
Normal file
1054
llvm/lib/Target/Foot/FootISelDAGToDAG.cpp
Normal file
File diff suppressed because it is too large
Load Diff
437
llvm/lib/Target/Foot/FootISelLowering.cpp
Normal file
437
llvm/lib/Target/Foot/FootISelLowering.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
#include "FootISelLowering.h"
|
||||
#include "FootCallingConvention.h"
|
||||
#include "FootSubtarget.h"
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.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);
|
||||
|
||||
setOperationAction(ISD::ADD, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SUB, MVT::i32, Legal);
|
||||
setOperationAction(ISD::MUL, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SREM, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SHL, MVT::i32, Legal);
|
||||
setOperationAction(ISD::ROTL, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SRA, MVT::i32, Legal);
|
||||
setOperationAction(ISD::OR, MVT::i32, Legal);
|
||||
setOperationAction(ISD::AND, MVT::i32, Legal);
|
||||
setOperationAction(ISD::XOR, MVT::i32, Legal);
|
||||
setOperationAction(ISD::STORE, MVT::i32, Legal);
|
||||
setOperationAction(ISD::LOAD, MVT::i32, Legal);
|
||||
setOperationAction(ISD::BR, MVT::i32, Legal);
|
||||
|
||||
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
|
||||
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SETCC, MVT::i32, Expand);
|
||||
|
||||
computeRegisterProperties(Subtarget.getRegisterInfo());
|
||||
}
|
||||
|
||||
const char *FootTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
case FootISD::FIRST_NUMBER:
|
||||
break;
|
||||
case FootISD::CALL:
|
||||
return "FootISD::CALL";
|
||||
}
|
||||
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();
|
||||
|
||||
MFI.CreateFixedObject(4, 0, true);
|
||||
|
||||
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);
|
||||
|
||||
if (Glue) {
|
||||
RetOps.push_back(Glue);
|
||||
}
|
||||
}
|
||||
|
||||
SDNode *NewNode =
|
||||
DAG.getMachineNode(Foot::PSEUDO_RET, DL, MVT::Other, RetOps);
|
||||
return SDValue(NewNode, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
MemOpChains.push_back(Store);
|
||||
}
|
||||
|
||||
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.getLocInfo() == 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);
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerOperation(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
switch (Op.getOpcode()) {
|
||||
case ISD::BR_CC:
|
||||
return LowerBrCC(Op, DAG);
|
||||
default:
|
||||
llvm_unreachable("unexpected custom operation");
|
||||
return SDValue();
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
FootTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||
MachineBasicBlock *MBB) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Foot::PSEUDO_SELECT:
|
||||
return EmitSelect(MI);
|
||||
|
||||
default:
|
||||
llvm_unreachable("custom inserter not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerBrCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
assert(Op.getOpcode() == ISD::BR_CC);
|
||||
|
||||
SDValue Cmp =
|
||||
DAG.getNode(FootISD::CMP_CHAIN, SDLoc(Op), MVT::Other, Op.getOperand(0),
|
||||
Op.getOperand(2), Op.getOperand(3));
|
||||
|
||||
assert(isa<CondCodeSDNode>(Op.getOperand(1).getNode()) &&
|
||||
"CC Must be CondCodeSDNode");
|
||||
|
||||
unsigned Opc;
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1).getNode())->get();
|
||||
switch (CC) {
|
||||
case ISD::SETLT:
|
||||
case ISD::SETULT:
|
||||
Opc = FootISD::BR_L;
|
||||
break;
|
||||
case ISD::SETLE:
|
||||
case ISD::SETULE:
|
||||
Opc = FootISD::BR_LE;
|
||||
break;
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETUEQ:
|
||||
Opc = FootISD::BR_E;
|
||||
break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETUGE:
|
||||
Opc = FootISD::BR_GE;
|
||||
break;
|
||||
case ISD::SETGT:
|
||||
case ISD::SETUGT:
|
||||
Opc = FootISD::BR_G;
|
||||
break;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETUNE:
|
||||
Opc = FootISD::BR_NE;
|
||||
break;
|
||||
default:
|
||||
dbgs() << CC << "\n";
|
||||
llvm_unreachable("Unexpected condition code");
|
||||
}
|
||||
|
||||
return DAG.getNode(Opc, SDLoc(Op), MVT::Other, {Op.getOperand(4), Cmp});
|
||||
}
|
||||
|
||||
MachineBasicBlock *FootTargetLowering::EmitSelect(MachineInstr &MI) const {
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(Foot::CMPR_D_D_A))
|
||||
.addReg(MI.getOperand(2).getReg())
|
||||
.addReg(MI.getOperand(1).getReg());
|
||||
|
||||
unsigned OpcTrue;
|
||||
unsigned OpcFalse;
|
||||
|
||||
// this should probably use enums instead
|
||||
// refer to DOCS.txt in the other repo
|
||||
switch (MI.getOperand(5).getImm()) {
|
||||
case 1:
|
||||
OpcTrue = Foot::COPY_D_D_L;
|
||||
OpcFalse = Foot::COPY_D_D_GE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
OpcTrue = Foot::COPY_D_D_LE;
|
||||
OpcFalse = Foot::COPY_D_D_G;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
OpcTrue = Foot::COPY_D_D_E;
|
||||
OpcFalse = Foot::COPY_D_D_NE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
OpcTrue = Foot::COPY_D_D_GE;
|
||||
OpcFalse = Foot::COPY_D_D_L;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
OpcTrue = Foot::COPY_D_D_G;
|
||||
OpcFalse = Foot::COPY_D_D_LE;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
OpcTrue = Foot::COPY_D_D_NE;
|
||||
OpcFalse = Foot::COPY_D_D_E;
|
||||
break;
|
||||
}
|
||||
|
||||
Register Out = MI.getOperand(0).getReg();
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(OpcTrue), Out)
|
||||
.addReg(MI.getOperand(3).getReg());
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(OpcFalse))
|
||||
.addReg(Out)
|
||||
.addReg(MI.getOperand(4).getReg());
|
||||
|
||||
MI.eraseFromParent();
|
||||
|
||||
return &MBB;
|
||||
}
|
||||
61
llvm/lib/Target/Foot/FootISelLowering.h
Normal file
61
llvm/lib/Target/Foot/FootISelLowering.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H
|
||||
|
||||
#include "llvm/CodeGen/TargetLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace FootISD {
|
||||
|
||||
enum NodeType : unsigned {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
CALL,
|
||||
CMP_CHAIN,
|
||||
BR_L,
|
||||
BR_LE,
|
||||
BR_E,
|
||||
BR_GE,
|
||||
BR_G,
|
||||
BR_NE
|
||||
};
|
||||
|
||||
} // namespace FootISD
|
||||
|
||||
class FootSubtarget;
|
||||
class FootTargetMachine;
|
||||
|
||||
class FootTargetLowering : public TargetLowering {
|
||||
const FootSubtarget &Subtarget;
|
||||
public:
|
||||
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;
|
||||
|
||||
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||
|
||||
MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override;
|
||||
|
||||
private:
|
||||
SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
MachineBasicBlock *EmitSelect(MachineInstr &MI) const;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTISELLOWERING_H
|
||||
318
llvm/lib/Target/Foot/FootInstrFormats.td
Normal file
318
llvm/lib/Target/Foot/FootInstrFormats.td
Normal file
@ -0,0 +1,318 @@
|
||||
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<5> dst;
|
||||
bits<16> imm;
|
||||
|
||||
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, dag oops, dag iops> {
|
||||
defm _M_M : _mFootInstructionB<!strconcat(asm, ".m.m"), "$dst, $a", 0b0001, 0b00, 0b00, opcode2, oops, iops>;
|
||||
defm _M_D : _mFootInstructionB<!strconcat(asm, ".m.d"), "$dst, $a", 0b0001, 0b00, 0b01, opcode2, oops, iops>;
|
||||
defm _M_I : _mFootInstructionB<!strconcat(asm, ".m.i"), "$dst, $a", 0b0001, 0b00, 0b10, opcode2, oops, iops>;
|
||||
defm _M_A : _mFootInstructionB<!strconcat(asm, ".m.a"), "$dst, $a", 0b0001, 0b00, 0b11, opcode2, oops, iops>;
|
||||
defm _D_M : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b00, opcode2, oops, iops>;
|
||||
defm _D_D : _mFootInstructionB<!strconcat(asm, ".d.d"), "$dst, $a", 0b0001, 0b01, 0b01, opcode2, oops, iops>;
|
||||
defm _D_I : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b10, opcode2, oops, iops>;
|
||||
defm _D_A : _mFootInstructionB<!strconcat(asm, ".d.m"), "$dst, $a", 0b0001, 0b01, 0b11, opcode2, oops, iops>;
|
||||
defm _I_M : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b00, opcode2, oops, iops>;
|
||||
defm _I_D : _mFootInstructionB<!strconcat(asm, ".i.d"), "$dst, $a", 0b0001, 0b10, 0b01, opcode2, oops, iops>;
|
||||
defm _I_I : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b10, opcode2, oops, iops>;
|
||||
defm _I_A : _mFootInstructionB<!strconcat(asm, ".i.m"), "$dst, $a", 0b0001, 0b10, 0b11, opcode2, oops, iops>;
|
||||
defm _A_M : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b00, opcode2, oops, iops>;
|
||||
defm _A_D : _mFootInstructionB<!strconcat(asm, ".a.d"), "$dst, $a", 0b0001, 0b11, 0b01, opcode2, oops, iops>;
|
||||
defm _A_I : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b10, opcode2, oops, iops>;
|
||||
defm _A_A : _mFootInstructionB<!strconcat(asm, ".a.m"), "$dst, $a", 0b0001, 0b11, 0b11, opcode2, oops, iops>;
|
||||
}
|
||||
|
||||
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} = bmode;
|
||||
let Inst{20-16} = dst;
|
||||
let Inst{15} = 0b0;
|
||||
let Inst{14-13} = dstmode;
|
||||
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, dag iops> {
|
||||
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,
|
||||
dag oops, dag iops> {
|
||||
defm _M : _mmmFootInstructionC<!strconcat(asm, ".m"), operands, opcode, 0b00, amode, bmode, oops, iops>;
|
||||
defm _D : _mmmFootInstructionC<!strconcat(asm, ".d"), operands, opcode, 0b01, amode, bmode, oops, iops>;
|
||||
defm _I : _mmmFootInstructionC<!strconcat(asm, ".i"), operands, opcode, 0b10, amode, bmode, oops, iops>;
|
||||
defm _A : _mmmFootInstructionC<!strconcat(asm, ".a"), operands, opcode, 0b11, amode, bmode, oops, iops>;
|
||||
}
|
||||
|
||||
multiclass _mFootInstructionC<string asm, string operands,
|
||||
bits<4> opcode, bits<2> bmode,
|
||||
dag oops, dag iops> {
|
||||
defm _M : _mmFootInstructionC<!strconcat(asm, ".m"), operands, opcode, 0b00, bmode, oops, iops>;
|
||||
defm _D : _mmFootInstructionC<!strconcat(asm, ".d"), operands, opcode, 0b01, bmode, oops, iops>;
|
||||
defm _I : _mmFootInstructionC<!strconcat(asm, ".i"), operands, opcode, 0b10, bmode, oops, iops>;
|
||||
defm _A : _mmFootInstructionC<!strconcat(asm, ".a"), operands, opcode, 0b11, bmode, oops, iops>;
|
||||
}
|
||||
|
||||
multiclass FootInstructionC<string asm, bits<4> opcode,
|
||||
dag oops = (outs), dag iops = (ins)> {
|
||||
defm _M : _mFootInstructionC<!strconcat(asm, ".m"), "$dst, $a, $b", opcode, 0b00, oops, iops>;
|
||||
defm _D : _mFootInstructionC<!strconcat(asm, ".d"), "$dst, $a, $b", opcode, 0b01, oops, iops>;
|
||||
defm _I : _mFootInstructionC<!strconcat(asm, ".i"), "$dst, $a, $b", opcode, 0b10, oops, iops>;
|
||||
defm _A : _mFootInstructionC<!strconcat(asm, ".a"), "$dst, $a, $b", opcode, 0b11, oops, iops>;
|
||||
}
|
||||
70
llvm/lib/Target/Foot/FootInstrInfo.cpp
Normal file
70
llvm/lib/Target/Foot/FootInstrInfo.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "FootInstrInfo.h"
|
||||
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
|
||||
#define GET_INSTRINFO_CTOR_DTOR
|
||||
#define ENABLE_INSTR_PREDICATE_VERIFIER
|
||||
#include "FootGenInstrInfo.inc"
|
||||
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
FootInstrInfo::FootInstrInfo() : FootGenInstrInfo() {}
|
||||
|
||||
void FootInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
Register SrcReg, bool IsKill, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI,
|
||||
Register VReg,
|
||||
MachineInstr::MIFlag Flag) const {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
|
||||
MachineMemOperand *MMO =
|
||||
MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
|
||||
MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
|
||||
|
||||
unsigned Opc = Foot::BWOR_I_D_M_A;
|
||||
MFI.setStackID(FrameIndex, TargetStackID::Default);
|
||||
BuildMI(MBB, MI, DebugLoc(), get(Opc))
|
||||
.addFrameIndex(FrameIndex)
|
||||
.addReg(SrcReg, getKillRegState(IsKill))
|
||||
.addImm(0)
|
||||
.addMemOperand(MMO);
|
||||
}
|
||||
|
||||
void FootInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
Register DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI,
|
||||
Register VReg,
|
||||
MachineInstr::MIFlag Flag) const {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
|
||||
MachineMemOperand *MMO =
|
||||
MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
|
||||
MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
|
||||
|
||||
unsigned Opc = Foot::BWOR_D_I_M_A;
|
||||
MFI.setStackID(FrameIndex, TargetStackID::Default);
|
||||
BuildMI(MBB, MI, DebugLoc(), get(Opc))
|
||||
.addReg(DestReg)
|
||||
.addFrameIndex(FrameIndex)
|
||||
.addImm(0)
|
||||
.addMemOperand(MMO);
|
||||
}
|
||||
|
||||
void FootInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, const DebugLoc &DL,
|
||||
Register DestReg, Register SrcReg, bool KillSrc,
|
||||
bool RenamableDest,
|
||||
bool RenamableSrc) const {
|
||||
BuildMI(MBB, MI, MI->getDebugLoc(), get(Foot::BWOR_D_D_M_A))
|
||||
.addReg(DestReg, RegState::Define | getRenamableRegState(RenamableDest))
|
||||
.addReg(SrcReg, getKillRegState(KillSrc) | getRenamableRegState(RenamableSrc))
|
||||
.addImm(0);
|
||||
}
|
||||
41
llvm/lib/Target/Foot/FootInstrInfo.h
Normal file
41
llvm/lib/Target/Foot/FootInstrInfo.h
Normal file
@ -0,0 +1,41 @@
|
||||
#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();
|
||||
|
||||
void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
Register SrcReg, bool IsKill, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI,
|
||||
Register VReg,
|
||||
MachineInstr::MIFlag Flags) const override;
|
||||
|
||||
void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
Register DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI,
|
||||
Register VReg,
|
||||
MachineInstr::MIFlag Flags) const override;
|
||||
|
||||
void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, const DebugLoc& DL,
|
||||
Register DestReg, Register SrcReg, bool KillSrc,
|
||||
bool RenamableDest,
|
||||
bool RenamableSrc) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTINSTRINFO_H
|
||||
84
llvm/lib/Target/Foot/FootInstrInfo.td
Normal file
84
llvm/lib/Target/Foot/FootInstrInfo.td
Normal file
@ -0,0 +1,84 @@
|
||||
include "FootInstrFormats.td"
|
||||
|
||||
def Footcall : SDNode<"FootISD::CALL",
|
||||
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
SDNPVariadic]>;
|
||||
|
||||
def Footcallseq_start : SDNode<"ISD::CALLSEQ_START",
|
||||
SDCallSeqStart<[SDTCisVT<0, i32>,
|
||||
SDTCisVT<0, i32>]>,
|
||||
[SDNPHasChain, SDNPOutGlue]>;
|
||||
|
||||
def Footcallseq_end : SDNode<"ISD::CALLSEQ_END",
|
||||
SDCallSeqStart<[SDTCisVT<0, i32>,
|
||||
SDTCisVT<0, i32>]>,
|
||||
[SDNPHasChain, SDNPOutGlue]>;
|
||||
|
||||
let mayLoad = 1, mayStore = 1, hasSideEffects = 1 in {
|
||||
defm CNST_M : FootInstructionA<"CNST.m", "$dst, $imm", 0b0000, 0b00, (outs GP32:$dst), (ins i16imm:$imm)>;
|
||||
defm CNST_D : FootInstructionA<"CNST.d", "$dst, $imm", 0b0000, 0b01, (outs GP32:$dst), (ins i16imm:$imm)>;
|
||||
defm CNST_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs GP32:$dst), (ins i16imm:$imm)>;
|
||||
defm CNST_A : FootInstructionA<"CNST.a", "$dst, $imm", 0b0000, 0b11, (outs GP32:$dst), (ins i16imm:$imm)>;
|
||||
|
||||
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
defm CNST_JMP_D : FootInstructionA<"CNST.d", "$dst, $imm", 0b0000, 0b01, (outs), (ins PC32:$dst, i16imm:$imm)>;
|
||||
}
|
||||
defm CNST_STR_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs), (ins GP32:$dst, i16imm:$imm)>;
|
||||
|
||||
defm CMPR : FootInstructionB<"CMPR", 0b00000000, (outs), (ins GP32:$dst, GP32:$a)>;
|
||||
defm BWNG : FootInstructionB<"BWNG", 0b00000001, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm ARNG : FootInstructionB<"ARNG", 0b00000010, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm LONG : FootInstructionB<"LONG", 0b00000011, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm CONF : FootInstructionB<"CONF", 0b00000100, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm COPY : FootInstructionB<"COPY", 0b00000101, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
|
||||
defm BWOR : FootInstructionC<"BWOR", 0b0010, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm BAND : FootInstructionC<"BAND", 0b0011, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm BXOR : FootInstructionC<"BXOR", 0b0100, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm ZRSH : FootInstructionC<"ZRSH", 0b0101, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm SRSH : FootInstructionC<"SRSH", 0b0110, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm ZLSH : FootInstructionC<"ZLSH", 0b0111, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm CLSH : FootInstructionC<"CLSH", 0b1000, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm ADDI : FootInstructionC<"ADDI", 0b1001, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm SUBT : FootInstructionC<"SUBT", 0b1010, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm MULT : FootInstructionC<"MULT", 0b1011, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm DIVI : FootInstructionC<"DIVI", 0b1100, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm MODU : FootInstructionC<"MODU", 0b1101, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
|
||||
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
defm BWOR_JMP : FootInstructionC<"BWOR", 0b0010, (outs), (ins PC32:$dst, GP32:$a, GP32:$b)>;
|
||||
defm ADDI_JMP : FootInstructionC<"ADDI", 0b0010, (outs), (ins PC32:$dst, GP32:$a, GP32:$b)>;
|
||||
}
|
||||
|
||||
defm BWOR_STR : FootInstructionC<"BWOR", 0b0010, (outs), (ins GP32:$dst, GP32:$a, GP32:$b)>;
|
||||
defm ADDI_STR : FootInstructionC<"ADDI", 0b1001, (outs), (ins GP32:$dst, GP32:$a, GP32:$b)>;
|
||||
}
|
||||
|
||||
let OutOperandList = (outs),
|
||||
InOperandList = (ins),
|
||||
isReturn = 1,
|
||||
isTerminator = 1,
|
||||
isBarrier = 1,
|
||||
Namespace = "Foot" in {
|
||||
def PSEUDO_RET : StandardPseudoInstruction;
|
||||
}
|
||||
|
||||
let OutOperandList = (outs GP32:$dst),
|
||||
InOperandList = (ins GP32:$a, GP32:$b, GP32:$iftrue, GP32:$iffalse, i16imm:$cc),
|
||||
usesCustomInserter = 1,
|
||||
Namespace = "Foot" in {
|
||||
def PSEUDO_SELECT : StandardPseudoInstruction;
|
||||
}
|
||||
|
||||
let Defs = [RSP], Uses = [RSP],
|
||||
isCodeGenOnly = 1, Namespace = "Foot",
|
||||
OutOperandList = (outs),
|
||||
InOperandList = (ins i32imm:$amt1, i32imm:$amt2) in {
|
||||
def ADJCALLSTACKDOWN : StandardPseudoInstruction {
|
||||
let Pattern = [(Footcallseq_start timm:$amt1, timm:$amt2)];
|
||||
}
|
||||
def ADJCALLSTACKUP : StandardPseudoInstruction {
|
||||
let Pattern = [(Footcallseq_end timm:$amt1, timm:$amt2)];
|
||||
}
|
||||
}
|
||||
8
llvm/lib/Target/Foot/FootMachineFunctionInfo.cpp
Normal file
8
llvm/lib/Target/Foot/FootMachineFunctionInfo.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "FootMachineFunctionInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
MachineFunctionInfo *FootMachineFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
|
||||
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) const {
|
||||
return new FootMachineFunctionInfo(*this);
|
||||
}
|
||||
24
llvm/lib/Target/Foot/FootMachineFunctionInfo.h
Normal file
24
llvm/lib/Target/Foot/FootMachineFunctionInfo.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOTMACHINEFUNCTIONINFO_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOTMACHINEFUNCTIONINFO_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FootMachineFunctionInfo : public MachineFunctionInfo {
|
||||
int RetAddrFI = -1;
|
||||
|
||||
public:
|
||||
FootMachineFunctionInfo() = default;
|
||||
|
||||
int getReturnAddressFrameIndex() const { return RetAddrFI; }
|
||||
void setReturnAddressFrameIndex(int RetAddrFI) { this->RetAddrFI = RetAddrFI; }
|
||||
|
||||
MachineFunctionInfo *
|
||||
clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
|
||||
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTMACHINEFUNCTIONINFO_H
|
||||
15
llvm/lib/Target/Foot/FootPassRegistry.def
Normal file
15
llvm/lib/Target/Foot/FootPassRegistry.def
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MODULE_PASS
|
||||
#define MODULE_PASS(NAME, CREATE_PASS)
|
||||
#endif
|
||||
#undef MODULE_PASS
|
||||
|
||||
#ifndef FUNCTION_PASS
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS)
|
||||
#endif
|
||||
#undef FUNCTION_PASS
|
||||
|
||||
#ifndef MACHINE_FUNCTION_PASS
|
||||
#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS)
|
||||
#endif
|
||||
MACHINE_FUNCTION_PASS("foot-remove-pseudo-instructions", FootRemovePseudoInstructionsNewPass())
|
||||
#undef MACHINE_FUNCTION_PASS
|
||||
73
llvm/lib/Target/Foot/FootRegisterInfo.cpp
Normal file
73
llvm/lib/Target/Foot/FootRegisterInfo.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "FootRegisterInfo.h"
|
||||
#include "FootFrameLowering.h"
|
||||
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
|
||||
#define GET_REGINFO_TARGET_DESC
|
||||
#include "FootGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
FootRegisterInfo::FootRegisterInfo() : FootGenRegisterInfo(Foot::RRA) {}
|
||||
|
||||
const MCPhysReg *
|
||||
FootRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
return CSR_Foot_Common_SaveList;
|
||||
}
|
||||
|
||||
const uint32_t *
|
||||
FootRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
|
||||
CallingConv::ID CC) const {
|
||||
return CSR_Foot_Common_RegMask;
|
||||
}
|
||||
|
||||
BitVector FootRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
BitVector Reserved;
|
||||
Reserved.set(Foot::R26);
|
||||
Reserved.set(Foot::R27);
|
||||
Reserved.set(Foot::RSP);
|
||||
Reserved.set(Foot::RRA);
|
||||
Reserved.set(Foot::RLC);
|
||||
Reserved.set(Foot::RPC);
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
bool FootRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, unsigned FIOperandNum,
|
||||
RegScavenger *RS) const {
|
||||
MachineInstr &MI = *II;
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
|
||||
MachineOperand &FIOp = MI.getOperand(FIOperandNum);
|
||||
int Index = FIOp.getIndex();
|
||||
int64_t Offset = MFI.getObjectOffset(Index);
|
||||
// adjust to account for stack pointer adjusted before load/store
|
||||
Offset += MFI.getStackSize();
|
||||
|
||||
Register DestReg = Foot::R27;
|
||||
if (FIOperandNum == 1) {
|
||||
DestReg = Foot::R26;
|
||||
}
|
||||
|
||||
BuildMI(MBB, MI, DebugLoc(), TII.get(Foot::ADDI_D_D_M_A), DestReg)
|
||||
.addReg(Foot::RSP)
|
||||
.addImm(Offset);
|
||||
|
||||
FIOp.ChangeToRegister(DestReg, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Register FootRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||
return Foot::RSP;
|
||||
}
|
||||
29
llvm/lib/Target/Foot/FootRegisterInfo.h
Normal file
29
llvm/lib/Target/Foot/FootRegisterInfo.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOTREGISTERINFO_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOTREGISTERINFO_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;
|
||||
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
|
||||
CallingConv::ID CC) 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_FOOTREGISTERINFO_H
|
||||
46
llvm/lib/Target/Foot/FootRegisterInfo.td
Normal file
46
llvm/lib/Target/Foot/FootRegisterInfo.td
Normal file
@ -0,0 +1,46 @@
|
||||
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">, DwarfRegNum<[0, 0, 0]>;
|
||||
def R1 : FootRegister<1, "r1">, DwarfRegNum<[1, 1, 1]>;
|
||||
def R2 : FootRegister<2, "r2">, DwarfRegNum<[2, 2, 2]>;
|
||||
def R3 : FootRegister<3, "r3">, DwarfRegNum<[3, 3, 3]>;
|
||||
def R4 : FootRegister<4, "r4">, DwarfRegNum<[4, 4, 4]>;
|
||||
def R5 : FootRegister<5, "r5">, DwarfRegNum<[5, 5, 5]>;
|
||||
def R6 : FootRegister<6, "r6">, DwarfRegNum<[6, 6, 6]>;
|
||||
def R7 : FootRegister<7, "r7">, DwarfRegNum<[7, 7, 7]>;
|
||||
def R8 : FootRegister<8, "r8">, DwarfRegNum<[8, 8, 8]>;
|
||||
def R9 : FootRegister<9, "r9">, DwarfRegNum<[9, 9, 9]>;
|
||||
def R10 : FootRegister<10, "r10">, DwarfRegNum<[10, 10, 10]>;
|
||||
def R11 : FootRegister<11, "r11">, DwarfRegNum<[11, 11, 11]>;
|
||||
def R12 : FootRegister<12, "r12">, DwarfRegNum<[12, 12, 12]>;
|
||||
def R13 : FootRegister<13, "r13">, DwarfRegNum<[13, 13, 13]>;
|
||||
def R14 : FootRegister<14, "r14">, DwarfRegNum<[14, 14, 14]>;
|
||||
def R15 : FootRegister<15, "r15">, DwarfRegNum<[15, 15, 15]>;
|
||||
def R16 : FootRegister<16, "r16">, DwarfRegNum<[16, 16, 16]>;
|
||||
def R17 : FootRegister<17, "r17">, DwarfRegNum<[17, 17, 17]>;
|
||||
def R18 : FootRegister<18, "r18">, DwarfRegNum<[18, 18, 18]>;
|
||||
def R19 : FootRegister<19, "r19">, DwarfRegNum<[19, 19, 19]>;
|
||||
def R20 : FootRegister<20, "r20">, DwarfRegNum<[20, 20, 20]>;
|
||||
def R21 : FootRegister<21, "r21">, DwarfRegNum<[21, 21, 21]>;
|
||||
def R22 : FootRegister<22, "r22">, DwarfRegNum<[22, 22, 22]>;
|
||||
def R23 : FootRegister<23, "r23">, DwarfRegNum<[23, 23, 23]>;
|
||||
def R24 : FootRegister<24, "r24">, DwarfRegNum<[24, 24, 24]>;
|
||||
def R25 : FootRegister<25, "r25">, DwarfRegNum<[25, 25, 25]>;
|
||||
def R26 : FootRegister<26, "r26">, DwarfRegNum<[26, 26, 26]>; /* used by compiler */
|
||||
def R27 : FootRegister<27, "r27">, DwarfRegNum<[27, 27, 27]>; /* used by compiler */
|
||||
def RSP : FootRegister<28, "rsp">, DwarfRegNum<[28, 28, 28]>; /* stack pointer */
|
||||
def RRA : FootRegister<29, "rra">, DwarfRegNum<[29, 29, 29]>; /* return address */
|
||||
def RLC : FootRegister<30, "rlc">, DwarfRegNum<[30, 30, 30]>; /* loop counter */
|
||||
def RPC : FootRegister<31, "rpc">, DwarfRegNum<[31, 31, 31]>; /* program counter */
|
||||
|
||||
def GP32 : RegisterClass<"Foot", [i32], 32, (sequence "R%u", 0, 27)>;
|
||||
def PC32 : RegisterClass<"Foot", [i32], 32, (add RPC)>;
|
||||
|
||||
}
|
||||
46
llvm/lib/Target/Foot/FootRemovePseudoInstructions.cpp
Normal file
46
llvm/lib/Target/Foot/FootRemovePseudoInstructions.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "Foot.h"
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
|
||||
#define DEBUG_TYPE "foot-remove-pseudo-instructions"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
class FootRemovePseudoInstructions : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FootRemovePseudoInstructions() : MachineFunctionPass(ID) {}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
LLVM_DEBUG(dbgs() << "Removing Foot pseudo-instructions from " << MF.getName() << "\n");
|
||||
bool MadeChanges = false;
|
||||
|
||||
for (auto &MBB : MF) {
|
||||
for (auto MI = MBB.begin(); MI != MBB.end();) {
|
||||
if (MI->isPseudo()) {
|
||||
MI = MBB.erase(MI);
|
||||
MadeChanges = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
++MI;
|
||||
}
|
||||
}
|
||||
|
||||
return MadeChanges;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
char FootRemovePseudoInstructions::ID = 0;
|
||||
|
||||
INITIALIZE_PASS(FootRemovePseudoInstructions, DEBUG_TYPE, "Foot remove pseudo-instructions", false, false)
|
||||
|
||||
Pass *llvm::createFootRemovePseudoInstructionsPassForLegacyPM() {
|
||||
return new FootRemovePseudoInstructions();
|
||||
}
|
||||
18
llvm/lib/Target/Foot/FootSubtarget.cpp
Normal file
18
llvm/lib/Target/Foot/FootSubtarget.cpp
Normal 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_SUBTARGETINFO_TARGET_DESC
|
||||
#define GET_SUBTARGETINFO_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), FrameLowering(*this), TLInfo(TM, *this) {}
|
||||
58
llvm/lib/Target/Foot/FootSubtarget.h
Normal file
58
llvm/lib/Target/Foot/FootSubtarget.h
Normal file
@ -0,0 +1,58 @@
|
||||
#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
|
||||
#include "FootGenSubtargetInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetMachine;
|
||||
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 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;
|
||||
}
|
||||
|
||||
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
|
||||
return &SDTgtInfo;
|
||||
}
|
||||
|
||||
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTSUBTARGET_H
|
||||
83
llvm/lib/Target/Foot/FootTargetMachine.cpp
Normal file
83
llvm/lib/Target/Foot/FootTargetMachine.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "Foot.h"
|
||||
#include "FootTargetMachine.h"
|
||||
#include "FootMachineFunctionInfo.h"
|
||||
#include "FootTargetObjectFile.h"
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static const char* FootDataLayoutStr =
|
||||
"e-"
|
||||
"p:32: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;
|
||||
}
|
||||
|
||||
const FootSubtarget *FootTargetMachine::getSubtargetImpl(const Function &F) const {
|
||||
Attribute CPUAttr = F.getFnAttribute("target-cpu");
|
||||
Attribute FSAttr = F.getFnAttribute("target-features");
|
||||
|
||||
StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
|
||||
StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
|
||||
|
||||
if (!SubtargetSingleton) {
|
||||
SubtargetSingleton = std::make_unique<FootSubtarget>(TargetTriple, CPU, FS, *this);
|
||||
}
|
||||
|
||||
return SubtargetSingleton.get();
|
||||
}
|
||||
|
||||
MachineFunctionInfo *
|
||||
FootTargetMachine::createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
|
||||
const TargetSubtargetInfo *STI) const {
|
||||
return new FootMachineFunctionInfo();
|
||||
}
|
||||
|
||||
FootPassConfig::FootPassConfig(TargetMachine &TM, PassManagerBase &PM) :
|
||||
TargetPassConfig(TM, PM) {}
|
||||
|
||||
bool FootPassConfig::addInstSelector() {
|
||||
addPass(createFootISelDAG(getFootTargetMachine()));
|
||||
return false;
|
||||
}
|
||||
|
||||
void FootPassConfig::addIRPasses() {
|
||||
TargetPassConfig::addIRPasses();
|
||||
}
|
||||
|
||||
void FootPassConfig::addPreEmitPass() {
|
||||
addPass(createFootRemovePseudoInstructionsPassForLegacyPM());
|
||||
}
|
||||
|
||||
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFootTarget()
|
||||
{
|
||||
RegisterTargetMachine<FootTargetMachine> X(getTheFootTarget());
|
||||
}
|
||||
47
llvm/lib/Target/Foot/FootTargetMachine.h
Normal file
47
llvm/lib/Target/Foot/FootTargetMachine.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
|
||||
#define LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
|
||||
|
||||
#include "FootSubtarget.h"
|
||||
#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FootTargetMachine : public CodeGenTargetMachineImpl {
|
||||
mutable std::unique_ptr<FootSubtarget> SubtargetSingleton;
|
||||
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;
|
||||
|
||||
const FootSubtarget *getSubtargetImpl(const Function &) const override;
|
||||
|
||||
MachineFunctionInfo *
|
||||
createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
|
||||
const TargetSubtargetInfo *STI) const override;
|
||||
};
|
||||
|
||||
class FootPassConfig : public TargetPassConfig {
|
||||
public:
|
||||
FootPassConfig(TargetMachine &TM, PassManagerBase &PM);
|
||||
|
||||
FootTargetMachine &getFootTargetMachine() const {
|
||||
return getTM<FootTargetMachine>();
|
||||
}
|
||||
|
||||
bool addInstSelector() override;
|
||||
void addIRPasses() override;
|
||||
void addPreEmitPass() override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_FOOTTARGETMACHINE_H
|
||||
5
llvm/lib/Target/Foot/FootTargetObjectFile.cpp
Normal file
5
llvm/lib/Target/Foot/FootTargetObjectFile.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "FootTargetObjectFile.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
FootTargetObjectFileELF::FootTargetObjectFileELF() {}
|
||||
15
llvm/lib/Target/Foot/FootTargetObjectFile.h
Normal file
15
llvm/lib/Target/Foot/FootTargetObjectFile.h
Normal 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
|
||||
14
llvm/lib/Target/Foot/MCTargetDesc/CMakeLists.txt
Normal file
14
llvm/lib/Target/Foot/MCTargetDesc/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
add_llvm_component_library(LLVMFootDesc
|
||||
FootMCAsmBackend.cpp
|
||||
FootMCTargetDesc.cpp
|
||||
FootAsmInfo.cpp
|
||||
FootMCCodeEmitter.cpp
|
||||
FootInstPrinter.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
BinaryFormat
|
||||
Support
|
||||
|
||||
ADD_TO_COMPONENT
|
||||
Foot
|
||||
)
|
||||
9
llvm/lib/Target/Foot/MCTargetDesc/FootAsmInfo.cpp
Normal file
9
llvm/lib/Target/Foot/MCTargetDesc/FootAsmInfo.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "FootAsmInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
FootMCAsmInfoELF::FootMCAsmInfoELF() : MCAsmInfoELF() {
|
||||
SupportsDebugInformation = true;
|
||||
DwarfUsesRelocationsAcrossSections = true;
|
||||
UsesCFIWithoutEH = true;
|
||||
}
|
||||
15
llvm/lib/Target/Foot/MCTargetDesc/FootAsmInfo.h
Normal file
15
llvm/lib/Target/Foot/MCTargetDesc/FootAsmInfo.h
Normal 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
|
||||
54
llvm/lib/Target/Foot/MCTargetDesc/FootInstPrinter.cpp
Normal file
54
llvm/lib/Target/Foot/MCTargetDesc/FootInstPrinter.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#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 if (Op.isExpr()) {
|
||||
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);
|
||||
}
|
||||
32
llvm/lib/Target/Foot/MCTargetDesc/FootInstPrinter.h
Normal file
32
llvm/lib/Target/Foot/MCTargetDesc/FootInstPrinter.h
Normal 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
|
||||
100
llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp
Normal file
100
llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
class FootELFObjectWriter : public MCELFObjectTargetWriter {
|
||||
public:
|
||||
FootELFObjectWriter()
|
||||
: MCELFObjectTargetWriter(false, ELF::ELFOSABI_NONE, ELF::EM_FOOT, true) {
|
||||
}
|
||||
|
||||
bool needsRelocateWithSymbol(const MCValue &Val,
|
||||
unsigned RelTy) const override {
|
||||
switch (RelTy) {
|
||||
case ELF::R_FOOT_CNST16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target,
|
||||
bool IsPcRel) const override {
|
||||
switch (Fixup.getKind()) {
|
||||
case FK_Data_2:
|
||||
return ELF::R_FOOT_CNST16;
|
||||
case FK_Data_4:
|
||||
return ELF::R_FOOT_32;
|
||||
case FK_Data_8:
|
||||
return ELF::R_FOOT_64;
|
||||
default:
|
||||
llvm_unreachable("unsupported relocation");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FootAsmBackend : public MCAsmBackend {
|
||||
Triple TheTriple;
|
||||
|
||||
public:
|
||||
FootAsmBackend(const Triple &TT)
|
||||
: MCAsmBackend(endianness::little), TheTriple(TT) {}
|
||||
|
||||
std::unique_ptr<MCObjectTargetWriter>
|
||||
createObjectTargetWriter() const override {
|
||||
return std::make_unique<FootELFObjectWriter>();
|
||||
}
|
||||
|
||||
void applyFixup(const MCFragment &Frag, const MCFixup &Fixup,
|
||||
const MCValue &Target, uint8_t *Data, uint64_t Value,
|
||||
bool IsResolved) override {
|
||||
switch (Fixup.getKind()) {
|
||||
case FK_Data_1:
|
||||
Data[0] = Value;
|
||||
break;
|
||||
case FK_Data_2:
|
||||
support::endian::write16le(Data, Value);
|
||||
break;
|
||||
case FK_Data_4:
|
||||
support::endian::write32le(Data, Value);
|
||||
break;
|
||||
case FK_Data_8:
|
||||
support::endian::write64le(Data, Value);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsResolved) {
|
||||
maybeAddReloc(Frag, Fixup, Target, Value, IsResolved);
|
||||
}
|
||||
}
|
||||
|
||||
bool writeNopData(raw_ostream &OS, uint64_t Count,
|
||||
const MCSubtargetInfo *STI) const override {
|
||||
for (uint64_t I = 0; I != Count; ++I) {
|
||||
OS.write("\x00\x00\x00\x00", 4);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
MCAsmBackend *llvm::createFootAsmBackend(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
const MCRegisterInfo &,
|
||||
const MCTargetOptions &) {
|
||||
const Triple &TheTriple = STI.getTargetTriple();
|
||||
return new FootAsmBackend(TheTriple);
|
||||
}
|
||||
75
llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp
Normal file
75
llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "MCTargetDesc/FootMCTargetDesc.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Casting.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());
|
||||
}
|
||||
if (MO.isImm()) {
|
||||
return static_cast<unsigned>(MO.getImm());
|
||||
}
|
||||
if (MO.isExpr()) {
|
||||
MCFixupKind FK = FK_Data_2;
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(), FK));
|
||||
return 0;
|
||||
}
|
||||
llvm_unreachable("Unsupported operation type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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"
|
||||
76
llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp
Normal file
76
llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "FootMCTargetDesc.h"
|
||||
#include "FootAsmInfo.h"
|
||||
#include "FootInstPrinter.h"
|
||||
#include "FootTargetObjectFile.h"
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/MC/MCELFStreamer.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;
|
||||
}
|
||||
|
||||
static MCStreamer *createELFStreamer(const Triple &T,
|
||||
MCContext &Ctx,
|
||||
std::unique_ptr<MCAsmBackend> &&TAB,
|
||||
std::unique_ptr<MCObjectWriter> &&OW,
|
||||
std::unique_ptr<MCCodeEmitter> &&Emitter) {
|
||||
return createELFStreamer(Ctx, std::move(TAB), std::move(OW), std::move(Emitter));
|
||||
}
|
||||
|
||||
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);
|
||||
TargetRegistry::RegisterMCCodeEmitter(TheTarget, createFootMCCodeEmitter);
|
||||
TargetRegistry::RegisterMCAsmBackend(TheTarget, createFootAsmBackend);
|
||||
TargetRegistry::RegisterELFStreamer(TheTarget, createELFStreamer);
|
||||
RegisterMCAsmInfoFn X(TheTarget, createFootMCAsmInfo);
|
||||
}
|
||||
36
llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h
Normal file
36
llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
|
||||
#define LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
|
||||
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCContext;
|
||||
class MCCodeEmitter;
|
||||
|
||||
MCCodeEmitter *createFootMCCodeEmitter(const MCInstrInfo &MII,
|
||||
MCContext &MCCtxt);
|
||||
|
||||
MCAsmBackend *createFootAsmBackend(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
const MCRegisterInfo &,
|
||||
const MCTargetOptions &);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#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"
|
||||
|
||||
#endif // LLVM_LIB_TARGET_FOOT_MC_TARGET_DESC_H
|
||||
10
llvm/lib/Target/Foot/TargetInfo/CMakeLists.txt
Normal file
10
llvm/lib/Target/Foot/TargetInfo/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
add_llvm_component_library(LLVMFootInfo
|
||||
FootTargetInfo.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
Support
|
||||
MC
|
||||
|
||||
ADD_TO_COMPONENT
|
||||
Foot
|
||||
)
|
||||
16
llvm/lib/Target/Foot/TargetInfo/FootTargetInfo.cpp
Normal file
16
llvm/lib/Target/Foot/TargetInfo/FootTargetInfo.cpp
Normal 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;
|
||||
}
|
||||
12
llvm/lib/Target/Foot/TargetInfo/FootTargetInfo.h
Normal file
12
llvm/lib/Target/Foot/TargetInfo/FootTargetInfo.h
Normal 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
|
||||
@ -39,6 +39,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
|
||||
case bpfel: return "bpfel";
|
||||
case csky: return "csky";
|
||||
case dxil: return "dxil";
|
||||
case foot: return "foot";
|
||||
case hexagon: return "hexagon";
|
||||
case hsail64: return "hsail64";
|
||||
case hsail: return "hsail";
|
||||
@ -198,6 +199,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
|
||||
case mips64:
|
||||
case mips64el: return "mips";
|
||||
|
||||
case foot: return "foot";
|
||||
|
||||
case hexagon: return "hexagon";
|
||||
|
||||
case amdgcn: return "amdgcn";
|
||||
@ -464,6 +467,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
||||
.Case("riscv64", riscv64)
|
||||
.Case("riscv32be", riscv32be)
|
||||
.Case("riscv64be", riscv64be)
|
||||
.Case("foot", foot)
|
||||
.Case("hexagon", hexagon)
|
||||
.Case("sparc", sparc)
|
||||
.Case("sparcel", sparcel)
|
||||
@ -611,6 +615,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
|
||||
.Case("riscv64", Triple::riscv64)
|
||||
.Case("riscv32be", Triple::riscv32be)
|
||||
.Case("riscv64be", Triple::riscv64be)
|
||||
.Case("foot", Triple::foot)
|
||||
.Case("hexagon", Triple::hexagon)
|
||||
.Cases("s390x", "systemz", Triple::systemz)
|
||||
.Case("sparc", Triple::sparc)
|
||||
@ -960,6 +965,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
|
||||
case Triple::bpfeb:
|
||||
case Triple::bpfel:
|
||||
case Triple::csky:
|
||||
case Triple::foot:
|
||||
case Triple::hexagon:
|
||||
case Triple::hsail64:
|
||||
case Triple::hsail:
|
||||
@ -1681,6 +1687,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
|
||||
return 0;
|
||||
|
||||
case llvm::Triple::avr:
|
||||
case llvm::Triple::foot:
|
||||
case llvm::Triple::msp430:
|
||||
return 16;
|
||||
|
||||
@ -1801,6 +1808,7 @@ Triple Triple::get32BitArchVariant() const {
|
||||
case Triple::armeb:
|
||||
case Triple::csky:
|
||||
case Triple::dxil:
|
||||
case Triple::foot:
|
||||
case Triple::hexagon:
|
||||
case Triple::hsail:
|
||||
case Triple::kalimba:
|
||||
@ -1871,6 +1879,7 @@ Triple Triple::get64BitArchVariant() const {
|
||||
case Triple::avr:
|
||||
case Triple::csky:
|
||||
case Triple::dxil:
|
||||
case Triple::foot:
|
||||
case Triple::hexagon:
|
||||
case Triple::kalimba:
|
||||
case Triple::lanai:
|
||||
@ -1958,6 +1967,7 @@ Triple Triple::getBigEndianArchVariant() const {
|
||||
case Triple::amdil:
|
||||
case Triple::avr:
|
||||
case Triple::dxil:
|
||||
case Triple::foot:
|
||||
case Triple::hexagon:
|
||||
case Triple::hsail64:
|
||||
case Triple::hsail:
|
||||
@ -2071,6 +2081,7 @@ bool Triple::isLittleEndian() const {
|
||||
case Triple::bpfel:
|
||||
case Triple::csky:
|
||||
case Triple::dxil:
|
||||
case Triple::foot:
|
||||
case Triple::hexagon:
|
||||
case Triple::hsail64:
|
||||
case Triple::hsail:
|
||||
|
||||
6
llvm/test/MC/Foot/CNST.s
Normal file
6
llvm/test/MC/Foot/CNST.s
Normal file
@ -0,0 +1,6 @@
|
||||
// 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