Runs in the emulator now

This commit is contained in:
shylie 2025-10-25 22:30:05 -04:00
parent 77be592768
commit 12cdefd2b9
18 changed files with 253 additions and 109 deletions

64
lld/ELF/Arch/Foot.cpp Normal file
View 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));
}

View File

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

View File

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

View File

@ -198,6 +198,7 @@ void setSPARCV9TargetInfo(Ctx &);
void setSystemZTargetInfo(Ctx &);
void setX86TargetInfo(Ctx &);
void setX86_64TargetInfo(Ctx &);
void setFootTargetInfo(Ctx &);
struct ErrorPlace {
InputSectionBase *isec;

View File

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

View File

@ -0,0 +1,7 @@
#ifndef ELF_RELOC
#error "ELF_RELOC must be defined"
#endif
ELF_RELOC(R_FOOT_NONE, 0)
ELF_RELOC(R_FOOT_CNST16, 1)

View File

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

View File

@ -1,5 +1,6 @@
#include "MCTargetDesc/FootMCTargetDesc.h"
#include "TargetInfo/FootTargetInfo.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/Constants.h"
#include "llvm/MC/MCContext.h"
@ -47,14 +48,24 @@ bool FootAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCO) {
}
case MachineOperand::MO_FrameIndex:
llvm_unreachable("frame index not yet implemented");
case MachineOperand::MO_ConstantPoolIndex:
llvm_unreachable("constant pool index not yet implemented");
case MachineOperand::MO_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:
llvm_unreachable("external symbol 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);

View File

@ -56,15 +56,12 @@ void FootDAGToDAGISel::SelectLoad(SDNode *N, SDLoc &Loc) {
SDValue Addr = LN->getBasePtr();
SDValue Chain = LN->getChain();
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Addr)) {
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Addr.getNode())) {
Addr = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
}
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Ops[] = { Addr, Zero, Chain };
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_D_I_M_A, Loc, {MVT::i32, MVT::Other}, Ops);
@ -78,34 +75,20 @@ void FootDAGToDAGISel::SelectStore(SDNode *N, SDLoc &Loc) {
SDValue Addr = SN->getBasePtr();
SDValue Chain = SN->getChain();
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Addr)) {
Addr = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
}
SDValue CopyOps[] = { Addr, Chain };
CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, CopyOps);
SDNode *Store;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val)) {
SDValue Imm = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
SDValue Ops[] = { Imm };
Store = CurDAG->getMachineNode(Foot::CNST_I_A, Loc, MVT::i32, Ops);
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode())) {
Val = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
SDValue Ops[] = { Addr, Val, Chain };
Store = CurDAG->getMachineNode(Foot::CNST_STR_I_A, Loc, MVT::Other, Ops);
}
else {
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Ops[] = { Val, Zero };
Store = CurDAG->getMachineNode(Foot::BWOR_I_D_M_A, Loc, MVT::i32, Ops);
SDValue Ops[] = { Addr, Val, Zero, Chain };
Store = CurDAG->getMachineNode(Foot::BWOR_STR_I_D_M_A, Loc, MVT::Other, Ops);
}
SDValue FakeStoreOps[] = { SDValue(Store, 0) };
SDNode* FakeStore = CurDAG->getMachineNode(Foot::PSEUDO_STORE, Loc, MVT::Other, FakeStoreOps);
ReplaceNode(N, FakeStore);
ReplaceNode(N, Store);
}
void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) {
@ -114,31 +97,25 @@ void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) {
int LHS_AddrMode = FOOT_ADDRMODE_D;
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(LHS)) {
LHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
if (isa<FrameIndexSDNode>(LHS.getNode())) {
LHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(LHS)) {
LHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
else if (isa<GlobalAddressSDNode>(LHS.getNode())) {
LHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(LHS)) {
LHS = CurDAG->getTargetConstant(CN->getZExtValue(), Loc, MVT::i32);
else if (isa<ConstantSDNode>(LHS.getNode())) {
LHS_AddrMode = FOOT_ADDRMODE_M;
}
int RHS_AddrMode = FOOT_ADDRMODE_D;
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(RHS)) {
RHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
if (isa<FrameIndexSDNode>(RHS.getNode())) {
RHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(RHS)) {
RHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32);
else if (isa<GlobalAddressSDNode>(RHS.getNode())) {
RHS_AddrMode = FOOT_ADDRMODE_I;
}
else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS)) {
RHS = CurDAG->getTargetConstant(CN->getZExtValue(), Loc, MVT::i32);
else if (isa<ConstantSDNode>(RHS.getNode())) {
RHS_AddrMode = FOOT_ADDRMODE_M;
}
@ -184,14 +161,10 @@ void FootDAGToDAGISel::SelectConstant(SDNode *N, SDLoc &Loc) {
SDNode *NewNode;
if (CN->getSExtValue() > 0xFFFF) {
SDValue Upper16 = CurDAG->getTargetConstant((CN->getSExtValue() & 0xFFFF0000) >> 16, Loc, MVT::i32);
SDValue Lower16 = CurDAG->getTargetConstant(CN->getSExtValue() & 0x0000FFFF, Loc, MVT::i32);
SDValue Sixteen = CurDAG->getTargetConstant(16, Loc, MVT::i32);
SDNode *Upper = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Upper16);
SDNode *Lower = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Lower16);
SDNode *UpperShifted = CurDAG->getMachineNode(Foot::ZLSH_D_D_M_A, Loc, MVT::i32, {SDValue(Upper, 0), Sixteen});
NewNode = CurDAG->getMachineNode(Foot::BWOR_D_D_D_A, Loc, MVT::i32, {SDValue(UpperShifted, 0), SDValue(Lower, 0)});
SDValue Val = CurDAG->getTargetConstantPool(CN->getConstantIntValue(), MVT::i32);
SDNode *Addr = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Val);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
NewNode = CurDAG->getMachineNode(Foot::BWOR_D_I_M_A, Loc, MVT::i32, {SDValue(Addr, 0), Zero});
}
else {
SDValue Val = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32);
@ -214,12 +187,10 @@ void FootDAGToDAGISel::SelectFrameIndex(SDNode *N, SDLoc &Loc) {
void FootDAGToDAGISel::SelectCall(SDNode *N, SDLoc &Loc) {
SDValue Chain = N->getOperand(0);
SDValue Callee = N->getOperand(1);
SDValue RPC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Ops[] = { RPC, Callee, Chain };
SDNode *Jump = CurDAG->getMachineNode(Foot::CNST_JMP_I_A, Loc, {MVT::Other, MVT::Glue}, Ops);
SDNode *Jump = CurDAG->getMachineNode(Foot::CNST_JMP_D_A, Loc, {MVT::Other, MVT::Glue}, Ops);
ReplaceNode(N, Jump);
}
@ -228,69 +199,100 @@ void FootDAGToDAGISel::SelectBr(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue MBB = N->getOperand(1);
SDValue Target = N->getOperand(1);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_A, Loc, MVT::Other, {PC, MBB, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_A, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_A, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectBrL(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue Target = N->getOperand(1);
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_L, Loc, MVT::Other, {PC, Target, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_L, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_L, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectBrLE(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue Target = N->getOperand(1);
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_LE, Loc, MVT::Other, {PC, Target, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_LE, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_LE, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectBrE(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue Target = N->getOperand(1);
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_E, Loc, MVT::Other, {PC, Target, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_E, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_E, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectBrGE(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue Target = N->getOperand(1);
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_GE, Loc, MVT::Other, {PC, Target, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_GE, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_GE, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}
void FootDAGToDAGISel::SelectBrG(SDNode *N, SDLoc &Loc) {
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDValue Chain = N->getOperand(0);
SDValue Target = N->getOperand(1);
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
SDNode *NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_G, Loc, MVT::Other, {PC, Target, Zero, Chain});
SDNode *NewNode;
if (isa<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(Target.getNode())) {
NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_G, Loc, MVT::Other, {PC, Target, Chain});
}
else {
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_G, Loc, MVT::Other, {PC, Target, Zero, Chain});
}
ReplaceNode(N, NewNode);
}

View File

@ -260,9 +260,6 @@ SDValue FootTargetLowering::LowerCall(CallLoweringInfo &CLI, SmallVectorImpl<SDV
else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
}
else if (BlockAddressSDNode *B = dyn_cast<BlockAddressSDNode>(Callee)) {
Callee = DAG.getTargetBlockAddress(B->getBlockAddress(), MVT::i32);
}
else {
report_fatal_error("Other calls not supported");
}

View File

@ -48,6 +48,7 @@ public:
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
private:
SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const;
};

View File

@ -216,10 +216,10 @@ class _FootInstructionC<string asm, string operands,
let Inst{28} = repeat;
let Inst{27-24} = opcode;
let Inst{23} = Vect{1};
let Inst{22-21} = dstmode;
let Inst{22-21} = bmode;
let Inst{20-16} = dst;
let Inst{15} = 0b0;
let Inst{14-13} = bmode;
let Inst{14-13} = dstmode;
let Inst{12-8} = b;
let Inst{7} = Vect{0};
let Inst{6-5} = amode;

View File

@ -21,7 +21,10 @@ defm CNST_D : FootInstructionA<"CNST.d", "$dst, $imm", 0b0000, 0b01, (outs GP32:
defm CNST_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs GP32:$dst), (ins i16imm:$imm)>;
defm CNST_A : FootInstructionA<"CNST.a", "$dst, $imm", 0b0000, 0b11, (outs GP32:$dst), (ins i16imm:$imm)>;
defm CNST_JMP_I : FootInstructionA<"CNST.i", "$dst, $imm", 0b0000, 0b10, (outs), (ins PC32:$dst, i16imm:$imm)>;
let isBranch = 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)>;
@ -45,6 +48,8 @@ let isBranch = 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)>;
}
let OutOperandList = (outs),
@ -56,14 +61,6 @@ let OutOperandList = (outs),
def PSEUDO_RET : StandardPseudoInstruction;
}
let OutOperandList = (outs),
InOperandList = (ins GP32:$a),
mayStore = 1,
isCodeGenOnly = 1,
Namespace = "Foot" in {
def PSEUDO_STORE : StandardPseudoInstruction;
}
let Defs = [RSP], Uses = [RSP],
isCodeGenOnly = 1, Namespace = "Foot",
OutOperandList = (outs),

View File

@ -2,9 +2,12 @@
#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"
#include "llvm/BinaryFormat/ELF.h"
using namespace llvm;
@ -13,10 +16,24 @@ namespace {
class FootELFObjectWriter : public MCELFObjectTargetWriter {
public:
FootELFObjectWriter()
: MCELFObjectTargetWriter(false, ELF::ELFOSABI_NONE, 0, false) {}
: 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 {
return Reloc::Static;
switch (Fixup.getKind()) {
case FK_Data_2:
return ELF::R_FOOT_CNST16;
default:
return ELF::R_FOOT_NONE;
}
}
};
@ -32,9 +49,27 @@ public:
return std::make_unique<FootELFObjectWriter>();
}
void applyFixup(const MCFragment &, const MCFixup &Fixup,
void applyFixup(const MCFragment &Frag, const MCFixup &Fixup,
const MCValue &Target, uint8_t* Data, uint64_t Value,
bool IsResolved) override {}
bool IsResolved) override {
unsigned Offset = Fixup.getOffset();
unsigned Kind = Fixup.getKind();
if (Value == 0) { return; }
maybeAddReloc(Frag, Fixup, Target, Value, IsResolved);
MCFixupKindInfo Info = getFixupKindInfo(Kind);
unsigned NumBits = Info.TargetSize;
uint64_t Mask = (1u << NumBits) - 1; // no need to handle 64-bit case, Foot is a 32-bit architecture
assert(Value % 4 == 0 && "invalid fixup value");
Value /= 4; // foot is 32-bit addressable
Value &= Mask;
support::endian::write16le(&Data[Offset], Value);
}
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override {

View File

@ -4,7 +4,10 @@
#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>
@ -23,22 +26,22 @@ public:
~FootMCCodeEmitter() override = default;
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
};
} // namespace
MCCodeEmitter *llvm::createFootMCCodeEmitter(const MCInstrInfo &MCII,
MCContext &MCCtxt) {
MCContext &MCCtxt) {
return new FootMCCodeEmitter(MCCtxt);
}
@ -53,20 +56,19 @@ unsigned FootMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand
}
if (MO.isExpr()) {
MCFixupKind FK = FK_Data_2;
Fixups.push_back(MCFixup::create(2, MO.getExpr(), FK));
Fixups.push_back(MCFixup::create(0, MO.getExpr(), FK));
return 0;
}
assert(MO.isImm() && "Unsupported operand type");
llvm_unreachable("Unsupported operation type");
return 0;
}
void FootMCCodeEmitter::encodeInstruction(const MCInst &MI,
SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
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");
assert(((Encoding & 0xffffffff00000000) == 0) && "Only the first 32 bits should be set");
support::endian::write<uint32_t>(CB, Encoding, llvm::endianness::little);
}

View File

@ -4,6 +4,7 @@
#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"
@ -53,6 +54,14 @@ static MCInstPrinter *createFootMCInstPrinter(const Triple &T,
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);
@ -61,5 +70,6 @@ extern "C" LLVM_C_ABI void LLVMInitializeFootTargetMC() {
TargetRegistry::RegisterMCInstPrinter(TheTarget, createFootMCInstPrinter);
TargetRegistry::RegisterMCCodeEmitter(TheTarget, createFootMCCodeEmitter);
TargetRegistry::RegisterMCAsmBackend(TheTarget, createFootAsmBackend);
TargetRegistry::RegisterELFStreamer(TheTarget, createELFStreamer);
RegisterMCAsmInfoFn X(TheTarget, createFootMCAsmInfo);
}

View File

@ -4,6 +4,7 @@
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/MC/MCFixup.h"
#include <cstdint>

View File

@ -945,7 +945,6 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::aarch64:
case Triple::aarch64_32:
case Triple::arm:
case Triple::foot:
case Triple::thumb:
case Triple::x86:
case Triple::x86_64:
@ -966,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: