Support more instructions
This commit is contained in:
parent
12cdefd2b9
commit
85073c9006
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<GlobalAddressSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<ConstantSDNode>(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<GlobalAddressSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<ConstantSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(LHS.getNode())) {
|
||||
LHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<FrameIndexSDNode>(RHS.getNode())) {
|
||||
RHS_AddrMode = FOOT_ADDRMODE_I;
|
||||
}
|
||||
else if (isa<GlobalAddressSDNode>(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<ConstantSDNode>(N) && "expected constant node");
|
||||
ConstantSDNode *CN = cast<ConstantSDNode>(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<int64_t>(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<GlobalAddressSDNode>(N) && "expected global address");
|
||||
GlobalAddressSDNode *GAN = cast<GlobalAddressSDNode>(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<BasicBlockSDNode>(Target.getNode()) || isa<GlobalAddressSDNode>(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<ConstantSDNode>(N)) {
|
||||
if (CN->getSExtValue() >= 0 && CN->getSExtValue() < 32) {
|
||||
return CN;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char FootDAGToDAGISelLegacy::ID = 0;
|
||||
|
||||
Pass *llvm::createFootISelDAG(FootTargetMachine &TM) {
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -15,7 +15,8 @@ enum NodeType : unsigned {
|
||||
BR_LE,
|
||||
BR_E,
|
||||
BR_GE,
|
||||
BR_G
|
||||
BR_G,
|
||||
BR_NE
|
||||
};
|
||||
|
||||
} // namespace FootISD
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user