diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 | 
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/Target/Mips/MipsISelLowering.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/Target/Mips/MipsISelLowering.cpp')
| -rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 99 | 
1 files changed, 96 insertions, 3 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 0677d378a115..8c2a364cdfa9 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1396,6 +1396,9 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,    case Mips::PseudoSELECTFP_T_D32:    case Mips::PseudoSELECTFP_T_D64:      return emitPseudoSELECT(MI, BB, true, Mips::BC1T); +  case Mips::PseudoD_SELECT_I: +  case Mips::PseudoD_SELECT_I64: +    return emitPseudoD_SELECT(MI, BB);    }  } @@ -2427,6 +2430,16 @@ SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,                               DAG.getConstant(VT.getSizeInBits(), DL, MVT::i32));    SDValue Ext = DAG.getNode(ISD::SRA, DL, VT, Hi,                              DAG.getConstant(VT.getSizeInBits() - 1, DL, VT)); + +  if (!(Subtarget.hasMips4() || Subtarget.hasMips32())) { +    SDVTList VTList = DAG.getVTList(VT, VT); +    return DAG.getNode(Subtarget.isGP64bit() ? Mips::PseudoD_SELECT_I64 +                                             : Mips::PseudoD_SELECT_I, +                       DL, VTList, Cond, ShiftRightHi, +                       IsSRA ? Ext : DAG.getConstant(0, DL, VT), Or, +                       ShiftRightHi); +  } +    Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or);    Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond,                     IsSRA ? Ext : DAG.getConstant(0, DL, VT), ShiftRightHi); @@ -2563,10 +2576,12 @@ static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG,  }  // Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). -static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG) { +static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG, +                                     bool SingleFloat) {    SDValue Val = SD->getValue(); -  if (Val.getOpcode() != ISD::FP_TO_SINT) +  if (Val.getOpcode() != ISD::FP_TO_SINT || +      (Val.getValueSizeInBits() > 32 && SingleFloat))      return SDValue();    EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); @@ -2587,7 +2602,7 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {        ((MemVT == MVT::i32) || (MemVT == MVT::i64)))      return lowerUnalignedIntStore(SD, DAG, Subtarget.isLittle()); -  return lowerFP_TO_SINT_STORE(SD, DAG); +  return lowerFP_TO_SINT_STORE(SD, DAG, Subtarget.isSingleFloat());  }  SDValue MipsTargetLowering::lowerEH_DWARF_CFA(SDValue Op, @@ -2603,6 +2618,9 @@ SDValue MipsTargetLowering::lowerEH_DWARF_CFA(SDValue Op,  SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op,                                              SelectionDAG &DAG) const { +  if (Op.getValueSizeInBits() > 32 && Subtarget.isSingleFloat()) +    return SDValue(); +    EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits());    SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy,                                Op.getOperand(0)); @@ -4340,6 +4358,81 @@ MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,    return BB;  } +MachineBasicBlock *MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI, +                                                          MachineBasicBlock *BB) const { +  assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) && +         "Subtarget already supports SELECT nodes with the use of" +         "conditional-move instructions."); + +  const TargetInstrInfo *TII = Subtarget.getInstrInfo(); +  DebugLoc DL = MI.getDebugLoc(); + +  // D_SELECT substitutes two SELECT nodes that goes one after another and +  // have the same condition operand. On machines which don't have +  // conditional-move instruction, it reduces unnecessary branch instructions +  // which are result of using two diamond patterns that are result of two +  // SELECT pseudo instructions. +  const BasicBlock *LLVM_BB = BB->getBasicBlock(); +  MachineFunction::iterator It = ++BB->getIterator(); + +  //  thisMBB: +  //  ... +  //   TrueVal = ... +  //   setcc r1, r2, r3 +  //   bNE   r1, r0, copy1MBB +  //   fallthrough --> copy0MBB +  MachineBasicBlock *thisMBB = BB; +  MachineFunction *F = BB->getParent(); +  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); +  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); +  F->insert(It, copy0MBB); +  F->insert(It, sinkMBB); + +  // Transfer the remainder of BB and its successor edges to sinkMBB. +  sinkMBB->splice(sinkMBB->begin(), BB, +                  std::next(MachineBasicBlock::iterator(MI)), BB->end()); +  sinkMBB->transferSuccessorsAndUpdatePHIs(BB); + +  // Next, add the true and fallthrough blocks as its successors. +  BB->addSuccessor(copy0MBB); +  BB->addSuccessor(sinkMBB); + +  // bne rs, $0, sinkMBB +  BuildMI(BB, DL, TII->get(Mips::BNE)) +      .addReg(MI.getOperand(2).getReg()) +      .addReg(Mips::ZERO) +      .addMBB(sinkMBB); + +  //  copy0MBB: +  //   %FalseValue = ... +  //   # fallthrough to sinkMBB +  BB = copy0MBB; + +  // Update machine-CFG edges +  BB->addSuccessor(sinkMBB); + +  //  sinkMBB: +  //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] +  //  ... +  BB = sinkMBB; + +  // Use two PHI nodes to select two reults +  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg()) +      .addReg(MI.getOperand(3).getReg()) +      .addMBB(thisMBB) +      .addReg(MI.getOperand(5).getReg()) +      .addMBB(copy0MBB); +  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(1).getReg()) +      .addReg(MI.getOperand(4).getReg()) +      .addMBB(thisMBB) +      .addReg(MI.getOperand(6).getReg()) +      .addMBB(copy0MBB); + +  MI.eraseFromParent(); // The pseudo instruction is gone now. + +  return BB; +} +  // FIXME? Maybe this could be a TableGen attribute on some registers and  // this table could be generated automatically from RegInfo.  unsigned MipsTargetLowering::getRegisterByName(const char* RegName, EVT VT,  | 
