mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Expand 64-bit shifts if target ABI is O32.
llvm-svn: 156457
This commit is contained in:
parent
f0a7637b27
commit
bd2f3d1c46
@ -164,6 +164,12 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
|||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
|
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!HasMips64) {
|
||||||
|
setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
|
||||||
|
}
|
||||||
|
|
||||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||||
@ -199,9 +205,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
|||||||
if (!Subtarget->hasMips64r2())
|
if (!Subtarget->hasMips64r2())
|
||||||
setOperationAction(ISD::ROTR, MVT::i64, Expand);
|
setOperationAction(ISD::ROTR, MVT::i64, Expand);
|
||||||
|
|
||||||
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
|
|
||||||
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
|
|
||||||
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
|
|
||||||
setOperationAction(ISD::FSIN, MVT::f32, Expand);
|
setOperationAction(ISD::FSIN, MVT::f32, Expand);
|
||||||
setOperationAction(ISD::FSIN, MVT::f64, Expand);
|
setOperationAction(ISD::FSIN, MVT::f64, Expand);
|
||||||
setOperationAction(ISD::FCOS, MVT::f32, Expand);
|
setOperationAction(ISD::FCOS, MVT::f32, Expand);
|
||||||
@ -750,6 +753,9 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
|||||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||||
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
|
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
|
||||||
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
|
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
|
||||||
|
case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
|
||||||
|
case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG, true);
|
||||||
|
case ISD::SRL_PARTS: return LowerShiftRightParts(Op, DAG, false);
|
||||||
}
|
}
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
@ -1964,6 +1970,78 @@ SDValue MipsTargetLowering::LowerATOMIC_FENCE(SDValue Op,
|
|||||||
DAG.getConstant(SType, MVT::i32));
|
DAG.getConstant(SType, MVT::i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue MipsTargetLowering::LowerShiftLeftParts(SDValue Op,
|
||||||
|
SelectionDAG& DAG) const {
|
||||||
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
|
||||||
|
SDValue Shamt = Op.getOperand(2);
|
||||||
|
|
||||||
|
// if shamt < 32:
|
||||||
|
// lo = (shl lo, shamt)
|
||||||
|
// hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt))
|
||||||
|
// else:
|
||||||
|
// lo = 0
|
||||||
|
// hi = (shl lo, shamt[4:0])
|
||||||
|
SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
|
||||||
|
DAG.getConstant(-1, MVT::i32));
|
||||||
|
SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo,
|
||||||
|
DAG.getConstant(1, MVT::i32));
|
||||||
|
SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, ShiftRight1Lo,
|
||||||
|
Not);
|
||||||
|
SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, Shamt);
|
||||||
|
SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
|
||||||
|
SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, MVT::i32, Lo, Shamt);
|
||||||
|
SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
|
||||||
|
DAG.getConstant(0x20, MVT::i32));
|
||||||
|
Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, DAG.getConstant(0, MVT::i32),
|
||||||
|
ShiftLeftLo);
|
||||||
|
Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftLeftLo, Or);
|
||||||
|
|
||||||
|
SDValue Ops[2] = {Lo, Hi};
|
||||||
|
return DAG.getMergeValues(Ops, 2, DL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue MipsTargetLowering::LowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
|
||||||
|
bool IsSRA) const {
|
||||||
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
|
||||||
|
SDValue Shamt = Op.getOperand(2);
|
||||||
|
|
||||||
|
// if shamt < 32:
|
||||||
|
// lo = (or (shl (shl hi, 1), ~shamt) (srl lo, shamt))
|
||||||
|
// if isSRA:
|
||||||
|
// hi = (sra hi, shamt)
|
||||||
|
// else:
|
||||||
|
// hi = (srl hi, shamt)
|
||||||
|
// else:
|
||||||
|
// if isSRA:
|
||||||
|
// lo = (sra hi, shamt[4:0])
|
||||||
|
// hi = (sra hi, 31)
|
||||||
|
// else:
|
||||||
|
// lo = (srl hi, shamt[4:0])
|
||||||
|
// hi = 0
|
||||||
|
SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
|
||||||
|
DAG.getConstant(-1, MVT::i32));
|
||||||
|
SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi,
|
||||||
|
DAG.getConstant(1, MVT::i32));
|
||||||
|
SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, ShiftLeft1Hi, Not);
|
||||||
|
SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, Shamt);
|
||||||
|
SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
|
||||||
|
SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, DL, MVT::i32,
|
||||||
|
Hi, Shamt);
|
||||||
|
SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
|
||||||
|
DAG.getConstant(0x20, MVT::i32));
|
||||||
|
SDValue Shift31 = DAG.getNode(ISD::SRA, DL, MVT::i32, Hi,
|
||||||
|
DAG.getConstant(31, MVT::i32));
|
||||||
|
Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftRightHi, Or);
|
||||||
|
Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond,
|
||||||
|
IsSRA ? Shift31 : DAG.getConstant(0, MVT::i32),
|
||||||
|
ShiftRightHi);
|
||||||
|
|
||||||
|
SDValue Ops[2] = {Lo, Hi};
|
||||||
|
return DAG.getMergeValues(Ops, 2, DL);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Calling Convention Implementation
|
// Calling Convention Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -135,6 +135,8 @@ namespace llvm {
|
|||||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
|
SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
|
||||||
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
|
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
|
||||||
|
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
|
||||||
|
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG& DAG, bool IsSRA) const;
|
||||||
|
|
||||||
virtual SDValue
|
virtual SDValue
|
||||||
LowerFormalArguments(SDValue Chain,
|
LowerFormalArguments(SDValue Chain,
|
||||||
|
29
test/CodeGen/Mips/shift-parts.ll
Normal file
29
test/CodeGen/Mips/shift-parts.ll
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
; RUN: llc -march=mipsel < %s | FileCheck %s
|
||||||
|
|
||||||
|
define i64 @shl0(i64 %a, i32 %b) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: shl0
|
||||||
|
; CHECK-NOT: lw $25, %call16(__
|
||||||
|
%sh_prom = zext i32 %b to i64
|
||||||
|
%shl = shl i64 %a, %sh_prom
|
||||||
|
ret i64 %shl
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @shr1(i64 %a, i32 %b) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: shr1
|
||||||
|
; CHECK-NOT: lw $25, %call16(__
|
||||||
|
%sh_prom = zext i32 %b to i64
|
||||||
|
%shr = lshr i64 %a, %sh_prom
|
||||||
|
ret i64 %shr
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @sra2(i64 %a, i32 %b) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: sra2
|
||||||
|
; CHECK-NOT: lw $25, %call16(__
|
||||||
|
%sh_prom = zext i32 %b to i64
|
||||||
|
%shr = ashr i64 %a, %sh_prom
|
||||||
|
ret i64 %shr
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user