diff options
Diffstat (limited to 'third_party/g7221/common/stl-files')
-rw-r--r-- | third_party/g7221/common/stl-files/basop32.c | 2724 | ||||
-rw-r--r-- | third_party/g7221/common/stl-files/basop32.h | 111 | ||||
-rw-r--r-- | third_party/g7221/common/stl-files/count.c | 303 | ||||
-rw-r--r-- | third_party/g7221/common/stl-files/count.h | 207 | ||||
-rw-r--r-- | third_party/g7221/common/stl-files/typedef.h | 55 |
5 files changed, 3400 insertions, 0 deletions
diff --git a/third_party/g7221/common/stl-files/basop32.c b/third_party/g7221/common/stl-files/basop32.c new file mode 100644 index 00000000..86d97dd6 --- /dev/null +++ b/third_party/g7221/common/stl-files/basop32.c @@ -0,0 +1,2724 @@ +/* v.1.0 - 26.Jan.2000 + ============================================================================= + + U U GGG SSSS TTTTT + U U G S T + U U G GG SSSS T + U U G G S T + UUU GG SSS T + + ======================================== + ITU-T - USER'S GROUP ON SOFTWARE TOOLS + ======================================== + + ============================================================= + COPYRIGHT NOTE: This source code, and all of its derivations, + is subject to the "ITU-T General Public License". Please have + it read in the distribution disk, or in the ITU-T + Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO + CODING STANDARDS". + ============================================================= + +MODULE: BASOP, BASIC OPERATORS + +ORIGINAL BY: + Incorporated from anonymous contributions for + ETSI Standards as well as G.723.1, G.729, and G.722.1 + +DESCRIPTION: + This file contains the definition of 16- and 32-bit basic + operators to be used in the implementation of signal + processing algorithms. The basic operators try to resemble + assembly language instructions that are commonly found in + digital signal processor (DSP) CPUs, thus allowing algorithm + C-code implementations more directly mapeable to DSP assembly + code. + + ********************************************************* + NOTE: so far, this module does not have a demo program! + ********************************************************* + +FUNCTIONS: + Defined in basop.h. Self-documentation within each function. + +HISTORY: + 26.Jan.00 v1.0 Incorporated to the STL from updated G.723.1/G.729 + basic operator library (based on basicop2.c) and + G.723.1's basop.c [L_mls(), div_l(), i_mult()] + 05.Jul.00 v1.1 Added 32-bit shiftless accumulation basic + operators (L_msu0, L_mac0, L_mult0). Improved + documentation for i_mult(). + ============================================================================= +*/ + +/*___________________________________________________________________________ + | | + | Basic arithmetic operators. | + | | + | $Id $ + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Include-Files | + |___________________________________________________________________________| +*/ + +#include <stdio.h> +#include <stdlib.h> +#include "typedef.h" +#include "basop32.h" + +#if (WMOPS) +#include "count.h" +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; + +#endif + +/*___________________________________________________________________________ + | | + | Local Functions | + |___________________________________________________________________________| +*/ +Word16 saturate (Word32 L_var1); + +/*___________________________________________________________________________ + | | + | Constants and Globals | + |___________________________________________________________________________| +*/ +Flag Overflow = 0; +Flag Carry = 0; + +/*___________________________________________________________________________ + | | + | Functions | + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Function Name : saturate | + | | + | Purpose : | + | | + | Limit the 32 bit input to the range of a 16 bit word. | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 saturate (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) + { + Overflow = 1; + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) + { + Overflow = 1; + var_out = MIN_16; + } + else + { + var_out = extract_l (L_var1); +#if (WMOPS) + multiCounter[currCounter].extract_l--; +#endif + } + + return (var_out); +} +/* ------------------------- End of saturate() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : add | + | | + | Purpose : | + | | + | Performs the addition (var1+var2) with overflow control and saturation;| + | the 16 bit result is set at +32767 when overflow occurs or at -32768 | + | when underflow occurs. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_sum; + + L_sum = (Word32) var1 + var2; + var_out = saturate (L_sum); +#if (WMOPS) + multiCounter[currCounter].add++; +#endif + return (var_out); +} +/* ------------------------- End of add() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : sub | + | | + | Purpose : | + | | + | Performs the subtraction (var1+var2) with overflow control and satu- | + | ration; the 16 bit result is set at +32767 when overflow occurs or at | + | -32768 when underflow occurs. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 sub (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = saturate (L_diff); +#if (WMOPS) + multiCounter[currCounter].sub++; +#endif + return (var_out); +} +/* ------------------------- End of sub() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : abs_s | + | | + | Purpose : | + | | + | Absolute value of var1; abs_s(-32768) = 32767. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 abs_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0X8000) + { + var_out = MAX_16; + } + else + { + if (var1 < 0) + { + var_out = -var1; + } + else + { + var_out = var1; + } + } +#if (WMOPS) + multiCounter[currCounter].abs_s++; +#endif + return (var_out); +} +/* ------------------------- End of abs_s() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : shl | + | | + | Purpose : | + | | + | Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill| + | the var2 LSB of the result. If var2 is negative, arithmetically shift | + | var1 right by -var2 with sign extension. Saturate the result in case of | + | underflows or overflows. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 shl (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 result; + + if (var2 < 0) + { + if (var2 < -16) + var2 = -16; + var_out = shr (var1, (Word16) -var2); +#if (WMOPS) + multiCounter[currCounter].shr--; +#endif + } + else + { + result = (Word32) var1 *((Word32) 1 << var2); + + if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) + { + Overflow = 1; + var_out = (var1 > 0) ? MAX_16 : MIN_16; + } + else + { + var_out = extract_l (result); +#if (WMOPS) + multiCounter[currCounter].extract_l--; +#endif + } + } +#if (WMOPS) + multiCounter[currCounter].shl++; +#endif + return (var_out); +} +/* ------------------------- End of shl() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : shr | + | | + | Purpose : | + | | + | Arithmetically shift the 16 bit input var1 right var2 positions with | + | sign extension. If var2 is negative, arithmetically shift var1 left by | + | -var2 with sign extension. Saturate the result in case of underflows or | + | overflows. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 shr (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) + { + if (var2 < -16) + var2 = -16; + var_out = shl (var1, (Word16) -var2); +#if (WMOPS) + multiCounter[currCounter].shl--; +#endif + } + else + { + if (var2 >= 15) + { + var_out = (var1 < 0) ? -1 : 0; + } + else + { + if (var1 < 0) + { + var_out = ~((~var1) >> var2); + } + else + { + var_out = var1 >> var2; + } + } + } + +#if (WMOPS) + multiCounter[currCounter].shr++; +#endif + return (var_out); +} +/* ------------------------- End of shr() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : mult | + | | + | Purpose : | + | | + | Performs the multiplication of var1 by var2 and gives a 16 bit result | + | which is scaled i.e.: | + | mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and | + | mult(-32768,-32768) = 32767. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 mult (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_product; + + L_product = (Word32) var1 *(Word32) var2; + + L_product = (L_product & (Word32) 0xffff8000L) >> 15; + + if (L_product & (Word32) 0x00010000L) + L_product = L_product | (Word32) 0xffff0000L; + + var_out = saturate (L_product); +#if (WMOPS) + multiCounter[currCounter].mult++; +#endif + return (var_out); +} +/* ------------------------- End of mult() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_mult | + | | + | Purpose : | + | | + | L_mult is the 32 bit result of the multiplication of var1 times var2 | + | with one shift left i.e.: | + | L_mult(var1,var2) = L_shl((var1 times var2),1) and | + | L_mult(-32768,-32768) = 2147483647. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_mult (Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + + if (L_var_out != (Word32) 0x40000000L) + { + L_var_out *= 2; + } + else + { + Overflow = 1; + L_var_out = MAX_32; + } + +#if (WMOPS) + multiCounter[currCounter].L_mult++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_mult() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : negate | + | | + | Purpose : | + | | + | Negate var1 with saturation, saturate in the case where input is -32768:| + | negate(var1) = sub(0,var1). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; +#if (WMOPS) + multiCounter[currCounter].negate++; +#endif + return (var_out); +} +/* ------------------------- End of negate() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : extract_h | + | | + | Purpose : | + | | + | Return the 16 MSB of L_var1. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32 ) whose value falls in the | + | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); +#if (WMOPS) + multiCounter[currCounter].extract_h++; +#endif + return (var_out); +} +/* ------------------------- End of extract_h() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : extract_l | + | | + | Purpose : | + | | + | Return the 16 LSB of L_var1. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32 ) whose value falls in the | + | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; +#if (WMOPS) + multiCounter[currCounter].extract_l++; +#endif + return (var_out); +} +/* ------------------------- End of extract_l() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : round | + | | + | Purpose : | + | | + | Round the lower 16 bits of the 32 bit input number into the MS 16 bits | + | with saturation. Shift the resulting bits right by 16 and return the 16 | + | bit number: | + | round(L_var1) = extract_h(L_add(L_var1,32768)) | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32 ) whose value falls in the | + | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 round (Word32 L_var1) +{ + Word16 var_out; + Word32 L_rounded; + + L_rounded = L_add (L_var1, (Word32) 0x00008000L); +#if (WMOPS) + multiCounter[currCounter].L_add--; +#endif + var_out = extract_h (L_rounded); +#if (WMOPS) + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].round++; +#endif + return (var_out); +} +/* ------------------------- End of round() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_mac | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit | + | result to L_var3 with saturation, return a 32 bit result: | + | L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult (var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_mult--; +#endif + L_var_out = L_add (L_var3, L_product); +#if (WMOPS) + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_mac++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_mac() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_msu | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 | + | bit result to L_var3 with saturation, return a 32 bit result: | + | L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult (var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_mult--; +#endif + L_var_out = L_sub (L_var3, L_product); +#if (WMOPS) + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].L_msu++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_msu() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_macNs | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit | + | result to L_var3 without saturation, return a 32 bit result. Generate | + | carry and overflow values : | + | L_macNs(L_var3,var1,var2) = L_add_c(L_var3,L_mult(var1,var2)). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + | | + | Caution : | + | | + | In some cases the Carry flag has to be cleared or set before using | + | operators which take into account its value. | + |___________________________________________________________________________| +*/ +Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = L_mult (var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_mult--; +#endif + L_var_out = L_add_c (L_var3, L_var_out); +#if (WMOPS) + multiCounter[currCounter].L_add_c--; + multiCounter[currCounter].L_macNs++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_macNs() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_msuNs | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 | + | bit result from L_var3 without saturation, return a 32 bit result. Ge- | + | nerate carry and overflow values : | + | L_msuNs(L_var3,var1,var2) = L_sub_c(L_var3,L_mult(var1,var2)). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + | | + | Caution : | + | | + | In some cases the Carry flag has to be cleared or set before using | + | operators which take into account its value. | + |___________________________________________________________________________| +*/ +Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = L_mult (var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_mult--; +#endif + L_var_out = L_sub_c (L_var3, L_var_out); +#if (WMOPS) + multiCounter[currCounter].L_sub_c--; + multiCounter[currCounter].L_msuNs++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_msuNs() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_add | + | | + | Purpose : | + | | + | 32 bits addition of the two 32 bits variables (L_var1+L_var2) with | + | overflow control and saturation; the result is set at +2147483647 when | + | overflow occurs or at -2147483648 when underflow occurs. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | L_var2 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_add (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) + { + if ((L_var_out ^ L_var1) & MIN_32) + { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + Overflow = 1; + } + } +#if (WMOPS) + multiCounter[currCounter].L_add++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_add() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_sub | + | | + | Purpose : | + | | + | 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with | + | overflow control and saturation; the result is set at +2147483647 when | + | overflow occurs or at -2147483648 when underflow occurs. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | L_var2 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_sub (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) + { + if ((L_var_out ^ L_var1) & MIN_32) + { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + Overflow = 1; + } + } +#if (WMOPS) + multiCounter[currCounter].L_sub++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_sub() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_add_c | + | | + | Purpose : | + | | + | Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)| + | with carry. No saturation. Generate carry and Overflow values. The car- | + | ry and overflow values are binary variables which can be tested and as- | + | signed values. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | L_var2 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + | | + | Caution : | + | | + | In some cases the Carry flag has to be cleared or set before using | + | operators which take into account its value. | + |___________________________________________________________________________| +*/ +Word32 L_add_c (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + Word32 L_test; + Flag carry_int = 0; + + L_var_out = L_var1 + L_var2 + Carry; + + L_test = L_var1 + L_var2; + + if ((L_var1 > 0) && (L_var2 > 0) && (L_test < 0)) + { + Overflow = 1; + carry_int = 0; + } + else + { + if ((L_var1 < 0) && (L_var2 < 0)) + { + if (L_test >= 0) + { + Overflow = 1; + carry_int = 1; + } + else + { + Overflow = 0; + carry_int = 1; + } + } + else + { + if (((L_var1 ^ L_var2) < 0) && (L_test >= 0)) + { + Overflow = 0; + carry_int = 1; + } + else + { + Overflow = 0; + carry_int = 0; + } + } + } + + if (Carry) + { + if (L_test == MAX_32) + { + Overflow = 1; + Carry = carry_int; + } + else + { + if (L_test == (Word32) 0xFFFFFFFFL) + { + Carry = 1; + } + else + { + Carry = carry_int; + } + } + } + else + { + Carry = carry_int; + } + +#if (WMOPS) + multiCounter[currCounter].L_add_c++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_add_c() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_sub_c | + | | + | Purpose : | + | | + | Performs 32 bits subtraction of the two 32 bits variables with carry | + | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow | + | values. The carry and overflow values are binary variables which can | + | be tested and assigned values. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | L_var2 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + | | + | Caution : | + | | + | In some cases the Carry flag has to be cleared or set before using | + | operators which take into account its value. | + |___________________________________________________________________________| +*/ +Word32 L_sub_c (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + Word32 L_test; + Flag carry_int = 0; + + if (Carry) + { + Carry = 0; + if (L_var2 != MIN_32) + { + L_var_out = L_add_c (L_var1, -L_var2); +#if (WMOPS) + multiCounter[currCounter].L_add_c--; +#endif + } + else + { + L_var_out = L_var1 - L_var2; + if (L_var1 > 0L) + { + Overflow = 1; + Carry = 0; + } + } + } + else + { + L_var_out = L_var1 - L_var2 - (Word32) 0X00000001L; + L_test = L_var1 - L_var2; + + if ((L_test < 0) && (L_var1 > 0) && (L_var2 < 0)) + { + Overflow = 1; + carry_int = 0; + } + else if ((L_test > 0) && (L_var1 < 0) && (L_var2 > 0)) + { + Overflow = 1; + carry_int = 1; + } + else if ((L_test > 0) && ((L_var1 ^ L_var2) > 0)) + { + Overflow = 0; + carry_int = 1; + } + if (L_test == MIN_32) + { + Overflow = 1; + Carry = carry_int; + } + else + { + Carry = carry_int; + } + } + +#if (WMOPS) + multiCounter[currCounter].L_sub_c++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_sub_c() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_negate | + | | + | Purpose : | + | | + | Negate the 32 bit variable L_var1 with saturation; saturate in the case | + | where input is -2147483648 (0x8000 0000). | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; +#if (WMOPS) + multiCounter[currCounter].L_negate++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_negate() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : mult_r | + | | + | Purpose : | + | | + | Same as mult with rounding, i.e.: | + | mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and | + | mult_r(-32768,-32768) = 32767. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_product_arr; + + L_product_arr = (Word32) var1 *(Word32) var2; /* product */ + L_product_arr += (Word32) 0x00004000L; /* round */ + L_product_arr &= (Word32) 0xffff8000L; + L_product_arr >>= 15; /* shift */ + + if (L_product_arr & (Word32) 0x00010000L) /* sign extend when necessary */ + { + L_product_arr |= (Word32) 0xffff0000L; + } + var_out = saturate (L_product_arr); +#if (WMOPS) + multiCounter[currCounter].mult_r++; +#endif + return (var_out); +} +/* ------------------------- End of mult_r() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_shl | + | | + | Purpose : | + | | + | Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero | + | fill the var2 LSB of the result. If var2 is negative, arithmetically | + | shift L_var1 right by -var2 with sign extension. Saturate the result in | + | case of underflows or overflows. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_shl (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 <= 0) + { + if (var2 < -32) + var2 = -32; + L_var_out = L_shr (L_var1, (Word16) -var2); +#if (WMOPS) + multiCounter[currCounter].L_shr--; +#endif + } + else + { + for (; var2 > 0; var2--) + { + if (L_var1 > (Word32) 0X3fffffffL) + { + Overflow = 1; + L_var_out = MAX_32; + break; + } + else + { + if (L_var1 < (Word32) 0xc0000000L) + { + Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } +#if (WMOPS) + multiCounter[currCounter].L_shl++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_shl() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_shr | + | | + | Purpose : | + | | + | Arithmetically shift the 32 bit input L_var1 right var2 positions with | + | sign extension. If var2 is negative, arithmetically shift L_var1 left | + | by -var2 and zero fill the -var2 LSB of the result. Saturate the result | + | in case of underflows or overflows. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_shr (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < 0) + { + if (var2 < -32) + var2 = -32; + L_var_out = L_shl (L_var1, (Word16) -var2); +#if (WMOPS) + multiCounter[currCounter].L_shl--; +#endif + } + else + { + if (var2 >= 31) + { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else + { + if (L_var1 < 0) + { + L_var_out = ~((~L_var1) >> var2); + } + else + { + L_var_out = L_var1 >> var2; + } + } + } +#if (WMOPS) + multiCounter[currCounter].L_shr++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_shr() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : shr_r | + | | + | Purpose : | + | | + | Same as shr(var1,var2) but with rounding. Saturate the result in case of| + | underflows or overflows : | + | - If var2 is greater than zero : | + | if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1)))) | + | is equal to zero | + | then | + | shr_r(var1,var2) = shr(var1,var2) | + | else | + | shr_r(var1,var2) = add(shr(var1,var2),1) | + | - If var2 is less than or equal to zero : | + | shr_r(var1,var2) = shr(var1,var2). | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > 15) + { + var_out = 0; + } + else + { + var_out = shr (var1, var2); +#if (WMOPS) + multiCounter[currCounter].shr--; +#endif + + if (var2 > 0) + { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) + { + var_out++; + } + } + } +#if (WMOPS) + multiCounter[currCounter].shr_r++; +#endif + return (var_out); +} +/* ------------------------- End of shr_r() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : mac_r | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit | + | result to L_var3 with saturation. Round the LS 16 bits of the result | + | into the MS 16 bits with saturation and shift the result right by 16. | + | Return a 16 bit result. | + | mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2)) | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac (L_var3, var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_mac--; +#endif + L_var3 = L_add (L_var3, (Word32) 0x00008000L); +#if (WMOPS) + multiCounter[currCounter].L_add--; +#endif + var_out = extract_h (L_var3); +#if (WMOPS) + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].mac_r++; +#endif + return (var_out); +} +/* ------------------------- End of mac_r() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : msu_r | + | | + | Purpose : | + | | + | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 | + | bit result to L_var3 with saturation. Round the LS 16 bits of the res- | + | ult into the MS 16 bits with saturation and shift the result right by | + | 16. Return a 16 bit result. | + | msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2)) | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var3 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu (L_var3, var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_msu--; +#endif + L_var3 = L_add (L_var3, (Word32) 0x00008000L); +#if (WMOPS) + multiCounter[currCounter].L_add--; +#endif + var_out = extract_h (L_var3); +#if (WMOPS) + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].msu_r++; +#endif + return (var_out); +} +/* ------------------------- End of msu_r() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_deposit_h | + | | + | Purpose : | + | | + | Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The | + | 16 LS bits of the output are zeroed. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var_out <= 0x7fff 0000. | + |___________________________________________________________________________| +*/ +Word32 L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; +#if (WMOPS) + multiCounter[currCounter].L_deposit_h++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_deposit_h() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_deposit_l | + | | + | Purpose : | + | | + | Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The | + | 16 MS bits of the output are sign extended. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word32 L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; +#if (WMOPS) + multiCounter[currCounter].L_deposit_l++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_deposit_l() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_shr_r | + | | + | Purpose : | + | | + | Same as L_shr(L_var1,var2) but with rounding. Saturate the result in | + | case of underflows or overflows : | + | - If var2 is greater than zero : | + | if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))| + | is equal to zero | + | then | + | L_shr_r(L_var1,var2) = L_shr(L_var1,var2) | + | else | + | L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1) | + | - If var2 is less than or equal to zero : | + | L_shr_r(L_var1,var2) = L_shr(L_var1,var2). | + | | + | Complexity weight : 3 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var1 <= 0x7fff ffff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 > 31) + { + L_var_out = 0; + } + else + { + L_var_out = L_shr (L_var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_shr--; +#endif + if (var2 > 0) + { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) + { + L_var_out++; + } + } + } +#if (WMOPS) + multiCounter[currCounter].L_shr_r++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_shr_r() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_abs | + | | + | Purpose : | + | | + | Absolute value of L_var1; Saturate in case where the input is | + | -214783648 | + | | + | Complexity weight : 3 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) + { + L_var_out = MAX_32; + } + else + { + if (L_var1 < 0) + { + L_var_out = -L_var1; + } + else + { + L_var_out = L_var1; + } + } + +#if (WMOPS) + multiCounter[currCounter].L_abs++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_abs() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : L_sat | + | | + | Purpose : | + | | + | 32 bit L_var1 is set to 2147483647 if an overflow occured or to | + | -2147483648 if an underflow occured on the most recent L_add_c, | + | L_sub_c, L_macNs or L_msuNs operations. The carry and overflow values | + | are binary values which can be tested and assigned values. | + | | + | Complexity weight : 4 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +Word32 L_sat (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = L_var1; + + if (Overflow) + { + + if (Carry) + { + L_var_out = MIN_32; + } + else + { + L_var_out = MAX_32; + } + + Carry = 0; + Overflow = 0; + } +#if (WMOPS) + multiCounter[currCounter].L_sat++; +#endif + return (L_var_out); +} +/* ------------------------- End of L_sat() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : norm_s | + | | + | Purpose : | + | | + | Produces the number of left shift needed to normalize the 16 bit varia- | + | ble var1 for positive values on the interval with minimum of 16384 and | + | maximum of 32767, and for negative values on the interval with minimum | + | of -32768 and maximum of -16384; in order to normalize the result, the | + | following operation must be done : | + | norm_var1 = shl(var1,norm_s(var1)). | + | | + | Complexity weight : 15 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x0000 000f. | + |___________________________________________________________________________| +*/ +Word16 norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == 0) + { + var_out = 0; + } + else + { + if (var1 == (Word16) 0xffff) + { + var_out = 15; + } + else + { + if (var1 < 0) + { + var1 = ~var1; + } + for (var_out = 0; var1 < 0x4000; var_out++) + { + var1 <<= 1; + } + } + } + +#if (WMOPS) + multiCounter[currCounter].norm_s++; +#endif + return (var_out); +} +/* ------------------------- End of norm_s() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : div_s | + | | + | Purpose : | + | | + | Produces a result which is the fractional integer division of var1 by | + | var2; var1 and var2 must be positive and var2 must be greater or equal | + | to var1; the result is positive (leading bit equal to 0) and truncated | + | to 16 bits. | + | If var1 = var2 then div(var1,var2) = 32767. | + | | + | Complexity weight : 18 | + | | + | Inputs : | + | | + | var1 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var1 <= var2 and var2 != 0. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : var1 <= var2 <= 0x0000 7fff and var2 != 0. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x0000 7fff. | + | It's a Q15 value (point between b15 and b14). | + |___________________________________________________________________________| +*/ +Word16 div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + + if ((var1 > var2) || (var1 < 0) || (var2 < 0)) + { + printf ("Division Error var1=%d var2=%d\n", var1, var2); + abort(); /* exit (0); */ + } + if (var2 == 0) + { + printf ("Division by 0, Fatal error \n"); + abort(); /* exit (0); */ + } + if (var1 == 0) + { + var_out = 0; + } + else + { + if (var1 == var2) + { + var_out = MAX_16; + } + else + { + L_num = L_deposit_l (var1); +#if (WMOPS) + multiCounter[currCounter].L_deposit_l--; +#endif + L_denom = L_deposit_l (var2); +#if (WMOPS) + multiCounter[currCounter].L_deposit_l--; +#endif + + for (iteration = 0; iteration < 15; iteration++) + { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) + { + L_num = L_sub (L_num, L_denom); +#if (WMOPS) + multiCounter[currCounter].L_sub--; +#endif + var_out = add (var_out, 1); +#if (WMOPS) + multiCounter[currCounter].add--; +#endif + } + } + } + } + +#if (WMOPS) + multiCounter[currCounter].div_s++; +#endif + return (var_out); +} +/* ------------------------- End of div_s() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : norm_l | + | | + | Purpose : | + | | + | Produces the number of left shifts needed to normalize the 32 bit varia-| + | ble L_var1 for positive values on the interval with minimum of | + | 1073741824 and maximum of 2147483647, and for negative values on the in-| + | terval with minimum of -2147483648 and maximum of -1073741824; in order | + | to normalize the result, the following operation must be done : | + | norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). | + | | + | Complexity weight : 30 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var1 <= 0x7fff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x0000 001f. | + |___________________________________________________________________________| +*/ +Word16 norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0) + { + var_out = 0; + } + else + { + if (L_var1 == (Word32) 0xffffffffL) + { + var_out = 31; + } + else + { + if (L_var1 < 0) + { + L_var1 = ~L_var1; + } + for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) + { + L_var1 <<= 1; + } + } + } + +#if (WMOPS) + multiCounter[currCounter].norm_l++; +#endif + return (var_out); +} +/* ------------------------- End of norm_l() ------------------------- */ + + +/* + ***************************************************************** + Additional operators extracted from the G.723.1 Library + Adapted for WMOPS calculations + ***************************************************************** +*/ + +/*___________________________________________________________________________ + | | + | Function Name : L_mls | + | | + | Purpose : | + | | + | Multiplies a 16 bit word v by a 32 bit word Lv and returns a 32 bit | + | word (multiplying 16 by 32 bit words gives 48 bit word; the function | + | extracts the 32 MSB and shift the result to the left by 1). | + | | + | A 32 bit word can be written as | + | Lv = a + b * 2^16 | + | where a= unsigned 16 LSBs and b= signed 16 MSBs. | + | The function returns v * Lv / 2^15 which is equivalent to | + | a*v / 2^15 + b*v*2 | + | | + | Complexity weight : 6 [to be confirmed] | + | | + | Inputs : | + | | + | Lv | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var1 <= 0x7fff ffff. | + | v | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x8000 <= var1 <= 0x7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | + | | + |___________________________________________________________________________| +*/ +Word32 L_mls (Word32 Lv, Word16 v) +{ + Word32 Temp ; + + Temp = Lv & (Word32) 0x0000ffff ; + Temp = Temp * (Word32) v ; + Temp = L_shr( Temp, (Word16) 15 ) ; + Temp = L_mac( Temp, v, extract_h(Lv) ) ; + +#if (WMOPS) + multiCounter[currCounter].L_shr--; + multiCounter[currCounter].L_mac--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].L_mls++; +#endif + + return Temp ; +} +/* ------------------------- End of L_mls() ------------------------- */ + + +/*__________________________________________________________________________ +| | +| Function Name : div_l | +| | +| Purpose : | +| | +| Produces a result which is the fractional integer division of L_var1 by| +| var2; L_var1 and var2 must be positive and var2 << 16 must be greater or| +| equal to L_var1; the result is positive (leading bit equal to 0) and | +| truncated to 16 bits. | +| If L_var1 == var2 << 16 then div_l(L_var1,var2) = 32767. | +| | +| Complexity weight : 20 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x0000 0000 <= var1 <= (var2 << 16) and var2 != 0. | +| L_var1 must be considered as a Q.31 value | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : var1 <= (var2<< 16) <= 0x7fff0000 and var2 != 0. | +| var2 must be considered as a Q.15 value | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| var_out | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0x0000 0000 <= var_out <= 0x0000 7fff. | +| It's a Q15 value (point between b15 and b14). | +|___________________________________________________________________________| +*/ +Word16 div_l (Word32 L_num, Word16 den) +{ + Word16 var_out = (Word16)0; + Word32 L_den; + Word16 iteration; + +#if (WMOPS) + multiCounter[currCounter].div_l++; +#endif + + if ( den == (Word16) 0 ) { + printf("Division by 0 in div_l, Fatal error \n"); + exit(0); + } + + if ( (L_num < (Word32) 0) || (den < (Word16) 0) ) { + printf("Division Error in div_l, Fatal error \n"); + exit(0); + } + + L_den = L_deposit_h( den ) ; +#if (WMOPS) + multiCounter[currCounter].L_deposit_h--; +#endif + + if ( L_num >= L_den ){ + return MAX_16 ; + } + else { + L_num = L_shr(L_num, (Word16)1) ; + L_den = L_shr(L_den, (Word16)1); +#if (WMOPS) + multiCounter[currCounter].L_shr-=2; +#endif + for(iteration=(Word16)0; iteration< (Word16)15;iteration++) { + var_out = shl( var_out, (Word16)1); + L_num = L_shl( L_num, (Word16)1); +#if (WMOPS) + multiCounter[currCounter].shl--; + multiCounter[currCounter].L_shl--; +#endif + if (L_num >= L_den) { + L_num = L_sub(L_num,L_den); + var_out = add(var_out, (Word16)1); +#if (WMOPS) + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].add--; +#endif + } + } + + return var_out; + } +} +/* ------------------------- End of div_l() ------------------------- */ + + +/*__________________________________________________________________________ +| | +| Function Name : i_mult | +| | +| Purpose : | +| | +| Integer 16-bit multiplication. No overflow protection is performed if | +| ORIGINAL_G7231 is defined. | +| | +| Complexity weight : TBD | +| | +| Inputs : | +| | +| a | +| 16 bit short signed integer (Word16). | +| | +| b | +| 16 bit short signed integer (Word16). | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| 16 bit short signed integer (Word16). No overflow checks | +| are performed if ORIGINAL_G7231 is defined. | +|___________________________________________________________________________| +*/ +Word16 i_mult (Word16 a, Word16 b) +{ +#ifdef ORIGINAL_G7231 + return a*b ; +#else + Word32 register c=a*b; +#if (WMOPS) + multiCounter[currCounter].i_mult++; +#endif + return saturate(c) ; +#endif +} +/* ------------------------- End of i_mult() ------------------------- */ + + +/* + ********************************************************************** + The following three operators are not part of the original + G.729/G.723.1 set of basic operators and implement shiftless + accumulation operation. + ********************************************************************** +*/ + +/*___________________________________________________________________________ + | + | Function Name : L_mult0 + | + | Purpose : + | + | L_mult0 is the 32 bit result of the multiplication of var1 times var2 + | without one left shift. + | + | Complexity weight : 1 + | + | Inputs : + | + | var1 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | var2 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | Return Value : + | + | L_var_out + | 32 bit long signed integer (Word32) whose value falls in the + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + |___________________________________________________________________________ +*/ +Word32 L_mult0 (Word16 var1,Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32)var1 * (Word32)var2; + +#if (WMOPS) + multiCounter[currCounter].L_mult0++; +#endif + return(L_var_out); +} +/* ------------------------- End of L_mult0() ------------------------- */ + + +/*___________________________________________________________________________ + | + | Function Name : L_mac0 + | + | Purpose : + | + | Multiply var1 by var2 (without left shift) and add the 32 bit result to + | L_var3 with saturation, return a 32 bit result: + | L_mac0(L_var3,var1,var2) = L_add(L_var3,(L_mult0(var1,var2)). + | + | Complexity weight : 1 + | + | Inputs : + | + | L_var3 32 bit long signed integer (Word32) whose value falls in the + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + | + | var1 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | var2 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | Return Value : + | + | L_var_out + | 32 bit long signed integer (Word32) whose value falls in the + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + |___________________________________________________________________________ +*/ +Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult0(var1,var2); + L_var_out = L_add(L_var3,L_product); + +#if (WMOPS) + multiCounter[currCounter].L_mac0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_add--; +#endif + return(L_var_out); +} +/* ------------------------- End of L_mac0() ------------------------- */ + + +/*___________________________________________________________________________ + | + | Function Name : L_msu0 + | + | Purpose : + | + | Multiply var1 by var2 (without left shift) and subtract the 32 bit + | result to L_var3 with saturation, return a 32 bit result: + | L_msu0(L_var3,var1,var2) = L_sub(L_var3,(L_mult0(var1,var2)). + | + | Complexity weight : 1 + | + | Inputs : + | + | L_var3 32 bit long signed integer (Word32) whose value falls in the + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + | + | var1 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | var2 16 bit short signed integer (Word16) whose value falls in the + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. + | + | Return Value : + | + | L_var_out + | 32 bit long signed integer (Word32) whose value falls in the + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + |___________________________________________________________________________ +*/ +Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult0(var1,var2); + L_var_out = L_sub(L_var3,L_product); + +#if (WMOPS) + multiCounter[currCounter].L_msu0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_sub--; +#endif + return(L_var_out); +} +/* ------------------------- End of L_msu0() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : LU_shl | + | | + | Purpose : | + | | + | Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero | + | fill the var2 LSB of the result. If var2 is negative, arithmetically | + | shift L_var1 right by -var2 with sign extension. Saturate the result in | + | case of underflows or overflows. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +UWord32 LU_shl (UWord32 L_var1, Word16 var2) +{ + Word16 neg_var2; + UWord32 L_var_out; + + if (var2 <= 0) + { + if (var2 < -32) + var2 = -32; + neg_var2 = negate(var2); + L_var_out = LU_shr (L_var1, neg_var2); +#if (WMOPS) + multiCounter[currCounter].negate--; + multiCounter[currCounter].LU_shr--; +#endif + } + else + { + for (; var2 > 0; var2--) + { + if (L_var1 > (UWord32) 0X7fffffffL) + { + Overflow = 1; + L_var_out = UMAX_32; + break; + } + else + { + if (L_var1 < (UWord32) 0x00000001L) + { + Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } +#if (WMOPS) + multiCounter[currCounter].LU_shl++; +#endif + return (L_var_out); +} +/* ------------------------- End of LU_shl() ------------------------- */ + + +/*___________________________________________________________________________ + | | + | Function Name : LU_shr | + | | + | Purpose : | + | | + | Arithmetically shift the 32 bit input L_var1 right var2 positions with | + | sign extension. If var2 is negative, arithmetically shift L_var1 left | + | by -var2 and zero fill the -var2 LSB of the result. Saturate the result | + | in case of underflows or overflows. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | L_var1 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. | + | | + | var2 | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L_var_out | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | + |___________________________________________________________________________| +*/ +UWord32 LU_shr (UWord32 L_var1, Word16 var2) +{ + Word16 neg_var2; + UWord32 L_var_out; + + if (var2 < 0) + { + if (var2 < -32) + var2 = -32; + neg_var2 = negate(var2); + L_var_out = LU_shl (L_var1, neg_var2); +#if (WMOPS) + multiCounter[currCounter].negate--; + multiCounter[currCounter].LU_shl--; +#endif + } + else + { + if (var2 >= 32) + { + L_var_out = 0L; + } + else + { + L_var_out = L_var1 >> var2; + } + } +#if (WMOPS) + multiCounter[currCounter].LU_shr++; +#endif + return (L_var_out); +} +/* ------------------------- End of LU_shr() ------------------------- */ + + +/* ************************** END OF BASOP32.C ************************** */ diff --git a/third_party/g7221/common/stl-files/basop32.h b/third_party/g7221/common/stl-files/basop32.h new file mode 100644 index 00000000..7b096454 --- /dev/null +++ b/third_party/g7221/common/stl-files/basop32.h @@ -0,0 +1,111 @@ +/* + =========================================================================== + File: BASOP.H v.1.1 - 05.Jul.2000 + =========================================================================== + + ITU-T STL BASIC OPERATORS + + GLOBAL FUNCTION PROTOTYPES + + History: + 26.Jan.00 v1.0 Incorporated to the STL from updated G.723.1/G.729 + basic operator library (based on basic_op.h) and + G.723.1's basop.h. + 05.Jul.00 v1.1 Added 32-bit shiftless mult/mac/msub operators + ============================================================================ +*/ + +#ifndef BASOP_H_DEFINED +#define BASOP_H_DEFINED 110 + +/*___________________________________________________________________________ + | | + | Constants and Globals | + | | + | $Id $ + |___________________________________________________________________________| +*/ + +extern Flag Overflow; +extern Flag Carry; + +#define MAX_32 (Word32)0x7fffffffL +#define MIN_32 (Word32)0x80000000L + +#define MAX_16 (Word16)0x7fff +#define MIN_16 (Word16)0x8000 + +#define UMAX_32 (Word32)0xffffffffL +#define UMIN_32 (Word32)0x00000000L + +/*___________________________________________________________________________ + | | + | Prototypes for basic arithmetic operators | + |___________________________________________________________________________| +*/ + +Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */ +Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */ +Word16 abs_s (Word16 var1); /* Short abs, 1 */ +Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ +Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ +Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ +Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ +Word16 negate (Word16 var1); /* Short negate, 1 */ +Word16 extract_h (Word32 L_var1); /* Extract high, 1 */ +Word16 extract_l (Word32 L_var1); /* Extract low, 1 */ +Word16 round (Word32 L_var1); /* Round, 1 */ +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ +Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2); /* Mac without + sat, 1 */ +Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2); /* Msu without + sat, 1 */ +Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */ +Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */ +Word32 L_add_c (Word32 L_var1, Word32 L_var2); /* Long add with c, 2 */ +Word32 L_sub_c (Word32 L_var1, Word32 L_var2); /* Long sub with c, 2 */ +Word32 L_negate (Word32 L_var1); /* Long negate, 2 */ +Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */ +Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */ +Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2*/ +Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with + round, 2 */ +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with + rounding,2 */ +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with + rounding,2 */ +Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */ +Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */ + +Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with + round, 3 */ +Word32 L_abs (Word32 L_var1); /* Long abs, 3 */ +Word32 L_sat (Word32 L_var1); /* Long saturation, 4 */ +Word16 norm_s (Word16 var1); /* Short norm, 15 */ +Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ +Word16 norm_l (Word32 L_var1); /* Long norm, 30 */ + +/* + Additional G.723.1 operators +*/ +Word32 L_mls( Word32, Word16 ) ; /* Weight FFS; currently assigned 1 */ +Word16 div_l( Word32, Word16 ) ; /* Weight FFS; currently assigned 1 */ +Word16 i_mult(Word16 a, Word16 b); /* Weight FFS; currently assigned 1 */ + +/* + New shiftless operators, not used in G.729/G.723.1 +*/ +Word32 L_mult0(Word16 v1, Word16 v2); /* 32-bit Multiply w/o shift 1 */ +Word32 L_mac0(Word32 L_v3, Word16 v1, Word16 v2); /* 32-bit Mac w/o shift 1 */ +Word32 L_msu0(Word32 L_v3, Word16 v1, Word16 v2); /* 32-bit Msu w/o shift 1 */ + +/* + Additional G.722.1 operators +*/ +UWord32 LU_shl (UWord32 L_var1, Word16 var2); +UWord32 LU_shr (UWord32 L_var1, Word16 var2); +#endif /* BASOP_H_DEFINED */ + + +/* ************************* END OF BASIC_OP.H ************************* */ diff --git a/third_party/g7221/common/stl-files/count.c b/third_party/g7221/common/stl-files/count.c new file mode 100644 index 00000000..17ce4b32 --- /dev/null +++ b/third_party/g7221/common/stl-files/count.c @@ -0,0 +1,303 @@ +/* + *************************************************************************** + * + * This file contains functions for the automatic complexity calculation + * $Id $ + *************************************************************************** +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "typedef.h" +#include "count.h" + +/* Global counter variable for calculation of complexity weight */ + +BASIC_OP multiCounter[MAXCOUNTERS]; +int currCounter=0; /* Zero equals global counter */ + +/*BASIC_OP counter;*/ +const BASIC_OP op_weight = +{ + /* G.729 & G.723.1 common operators */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 4, 15, 18, 30, 1, 2, 1, 2, 2, + /* G.723.1 exclusives */ + 6, 1, 1, + /* shiftless 32-bit operators */ + 1, 1, 1, + /* G.722.1 exclusives */ + 1, 1 +}; + +/* function prototypes */ +Word32 TotalWeightedOperation (void); +Word32 DeltaWeightedOperation (void); + +/* local variable */ +#if WMOPS + +/* Counters for separating counting for different objects */ +static int maxCounter=0; +static char* objectName[MAXCOUNTERS+1]; +static Word16 fwc_corr[MAXCOUNTERS+1]; + +#define NbFuncMax 1024 + +static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS]; +static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax]; +static float total_wmops[MAXCOUNTERS]; + +static Word32 LastWOper[MAXCOUNTERS]; + +static char* my_strdup(const char *s) +/* + * duplicates UNIX function strdup() which is not ANSI standard: + * -- malloc() memory area big enough to hold the string s + * -- copy string into new area + * -- return pointer to new area + * + * returns NULL if either s==NULL or malloc() fails + */ +{ + char *dup; + + if (s == NULL) + return NULL; + + /* allocate memory for copy of ID string (including string terminator) */ + /* NOTE: the ID strings will never be deallocated because there is no + way to "destroy" a counter that is not longer needed */ + if ((dup = (char *) malloc(strlen(s)+1)) == NULL) + return NULL; + + return strcpy(dup, s); +} + +#endif + +int getCounterId(char *objectNameArg) +{ +#if WMOPS + if(maxCounter>=MAXCOUNTERS-1) return 0; + objectName[++maxCounter]=my_strdup(objectNameArg); + return maxCounter; +#else + return 0; /* Dummy */ +#endif +} + +void setCounter(int counterId) +{ +#if WMOPS + if(counterId>maxCounter || counterId<0) + { + currCounter=0; + return; + } + currCounter=counterId; +#endif +} + +#if WMOPS +static Word32 WMOPS_frameStat() +/* calculate the WMOPS seen so far and update the global + per-frame maximum (glob_wc) + */ +{ + Word32 tot; + + tot = TotalWeightedOperation (); + if (tot > glob_wc[currCounter]) + glob_wc[currCounter] = tot; + + /* check if fwc() was forgotten at end of last frame */ + if (tot > LastWOper[currCounter]) { + if (!fwc_corr[currCounter]) { + fprintf(stderr, + "count: operations counted after last fwc() for '%s'; " + "-> fwc() called\n", + objectName[currCounter]?objectName[currCounter]:""); + } + fwc(); + } + + return tot; +} + +static void WMOPS_clearMultiCounter() +{ + Word16 i; + + Word32 *ptr = (Word32 *) &multiCounter[currCounter]; + for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) + { + *ptr++ = 0; + } +} +#endif + +Word32 TotalWeightedOperation () +{ +#if WMOPS + Word16 i; + Word32 tot, *ptr, *ptr2; + + tot = 0; + ptr = (Word32 *) &multiCounter[currCounter]; + ptr2 = (Word32 *) &op_weight; + for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) + { + tot += ((*ptr++) * (*ptr2++)); + } + + return ((Word32) tot); +#else + return 0; /* Dummy */ +#endif +} + +Word32 DeltaWeightedOperation () +{ +#if WMOPS + Word32 NewWOper, delta; + + NewWOper = TotalWeightedOperation (); + delta = NewWOper - LastWOper[currCounter]; + LastWOper[currCounter] = NewWOper; + return (delta); +#else + return 0; /* Dummy */ +#endif +} + +void move16 (void) +{ +#if WMOPS + multiCounter[currCounter].DataMove16++; +#endif +} + +void move32 (void) +{ +#if WMOPS + multiCounter[currCounter].DataMove32++; +#endif +} + +void test (void) +{ +#if WMOPS + multiCounter[currCounter].Test++; +#endif +} + +void logic16 (void) +{ +#if WMOPS + multiCounter[currCounter].Logic16++; +#endif +} + +void logic32 (void) +{ +#if WMOPS + multiCounter[currCounter].Logic32++; +#endif +} + +void Init_WMOPS_counter (void) +{ +#if WMOPS + Word16 i; + + /* reset function weight operation counter variable */ + + for (i = 0; i < NbFuncMax; i++) + wc[currCounter][i] = (Word32) 0; + glob_wc[currCounter] = 0; + nbframe[currCounter] = 0; + total_wmops[currCounter] = 0.0; + + /* initially clear all counters */ + WMOPS_clearMultiCounter(); + LastWOper[currCounter] = 0; + funcid[currCounter] = 0; +#endif +} + + +void Reset_WMOPS_counter (void) +{ +#if WMOPS + Word32 tot = WMOPS_frameStat(); + + /* increase the frame counter --> a frame is counted WHEN IT BEGINS */ + nbframe[currCounter]++; + /* add wmops used in last frame to count, then reset counter */ + /* (in first frame, this is a no-op */ + total_wmops[currCounter] += ((float) tot) * 0.00005; + + /* clear counter before new frame starts */ + WMOPS_clearMultiCounter(); + LastWOper[currCounter] = 0; + funcid[currCounter] = 0; /* new frame, set function id to zero */ +#endif +} + +Word32 fwc (void) /* function worst case */ +{ +#if WMOPS + Word32 tot; + + tot = DeltaWeightedOperation (); + if (tot > wc[currCounter][funcid[currCounter]]) + wc[currCounter][funcid[currCounter]] = tot; + + funcid[currCounter]++; + + return (tot); +#else + return 0; /* Dummy */ +#endif +} + +void WMOPS_output (Word16 dtx_mode) +{ +#if WMOPS + Word16 i; + Word32 tot, tot_wm, tot_wc; + + /* get operations since last reset (or init), + but do not update the counters (except the glob_wc[] maximum) + so output CAN be called in each frame without problems. + The frame counter is NOT updated! + */ + tot = WMOPS_frameStat(); + tot_wm = total_wmops[currCounter] + ((float) tot) * 0.00005; + + fprintf (stdout, "%10s:WMOPS=%.3f", + objectName[currCounter]?objectName[currCounter]:"", + ((float) tot) * 0.00005); + + if (nbframe[currCounter] != 0) + fprintf (stdout, " Average=%.3f", + tot_wm / (float) nbframe[currCounter]); + + fprintf (stdout, " WorstCase=%.3f", + ((float) glob_wc[currCounter]) * 0.00005); + + /* Worst worst case printed only when not in DTX mode */ + if (dtx_mode == 0) + { + tot_wc = 0L; + for (i = 0; i < funcid[currCounter]; i++) + tot_wc += wc[currCounter][i]; + fprintf (stdout, " WorstWC=%.3f", ((float) tot_wc) * 0.00005); + } + fprintf (stdout, " (%d frames)\n", nbframe[currCounter]); + +#endif +} diff --git a/third_party/g7221/common/stl-files/count.h b/third_party/g7221/common/stl-files/count.h new file mode 100644 index 00000000..5f2227ef --- /dev/null +++ b/third_party/g7221/common/stl-files/count.h @@ -0,0 +1,207 @@ +/* + =========================================================================== + COUNT.H + ~~~~~~~ + + Prototypes and definitions for counting operations + + These functions, and the ones in basop32.h, makes it possible to + measure the wMOPS of a codec. + + All functions in this file, and in basop32.h, updates a structure + so that it will be possible the see how many calls to add, mul mulAdd + ... that the code made, and estimate the wMOPS (and MIPS) for a + sertain part of code + + It is also possible to measure the wMOPS separatly for different + parts of the codec. + + This is done by creating a counter group (getCounterId) for each part + of the code that one wants a separte measure for. Before a part of + the code is executed a call to the "setCounter" function is needed to + identify which counter group to use. + + Currently there is a limit of 255 different counter groups. + + In the end of this file there is a pice of code illustration how the + functions can be used. + + History + ~~~~~~~ + 09.Aug.1999 V1.0.0 Input to UGST from ETSI AMR (count.h); + 26.Jan.2000 V1.1.0 Added counter entries for G.723.1's + L_mls(), div_l(), i_mult() [from basop32.c] + 05.Jul.2000 V1.2.0 Added counter entries for 32bit shiftless + operators L_mult0(), L_mac0(), L_msu0() + =========================================================================== +*/ +#ifndef COUNT_H +#define COUNT_H "$Id $" + +#define MAXCOUNTERS 256 + +int getCounterId(char *objectName); +/* + * Create a counter group, the "objectname" will be used when printing + * statistics for this counter group. + * + * Returns 0 if no more counter groups are available. + */ + +void setCounter(int counterId); +/* + * Defines which counter group to use, default is zero. + */ + +void Init_WMOPS_counter (void); +/* + * Initiates the current counter group. + */ + +void Reset_WMOPS_counter (void); +/* + * Resets the current counter group. + */ + +void WMOPS_output (Word16 notPrintWorstWorstCase); +/* + * Prints the statistics to the screen, if the argument if non zero + * the statistics for worst worst case will not be printed. This is typically + * done for dtx frames. + * + */ + +Word32 fwc (void); +/* + * worst worst case counter. + * + * This function calculates the worst possible case that can be reached. + * + * This is done by calling this function for each subpart of the calculations + * for a frame. This function then stores the maximum wMOPS for each part. + * + * The WMOPS_output function add together all parts and presents the sum. + */ + +void move16 (void); +void move32 (void); +void logic16 (void); +void logic32 (void); +void test (void); +/* + * The functions above increases the corresponding operation counter for + * the current counter group. + */ + +typedef struct +{ + Word32 add; /* Complexity Weight of 1 */ + Word32 sub; + Word32 abs_s; + Word32 shl; + Word32 shr; + Word32 extract_h; + Word32 extract_l; + Word32 mult; + Word32 L_mult; + Word32 negate; + Word32 round; + Word32 L_mac; + Word32 L_msu; + Word32 L_macNs; + Word32 L_msuNs; + Word32 L_add; /* Complexity Weight of 2 */ + Word32 L_sub; + Word32 L_add_c; + Word32 L_sub_c; + Word32 L_negate; + Word32 L_shl; + Word32 L_shr; + Word32 mult_r; + Word32 shr_r; + Word32 shift_r; + Word32 mac_r; + Word32 msu_r; + Word32 L_deposit_h; + Word32 L_deposit_l; + Word32 L_shr_r; /* Complexity Weight of 3 */ + Word32 L_shift_r; + Word32 L_abs; + Word32 L_sat; /* Complexity Weight of 4 */ + Word32 norm_s; /* Complexity Weight of 15 */ + Word32 div_s; /* Complexity Weight of 18 */ + Word32 norm_l; /* Complexity Weight of 30 */ + Word32 DataMove16; /* Complexity Weight of 1 */ + Word32 DataMove32; /* Complexity Weight of 2 */ + Word32 Logic16; /* Complexity Weight of 1 */ + Word32 Logic32; /* Complexity Weight of 2 */ + Word32 Test; /* Complexity Weight of 2 */ + /* Counters for G.723.1 basic operators*/ + Word32 L_mls; /* Complexity Weight of 1 */ + Word32 div_l; /* Complexity Weight of 1 */ + Word32 i_mult; /* Complexity Weight of 1 */ + Word32 L_mult0; /* Complexity Weight of 1 */ + Word32 L_mac0; /* Complexity Weight of 1 */ + Word32 L_msu0; /* Complexity Weight of 1 */ + /* Counters for G.722.1 basic operators*/ + Word32 LU_shl; /* Complexity Weight of 1 */ + Word32 LU_shr; /* Complexity Weight of 1 */ +} +BASIC_OP; + +#ifdef THISISANEXAMPLE_0123456789 +/* + ----------------------------------------------------------------------- + Example of how count.h could be used. + + In the example below it is assumed that the init_OBJECT functions + does not use any calls to counter.h or basic_op.h. If this is the + case a call to the function Reset_WMOPS_counter() must be done after + each call to init_OBJECT if these operations is not to be included + in the statistics. + ----------------------------------------------------------------------- +*/ + +int main() +{ + int spe1Id,spe2Id,cheId; + + /* initiate counters and objects */ + spe1Id=getCounterId("Spe 5k8"); + setCounter(spe1Id); + Init_WMOPS_counter (); + init_spe1(...); + + spe2Id=getCounterId("Spe 12k2"); + setCounter(spe2Id); + Init_WMOPS_counter (); + init_spe2(...); + + cheId=getCounterId("Channel encoder"); + setCounter(cheId); + Init_WMOPS_counter (); + init_che(...); + ... + + while(data) + { + test(); /* Note this call to test(); */ + if(useSpe1) + setCounter(spe1Id); + else + setCounter(spe2Id); + Reset_WMOPS_counter(); + speEncode(...); + WMOPS_output(0); /* Normal routine for displaying WMOPS info */ + + setCounter(cheId); + Reset_WMOPS_counter(); + preChannelInter(...); fwc(); /* Note the call to fwc() for each part */ + convolve(...); fwc(); /* of the channel encoder. */ + interleave(...); fwc(); + WMOPS_output(0); /* Normal routine for displaying WMOPS info */ + } +} +#endif /* Example */ + +#endif /* COUNT_H */ diff --git a/third_party/g7221/common/stl-files/typedef.h b/third_party/g7221/common/stl-files/typedef.h new file mode 100644 index 00000000..6c06541f --- /dev/null +++ b/third_party/g7221/common/stl-files/typedef.h @@ -0,0 +1,55 @@ +/* + =========================================================================== + File: TYPEDEF.H v.1.0 - 26.Jan.2000 + =========================================================================== + + ITU-T STL BASIC OPERATORS + + TYPE DEFINITION PROTOTYPES + + History: + 26.Jan.00 v1.0 Incorporated to the STL from updated G.723.1/G.729 + basic operator library (based on basic_op.h) + ============================================================================ +*/ + +#ifndef TYPEDEF_H +#define TYPEDEF_H "$Id $" + +#include <limits.h> + +#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__) || defined(__CYGWIN__) +typedef signed char Word8; +typedef short Word16; +typedef long Word32; +typedef int Flag; + +#elif defined(__sun) +typedef signed char Word8; +typedef short Word16; +typedef long Word32; +typedef int Flag; + +#elif defined(__unix__) || defined(__unix) +typedef signed char Word8; +typedef short Word16; +typedef int Word32; +typedef int Flag; + +#endif + +/* define 16 bit unsigned types for G.722.1 */ +#if INT_MAX == 32767 +typedef unsigned int UWord16; +#elif SHRT_MAX == 32767 +typedef unsigned short UWord16; +#endif + +/* define 32 bit unsigned types for G.722.1 */ +#if INT_MAX == 2147483647L +typedef unsigned int UWord32; +#elif LONG_MAX == 2147483647L +typedef unsigned long UWord32; +#endif + +#endif /* TYPEDEF_H */ |