From 85073c900631b5c51449a7f16593efb4eb577e20 Mon Sep 17 00:00:00 2001 From: shylie Date: Tue, 28 Oct 2025 12:08:17 -0400 Subject: [PATCH] Support more instructions --- llvm/lib/Target/Foot/FootAsmPrinter.cpp | 7 +- llvm/lib/Target/Foot/FootFrameLowering.cpp | 8 +- llvm/lib/Target/Foot/FootISelDAGToDAG.cpp | 642 +++++++++++++++++- llvm/lib/Target/Foot/FootISelLowering.cpp | 11 +- llvm/lib/Target/Foot/FootISelLowering.h | 3 +- llvm/lib/Target/Foot/FootInstrInfo.td | 2 + .../Foot/MCTargetDesc/FootMCAsmBackend.cpp | 21 +- 7 files changed, 660 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Target/Foot/FootAsmPrinter.cpp b/llvm/lib/Target/Foot/FootAsmPrinter.cpp index 1c46c7f078a8..8ae58baa3959 100644 --- a/llvm/lib/Target/Foot/FootAsmPrinter.cpp +++ b/llvm/lib/Target/Foot/FootAsmPrinter.cpp @@ -2,12 +2,14 @@ #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; @@ -24,6 +26,8 @@ public: bool lowerOperand(const MachineOperand &MO, MCOperand &MCO); void emitInstruction(const MachineInstr *MI) override; + + StringRef getPassName() const override { return "FootAsmPrinter"; } }; } // namespace @@ -41,7 +45,8 @@ bool FootAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCO) { case MachineOperand::MO_FPImmediate: llvm_unreachable("fpimm not yet implemented"); case MachineOperand::MO_MachineBasicBlock: { - const MachineBasicBlock *MBB = MO.getMBB(); + MachineBasicBlock *MBB = MO.getMBB(); + MBB->setLabelMustBeEmitted(); MCSymbol *Label = MBB->getSymbol(); MCO = MCOperand::createExpr(MCSymbolRefExpr::create(Label, OutContext)); break; diff --git a/llvm/lib/Target/Foot/FootFrameLowering.cpp b/llvm/lib/Target/Foot/FootFrameLowering.cpp index b5e92fd5eb57..ca5d07f694ac 100644 --- a/llvm/lib/Target/Foot/FootFrameLowering.cpp +++ b/llvm/lib/Target/Foot/FootFrameLowering.cpp @@ -17,14 +17,14 @@ void FootFrameLowering::emitPrologue(MachineFunction &MF, MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - int FrameIndex = MFI.CreateFixedObject(4, 4, true); + int FrameIndex = MFI.CreateFixedObject(4, -4, true); 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_D_A), Foot::RSP) + BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_M_A), Foot::RSP) .addReg(Foot::RSP) .addImm(NumBytes); } @@ -53,7 +53,7 @@ void FootFrameLowering::emitEpilogue(MachineFunction &MF, if (NumBytes > 0) { const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); if (NumBytes < (1 << 5)) { - BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), TII->get(Foot::ADDI_D_D_D_A), Foot::RSP) + BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), TII->get(Foot::ADDI_D_D_M_A), Foot::RSP) .addReg(Foot::RSP) .addImm(NumBytes); } @@ -69,7 +69,7 @@ void FootFrameLowering::emitEpilogue(MachineFunction &MF, const auto& I = MBB.getFirstTerminator(); BuildMI(MBB, I, I->getDebugLoc(), TII->get(Foot::BWOR_D_I_M_A)) .addReg(Foot::RPC) - .addFrameIndex(-1) + .addFrameIndex(0) .addImm(0); MBB.erase(I); diff --git a/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp b/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp index 3cb8ec397ffe..de9b77bad223 100644 --- a/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp +++ b/llvm/lib/Target/Foot/FootISelDAGToDAG.cpp @@ -27,18 +27,29 @@ private: void SelectStore(SDNode *N, SDLoc &Loc); void SelectAdd(SDNode *N, SDLoc &Loc); void SelectSub(SDNode *N, SDLoc &Loc); + void SelectMul(SDNode *N, SDLoc &Loc); + void SelectSrem(SDNode *N, SDLoc &Loc); + void SelectOr(SDNode *N, SDLoc &Loc); + void SelectAnd(SDNode *N, SDLoc &Loc); + void SelectShl(SDNode *N, SDLoc &Loc); + void SelectSra(SDNode *N, SDLoc &Loc); + void SelectSrl(SDNode *N, SDLoc &Loc); void SelectConstant(SDNode *N, SDLoc &Loc); + void SelectGlobalAddress(SDNode *N, SDLoc &Loc); void SelectFrameIndex(SDNode *N, SDLoc &Loc); void SelectCall(SDNode *N, SDLoc &Loc); void SelectBr(SDNode *N, SDLoc &Loc); - void SelectCmp(SDNode *N, SDLoc &Loc); void SelectBrL(SDNode *N, SDLoc &Loc); void SelectBrLE(SDNode *N, SDLoc &Loc); void SelectBrE(SDNode *N, SDLoc &Loc); void SelectBrGE(SDNode *N, SDLoc &Loc); void SelectBrG(SDNode *N, SDLoc &Loc); + void SelectBrNE(SDNode *N, SDLoc &Loc); + void SelectCmp(SDNode *N, SDLoc &Loc); void Select(SDNode *N) override; + + ConstantSDNode *DoesConstantFitImm(SDNode* N); #include "FootGenDAGISel.inc" }; @@ -103,7 +114,8 @@ void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) { else if (isa(LHS.getNode())) { LHS_AddrMode = FOOT_ADDRMODE_I; } - else if (isa(LHS.getNode())) { + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); LHS_AddrMode = FOOT_ADDRMODE_M; } @@ -115,7 +127,8 @@ void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) { else if (isa(RHS.getNode())) { RHS_AddrMode = FOOT_ADDRMODE_I; } - else if (isa(RHS.getNode())) { + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); RHS_AddrMode = FOOT_ADDRMODE_M; } @@ -153,27 +166,547 @@ void FootDAGToDAGISel::SelectAdd(SDNode *N, SDLoc &Loc) { } void FootDAGToDAGISel::SelectSub(SDNode *N, SDLoc &Loc) { - llvm_unreachable("not yet implemented"); + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::SUBT_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::SUBT_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SUBT_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::SUBT_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SUBT_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::SUBT_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::SUBT_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SUBT_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectMul(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::MULT_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::MULT_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MULT_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::MULT_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MULT_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::MULT_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::MULT_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MULT_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectSrem(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::MODU_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::MODU_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MODU_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::MODU_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MODU_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::MODU_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::MODU_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::MODU_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectOr(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::BWOR_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::BWOR_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BWOR_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::BWOR_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BWOR_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::BWOR_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::BWOR_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BWOR_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectAnd(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::BAND_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::BAND_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BAND_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::BAND_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BAND_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::BAND_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::BAND_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::BAND_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectShl(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::ZLSH_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::ZLSH_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZLSH_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::ZLSH_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZLSH_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::ZLSH_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::ZLSH_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZLSH_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectSra(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::SRSH_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::SRSH_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SRSH_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::SRSH_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SRSH_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::SRSH_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::SRSH_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::SRSH_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); +} + +void FootDAGToDAGISel::SelectSrl(SDNode *N, SDLoc &Loc) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(LHS.getNode())) { + LHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (isa(RHS.getNode())) { + RHS_AddrMode = FOOT_ADDRMODE_I; + } + else if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::ZRSH_D_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::ZRSH_D_D_M_A; + break; + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZRSH_D_D_I_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::ZRSH_D_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZRSH_D_M_I_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::ZRSH_D_I_D_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::ZRSH_D_I_M_A; + break; + case FOOT_ADDRMODE_I + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_I: + Opc = Foot::ZRSH_D_I_I_A; + break; + } + + SDValue Ops[] = { LHS, RHS }; + + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::i32, Ops); + + ReplaceNode(N, NewNode); } void FootDAGToDAGISel::SelectConstant(SDNode *N, SDLoc &Loc) { + assert(isa(N) && "expected constant node"); ConstantSDNode *CN = cast(N); SDNode *NewNode; - if (CN->getSExtValue() > 0xFFFF) { - SDValue Val = CurDAG->getTargetConstantPool(CN->getConstantIntValue(), MVT::i32); - SDNode *Addr = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Val); + + int64_t Val = CN->getSExtValue(); + assert(Val >= -static_cast(0xFFFFFFFF) && Val <= 0xFFFFFFFF && "Constant too large!"); + + Val &= 0xFFFFFFFF; + + if (Val > 0xFFFF) { + APInt Adjusted(32, Val); + ConstantInt *CI = ConstantInt::get(*CurDAG->getContext(), Adjusted); + SDValue TgtVal = CurDAG->getTargetConstantPool(CI, MVT::i32); + SDNode *Addr = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, TgtVal); 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); - NewNode = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, Val); + SDValue TgtVal = CurDAG->getTargetConstant(Val, Loc, MVT::i32); + NewNode = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, TgtVal); } ReplaceNode(N, NewNode); } +void FootDAGToDAGISel::SelectGlobalAddress(SDNode *N, SDLoc &Loc) { + assert(isa(N) && "expected global address"); + GlobalAddressSDNode *GAN = cast(N); + + SDValue TgtGA = CurDAG->getTargetGlobalAddress(GAN->getGlobal(), Loc, MVT::i32); + + SDNode *NewNode = CurDAG->getMachineNode(Foot::CNST_D_A, Loc, MVT::i32, TgtGA); + + ReplaceNode(N, NewNode); +} + void FootDAGToDAGISel::SelectFrameIndex(SDNode *N, SDLoc &Loc) { assert(N->getOpcode() == ISD::FrameIndex && "expected frame index"); @@ -188,8 +721,13 @@ 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 RRA = CurDAG->getRegister(Foot::RRA, MVT::i32); + SDValue One = CurDAG->getTargetConstant(1, Loc, MVT::i32); - SDValue Ops[] = { RPC, Callee, Chain }; + SDValue CopyOps[] = { RRA, RPC, One, Chain }; + SDNode *CopyToRA = CurDAG->getMachineNode(Foot::ADDI_STR_D_D_M_A, Loc, MVT::Other, CopyOps); + + SDValue Ops[] = { RPC, Callee, SDValue(CopyToRA, 0) }; SDNode *Jump = CurDAG->getMachineNode(Foot::CNST_JMP_D_A, Loc, {MVT::Other, MVT::Glue}, Ops); ReplaceNode(N, Jump); @@ -297,12 +835,58 @@ void FootDAGToDAGISel::SelectBrG(SDNode *N, SDLoc &Loc) { ReplaceNode(N, NewNode); } +void FootDAGToDAGISel::SelectBrNE(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); + + SDNode *NewNode; + if (isa(Target.getNode()) || isa(Target.getNode())) { + NewNode = CurDAG->getMachineNode(Foot::CNST_JMP_D_NE, Loc, MVT::Other, {PC, Target, Chain}); + } + else { + NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_NE, Loc, MVT::Other, {PC, Target, Zero, Chain}); + } + + ReplaceNode(N, NewNode); +} + void FootDAGToDAGISel::SelectCmp(SDNode *N, SDLoc &Loc) { SDValue Chain = N->getOperand(0); SDValue LHS = N->getOperand(1); SDValue RHS = N->getOperand(2); - SDNode *NewNode = CurDAG->getMachineNode(Foot::CMPR_D_D_A, Loc, MVT::Other, {LHS, RHS, Chain}); + int LHS_AddrMode = FOOT_ADDRMODE_D; + + if (ConstantSDNode *CN = DoesConstantFitImm(LHS.getNode())) { + LHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + LHS_AddrMode = FOOT_ADDRMODE_M; + } + + int RHS_AddrMode = FOOT_ADDRMODE_D; + + if (ConstantSDNode *CN = DoesConstantFitImm(RHS.getNode())) { + RHS = CurDAG->getTargetConstant(CN->getSExtValue(), Loc, MVT::i32); + RHS_AddrMode = FOOT_ADDRMODE_M; + } + + unsigned Opc = Foot::CMPR_D_D_A; + + switch (LHS_AddrMode + FOOT_ADDRMODE_COUNT * RHS_AddrMode) { + case FOOT_ADDRMODE_D + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::CMPR_D_M_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_D: + Opc = Foot::CMPR_M_D_A; + break; + case FOOT_ADDRMODE_M + FOOT_ADDRMODE_COUNT * FOOT_ADDRMODE_M: + Opc = Foot::CMPR_M_M_A; + break; + } + + // TODO: investigate cause of binary errors, and fix operand order + SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::Other, {RHS, LHS, Chain}); ReplaceNode(N, NewNode); } @@ -327,9 +911,33 @@ void FootDAGToDAGISel::Select(SDNode *N) { case ISD::SUB: SelectSub(N, DL); break; + case ISD::MUL: + SelectMul(N, DL); + break; + case ISD::SREM: + SelectSrem(N, DL); + break; + case ISD::OR: + SelectOr(N, DL); + break; + case ISD::AND: + SelectAnd(N, DL); + break; + case ISD::SHL: + SelectShl(N, DL); + break; + case ISD::SRA: + SelectSra(N, DL); + break; + case ISD::SRL: + SelectSrl(N, DL); + break; case ISD::Constant: SelectConstant(N, DL); break; + case ISD::GlobalAddress: + SelectGlobalAddress(N, DL); + break; case ISD::FrameIndex: SelectFrameIndex(N, DL); break; @@ -354,6 +962,9 @@ void FootDAGToDAGISel::Select(SDNode *N) { case FootISD::BR_G: SelectBrG(N, DL); break; + case FootISD::BR_NE: + SelectBrNE(N, DL); + break; case FootISD::CMP: SelectCmp(N, DL); break; @@ -363,6 +974,15 @@ void FootDAGToDAGISel::Select(SDNode *N) { } } +ConstantSDNode *FootDAGToDAGISel::DoesConstantFitImm(SDNode *N) { + if (ConstantSDNode *CN = dyn_cast(N)) { + if (CN->getSExtValue() >= 0 && CN->getSExtValue() < 32) { + return CN; + } + } + return nullptr; +} + char FootDAGToDAGISelLegacy::ID = 0; Pass *llvm::createFootISelDAG(FootTargetMachine &TM) { diff --git a/llvm/lib/Target/Foot/FootISelLowering.cpp b/llvm/lib/Target/Foot/FootISelLowering.cpp index f904acf84c31..206394b52951 100644 --- a/llvm/lib/Target/Foot/FootISelLowering.cpp +++ b/llvm/lib/Target/Foot/FootISelLowering.cpp @@ -17,8 +17,8 @@ FootTargetLowering::FootTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ADD, MVT::i32, Legal); setOperationAction(ISD::SUB, MVT::i32, Legal); setOperationAction(ISD::MUL, MVT::i32, Legal); - setOperationAction(ISD::UDIV, MVT::i32, Legal); - setOperationAction(ISD::UREM, 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); @@ -28,8 +28,11 @@ FootTargetLowering::FootTargetLowering(const TargetMachine &TM, 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::ADD, MVT::v2i16, Legal); setOperationAction(ISD::SUB, MVT::v2i16, Legal); @@ -361,6 +364,10 @@ SDValue FootTargetLowering::LowerBrCC(SDValue Op, SelectionDAG &DAG) const { 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"); diff --git a/llvm/lib/Target/Foot/FootISelLowering.h b/llvm/lib/Target/Foot/FootISelLowering.h index 62249aec4dc3..a37d3d8a3b04 100644 --- a/llvm/lib/Target/Foot/FootISelLowering.h +++ b/llvm/lib/Target/Foot/FootISelLowering.h @@ -15,7 +15,8 @@ enum NodeType : unsigned { BR_LE, BR_E, BR_GE, - BR_G + BR_G, + BR_NE }; } // namespace FootISD diff --git a/llvm/lib/Target/Foot/FootInstrInfo.td b/llvm/lib/Target/Foot/FootInstrInfo.td index 615ab08fc613..9c421964c063 100644 --- a/llvm/lib/Target/Foot/FootInstrInfo.td +++ b/llvm/lib/Target/Foot/FootInstrInfo.td @@ -35,6 +35,7 @@ defm CONF : FootInstructionB<"CONF", 0b00000100, (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)>; @@ -50,6 +51,7 @@ defm ADDI_JMP : FootInstructionC<"ADDI", 0b0010, (outs), (ins PC32:$dst, GP32:$a } 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), diff --git a/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp b/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp index bbe74557f241..d4d8e457287a 100644 --- a/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp +++ b/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp @@ -52,23 +52,14 @@ public: void applyFixup(const MCFragment &Frag, const MCFixup &Fixup, const MCValue &Target, uint8_t* Data, uint64_t Value, bool IsResolved) override { - unsigned Offset = Fixup.getOffset(); - unsigned Kind = Fixup.getKind(); - - if (Value == 0) { return; } + if (Value == 0 && !Target.getAddSym()->isInSection()) { + errs() << Fixup.getOffset() << "\n"; + errs() << Target.getAddSym()->getName() << " skipped\n"; + errs() << (Target.getAddSym()->isTemporary() ? "temp" : "not temp") << "\n"; + 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,