diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-08 21:33:23 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-08 21:33:23 +0000 |
commit | 25388199a2d347d465bf78bd543a185466c19b9a (patch) | |
tree | a075167bf83c94e6fca3c0d72a3fe62fe8656e64 /llvm/lib | |
parent | 8e9dc3192846919705d9176f51659409e437c2ec (diff) | |
download | bcm5719-llvm-25388199a2d347d465bf78bd543a185466c19b9a.tar.gz bcm5719-llvm-25388199a2d347d465bf78bd543a185466c19b9a.zip |
Add new immediate handling support for mul/div.
Patch by Jim Laskey!
llvm-svn: 22715
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp index e0cb1f1ff62..4e9f5ba8510 100644 --- a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp +++ b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp @@ -1890,9 +1890,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { case ISD::MUL: Tmp1 = SelectExpr(N.getOperand(0)); - if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) + if (isImmediate(N.getOperand(1), Tmp2) && isInt16(Tmp2)) { + Tmp2 = Lo16(Tmp2); BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); - else { + } else { Tmp2 = SelectExpr(N.getOperand(1)); switch (DestType) { default: assert(0 && "Unknown type to ISD::MUL"); break; @@ -1913,31 +1914,39 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { return Result; case ISD::SDIV: - case ISD::UDIV: - switch (getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { - default: break; - // If this is an sdiv by a power of two, we can use an srawi/addze pair. - case 3: - Tmp1 = MakeReg(MVT::i32); - Tmp2 = SelectExpr(N.getOperand(0)); - if ((int)Tmp3 < 0) { + if (isImmediate(N.getOperand(1), Tmp3)) { + if ((signed)Tmp3 > 0 && isPowerOf2_32(Tmp3)) { + Tmp3 = Log2_32(Tmp3); + Tmp1 = MakeReg(MVT::i32); + Tmp2 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); + BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); + return Result; + } else if ((signed)Tmp3 < 0 && isPowerOf2_32(-Tmp3)) { + Tmp3 = Log2_32(-Tmp3); unsigned Tmp4 = MakeReg(MVT::i32); - BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(-Tmp3); + BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1); BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4); - } else { - BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); - BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); + return Result; } - return Result; + } + // fall thru + case ISD::UDIV: // If this is a divide by constant, we can emit code using some magic // constants to implement it as a multiply instead. - case 4: - ExprMap.erase(N); - if (opcode == ISD::SDIV) - return SelectExpr(BuildSDIVSequence(N)); - else - return SelectExpr(BuildUDIVSequence(N)); + if (isImmediate(N.getOperand(1), Tmp3)) { + if (opcode == ISD::SDIV) { + if ((signed)Tmp3 < -1 || (signed)Tmp3 > 1) { + ExprMap.erase(N); + return SelectExpr(BuildSDIVSequence(N)); + } + } else { + if ((signed)Tmp3 > 1) { + ExprMap.erase(N); + return SelectExpr(BuildUDIVSequence(N)); + } + } } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); |