diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-05-11 23:43:56 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-05-11 23:43:56 +0000 |
commit | d7c4a4a6c048d4174b8795598f50fd76c30731ed (patch) | |
tree | 85b97af7b609ee67259289a1f11a323be8fade78 /lib/Target/PowerPC/PPCISelPattern.cpp | |
parent | a65640edd0d77400e3d9d1e1ae189c44fa0c2e34 (diff) |
Necessary changes to codegen cttz efficiently on PowerPC
1. Teach LegalizeDAG how to better legalize CTTZ if the target doesn't have
CTPOP, but does have CTLZ
2. Teach PPC32 how to do sub x, const -> add x, -const for valid consts
3. Teach PPC32 how to do and (xor a, -1) b -> andc b, a
4. Teach PPC32 that ISD::CTLZ -> PPC::CNTLZW
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21880 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelPattern.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCISelPattern.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp index 6d687ef9f3..536a07710d 100644 --- a/lib/Target/PowerPC/PPCISelPattern.cpp +++ b/lib/Target/PowerPC/PPCISelPattern.cpp @@ -69,10 +69,9 @@ namespace { setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); - //PowerPC has these, but they are not implemented + //PowerPC does not have CTPOP or CTTZ setOperationAction(ISD::CTPOP, MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand); - setOperationAction(ISD::CTLZ , MVT::i32 , Expand); setSetCCResultContents(ZeroOrOneSetCCResult); addLegalFPImmediate(+0.0); // Necessary for FSEL @@ -654,9 +653,13 @@ static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode, if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } break; case ISD::MUL: - case ISD::SUB: if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } break; + case ISD::SUB: + // handle subtract-from separately from subtract, since subi is really addi + if (U && v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } + if (!U && v <= 32768 && v >= -32767) { Imm = (-v) & 0xFFFF; return 1; } + break; case ISD::SETCC: if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; } if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; } @@ -1817,6 +1820,11 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { } return Result; + case ISD::CTLZ: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::CNTLZW, 1, Result).addReg(Tmp1); + return Result; + case ISD::ADD: assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); Tmp1 = SelectExpr(N.getOperand(0)); @@ -1851,6 +1859,16 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { 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()) { + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp2).addReg(Tmp1); + return Result; + } + // 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; @@ -1976,11 +1994,15 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { } case ISD::SUB: - Tmp2 = SelectExpr(N.getOperand(1)); - if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1)) + if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1, true)) { + Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1); - else { + } else if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2); + } else { + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); } return Result; |