Line data Source code
1 : /* 2 : ============================================================================ 3 : File: ENHUL32.C v.1.0 - 01.July.2018 4 : ============================================================================ 5 : 6 : ENHANCED UNSIGNED 32-BIT ARITHMETIC OPERATORS 7 : History: 8 : v.0.5 - 21.March.2014 9 : 10 : ============================================================================ 11 : */ 12 : 13 : /***************************************************************************** 14 : * 15 : * Enhanced Unsigned 32 bit operators : 16 : * see complete list in .h file 17 : * 18 : *****************************************************************************/ 19 : 20 : /***************************************************************************** 21 : * 22 : * Include-Files 23 : * 24 : *****************************************************************************/ 25 : #include <stdio.h> 26 : #include <stdlib.h> 27 : #include "stl.h" 28 : #include "stl.h" 29 : 30 : #define WMC_TOOL_SKIP 31 : 32 : /***************************************************************************** 33 : * 34 : * Constants and Globals 35 : * 36 : *****************************************************************************/ 37 : 38 : 39 : /***************************************************************************** 40 : * 41 : * Functions 42 : * 43 : *****************************************************************************/ 44 : #ifdef ENH_U_32_BIT_OPERATOR 45 : 46 : /*___________________________________________________________________________ 47 : | | 48 : | Function Name : UL_deposit_l | 49 : | | 50 : | Purpose : | 51 : | | 52 : | Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The | 53 : | 16 MS bits of the output are not sign extended. | 54 : |___________________________________________________________________________| 55 : */ 56 : 57 15276781 : UWord32 UL_deposit_l( UWord16 uvar ) 58 : { 59 : UWord32 UL_result; 60 15276781 : UL_result = (UWord32) uvar; /* no sign extension*/ 61 : #ifdef WMOPS 62 : multiCounter[currCounter].UL_deposit_l++; 63 : #endif 64 15276781 : return ( UL_result ); 65 : } 66 : 67 : /*___________________________________________________________________________ 68 : | | 69 : | Function Name : UL_addNs | 70 : | | 71 : | Purpose : | 72 : | | 73 : | 32 bits addition of the two unsigned 32 bits variables | 74 : | (L_var1+L_var2) with overflow control, but without saturation | 75 : | | 76 : | Outputs : | 77 : | | 78 : | *wrap = 1 if wrap occured, otherwize 0 | 79 : | | 80 : | Return Value : | 81 : | | 82 : | UL_var3 = modulo(UL_var1+UL_var2,32) | 83 : |___________________________________________________________________________| 84 : */ 85 : 86 585806078 : UWord32 UL_addNs( UWord32 UL_var1, UWord32 UL_var2, UWord16 *wrap ) 87 : { 88 : UWord32 UL_var3; 89 : 90 : /* STL Overflow flag is not updated */ 91 585806078 : UL_var3 = UL_var1 + UL_var2; /* 32-bit wrap may occur, like in C */ 92 : 93 585806078 : if ( ( (UWord64) UL_var1 + (UWord64) UL_var2 ) > 0xFFFFFFFFU ) 94 : { 95 11482461 : *wrap = 1; /* wrapped output */ 96 : } 97 : else 98 : { 99 574323617 : *wrap = 0; 100 : } 101 : 102 : #ifdef WMOPS 103 : multiCounter[currCounter].UL_addNs++; 104 : #endif 105 : 106 585806078 : return UL_var3; 107 : } 108 : 109 : /*___________________________________________________________________________ 110 : | | 111 : | Function Name : UL_subNs | 112 : | | 113 : | Purpose : | 114 : | | 115 : | 32 bits subtraction of the two unsigned 32 bits variables | 116 : | (L_var1-L_var2) with overflow control, but without saturation | 117 : | | 118 : | Outputs : | 119 : | | 120 : | *sgn = 1 if wrap (to "negative" occured, otherwise 0) | 121 : | | 122 : | Return Value : | 123 : | | 124 : | UL_var3 = modulo(UL_var1-UL_var2,32) | 125 : |___________________________________________________________________________| 126 : */ 127 : 128 722488896 : UWord32 UL_subNs( UWord32 UL_var1, UWord32 UL_var2, UWord16 *sgn ) 129 : { 130 : UWord32 UL_var3; 131 : 132 722488896 : UL_var3 = UL_var1 - UL_var2; /*wrap may occur, like in C */ 133 722488896 : if ( UL_var1 >= UL_var2 ) 134 : { 135 720503934 : *sgn = 0; 136 : } 137 : else 138 : { 139 1984962 : *sgn = 1; /* "negative", wrapped output */ 140 : } 141 : 142 : #ifdef WMOPS 143 : multiCounter[currCounter].UL_subNs++; 144 : #endif 145 722488896 : return UL_var3; 146 : } 147 : 148 : /*________________________________________________________________________________ 149 : | | 150 : | Function Name : Mpy_32_16_uu | 151 : | | 152 : | Purpose : | 153 : | | 154 : | Multiplies the 2 unsigned values UL_var1 and uvar2. | 155 : | The operation is performed in fractional mode : | 156 : | - UL_var1 is supposed to be in Q32 format. | 157 : | - var2 is supposed to be in Q16 format. | 158 : | - The result is produced in Q48 format : UL_varout_h points to the | 159 : | 32 MSBits while varout_l points to the 16 LSBits. | 160 : | | 161 : | Complexity weight : 2 | 162 : | | 163 : | Inputs : | 164 : | | 165 : | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in | 166 : | the range : 0x0000 0000 <= L_var1 <= 0xffff ffff. | 167 : | | 168 : | var2 16 bit short unsigned integer (UWord16) whose value falls in | 169 : | the range : 0x0000 <= var2 <= 0x0000 ffff. | 170 : | | 171 : | Outputs : | 172 : | | 173 : | *UL_varout_h 32 bit long unsigned integer (UWord32) whose value falls in | 174 : | the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff. | 175 : | | 176 : | *varout_l 16 bit short unsigned integer (UWord16) whose value falls in | 177 : | the range : 0x0000 0000 <= varout_l <= 0x0000 ffff. | 178 : | | 179 : | Return Value : | 180 : | | 181 : | none | 182 : |________________________________________________________________________________| 183 : */ 184 2059347 : void Mpy_32_16_uu( UWord32 UL_var1, UWord16 uvar2, UWord32 *UL_varout_h, UWord16 *varout_l ) 185 : { 186 : UWord64 UL64_var1; 187 : 188 : /* 4294967295 * 65535 < 281474976710655 */ 189 : /* (uint64(2)^16-1 )*(uint64(2)^32-1) < (uint64(2)^(16+32)-1) */ 190 2059347 : UL64_var1 = ( (UWord64) UL_var1 ) * ( (UWord64) uvar2 ); 191 2059347 : *varout_l = (UWord16) UL64_var1; 192 2059347 : *UL_varout_h = (UWord32) ( UL64_var1 >> 16 ); 193 : 194 : #ifdef WMOPS 195 : multiCounter[currCounter].Mpy_32_16_uu++; 196 : #endif /* if WMOPS */ 197 : 198 2059347 : return; 199 : } 200 : 201 : /*__________________________________________________________________________________ 202 : | | 203 : | Function Name : Mpy_32_32_uu | 204 : | | 205 : | Purpose : | 206 : | | 207 : | Multiplies the 2 unsigned values UL_var1 and UL_var2. | 208 : | The operation is performed in fractional mode : | 209 : | - UL_var1 and UL_var2 are supposed to be in Q32 format. | 210 : | - The result is produced in Q64 format : UL_varout_h points to the | 211 : | 32 MSBits while UL_varout_l points to the 32 LSBits. | 212 : | | 213 : | Complexity weight : 4 | 214 : | | 215 : | Inputs : | 216 : | | 217 : | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the | 218 : | range : 0x0000 0000 <= L_var1 <= 0xffff ffff. | 219 : | | 220 : | UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the | 221 : | range : 0x0000 0000 <= L_var2 <= 0xffff ffff. | 222 : | | 223 : | Outputs : | 224 : | | 225 : | *UL_varout_h 32 bit long signed integer (Word32) whose value falls in | 226 : | the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff. | 227 : | | 228 : | *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in | 229 : | the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff. | 230 : | | 231 : | Return Value : | 232 : | | 233 : | none | 234 : |__________________________________________________________________________________| 235 : */ 236 11653858 : void Mpy_32_32_uu( UWord32 UL_var1, UWord32 UL_var2, UWord32 *UL_varout_h, UWord32 *UL_varout_l ) 237 : { 238 : UWord64 UL64_var1; 239 : /* (uint64(2)^32-1 )*(uint64(2)^32-1) < (uint64(2)^(32+32)-1) */ 240 11653858 : UL64_var1 = ( (UWord64) UL_var1 ) * ( (UWord64) UL_var2 ); 241 11653858 : *UL_varout_h = (UWord32) ( UL64_var1 >> 32 ); 242 11653858 : *UL_varout_l = (UWord32) ( UL64_var1 ); 243 : 244 : #ifdef WMOPS 245 : multiCounter[currCounter].Mpy_32_32_uu++; 246 : #endif /* if WMOPS */ 247 : 248 11653858 : return; 249 : } 250 : 251 : /*_____________________________________________________________________________________ 252 : | | 253 : | Function Name : UL_Mpy_32_32 | 254 : | | 255 : | Purpose : | 256 : | | 257 : | Multiplies the 2 unsigned values UL_var1 and UL_var2 | 258 : | and returns the lower 32 bits, without saturation control. | 259 : | | 260 : | - UL_var1 and UL_var2 are supposed to be in Q32 format. | 261 : | - The result is produced in Q64 format, the 32 LSBits. | 262 : | | 263 : | operates like a regular 32-by-32 bit unsigned int multiplication in ANSI-C. | 264 : | UWord32) = (unsigned int)*(unsigned int); | 265 : | | 266 : | | 267 : | Complexity weight : 2 | 268 : | | 269 : | Inputs : | 270 : | | 271 : | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the | 272 : | range : 0x0000 0000 <= UL_var1 <= 0xffff ffff. | 273 : | | 274 : | UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the | 275 : | range : 0x0000 0000 <= UL_var2 <= 0xffff ffff. | 276 : | | 277 : | Outputs : | 278 : | | 279 : | none | 280 : | | 281 : | Return Value : | 282 : | *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in | 283 : | the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff. | 284 : | | 285 : |_____________________________________________________________________________________| 286 : */ 287 1948298100 : UWord32 UL_Mpy_32_32( UWord32 UL_var1, UWord32 UL_var2 ) 288 : { 289 : UWord32 UL_varout_l; 290 : 291 : #define MASK32 0xFFFFFFFFU 292 : /* MASK32 may be needed in case Hardware is using larger than 32 bits for UWord32 type */ 293 1948298100 : UL_varout_l = ( UL_var1 & MASK32 ) * ( UL_var2 & MASK32 ); 294 1948298100 : UL_varout_l = UL_varout_l & MASK32; 295 : #undef MASK32 296 : 297 : #ifdef WMOPS 298 : multiCounter[currCounter].UL_Mpy_32_32++; 299 : #endif /* if WMOPS */ 300 : 301 1948298100 : return UL_varout_l; 302 : } 303 : 304 : 305 : #ifdef STL_TYPECASTS 306 : /* (Reuse of existing signed STL "L" operators) with 307 : typecasting to make the resulting "UL" code a lot cleaner and more readable. */ 308 : 309 691536761 : UWord32 UL_lshl( UWord32 UL_var1, Word16 var2 ) 310 : { 311 691536761 : return ( (UWord32) L_lshl( (Word32) UL_var1, var2 ) ); 312 : } 313 : 314 667052342 : UWord32 UL_lshr( UWord32 UL_var1, Word16 var2 ) 315 : { 316 667052342 : return ( (UWord32) L_lshr( (Word32) UL_var1, var2 ) ); 317 : } 318 : 319 6401776 : UWord32 UL_and( UWord32 UL_var1, UWord32 UL_var2 ) 320 : { 321 6401776 : return (UWord32) L_and( (Word32) UL_var1, (Word32) UL_var2 ); 322 : } 323 : 324 24659695 : UWord32 UL_or( UWord32 UL_var1, UWord32 UL_var2 ) 325 : { 326 24659695 : return (UWord32) L_or( (Word32) UL_var1, (Word32) UL_var2 ); 327 : } 328 : 329 0 : UWord32 UL_xor( UWord32 UL_var1, UWord32 UL_var2 ) 330 : { 331 0 : return (UWord32) L_xor( (Word32) UL_var1, (Word32) UL_var2 ); 332 : } 333 : 334 577292 : UWord32 UL_deposit_h( UWord16 uvar1 ) 335 : { 336 577292 : return (UWord32) L_deposit_h( (Word32) uvar1 ); 337 : } 338 : 339 0 : UWord16 u_extract_h( UWord32 UL_var1 ) 340 : { 341 0 : return (UWord16) extract_h( (Word32) UL_var1 ); 342 : } 343 : 344 83578398 : UWord16 u_extract_l( UWord32 UL_var1 ) 345 : { 346 83578398 : return (UWord16) extract_l( (Word32) UL_var1 ); 347 : } 348 : 349 : /* enable convenient reuse of Non-saturating UL_subNs , UL_addNs while "D"iscarding the sgn/wrap output flags */ 350 717222901 : UWord32 UL_subNsD( UWord32 UL_var1, UWord32 UL_var2 ) 351 : { 352 : UWord16 dummy_sign; 353 717222901 : return UL_subNs( UL_var1, UL_var2, &dummy_sign ); 354 : } 355 : 356 585419239 : UWord32 UL_addNsD( UWord32 UL_var1, UWord32 UL_var2 ) 357 : { 358 : UWord16 dummy_wrap; 359 585419239 : return UL_addNs( UL_var1, UL_var2, &dummy_wrap ); 360 : } 361 : #endif 362 : 363 : #endif /* ENH_U_32_BIT_OPERATOR */ 364 : #undef WMC_TOOL_SKIP 365 : 366 : /* end of file */