diff --git a/lld/ELF/Arch/Foot.cpp b/lld/ELF/Arch/Foot.cpp new file mode 100644 index 000000000000..8648ffd287ea --- /dev/null +++ b/lld/ELF/Arch/Foot.cpp @@ -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)); +} diff --git a/lld/ELF/CMakeLists.txt b/lld/ELF/CMakeLists.txt index ec3f6382282b..b1ade1d2a21a 100644 --- a/lld/ELF/CMakeLists.txt +++ b/lld/ELF/CMakeLists.txt @@ -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 diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 4946484074d0..88b06b88978e 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.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; } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index e121fa1183e9..ab7fcc0697d3 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -198,6 +198,7 @@ void setSPARCV9TargetInfo(Ctx &); void setSystemZTargetInfo(Ctx &); void setX86TargetInfo(Ctx &); void setX86_64TargetInfo(Ctx &); +void setFootTargetInfo(Ctx &); struct ErrorPlace { InputSectionBase *isec; diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 749971e354f6..f133852209be 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -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. diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def new file mode 100644 index 000000000000..f34e842ba57d --- /dev/null +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/Foot.def @@ -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) diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 788c6020a7f9..05ac62806a56 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -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; } diff --git a/llvm/lib/Target/Foot/FootAsmPrinter.cpp b/llvm/lib/Target/Foot/FootAsmPrinter.cpp index f61cc3188ead..1c46c7f078a8 100644 --- a/llvm/lib/Target/Foot/FootAsmPrinter.cpp +++ b/llvm/lib/Target/Foot/FootAsmPrinter.cpp @@ -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); diff --git a/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp b/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp index 3abb52d3ee25..3cb8ec397ffe 100644 --- a/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp +++ b/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp @@ -56,15 +56,12 @@ void FootDAGToDAGISel::SelectLoad(SDNode *N, SDLoc &Loc) { SDValue Addr = LN->getBasePtr(); SDValue Chain = LN->getChain(); - if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { - Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - } - else if (GlobalAddressSDNode *GAN = dyn_cast(Addr)) { + SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32); + + if (GlobalAddressSDNode *GAN = dyn_cast(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(Addr)) { - Addr = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - } - else if (GlobalAddressSDNode *GAN = dyn_cast(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(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(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(LHS)) { - LHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); + if (isa(LHS.getNode())) { LHS_AddrMode = FOOT_ADDRMODE_I; } - else if (GlobalAddressSDNode *GAN = dyn_cast(LHS)) { - LHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32); + else if (isa(LHS.getNode())) { LHS_AddrMode = FOOT_ADDRMODE_I; } - else if (ConstantSDNode *CN = dyn_cast(LHS)) { - LHS = CurDAG->getTargetConstant(CN->getZExtValue(), Loc, MVT::i32); + else if (isa(LHS.getNode())) { LHS_AddrMode = FOOT_ADDRMODE_M; } int RHS_AddrMode = FOOT_ADDRMODE_D; - if (FrameIndexSDNode *FIN = dyn_cast(RHS)) { - RHS = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); + if (isa(RHS.getNode())) { RHS_AddrMode = FOOT_ADDRMODE_I; } - else if (GlobalAddressSDNode *GAN = dyn_cast(RHS)) { - RHS = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32); + else if (isa(RHS.getNode())) { RHS_AddrMode = FOOT_ADDRMODE_I; } - else if (ConstantSDNode *CN = dyn_cast(RHS)) { - RHS = CurDAG->getTargetConstant(CN->getZExtValue(), Loc, MVT::i32); + else if (isa(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(Target.getNode()) || isa(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(Target.getNode()) || isa(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(Target.getNode()) || isa(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(Target.getNode()) || isa(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(Target.getNode()) || isa(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(Target.getNode()) || isa(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); } diff --git a/llvm/lib/Target/Foot/FootISelLowering.cpp b/llvm/lib/Target/Foot/FootISelLowering.cpp index 59d4fdcf8d01..f904acf84c31 100644 --- a/llvm/lib/Target/Foot/FootISelLowering.cpp +++ b/llvm/lib/Target/Foot/FootISelLowering.cpp @@ -260,9 +260,6 @@ SDValue FootTargetLowering::LowerCall(CallLoweringInfo &CLI, SmallVectorImpl(Callee)) { Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); } - else if (BlockAddressSDNode *B = dyn_cast(Callee)) { - Callee = DAG.getTargetBlockAddress(B->getBlockAddress(), MVT::i32); - } else { report_fatal_error("Other calls not supported"); } diff --git a/llvm/lib/Target/Foot/FootISelLowering.h b/llvm/lib/Target/Foot/FootISelLowering.h index 68faea438dbd..62249aec4dc3 100644 --- a/llvm/lib/Target/Foot/FootISelLowering.h +++ b/llvm/lib/Target/Foot/FootISelLowering.h @@ -48,6 +48,7 @@ public: SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; +private: SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const; }; diff --git a/llvm/lib/Target/Foot/FootInstrFormats.td b/llvm/lib/Target/Foot/FootInstrFormats.td index f63b028ee4cc..d389fa71305d 100644 --- a/llvm/lib/Target/Foot/FootInstrFormats.td +++ b/llvm/lib/Target/Foot/FootInstrFormats.td @@ -216,10 +216,10 @@ class _FootInstructionC; 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), diff --git a/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp b/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp index 23fbb0166fcb..bbe74557f241 100644 --- a/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp +++ b/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp @@ -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(); } - 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 { diff --git a/llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp b/llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp index e86b2fccf2df..babed1d4368b 100644 --- a/llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp +++ b/llvm/lib/Target/Foot/MCTargetDesc/FootMCCodeEmitter.cpp @@ -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 @@ -23,22 +26,22 @@ public: ~FootMCCodeEmitter() override = default; uint64_t getBinaryCodeForInstr(const MCInst &MI, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; void encodeInstruction(const MCInst &MI, SmallVectorImpl &CB, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const override; + SmallVectorImpl &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 &CB, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { + SmallVectorImpl &CB, + SmallVectorImpl &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(CB, Encoding, llvm::endianness::little); } diff --git a/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp b/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp index 2f03c3010194..41a029e481ba 100644 --- a/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp +++ b/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.cpp @@ -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 &&TAB, + std::unique_ptr &&OW, + std::unique_ptr &&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); } diff --git a/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h b/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h index 1ae51b362b6a..0602aa8019e2 100644 --- a/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h +++ b/llvm/lib/Target/Foot/MCTargetDesc/FootMCTargetDesc.h @@ -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 diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index b9bd10003d1a..68e8b692bf14 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -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: