aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsSEISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsSEISelLowering.cpp')
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.cpp126
1 files changed, 82 insertions, 44 deletions
diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp
index a78e544c35f0..edf57a3840d1 100644
--- a/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -1,9 +1,8 @@
//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -214,6 +213,11 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
+ if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
+ !Subtarget.hasMips64()) {
+ setOperationAction(ISD::BITCAST, MVT::i64, Custom);
+ }
+
if (NoDPLoadStore) {
setOperationAction(ISD::LOAD, MVT::f64, Custom);
setOperationAction(ISD::STORE, MVT::f64, Custom);
@@ -415,11 +419,8 @@ SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
Op->getOperand(2));
}
-bool
-MipsSETargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
- unsigned,
- unsigned,
- bool *Fast) const {
+bool MipsSETargetLowering::allowsMisalignedMemoryAccesses(
+ EVT VT, unsigned, unsigned, MachineMemOperand::Flags, bool *Fast) const {
MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
if (Subtarget.systemSupportsUnalignedAccess()) {
@@ -463,6 +464,7 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
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);
+ case ISD::BITCAST: return lowerBITCAST(Op, DAG);
}
return MipsTargetLowering::LowerOperation(Op, DAG);
@@ -714,8 +716,31 @@ static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT,
SelectionDAG &DAG,
const MipsSubtarget &Subtarget) {
// Estimate the number of operations the below transform will turn a
- // constant multiply into. The number is approximately how many powers
- // of two summed together that the constant can be broken down into.
+ // constant multiply into. The number is approximately equal to the minimal
+ // number of powers of two that constant can be broken down to by adding
+ // or subtracting them.
+ //
+ // If we have taken more than 12[1] / 8[2] steps to attempt the
+ // optimization for a native sized value, it is more than likely that this
+ // optimization will make things worse.
+ //
+ // [1] MIPS64 requires 6 instructions at most to materialize any constant,
+ // multiplication requires at least 4 cycles, but another cycle (or two)
+ // to retrieve the result from the HI/LO registers.
+ //
+ // [2] For MIPS32, more than 8 steps is expensive as the constant could be
+ // materialized in 2 instructions, multiplication requires at least 4
+ // cycles, but another cycle (or two) to retrieve the result from the
+ // HI/LO registers.
+ //
+ // TODO:
+ // - MaxSteps needs to consider the `VT` of the constant for the current
+ // target.
+ // - Consider to perform this optimization after type legalization.
+ // That allows to remove a workaround for types not supported natively.
+ // - Take in account `-Os, -Oz` flags because this optimization
+ // increases code size.
+ unsigned MaxSteps = Subtarget.isABI_O32() ? 8 : 12;
SmallVector<APInt, 16> WorkStack(1, C);
unsigned Steps = 0;
@@ -727,6 +752,9 @@ static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT,
if (Val == 0 || Val == 1)
continue;
+ if (Steps >= MaxSteps)
+ return false;
+
if (Val.isPowerOf2()) {
++Steps;
continue;
@@ -735,36 +763,15 @@ static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT,
APInt Floor = APInt(BitWidth, 1) << Val.logBase2();
APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0)
: APInt(BitWidth, 1) << C.ceilLogBase2();
-
if ((Val - Floor).ule(Ceil - Val)) {
WorkStack.push_back(Floor);
WorkStack.push_back(Val - Floor);
- ++Steps;
- continue;
+ } else {
+ WorkStack.push_back(Ceil);
+ WorkStack.push_back(Ceil - Val);
}
- WorkStack.push_back(Ceil);
- WorkStack.push_back(Ceil - Val);
++Steps;
-
- // If we have taken more than 12[1] / 8[2] steps to attempt the
- // optimization for a native sized value, it is more than likely that this
- // optimization will make things worse.
- //
- // [1] MIPS64 requires 6 instructions at most to materialize any constant,
- // multiplication requires at least 4 cycles, but another cycle (or two)
- // to retrieve the result from the HI/LO registers.
- //
- // [2] For MIPS32, more than 8 steps is expensive as the constant could be
- // materialized in 2 instructions, multiplication requires at least 4
- // cycles, but another cycle (or two) to retrieve the result from the
- // HI/LO registers.
-
- if (Steps > 12 && (Subtarget.isABI_N32() || Subtarget.isABI_N64()))
- return false;
-
- if (Steps > 8 && Subtarget.isABI_O32())
- return false;
}
// If the value being multiplied is not supported natively, we have to pay
@@ -1221,6 +1228,36 @@ SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
}
+SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ MVT Src = Op.getOperand(0).getValueType().getSimpleVT();
+ MVT Dest = Op.getValueType().getSimpleVT();
+
+ // Bitcast i64 to double.
+ if (Src == MVT::i64 && Dest == MVT::f64) {
+ SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
+ Op.getOperand(0), DAG.getIntPtrConstant(0, DL));
+ SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
+ Op.getOperand(0), DAG.getIntPtrConstant(1, DL));
+ return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+ }
+
+ // Bitcast double to i64.
+ if (Src == MVT::f64 && Dest == MVT::i64) {
+ SDValue Lo =
+ DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
+ DAG.getConstant(0, DL, MVT::i32));
+ SDValue Hi =
+ DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
+ DAG.getConstant(1, DL, MVT::i32));
+ return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
+ }
+
+ // Skip other cases of bitcast and use default lowering.
+ return SDValue();
+}
+
SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
bool HasLo, bool HasHi,
SelectionDAG &DAG) const {
@@ -1379,9 +1416,10 @@ static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) {
static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG,
bool IsSigned = false) {
+ auto *CImm = cast<ConstantSDNode>(Op->getOperand(ImmOp));
return DAG.getConstant(
APInt(Op->getValueType(0).getScalarType().getSizeInBits(),
- Op->getConstantOperandVal(ImmOp), IsSigned),
+ IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
SDLoc(Op), Op->getValueType(0));
}
@@ -3725,8 +3763,8 @@ MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
DebugLoc DL = MI.getDebugLoc();
- unsigned Fd = MI.getOperand(0).getReg();
- unsigned Ws = MI.getOperand(1).getReg();
+ Register Fd = MI.getOperand(0).getReg();
+ Register Ws = MI.getOperand(1).getReg();
MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
const TargetRegisterClass *GPRRC =
@@ -3734,10 +3772,10 @@ MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
unsigned MTC1Opc = IsFGR64onMips64
? Mips::DMTC1
: (IsFGR64onMips32 ? Mips::MTC1_D64 : Mips::MTC1);
- unsigned COPYOpc = IsFGR64onMips64 ? Mips::COPY_S_D : Mips::COPY_S_W;
+ Register COPYOpc = IsFGR64onMips64 ? Mips::COPY_S_D : Mips::COPY_S_W;
- unsigned Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
- unsigned WPHI = Wtemp;
+ Register Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+ Register WPHI = Wtemp;
BuildMI(*BB, MI, DL, TII->get(Mips::FEXUPR_W), Wtemp).addReg(Ws);
if (IsFGR64) {
@@ -3746,15 +3784,15 @@ MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
}
// Perform the safety regclass copy mentioned above.
- unsigned Rtemp = RegInfo.createVirtualRegister(GPRRC);
- unsigned FPRPHI = IsFGR64onMips32
+ Register Rtemp = RegInfo.createVirtualRegister(GPRRC);
+ Register FPRPHI = IsFGR64onMips32
? RegInfo.createVirtualRegister(&Mips::FGR64RegClass)
: Fd;
BuildMI(*BB, MI, DL, TII->get(COPYOpc), Rtemp).addReg(WPHI).addImm(0);
BuildMI(*BB, MI, DL, TII->get(MTC1Opc), FPRPHI).addReg(Rtemp);
if (IsFGR64onMips32) {
- unsigned Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
+ Register Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
BuildMI(*BB, MI, DL, TII->get(Mips::COPY_S_W), Rtemp2)
.addReg(WPHI)
.addImm(1);