Fix br_cc
This commit is contained in:
parent
85073c9006
commit
429540e1c6
@ -45,7 +45,9 @@ private:
|
||||
void SelectBrGE(SDNode *N, SDLoc &Loc);
|
||||
void SelectBrG(SDNode *N, SDLoc &Loc);
|
||||
void SelectBrNE(SDNode *N, SDLoc &Loc);
|
||||
void SelectCmpChain(SDNode *N, SDLoc &Loc);
|
||||
void SelectCmp(SDNode *N, SDLoc &Loc);
|
||||
void SelectSelectCC(SDNode *N, SDLoc &Loc);
|
||||
|
||||
void Select(SDNode *N) override;
|
||||
|
||||
@ -733,126 +735,7 @@ void FootDAGToDAGISel::SelectCall(SDNode *N, SDLoc &Loc) {
|
||||
ReplaceNode(N, Jump);
|
||||
}
|
||||
|
||||
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 Target = N->getOperand(1);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
void FootDAGToDAGISel::SelectCmpChain(SDNode *N, SDLoc &Loc) {
|
||||
SDValue Chain = N->getOperand(0);
|
||||
SDValue LHS = N->getOperand(1);
|
||||
SDValue RHS = N->getOperand(2);
|
||||
@ -885,12 +768,215 @@ void FootDAGToDAGISel::SelectCmp(SDNode *N, SDLoc &Loc) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: investigate cause of binary errors, and fix operand order
|
||||
// swap LHS and RHS, as dst is 'b' operand, so it should be first
|
||||
SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::Other, {RHS, LHS, Chain});
|
||||
|
||||
ReplaceNode(N, NewNode);
|
||||
}
|
||||
|
||||
void FootDAGToDAGISel::SelectCmp(SDNode *N, SDLoc &Loc) {
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// swap LHS and RHS, as dst is 'b' operand, so it should be first
|
||||
SDNode *NewNode = CurDAG->getMachineNode(Opc, Loc, MVT::Other, {RHS, LHS});
|
||||
|
||||
ReplaceNode(N, NewNode);
|
||||
}
|
||||
|
||||
void FootDAGToDAGISel::SelectBr(SDNode *N, SDLoc &Loc) {
|
||||
SDValue PC = CurDAG->getRegister(Foot::RPC, 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_A, Loc, MVT::Other, {PC, Target, Chain});
|
||||
}
|
||||
else {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
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 Target = N->getOperand(0);
|
||||
SDValue Chain = N->getOperand(1);
|
||||
|
||||
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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
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 Target = N->getOperand(0);
|
||||
SDValue Chain = N->getOperand(1);
|
||||
|
||||
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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
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 Target = N->getOperand(0);
|
||||
SDValue Chain = N->getOperand(1);
|
||||
|
||||
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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
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 Target = N->getOperand(0);
|
||||
SDValue Chain = N->getOperand(1);
|
||||
|
||||
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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
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 Target = N->getOperand(0);
|
||||
SDValue Chain = N->getOperand(1);
|
||||
|
||||
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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_G, Loc, MVT::Other, {PC, Target, Zero, Chain});
|
||||
}
|
||||
|
||||
ReplaceNode(N, NewNode);
|
||||
}
|
||||
|
||||
void FootDAGToDAGISel::SelectBrNE(SDNode *N, SDLoc &Loc) {
|
||||
SDValue PC = CurDAG->getRegister(Foot::RPC, MVT::i32);
|
||||
SDValue Target = N->getOperand(0);
|
||||
SDValue Chain = 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 {
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, Loc, MVT::i32);
|
||||
NewNode = CurDAG->getMachineNode(Foot::BWOR_JMP_D_D_M_NE, Loc, MVT::Other, {PC, Target, Zero, Chain});
|
||||
}
|
||||
|
||||
ReplaceNode(N, NewNode);
|
||||
}
|
||||
|
||||
void FootDAGToDAGISel::SelectSelectCC(SDNode *N, SDLoc &Loc) {
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
SDValue IfTrue = N->getOperand(2);
|
||||
SDValue IfFalse = N->getOperand(3);
|
||||
SDValue CC = N->getOperand(4);
|
||||
|
||||
unsigned TCCVal = 0; // always
|
||||
|
||||
assert(isa<CondCodeSDNode>(CC.getNode()) && "expected condition code");
|
||||
switch (cast<CondCodeSDNode>(CC.getNode())->get()) {
|
||||
case ISD::SETLT:
|
||||
case ISD::SETULT:
|
||||
TCCVal = 1;
|
||||
break;
|
||||
case ISD::SETLE:
|
||||
case ISD::SETULE:
|
||||
TCCVal = 2;
|
||||
break;
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETUEQ:
|
||||
TCCVal = 3;
|
||||
break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETUGE:
|
||||
TCCVal = 4;
|
||||
break;
|
||||
case ISD::SETGT:
|
||||
case ISD::SETUGT:
|
||||
TCCVal = 5;
|
||||
break;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETUNE:
|
||||
TCCVal = 6;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected condition code");
|
||||
}
|
||||
|
||||
SDValue TCC = CurDAG->getTargetConstant(TCCVal, Loc, MVT::i32);
|
||||
|
||||
SDNode *Pseudo = CurDAG->getMachineNode(Foot::PSEUDO_SELECT, Loc, MVT::i32, {LHS, RHS, IfTrue, IfFalse, TCC});
|
||||
|
||||
ReplaceNode(N, Pseudo);
|
||||
}
|
||||
|
||||
void FootDAGToDAGISel::Select(SDNode *N) {
|
||||
if (N->isMachineOpcode()) {
|
||||
return;
|
||||
@ -944,9 +1030,18 @@ void FootDAGToDAGISel::Select(SDNode *N) {
|
||||
case ISD::BR:
|
||||
SelectBr(N, DL);
|
||||
break;
|
||||
case ISD::SELECT_CC:
|
||||
SelectSelectCC(N, DL);
|
||||
break;
|
||||
case FootISD::CALL:
|
||||
SelectCall(N, DL);
|
||||
break;
|
||||
case FootISD::CMP_CHAIN:
|
||||
SelectCmpChain(N, DL);
|
||||
break;
|
||||
case FootISD::CMP:
|
||||
SelectCmp(N, DL);
|
||||
break;
|
||||
case FootISD::BR_L:
|
||||
SelectBrL(N, DL);
|
||||
break;
|
||||
@ -965,9 +1060,6 @@ void FootDAGToDAGISel::Select(SDNode *N) {
|
||||
case FootISD::BR_NE:
|
||||
SelectBrNE(N, DL);
|
||||
break;
|
||||
case FootISD::CMP:
|
||||
SelectCmp(N, DL);
|
||||
break;
|
||||
default:
|
||||
SelectCode(N);
|
||||
break;
|
||||
|
||||
@ -33,31 +33,6 @@ FootTargetLowering::FootTargetLowering(const TargetMachine &TM,
|
||||
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
|
||||
|
||||
/*
|
||||
setOperationAction(ISD::ADD, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::SUB, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::MUL, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::UDIV, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::OR, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::AND, MVT::v2i16, Legal);
|
||||
setOperationAction(ISD::XOR, MVT::v2i16, Legal);
|
||||
|
||||
setOperationAction(ISD::ADD, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::SUB, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::MUL, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::UDIV, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::UREM, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::OR, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::AND, MVT::v4i8, Legal);
|
||||
setOperationAction(ISD::XOR, MVT::v4i8, Legal);
|
||||
|
||||
setOperationAction(ISD::FADD, MVT::f32, LibCall);
|
||||
setOperationAction(ISD::FSUB, MVT::f32, LibCall);
|
||||
setOperationAction(ISD::FMUL, MVT::f32, LibCall);
|
||||
setOperationAction(ISD::FDIV, MVT::f32, LibCall);
|
||||
setOperationAction(ISD::FREM, MVT::f32, LibCall);
|
||||
*/
|
||||
|
||||
computeRegisterProperties(Subtarget.getRegisterInfo());
|
||||
}
|
||||
|
||||
@ -334,10 +309,20 @@ SDValue FootTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock *FootTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Foot::PSEUDO_SELECT:
|
||||
return EmitSelect(MI);
|
||||
|
||||
default:
|
||||
llvm_unreachable("custom inserter not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
SDValue FootTargetLowering::LowerBrCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
assert(Op.getOpcode() == ISD::BR_CC);
|
||||
|
||||
SDValue Cmp = DAG.getNode(FootISD::CMP, SDLoc(Op), MVT::Other, Op.getOperand(0), Op.getOperand(2), Op.getOperand(3));
|
||||
SDValue Cmp = DAG.getNode(FootISD::CMP_CHAIN, SDLoc(Op), MVT::Other, Op.getOperand(0), Op.getOperand(2), Op.getOperand(3));
|
||||
|
||||
assert(isa<CondCodeSDNode>(Op.getOperand(1).getNode()) && "CC Must be CondCodeSDNode");
|
||||
|
||||
@ -373,5 +358,64 @@ SDValue FootTargetLowering::LowerBrCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
llvm_unreachable("Unexpected condition code");
|
||||
}
|
||||
|
||||
return DAG.getNode(Opc, SDLoc(Op), MVT::Other, {Cmp, Op.getOperand(4)});
|
||||
return DAG.getNode(Opc, SDLoc(Op), MVT::Other, {Op.getOperand(4), Cmp});
|
||||
}
|
||||
|
||||
MachineBasicBlock *FootTargetLowering::EmitSelect(MachineInstr &MI) const {
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(Foot::CMPR_D_D_A))
|
||||
.addReg(MI.getOperand(1).getReg())
|
||||
.addReg(MI.getOperand(2).getReg());
|
||||
|
||||
unsigned OpcTrue;
|
||||
unsigned OpcFalse;
|
||||
|
||||
// this should probably use enums instead
|
||||
// refer to DOCS.txt in the other repo
|
||||
switch (MI.getOperand(5).getImm()) {
|
||||
case 1:
|
||||
OpcTrue = Foot::COPY_D_D_L;
|
||||
OpcFalse = Foot::COPY_D_D_GE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
OpcTrue = Foot::COPY_D_D_LE;
|
||||
OpcFalse = Foot::COPY_D_D_G;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
OpcTrue = Foot::COPY_D_D_E;
|
||||
OpcFalse = Foot::COPY_D_D_NE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
OpcTrue = Foot::COPY_D_D_GE;
|
||||
OpcFalse = Foot::COPY_D_D_L;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
OpcTrue = Foot::COPY_D_D_G;
|
||||
OpcFalse = Foot::COPY_D_D_LE;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
OpcTrue = Foot::COPY_D_D_NE;
|
||||
OpcFalse = Foot::COPY_D_D_E;
|
||||
break;
|
||||
}
|
||||
|
||||
Register Out = MI.getOperand(0).getReg();
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(OpcTrue), Out)
|
||||
.addReg(MI.getOperand(3).getReg());
|
||||
|
||||
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(OpcFalse))
|
||||
.addReg(Out)
|
||||
.addReg(MI.getOperand(4).getReg());
|
||||
|
||||
MI.eraseFromParent();
|
||||
|
||||
return &MBB;
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ enum NodeType : unsigned {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
CALL,
|
||||
CMP,
|
||||
CMP_CHAIN,
|
||||
BR_L,
|
||||
BR_LE,
|
||||
BR_E,
|
||||
@ -49,8 +50,11 @@ public:
|
||||
|
||||
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||
|
||||
MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override;
|
||||
|
||||
private:
|
||||
SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
MachineBasicBlock *EmitSelect(MachineInstr &MI) const;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -21,16 +21,17 @@ 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)>;
|
||||
|
||||
let isBranch = 1 in {
|
||||
let isBranch = 1, isTerminator = 1, isBarrier = 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 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)>;
|
||||
defm ARNG : FootInstructionB<"ARNG", 0b00000010, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm LONG : FootInstructionB<"LONG", 0b00000011, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm CONF : FootInstructionB<"CONF", 0b00000100, (outs GP32:$dst), (ins GP32:$a)>;
|
||||
defm COPY : FootInstructionB<"COPY", 0b00000101, (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)>;
|
||||
@ -45,7 +46,7 @@ defm MULT : FootInstructionC<"MULT", 0b1011, (outs GP32:$dst), (ins GP32:$a, GP3
|
||||
defm DIVI : FootInstructionC<"DIVI", 0b1100, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
defm MODU : FootInstructionC<"MODU", 0b1101, (outs GP32:$dst), (ins GP32:$a, GP32:$b)>;
|
||||
|
||||
let isBranch = 1 in {
|
||||
let isBranch = 1, isTerminator = 1, isBarrier = 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)>;
|
||||
}
|
||||
@ -63,6 +64,13 @@ let OutOperandList = (outs),
|
||||
def PSEUDO_RET : StandardPseudoInstruction;
|
||||
}
|
||||
|
||||
let OutOperandList = (outs GP32:$dst),
|
||||
InOperandList = (ins GP32:$a, GP32:$b, GP32:$iftrue, GP32:$iffalse, i16imm:$cc),
|
||||
usesCustomInserter = 1,
|
||||
Namespace = "Foot" in {
|
||||
def PSEUDO_SELECT : StandardPseudoInstruction;
|
||||
}
|
||||
|
||||
let Defs = [RSP], Uses = [RSP],
|
||||
isCodeGenOnly = 1, Namespace = "Foot",
|
||||
OutOperandList = (outs),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "FootMCTargetDesc.h"
|
||||
#include "FootAsmInfo.h"
|
||||
#include "FootInstPrinter.h"
|
||||
#include "FootTargetObjectFile.h"
|
||||
#include "TargetInfo/FootTargetInfo.h"
|
||||
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user