source: svn/newcon3bcm2_21bu/magnum/commonutils/xdm/bxdm_pp_fp.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 8.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bxdm_pp_fp.c $
11 * $brcm_Revision: Hydra_Software_Devel/2 $
12 * $brcm_Date: 4/26/11 1:00p $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/xdm/bxdm_pp_fp.c $
19 *
20 * Hydra_Software_Devel/2   4/26/11 1:00p btosi
21 * SW7405-4736: tweaked the base 10 conversion code
22 *
23 * Hydra_Software_Devel/1   2/16/10 10:51a nilesh
24 * SW7405-2993: Initial XDM version
25 *
26 ***************************************************************************/
27
28#include "bstd.h"
29#include "bdbg.h"                /* Dbglib */
30#include "bxdm_pp_fp.h"
31
32BDBG_MODULE(BXDM_PPFP);
33
34const char BXDM_PictureProvider_P_DISPMGR_FP_NODE[]="DMFP:\t""$brcm_Revision: Hydra_Software_Devel/2 $";
35
36/* Fixed Point Arithmetic */
37void BXDM_PPFP_P_FixPtAdd(
38   const BXDM_PPFP_P_DataType* pstOperandA, 
39   const BXDM_PPFP_P_DataType* pstOperandB,
40   BXDM_PPFP_P_DataType* pstResult
41   )
42{
43   BXDM_PPFP_P_DataType stTempResult;
44   
45   BDBG_ASSERT(pstOperandA);
46   BDBG_ASSERT(pstOperandB);
47   BDBG_ASSERT(pstResult);
48   
49   /* TODO: Add overflow checking */   
50   stTempResult.uiWhole = pstOperandA->uiWhole + pstOperandB->uiWhole;
51   stTempResult.uiFractional = pstOperandA->uiFractional + pstOperandB->uiFractional;
52   
53   if ( stTempResult.uiFractional >= BXDM_PictureProvider_P_FixedPoint_FractionalOverflow )
54   {
55      stTempResult.uiWhole += 1;
56      stTempResult.uiFractional = stTempResult.uiFractional & (BXDM_PictureProvider_P_FixedPoint_FractionalOverflow - 1);
57   }
58
59   *pstResult = stTempResult;
60
61   return;
62}
63
64void BXDM_PPFP_P_FixPtSub(
65   const BXDM_PPFP_P_DataType* pstOperandA, 
66   const BXDM_PPFP_P_DataType* pstOperandB,
67   BXDM_PPFP_P_DataType* pstResult
68   )
69{
70   BXDM_PPFP_P_DataType stTempResult;
71   
72   BDBG_ASSERT(pstOperandA);
73   BDBG_ASSERT(pstOperandB);
74   BDBG_ASSERT(pstResult);
75   
76   /* TODO: Add underflow checking */   
77   stTempResult.uiWhole = pstOperandA->uiWhole - pstOperandB->uiWhole;
78   if ( pstOperandA->uiFractional >= pstOperandB->uiFractional )
79   {
80      stTempResult.uiFractional = pstOperandA->uiFractional - pstOperandB->uiFractional;
81   }
82   else
83   {
84      /* Do the carry */
85      stTempResult.uiWhole -= 1;
86      stTempResult.uiFractional = (BXDM_PictureProvider_P_FixedPoint_FractionalOverflow + pstOperandA->uiFractional) - pstOperandB->uiFractional;
87   }
88
89   *pstResult = stTempResult;
90
91   return;
92}
93
94void BXDM_PPFP_P_FixPtDiv(
95   const BXDM_PPFP_P_DataType* pstOperand,
96   const uint32_t uiDivisor,
97   BXDM_PPFP_P_DataType* pstResult
98   )
99{
100   uint32_t uiFractionalRemainder;
101   
102   BDBG_ASSERT(pstOperand);
103   BDBG_ASSERT(pstResult);
104   
105   if ( uiDivisor == 0 )
106   {
107      BDBG_WRN(("Divide by zero!"));
108      return;
109   }
110   
111   /* Copy operand into result */
112   *pstResult = *pstOperand;
113   
114   if ( uiDivisor == 1 )
115   {
116      return;
117   }
118
119   /* Do the divide */
120   
121   /* Carry a 1 into the fractional component */
122   if (pstResult->uiWhole)
123   {
124      pstResult->uiWhole--;
125      pstResult->uiFractional += BXDM_PictureProvider_P_FixedPoint_FractionalOverflow;
126   }
127   
128   /* Divide the fractional component */
129   uiFractionalRemainder = pstResult->uiFractional % uiDivisor;
130   pstResult->uiFractional /= uiDivisor;
131   
132   if (pstResult->uiWhole) 
133   {
134      /* Add the remainder from division of whole component to the
135       * fractional component */
136      pstResult->uiFractional += (((pstResult->uiWhole % uiDivisor) * BXDM_PictureProvider_P_FixedPoint_FractionalOverflow) + uiFractionalRemainder) / uiDivisor;
137     
138      /* Divide the whole component */
139      pstResult->uiWhole /= uiDivisor;
140     
141      /* Normalize the improper fractional component */
142      pstResult->uiWhole += pstResult->uiFractional / BXDM_PictureProvider_P_FixedPoint_FractionalOverflow;
143      pstResult->uiFractional %= BXDM_PictureProvider_P_FixedPoint_FractionalOverflow;   
144   }
145   
146   return;   
147}
148
149void BXDM_PPFP_P_FixPtMult(
150   const BXDM_PPFP_P_DataType* pstOperand,
151   const uint32_t uiMultiplier,
152   BXDM_PPFP_P_DataType* pstResult
153   )
154{
155   uint32_t i;
156   BXDM_PPFP_P_DataType stLocalResult;
157   BDBG_ASSERT(pstOperand);
158   BDBG_ASSERT(pstResult);
159
160   if (uiMultiplier == 0)
161   {
162      stLocalResult.uiWhole = 0;
163      stLocalResult.uiFractional = 0;
164   }
165   else
166   {
167      stLocalResult = *pstOperand;
168     
169      for (i = 1; i < uiMultiplier; i++)
170      {
171         BXDM_PPFP_P_FixPtAdd(
172            &stLocalResult,
173            pstOperand,
174            &stLocalResult
175            );
176      }
177   }
178
179   *pstResult = stLocalResult;
180   
181   return;   
182}
183
184void BXDM_PPFP_P_FixPtFractionalMul(
185   const BXDM_PPFP_P_DataType* pstOperand,
186   const uint16_t uiNumerator,
187   const uint16_t uiDenominator,
188   BXDM_PPFP_P_DataType* pstResult
189   )
190{
191   BDBG_ASSERT(pstOperand);
192   BDBG_ASSERT(pstResult);
193   
194   if ( uiDenominator == uiNumerator )
195   {
196      *pstResult = *pstOperand;
197   }
198   else if ( 0 == uiNumerator )
199   {
200      pstResult->uiWhole = 0;
201      pstResult->uiFractional = 0;
202   }
203   else 
204   {
205      pstResult->uiFractional = ( pstOperand->uiFractional * uiNumerator ) / uiDenominator ;
206      pstResult->uiFractional += ( pstOperand->uiWhole * uiNumerator ) % uiDenominator ;
207
208      pstResult->uiWhole = ( pstOperand->uiWhole * uiNumerator ) / uiDenominator ;
209
210      /* Check for overflow on the fractional component. */
211      if ( pstResult->uiFractional >= BXDM_PictureProvider_P_FixedPoint_FractionalOverflow )
212      {
213         pstResult->uiWhole += ( pstResult->uiFractional >> BXDM_PictureProvider_P_FixedPoint_FractionalShift );
214
215         pstResult->uiFractional = pstResult->uiFractional & BXDM_PictureProvider_P_FixedPoint_FractionalMask;
216      }
217   }
218
219   return;   
220}
221
222/* Convert the binary digits to the right of the decimal point to a base 10 number.
223 * Recall that the values of the digits are, 1/2, 1/4, 1/8, 1/16....
224 */
225static const uint32_t s_auiBinaryDecimalValueToBase10LUT[BXDM_PictureProvider_P_FixedPoint_FractionalBitsOfPrecision] = 
226{
227   500000,  /* 1/2 */ 
228   250000,  /* 1/4 */
229   125000,  /* 1/8 */
230    62500,  /* 1/16 */
231    31250,  /* 1/32 */
232    15625,  /* 1/64 */
233     7812,  /* 1/128 */
234     3906,  /* 1/256 */
235     1953,  /* 1/512 */
236      976,  /* 1/1024 */
237      488,  /* 1/2048 */
238      244,  /* 1/4096 */
239      122,  /* 1/8192 */
240       61,  /* 1/16384 */
241       30,  /* 1/32768 */
242       15   /* 1/65536 */
243};
244
245/* Precision of the preceding table. */
246#define BXDM_PictureProvider_P_FixedPoint_DecimalPrecision 6
247
248
249void BXDM_PPFP_P_FixPtBinaryFractionToBase10(
250   BXDM_PPFP_P_DataType* pstOperand,
251   uint32_t uiDstPrecision,
252   uint32_t * puiBase10Fraction
253   )
254{
255   uint32_t uiFracBase10=0;
256   uint32_t uiDivisor=1;
257
258   BDBG_ASSERT(pstOperand);
259   BDBG_ASSERT(puiBase10Fraction);
260
261   if ( 0 != pstOperand->uiFractional )
262   {
263      uint32_t uiMask=BXDM_PictureProvider_P_FixedPoint_FractionalMsbMask;
264      uint32_t i;
265
266      /* For each bit set in the binary fraction, add the appropriate
267       * base 10 value to the sum.
268       */
269      for ( i=0; i < BXDM_PictureProvider_P_FixedPoint_FractionalBitsOfPrecision ; i++ )
270      {
271         if ( pstOperand->uiFractional & uiMask  )
272         {
273            uiFracBase10 += s_auiBinaryDecimalValueToBase10LUT[ i ];
274         }
275
276         uiMask >>= 1;
277      }
278
279      /* Adjust the result to the desired number of places.
280       */
281      if ( uiDstPrecision < BXDM_PictureProvider_P_FixedPoint_DecimalPrecision )
282      {
283         i = BXDM_PictureProvider_P_FixedPoint_DecimalPrecision - uiDstPrecision;
284
285         /* This switch statement is a bit clunky and limited, but is saves doing a
286          * bunch of mulitplies in a loop to raise "uiDivisor" to the power of "i".
287          */
288         switch( i )
289         {
290            case 5:     uiDivisor = 100000;  break;
291            case 4:     uiDivisor = 10000;   break;
292            case 3:     uiDivisor = 1000;    break;
293            case 2:     uiDivisor = 100;     break;
294            case 1:     uiDivisor = 10;      break;
295            default:    uiDivisor = 1;       break;
296         }
297
298         uiFracBase10 /= uiDivisor;
299
300      }
301   }
302
303   *puiBase10Fraction = uiFracBase10;
304   
305   return;   
306}
307
Note: See TracBrowser for help on using the repository browser.