summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp')
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp85
1 files changed, 58 insertions, 27 deletions
diff --git a/gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 72b2738bfac..f7d7e2af85e 100644
--- a/gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/gnu/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -1,4 +1,4 @@
-//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
+//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,19 +10,43 @@
// Subclass of MipsTargetLowering specialized for mips32/64.
//
//===----------------------------------------------------------------------===//
+
#include "MipsSEISelLowering.h"
#include "MipsMachineFunction.h"
#include "MipsRegisterInfo.h"
-#include "MipsTargetMachine.h"
+#include "MipsSubtarget.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <utility>
using namespace llvm;
@@ -220,7 +244,7 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
setOperationAction(ISD::SETCC, MVT::f64, Legal);
- setOperationAction(ISD::SELECT, MVT::f64, Legal);
+ setOperationAction(ISD::SELECT, MVT::f64, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
setOperationAction(ISD::BRCOND, MVT::Other, Legal);
@@ -367,6 +391,21 @@ addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
}
}
+SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
+ if(!Subtarget.hasMips32r6())
+ return MipsTargetLowering::LowerOperation(Op, DAG);
+
+ EVT ResTy = Op->getValueType(0);
+ SDLoc DL(Op);
+
+ // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
+ // floating point register are undefined. Not really an issue as sel.d, which
+ // is produced from an FSELECT node, only looks at bit 0.
+ SDValue Tmp = DAG.getNode(MipsISD::MTC1_D64, DL, MVT::f64, Op->getOperand(0));
+ return DAG.getNode(MipsISD::FSELECT, DL, ResTy, Tmp, Op->getOperand(1),
+ Op->getOperand(2));
+}
+
bool
MipsSETargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
unsigned,
@@ -414,6 +453,7 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
+ case ISD::SELECT: return lowerSELECT(Op, DAG);
}
return MipsTargetLowering::LowerOperation(Op, DAG);
@@ -661,11 +701,8 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-static SDValue genConstMult(SDValue X, uint64_t C, const SDLoc &DL, EVT VT,
+static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT,
EVT ShiftTy, SelectionDAG &DAG) {
- // Clear the upper (64 - VT.sizeInBits) bits.
- C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
-
// Return 0.
if (C == 0)
return DAG.getConstant(0, DL, VT);
@@ -675,18 +712,19 @@ static SDValue genConstMult(SDValue X, uint64_t C, const SDLoc &DL, EVT VT,
return X;
// If c is power of 2, return (shl x, log2(c)).
- if (isPowerOf2_64(C))
+ if (C.isPowerOf2())
return DAG.getNode(ISD::SHL, DL, VT, X,
- DAG.getConstant(Log2_64(C), DL, ShiftTy));
+ DAG.getConstant(C.logBase2(), DL, ShiftTy));
- unsigned Log2Ceil = Log2_64_Ceil(C);
- uint64_t Floor = 1LL << Log2_64(C);
- uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
+ unsigned BitWidth = C.getBitWidth();
+ APInt Floor = APInt(BitWidth, 1) << C.logBase2();
+ APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
+ APInt(BitWidth, 1) << C.ceilLogBase2();
// If |c - floor_c| <= |c - ceil_c|,
// where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
// return (add constMult(x, floor_c), constMult(x, c - floor_c)).
- if (C - Floor <= Ceil - C) {
+ if ((C - Floor).ule(Ceil - C)) {
SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
@@ -706,7 +744,7 @@ static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
if (!VT.isVector())
- return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), VT,
+ return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT,
TL->getScalarShiftAmountTy(DAG.getDataLayout(), VT),
DAG);
@@ -1073,7 +1111,7 @@ bool MipsSETargetLowering::isEligibleForTailCallOptimization(
void MipsSETargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
- std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
+ std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const {
@@ -1689,11 +1727,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
case Intrinsic::mips_fadd_w:
- case Intrinsic::mips_fadd_d: {
+ case Intrinsic::mips_fadd_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
// Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
case Intrinsic::mips_fceq_w:
case Intrinsic::mips_fceq_d:
@@ -1736,11 +1773,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2), ISD::SETUNE);
case Intrinsic::mips_fdiv_w:
- case Intrinsic::mips_fdiv_d: {
+ case Intrinsic::mips_fdiv_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_ffint_u_w:
case Intrinsic::mips_ffint_u_d:
return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0),
@@ -1777,11 +1813,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0),
Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
case Intrinsic::mips_fmul_w:
- case Intrinsic::mips_fmul_d: {
+ case Intrinsic::mips_fmul_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_fmsub_w:
case Intrinsic::mips_fmsub_d: {
// TODO: If intrinsics have fast-math-flags, propagate them.
@@ -1797,11 +1832,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::mips_fsqrt_d:
return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1));
case Intrinsic::mips_fsub_w:
- case Intrinsic::mips_fsub_d: {
+ case Intrinsic::mips_fsub_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_ftrunc_u_w:
case Intrinsic::mips_ftrunc_u_d:
return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0),
@@ -3455,7 +3489,6 @@ MipsSETargetLowering::emitST_F16_PSEUDO(MachineInstr &MI,
// memory it's not supposed to.
// b) The load crosses an implementation specific boundary, requiring OS
// intervention.
-//
MachineBasicBlock *
MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB) const {
@@ -3542,7 +3575,6 @@ MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
// insert.w for one element, we avoid that potiential case. If
// fexdo.[hw] causes an exception in, the exception is valid and it
// occurs for all elements.
-//
MachineBasicBlock *
MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB,
@@ -3648,7 +3680,6 @@ MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
// mtc1 $rtemp, $ftemp
// copy_s.w $rtemp2, $wtemp2[1]
// $fd = mthc1 $rtemp2, $ftemp
-//
MachineBasicBlock *
MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB,