aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-08 21:24:57 +0000
committerChris Lattner <sabre@nondot.org>2005-08-08 21:24:57 +0000
commit2f57c4da2164de3dfeebb3c25d81c49e6574a12a (patch)
treeda402f32eebf0344d255aa1f336ea1a6b0ad3ab1
parent39c6896d22a89444292494107c89e10c79c0de13 (diff)
Modify the ISD::AND opcode case to use new immediate constant predicates.
Includes wider support for rotate and mask cases. Patch by Jim Laskey. I've requested that Jim add new regression tests the newly handled cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22712 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCISelPattern.cpp81
1 files changed, 36 insertions, 45 deletions
diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp
index 6128590175..20dd4e8bb4 100644
--- a/lib/Target/PowerPC/PPCISelPattern.cpp
+++ b/lib/Target/PowerPC/PPCISelPattern.cpp
@@ -1709,58 +1709,49 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
return Result;
case ISD::AND:
- switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
- default: assert(0 && "unhandled result code");
- case 0: // No immediate
- // Check for andc: and, (xor a, -1), b
- if (N.getOperand(0).getOpcode() == ISD::XOR &&
- N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
- cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
+ if (isImmediate(N.getOperand(1), Tmp2)) {
+ if (isShiftedMask_32(Tmp2) || isShiftedMask_32(~Tmp2)) {
+ unsigned SH, MB, ME;
+ Opc = Recording ? PPC::RLWINMo : PPC::RLWINM;
+ unsigned OprOpc;
+ if (isOprShiftImm(N.getOperand(0), OprOpc, Tmp3) &&
+ isRotateAndMask(OprOpc, Tmp3, Tmp2, false, SH, MB, ME)) {
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp2).addReg(Tmp1);
- return Result;
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ isRunOfOnes(Tmp2, MB, ME);
+ SH = 0;
}
- // It wasn't and-with-complement, emit a regular and
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- Opc = Recording ? PPC::ANDo : PPC::AND;
- BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
- break;
- case 1: // Low immediate
+ BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(SH)
+ .addImm(MB).addImm(ME);
+ RecordSuccess = true;
+ return Result;
+ } else if (isUInt16(Tmp2)) {
+ Tmp2 = Lo16(Tmp2);
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::ANDIo, 2, Result).addReg(Tmp1).addImm(Tmp2);
- break;
- case 2: // Shifted immediate
+ RecordSuccess = true;
+ return Result;
+ } else if (isUInt16(Tmp2)) {
+ Tmp2 = Hi16(Tmp2);
Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2);
- break;
- case 5: // Bitfield mask
- Opc = Recording ? PPC::RLWINMo : PPC::RLWINM;
- Tmp3 = Tmp2 >> 16; // MB
- Tmp2 &= 0xFFFF; // ME
-
- // FIXME: Catch SHL-AND in addition to SRL-AND in this block.
- if (N.getOperand(0).getOpcode() == ISD::SRL)
- if (ConstantSDNode *SA =
- dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
-
- // We can fold the RLWINM and the SRL together if the mask is
- // clearing the top bits which are rotated around.
- unsigned RotAmt = 32-(SA->getValue() & 31);
- if (Tmp2 <= RotAmt) {
- Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
- BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(RotAmt)
- .addImm(Tmp3).addImm(Tmp2);
- break;
- }
- }
-
- Tmp1 = SelectExpr(N.getOperand(0));
- BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(0)
- .addImm(Tmp3).addImm(Tmp2);
- break;
+ RecordSuccess = true;
+ return Result;
+ }
+ }
+ if (isOprNot(N.getOperand(0))) {
+ Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp2).addReg(Tmp1);
+ RecordSuccess = false;
+ return Result;
}
+ // emit a regular and
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Opc = Recording ? PPC::ANDo : PPC::AND;
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
RecordSuccess = true;
return Result;