diff options
| author | Nate Begeman <natebegeman@mac.com> | 2004-10-08 02:49:24 +0000 | 
|---|---|---|
| committer | Nate Begeman <natebegeman@mac.com> | 2004-10-08 02:49:24 +0000 | 
| commit | b58dd6799f4bed89a072d60f2e0cfae478592098 (patch) | |
| tree | e9a50d0bffe1eb6b98917ba09e45caaef8b4a813 /llvm/lib | |
| parent | 3e0a20ebb8a20649ed075cf13a96a7186a957381 (diff) | |
| download | bcm5719-llvm-b58dd6799f4bed89a072d60f2e0cfae478592098.tar.gz bcm5719-llvm-b58dd6799f4bed89a072d60f2e0cfae478592098.zip | |
Implement logical and with an immediate that consists of a contiguous block
of one or more 1 bits (may wrap from least significant bit to most
significant bit) as the rlwinm rather than andi., andis., or some longer
instructons sequence.
int andn4(int z) { return z & -4; }
int clearhi(int z) { return z & 0x0000FFFF; }
int clearlo(int z) { return z & 0xFFFF0000; }
int clearmid(int z) { return z & 0x00FFFF00; }
int clearwrap(int z) { return z & 0xFF0000FF; }
_andn4:
        rlwinm r3, r3, 0, 0, 29
        blr
_clearhi:
        rlwinm r3, r3, 0, 16, 31
        blr
_clearlo:
        rlwinm r3, r3, 0, 0, 15
        blr
_clearmid:
        rlwinm r3, r3, 0, 8, 23
        blr
_clearwrap:
        rlwinm r3, r3, 0, 24, 7
        blr
llvm-svn: 16832
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp | 74 | 
1 files changed, 69 insertions, 5 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp b/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp index e22da0fa2eb..890ccb95dc6 100644 --- a/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -32,7 +32,7 @@  using namespace llvm;  namespace { -  Statistic<> ShiftedImm("ppc-codegen", "Number of shifted immediates used"); +  Statistic<> NumClear("ppc-codegen", "Number of AND turned into mask");    /// TypeClass - Used by the PowerPC backend to group LLVM types by their basic    /// PPC Representation. @@ -499,11 +499,10 @@ bool PPC32ISel::canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Opcode,    // For shifted immediates, any value with the low halfword cleared may be used    if (Shifted) { -    if (((int32_t)CI->getRawValue() & 0x0000FFFF) == 0) { -      ++ShiftedImm; +    if (((int32_t)CI->getRawValue() & 0x0000FFFF) == 0)        return true; -    } -    return false; +    else +      return false;    }    // ADDI, Compare, and non-indexed Load take SIMM @@ -2038,6 +2037,61 @@ static unsigned ExactLog2(unsigned Val) {    return Count;  } +// isRunOfOnes - returns true if Val consists of one contiguous run of 1's with +// any number of 0's on either side.  the 1's are allowed to wrap from LSB to +// MSB.  so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs.  0x0F0F0000 is +// not, since all 1's are not contiguous. +static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { +  bool isRun = true; +  MB = 0;  +  ME = 0; + +  // look for first set bit +  int i = 0; +  for (; i < 32; i++) { +    if ((Val & (1 << (31 - i))) != 0) { +      MB = i; +      ME = i; +      break; +    } +  } +   +  // look for last set bit +  for (; i < 32; i++) { +    if ((Val & (1 << (31 - i))) == 0) +      break; +    ME = i; +  } + +  // look for next set bit +  for (; i < 32; i++) { +    if ((Val & (1 << (31 - i))) != 0) +      break; +  } +   +  // if we exhausted all the bits, we found a match at this point for 0*1*0* +  if (i == 32) +    return true; + +  // since we just encountered more 1's, if it doesn't wrap around to the +  // most significant bit of the word, then we did not find a match to 1*0*1* so +  // exit. +  if (MB != 0) +    return false; + +  // look for last set bit +  for (MB = i; i < 32; i++) { +    if ((Val & (1 << (31 - i))) == 0) +      break; +  } +   +  // if we exhausted all the bits, then we found a match for 1*0*1*, otherwise, +  // the value is not a run of ones. +  if (i == 32) +    return true; +  return false; +} +  /// emitBinaryConstOperation - Implement simple binary operators for integral  /// types with a constant operand.  Opcode is one of: 0 for Add, 1 for Sub,   /// 2 for And, 3 for Or, 4 for Xor, and 5 for Subtract-From. @@ -2070,6 +2124,16 @@ void PPC32ISel::emitBinaryConstOperation(MachineBasicBlock *MBB,        return;      }    } +   +  if (Opcode == 2) { +    unsigned MB, ME, mask = CI->getRawValue(); +    if (isRunOfOnes(mask, MB, ME)) { +      ++NumClear; +      BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0) +        .addImm(MB).addImm(ME); +      return; +    } +  }    // For Add, Sub, and SubF the instruction takes a signed immediate.  For And,    // Or, and Xor, the instruction takes an unsigned immediate.  There is no  | 

