From c02780eed1f78130e8ebff3c3800fcbb1cc79cfd Mon Sep 17 00:00:00 2001 From: Duraid Madina Date: Wed, 13 Apr 2005 04:50:54 +0000 Subject: [PATCH] * if ANDing with a constant of the form: 0x00000..00FFF..FF ^ ^ ^ ^ any number of 0's followed by some number of 1's then we use dep.z to just paste zeros over the input. For the special cases where this is zxt1/zxt2/zxt4, we use those instructions instead, because we're all about readability!!! that's what it's about!! readability! *twitch* ;D git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21279 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/IA64/IA64ISelPattern.cpp | 47 +++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/Target/IA64/IA64ISelPattern.cpp b/lib/Target/IA64/IA64ISelPattern.cpp index c2623d020cf..c501fa1c331 100644 --- a/lib/Target/IA64/IA64ISelPattern.cpp +++ b/lib/Target/IA64/IA64ISelPattern.cpp @@ -445,7 +445,7 @@ void ISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { /// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It /// returns zero when the input is not exactly a power of two. -static uint64_t ExactLog2(uint64_t Val) { +static unsigned ExactLog2(uint64_t Val) { if (Val == 0 || (Val & (Val-1))) return 0; unsigned Count = 0; while (Val != 1) { @@ -455,6 +455,17 @@ static uint64_t ExactLog2(uint64_t Val) { return Count; } +/// ExactLog2sub1 - This function solves for (Val == (1 << (N-1))-1) +/// and returns N. It returns 666 if Val is not 2^n -1 for some n. +static unsigned ExactLog2sub1(uint64_t Val) { + unsigned int n; + for(n=0; n<64; n++) { + if(Val==(uint64_t)((1<(N)->getSignExtended(); + + if ((Imm = ExactLog2sub1(v))!=666) { // if ANDing with ((2^n)-1) for some n + return 1; // say so + } + + return 0; // fallthrough +} + static unsigned ponderIntegerAdditionWith(SDOperand N, unsigned& Imm) { if (N.getOpcode() != ISD::Constant) return 0; // if not adding a // constant, give up. @@ -967,15 +991,34 @@ assert(0 && "hmm, ISD::SIGN_EXTEND: shouldn't ever be reached. bad luck!\n"); .addReg(bogusTemp1).addReg(IA64::r0).addReg(IA64::r0).addReg(pTemp); break; } + // if not a bool, we just AND away: case MVT::i8: case MVT::i16: case MVT::i32: case MVT::i64: { Tmp1 = SelectExpr(N.getOperand(0)); + switch (ponderIntegerAndWith(N.getOperand(1), Tmp3)) { + case 1: // ANDing a constant that is 2^n-1 for some n + switch (Tmp3) { + case 8: // if AND 0x00000000000000FF, be quaint and use zxt1 + BuildMI(BB, IA64::ZXT1, 1, Result).addReg(Tmp1); + break; + case 16: // if AND 0x000000000000FFFF, be quaint and use zxt2 + BuildMI(BB, IA64::ZXT2, 1, Result).addReg(Tmp1); + break; + case 32: // if AND 0x00000000FFFFFFFF, be quaint and use zxt4 + BuildMI(BB, IA64::ZXT4, 1, Result).addReg(Tmp1); + break; + default: // otherwise, use dep.z to paste zeros + BuildMI(BB, IA64::DEPZ, 3, Result).addReg(Tmp1) + .addImm(0).addImm(Tmp3); + break; + } + return Result; // early exit + } // fallthrough and emit a simple AND: Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, IA64::AND, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; } } return Result;