00001
00021 #include "if.h"
00022
00026
00030
00042 static inline int If_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
00043 static inline void If_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
00044 {
00045 int w;
00046 for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
00047 pOut[w] = ~pIn[w];
00048 }
00049 static inline void If_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
00050 {
00051 int w;
00052 for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
00053 pOut[w] = pIn[w];
00054 }
00055 static inline void If_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
00056 {
00057 int w;
00058 for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
00059 pOut[w] = ~(pIn0[w] & pIn1[w]);
00060 }
00061 static inline void If_TruthAnd( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
00062 {
00063 int w;
00064 for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
00065 pOut[w] = pIn0[w] & pIn1[w];
00066 }
00067
00080 void If_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int iVar )
00081 {
00082 static unsigned PMasks[4][3] = {
00083 { 0x99999999, 0x22222222, 0x44444444 },
00084 { 0xC3C3C3C3, 0x0C0C0C0C, 0x30303030 },
00085 { 0xF00FF00F, 0x00F000F0, 0x0F000F00 },
00086 { 0xFF0000FF, 0x0000FF00, 0x00FF0000 }
00087 };
00088 int nWords = If_TruthWordNum( nVars );
00089 int i, k, Step, Shift;
00090
00091 assert( iVar < nVars - 1 );
00092 if ( iVar < 4 )
00093 {
00094 Shift = (1 << iVar);
00095 for ( i = 0; i < nWords; i++ )
00096 pOut[i] = (pIn[i] & PMasks[iVar][0]) | ((pIn[i] & PMasks[iVar][1]) << Shift) | ((pIn[i] & PMasks[iVar][2]) >> Shift);
00097 }
00098 else if ( iVar > 4 )
00099 {
00100 Step = (1 << (iVar - 5));
00101 for ( k = 0; k < nWords; k += 4*Step )
00102 {
00103 for ( i = 0; i < Step; i++ )
00104 pOut[i] = pIn[i];
00105 for ( i = 0; i < Step; i++ )
00106 pOut[Step+i] = pIn[2*Step+i];
00107 for ( i = 0; i < Step; i++ )
00108 pOut[2*Step+i] = pIn[Step+i];
00109 for ( i = 0; i < Step; i++ )
00110 pOut[3*Step+i] = pIn[3*Step+i];
00111 pIn += 4*Step;
00112 pOut += 4*Step;
00113 }
00114 }
00115 else
00116 {
00117 for ( i = 0; i < nWords; i += 2 )
00118 {
00119 pOut[i] = (pIn[i] & 0x0000FFFF) | ((pIn[i+1] & 0x0000FFFF) << 16);
00120 pOut[i+1] = (pIn[i+1] & 0xFFFF0000) | ((pIn[i] & 0xFFFF0000) >> 16);
00121 }
00122 }
00123 }
00124
00138 void If_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase )
00139 {
00140 unsigned * pTemp;
00141 int i, k, Var = nVars - 1, Counter = 0;
00142 for ( i = nVarsAll - 1; i >= 0; i-- )
00143 if ( Phase & (1 << i) )
00144 {
00145 for ( k = Var; k < i; k++ )
00146 {
00147 If_TruthSwapAdjacentVars( pOut, pIn, nVarsAll, k );
00148 pTemp = pIn; pIn = pOut; pOut = pTemp;
00149 Counter++;
00150 }
00151 Var--;
00152 }
00153 assert( Var == -1 );
00154
00155 if ( !(Counter & 1) )
00156 If_TruthCopy( pOut, pIn, nVarsAll );
00157 }
00158
00170 static inline unsigned If_CutTruthPhase( If_Cut_t * pCut, If_Cut_t * pCut1 )
00171 {
00172 unsigned uPhase = 0;
00173 int i, k;
00174 for ( i = k = 0; i < (int)pCut->nLeaves; i++ )
00175 {
00176 if ( k == (int)pCut1->nLeaves )
00177 break;
00178 if ( pCut->pLeaves[i] < pCut1->pLeaves[k] )
00179 continue;
00180 assert( pCut->pLeaves[i] == pCut1->pLeaves[k] );
00181 uPhase |= (1 << i);
00182 k++;
00183 }
00184 return uPhase;
00185 }
00186
00198 void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
00199 {
00200 extern void Kit_FactorTest( unsigned * pTruth, int nVars );
00201
00202
00203 if ( fCompl0 ^ pCut0->fCompl )
00204 If_TruthNot( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit );
00205 else
00206 If_TruthCopy( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit );
00207 If_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nLimit, If_CutTruthPhase(pCut, pCut0) );
00208
00209 if ( fCompl1 ^ pCut1->fCompl )
00210 If_TruthNot( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit );
00211 else
00212 If_TruthCopy( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit );
00213 If_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nLimit, If_CutTruthPhase(pCut, pCut1) );
00214
00215 assert( pCut->fCompl == 0 );
00216 if ( pCut->fCompl )
00217 If_TruthNand( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit );
00218 else
00219 If_TruthAnd( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit );
00220
00221
00222
00223
00224 }
00225
00229
00230