diff options
| author | Jim Grosbach <grosbach@apple.com> | 2010-01-18 19:58:49 +0000 |
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2010-01-18 19:58:49 +0000 |
| commit | 8546ec9c1466c507dd2fc376cd2d21dd3e5c0983 (patch) | |
| tree | e05b7db23b79eaac3e832d62d8dfff574c8ed68d /llvm/lib/Target | |
| parent | 696cb8d410a95ee2b08bac2fa87525f48fac11b7 (diff) | |
| download | bcm5719-llvm-8546ec9c1466c507dd2fc376cd2d21dd3e5c0983.tar.gz bcm5719-llvm-8546ec9c1466c507dd2fc376cd2d21dd3e5c0983.zip | |
Patch by David Conrad:
"On ARMv6T2 this turns cttz into rbit, clz instead of the 4 instruction
sequence it is now."
llvm-svn: 93758
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 3 |
5 files changed, 34 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index a260050cf36..073cbffa4bd 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1680,6 +1680,12 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, N->getOperand(0), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32)); + case ARMISD::RBIT: { + EVT VT = N->getValueType(0); + SDValue Ops[] = { N->getOperand(0), + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getMachineNode(ARM::RBIT, dl, VT, Ops, 3); + } case ISD::UMUL_LOHI: { if (Subtarget->isThumb1Only()) break; diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 7b62c00e1db..73545298f9c 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -340,7 +340,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) // ARM does not have ROTL. setOperationAction(ISD::ROTL, MVT::i32, Expand); - setOperationAction(ISD::CTTZ, MVT::i32, Expand); + setOperationAction(ISD::CTTZ, MVT::i32, Custom); setOperationAction(ISD::CTPOP, MVT::i32, Expand); if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) setOperationAction(ISD::CTLZ, MVT::i32, Expand); @@ -482,6 +482,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::CMOV: return "ARMISD::CMOV"; case ARMISD::CNEG: return "ARMISD::CNEG"; + case ARMISD::RBIT: return "ARMISD::RBIT"; + case ARMISD::FTOSI: return "ARMISD::FTOSI"; case ARMISD::FTOUI: return "ARMISD::FTOUI"; case ARMISD::SITOF: return "ARMISD::SITOF"; @@ -2231,6 +2233,18 @@ SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) { return DAG.getMergeValues(Ops, 2, dl); } +static SDValue LowerCTTZ(SDNode *N, SelectionDAG &DAG, + const ARMSubtarget *ST) { + EVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); + + if (!ST->hasV6T2Ops()) + return SDValue(); + + SDValue rbit = DAG.getNode(ARMISD::RBIT, dl, VT, N->getOperand(0)); + return DAG.getNode(ISD::CTLZ, dl, VT, rbit); +} + static SDValue LowerShift(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { EVT VT = N->getValueType(0); @@ -3016,6 +3030,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG); case ISD::SRL_PARTS: case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG); + case ISD::CTTZ: return LowerCTTZ(Op.getNode(), DAG, Subtarget); case ISD::VSETCC: return LowerVSETCC(Op, DAG); case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index e1b3348c261..cd9c027743a 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -53,6 +53,8 @@ namespace llvm { CMOV, // ARM conditional move instructions. CNEG, // ARM conditional negate instructions. + RBIT, // ARM bitreverse instruction + FTOSI, // FP to sint within a FP register. FTOUI, // FP to uint within a FP register. SITOF, // sint to FP within a FP register. diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index f67e74a99ed..6ea56753f31 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1455,6 +1455,13 @@ def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, let Inst{19-16} = 0b1111; } +def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, + "rbit", "\t$dst, $src", []>, Requires<[IsARM, HasV6T2]> { + let Inst{7-4} = 0b0011; + let Inst{11-8} = 0b1111; + let Inst{19-16} = 0b1111; +} + def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, "rev", "\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> { diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 769df7ed916..3670d0fefd7 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -1540,6 +1540,9 @@ class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, InstrItinClass itin def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, "clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>; +def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, + "rbit", "\t$dst, $src", []>; + def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, "rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>; |

