| 1 | /* |
|---|
| 2 | * ==================================================== |
|---|
| 3 | * |
|---|
| 4 | * Portions of file Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|---|
| 5 | * |
|---|
| 6 | * ==================================================== |
|---|
| 7 | */ |
|---|
| 8 | /*************************************************************************** |
|---|
| 9 | * Copyright (c) 2003-2011, Broadcom Corporation |
|---|
| 10 | * All Rights Reserved |
|---|
| 11 | * Confidential Property of Broadcom Corporation |
|---|
| 12 | * |
|---|
| 13 | * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE |
|---|
| 14 | * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR |
|---|
| 15 | * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 16 | * |
|---|
| 17 | * $brcm_Workfile: bmth.c $ |
|---|
| 18 | * $brcm_Revision: Hydra_Software_Devel/15 $ |
|---|
| 19 | * $brcm_Date: 12/20/11 6:18p $ |
|---|
| 20 | * |
|---|
| 21 | * Module Description: |
|---|
| 22 | * |
|---|
| 23 | * Revision History: |
|---|
| 24 | * |
|---|
| 25 | * $brcm_Log: /magnum/commonutils/mth/bmth.c $ |
|---|
| 26 | * |
|---|
| 27 | * Hydra_Software_Devel/15 12/20/11 6:18p farshidf |
|---|
| 28 | * SW3461-108: fix the log math function |
|---|
| 29 | * |
|---|
| 30 | * Hydra_Software_Devel/14 4/20/11 11:38a farshidf |
|---|
| 31 | * SWDTV-6190: add the BMTH_2560log10 used by frontend code |
|---|
| 32 | * |
|---|
| 33 | * Hydra_Software_Devel/13 6/25/10 6:17p VISHK |
|---|
| 34 | * SW7405-4552: Update bmth.h to include SunPro license |
|---|
| 35 | * |
|---|
| 36 | * Hydra_Software_Devel/12 2/25/10 4:29p albertl |
|---|
| 37 | * SW7550-273: Changed HILO 64 bit division to use David's bit shifting |
|---|
| 38 | * implementation with 64-bit intermediates. |
|---|
| 39 | * |
|---|
| 40 | * Hydra_Software_Devel/11 12/10/07 12:38p albertl |
|---|
| 41 | * PR37989: Removed functions using floats that are no longer needed. |
|---|
| 42 | * |
|---|
| 43 | * Hydra_Software_Devel/10 6/12/07 1:52p albertl |
|---|
| 44 | * PR31093: Added new 64-bit hi lo math operations. |
|---|
| 45 | * |
|---|
| 46 | * Hydra_Software_Devel/8 9/22/04 12:38p dlwin |
|---|
| 47 | * PR 12728: Modified to support compiling with -O and with -pedantic |
|---|
| 48 | * |
|---|
| 49 | * Hydra_Software_Devel/7 8/12/04 4:15p garylin |
|---|
| 50 | * PR12273: use SDE math lib instead of Brcm math |
|---|
| 51 | * |
|---|
| 52 | * Hydra_Software_Devel/6 12/30/03 6:29p dlwin |
|---|
| 53 | * PR 9160: Removed warning from GNU C with -W |
|---|
| 54 | * |
|---|
| 55 | * Hydra_Software_Devel/5 9/30/03 6:27p dlwin |
|---|
| 56 | * Removed warnings when compiled for debug. |
|---|
| 57 | * |
|---|
| 58 | * Hydra_Software_Devel/4 9/18/03 5:33p dlwin |
|---|
| 59 | * Removed warnings |
|---|
| 60 | * |
|---|
| 61 | * Hydra_Software_Devel/3 9/8/03 6:25p dlwin |
|---|
| 62 | * Updated API function parameter comment for DocJet. |
|---|
| 63 | * |
|---|
| 64 | * Hydra_Software_Devel/2 9/8/03 9:47a dlwin |
|---|
| 65 | * Added code to implement these math functions. |
|---|
| 66 | * |
|---|
| 67 | * Hydra_Software_Devel/1 9/3/03 3:31p dlwin |
|---|
| 68 | * Initial version |
|---|
| 69 | * |
|---|
| 70 | ***************************************************************************/ |
|---|
| 71 | #include "bstd.h" |
|---|
| 72 | #include "bmth.h" |
|---|
| 73 | #include "bmth_fix.h" |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | /******************************************************************************* |
|---|
| 77 | * |
|---|
| 78 | * This file was implemented using the code from previous project. To |
|---|
| 79 | * minimize changes, the code has not been reformated. |
|---|
| 80 | * |
|---|
| 81 | * |
|---|
| 82 | *******************************************************************************/ |
|---|
| 83 | |
|---|
| 84 | /* BDBG_MODULE(bmth); enable when adding debug prints */ |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | void BMTH_HILO_64TO64_Neg(uint32_t xhi, uint32_t xlo, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 88 | { |
|---|
| 89 | *poutlo = -(int32_t)xlo; |
|---|
| 90 | *pouthi = -(int32_t)xhi - *poutlo; |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | void BMTH_HILO_32TO64_Mul(uint32_t x, uint32_t y, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 94 | { |
|---|
| 95 | uint32_t xhi, xlo, yhi, ylo, ahi, alo, bhi, blo; |
|---|
| 96 | |
|---|
| 97 | xhi = (x >> 16) & 0xffff; |
|---|
| 98 | xlo = x & 0xffff; |
|---|
| 99 | yhi = (y >> 16) & 0xffff; |
|---|
| 100 | ylo = y & 0xffff; |
|---|
| 101 | |
|---|
| 102 | *poutlo = xlo * ylo; |
|---|
| 103 | |
|---|
| 104 | BMTH_HILO_64TO64_Add(0, (xhi * ylo), 0, (yhi * xlo), &ahi, &alo); |
|---|
| 105 | BMTH_HILO_64TO64_Add(0, ((*poutlo >> 16) & 0xffff), ahi, alo, &bhi, &blo); |
|---|
| 106 | |
|---|
| 107 | *poutlo = (*poutlo & 0xffff) | ((blo & 0xffff) << 16); |
|---|
| 108 | *pouthi = ((blo >> 16) & 0xffff) | ((bhi &0xffff) << 16); |
|---|
| 109 | *pouthi += xhi * yhi; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | void BMTH_HILO_64TO64_Mul(uint32_t xhi, uint32_t xlo, uint32_t yhi, uint32_t ylo, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 113 | { |
|---|
| 114 | BMTH_HILO_32TO64_Mul(xlo, ylo, pouthi, poutlo); |
|---|
| 115 | *pouthi += (xhi * ylo) + (xlo * yhi); |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | void BMTH_HILO_64TO64_Add(uint32_t xhi, uint32_t xlo, uint32_t yhi, uint32_t ylo, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 119 | { |
|---|
| 120 | uint32_t tempxlo = xlo; |
|---|
| 121 | uint32_t tempxhi = xhi; |
|---|
| 122 | uint32_t tempylo = ylo; |
|---|
| 123 | uint32_t tempyhi = yhi; |
|---|
| 124 | |
|---|
| 125 | *poutlo = tempxlo + tempylo; |
|---|
| 126 | *pouthi = tempxhi + tempyhi + (*poutlo < tempylo); |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | #if 0 |
|---|
| 130 | void BMTH_HILO_64TO64_Div32(uint32_t xhi, uint32_t xlo, uint32_t y, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 131 | { |
|---|
| 132 | uint32_t newxhi = xhi; |
|---|
| 133 | uint32_t newxlo = xlo; |
|---|
| 134 | uint32_t newq1 = 0; |
|---|
| 135 | uint32_t r = 0; |
|---|
| 136 | uint32_t curshift = 32; /* shift value of current 32 bits being divided */ |
|---|
| 137 | uint32_t rbits = 0; /* remainder bits */ |
|---|
| 138 | uint32_t xlowbits = 0; /* bits to concatenate from xlo with r to form new xhi*/ |
|---|
| 139 | *pouthi = 0; |
|---|
| 140 | *poutlo = 0; |
|---|
| 141 | uint32_t loop = 0; |
|---|
| 142 | |
|---|
| 143 | while (1) |
|---|
| 144 | { |
|---|
| 145 | newq1 = (newxhi / y); |
|---|
| 146 | r = newxhi % y; |
|---|
| 147 | |
|---|
| 148 | BMTH_HILO_64TO64_Add(*pouthi, *poutlo, |
|---|
| 149 | (curshift > 0)? (newq1 >> (32 - curshift)) : 0, |
|---|
| 150 | (curshift < 32)? (newq1 << curshift) : 0, |
|---|
| 151 | pouthi, poutlo); |
|---|
| 152 | |
|---|
| 153 | if (curshift == 0) |
|---|
| 154 | { |
|---|
| 155 | break; |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | rbits = BMTH_FIX_LOG2(r) + 1; |
|---|
| 159 | xlowbits = 32 - rbits; |
|---|
| 160 | |
|---|
| 161 | if (xlowbits > curshift) |
|---|
| 162 | { |
|---|
| 163 | xlowbits = curshift; |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | newxhi = (r << xlowbits) | (newxlo >> (32 - xlowbits)); |
|---|
| 167 | newxlo = newxlo << xlowbits; |
|---|
| 168 | curshift -= xlowbits; |
|---|
| 169 | } |
|---|
| 170 | printf("loop %d\n", loop); |
|---|
| 171 | } |
|---|
| 172 | #else |
|---|
| 173 | #define BMTH_PRINTF(x) |
|---|
| 174 | |
|---|
| 175 | void BMTH_HILO_64TO64_Div32(uint32_t xhi, uint32_t xlo, uint32_t y, uint32_t *pouthi, uint32_t *poutlo) |
|---|
| 176 | { |
|---|
| 177 | /* this algo uses 64 bit add/subtract/bitshift, but not 64 bit multiply/divide */ |
|---|
| 178 | uint64_t xx = (uint64_t)xhi << 32 | xlo; |
|---|
| 179 | uint64_t yy = y; |
|---|
| 180 | uint64_t result = 0; |
|---|
| 181 | |
|---|
| 182 | if (y == 0) { |
|---|
| 183 | *pouthi = 0; |
|---|
| 184 | *poutlo = 0; |
|---|
| 185 | return; |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | while (1) { |
|---|
| 189 | uint64_t prev_yy = 0; |
|---|
| 190 | uint64_t temp_yy = yy; |
|---|
| 191 | uint64_t shift = 0; |
|---|
| 192 | |
|---|
| 193 | BMTH_PRINTF(("%llx / %llx = \n", xx, yy)); |
|---|
| 194 | while (xx >= temp_yy) { |
|---|
| 195 | if (shift == 0) |
|---|
| 196 | shift = 1; |
|---|
| 197 | else |
|---|
| 198 | shift <<= 1; |
|---|
| 199 | prev_yy = temp_yy; /* if we fail the next test, prev_yy is it */ |
|---|
| 200 | temp_yy <<= 1; |
|---|
| 201 | } |
|---|
| 202 | if (!shift) break; |
|---|
| 203 | |
|---|
| 204 | BMTH_PRINTF(("%llx -= %llx, %llx += %llx\n", xx, prev_yy, result, shift)); |
|---|
| 205 | xx -= prev_yy; |
|---|
| 206 | result += shift; |
|---|
| 207 | } |
|---|
| 208 | *pouthi = (uint32_t)(result >> 32); |
|---|
| 209 | *poutlo = (uint32_t)(result & 0xFFFFFFFF); |
|---|
| 210 | BMTH_PRINTF(("result = %08x%08x\n", *pouthi, *poutlo)); |
|---|
| 211 | } |
|---|
| 212 | #endif |
|---|
| 213 | |
|---|
| 214 | uint32_t BMTH_2560log10(uint32_t x) |
|---|
| 215 | { |
|---|
| 216 | int32_t x1; |
|---|
| 217 | int32_t x2; |
|---|
| 218 | int32_t x3; |
|---|
| 219 | int32_t x4; |
|---|
| 220 | |
|---|
| 221 | if (x == 0) |
|---|
| 222 | return 0; |
|---|
| 223 | |
|---|
| 224 | x1 = 31; |
|---|
| 225 | while (!((x >> x1) & 1)) |
|---|
| 226 | x1 = x1-1; |
|---|
| 227 | x1 = x1+1; |
|---|
| 228 | |
|---|
| 229 | if (x1 > 20) |
|---|
| 230 | x2 = (int32_t)(x >> (x1 - 8)); |
|---|
| 231 | else |
|---|
| 232 | x2 = (int32_t)((x << 8) >> x1); |
|---|
| 233 | |
|---|
| 234 | x3 = -24381739 + x2*(62348 + (x2 << 7)); |
|---|
| 235 | x4 = 5907991 + (x2 << 16); |
|---|
| 236 | |
|---|
| 237 | return (unsigned)((770*(x3/(x4 >> 8) + (x1 << 8))) >> 8); |
|---|
| 238 | } |
|---|