Runs in the emulator now
This commit is contained in:
parent
77be592768
commit
12cdefd2b9
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;
|
||||
|
||||
@ -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.
|
||||
|
||||
7
llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def
Normal file
7
llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def
Normal 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)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ public:
|
||||
|
||||
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||
|
||||
private:
|
||||
SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user