diff --git a/src/basop/basop32.c b/src/basop/basop32.c index 9625064..ba59dde 100644 --- a/src/basop/basop32.c +++ b/src/basop/basop32.c @@ -124,6 +124,9 @@ ORIGINAL BY: #include #include #include "stl.h" +#ifdef BASOP_NOGLOB +#include +#endif /* BASOP_NOGLOB */ #if (WMOPS) @@ -137,6 +140,9 @@ extern int currCounter; | Local Functions | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +static Word16 saturate_o (Word32 L_var1, Flag * Overflow); +#endif /* BASOP_NOGLOB */ static Word16 saturate (Word32 L_var1); @@ -145,8 +151,15 @@ static Word16 saturate (Word32 L_var1); | Constants and Globals | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +/* +Flag BASOP_Overflow = 0; +Flag BASOP_Carry = 0; +*/ +#else /* BASOP_NOGLOB */ Flag Overflow = 0; Flag Carry = 0; +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -181,14 +194,26 @@ Flag Carry = 0; | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +static Word16 saturate_o (Word32 L_var1, Flag *Overflow) { +#else /* BASOP_NOGLOB */ static Word16 saturate (Word32 L_var1) { +#endif /* BASOP_NOGLOB */ Word16 var_out; if (L_var1 > 0X00007fffL) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = MAX_16; } else if (L_var1 < (Word32) 0xffff8000L) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = MIN_16; } else { var_out = extract_l (L_var1); @@ -200,6 +225,12 @@ static Word16 saturate (Word32 L_var1) { return (var_out); } +#ifdef BASOP_NOGLOB +static Word16 saturate (Word32 L_var1) { + return saturate_o (L_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -234,12 +265,20 @@ static Word16 saturate (Word32 L_var1) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 add_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 add (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_sum; L_sum = (Word32) var1 + var2; +#ifdef BASOP_NOGLOB + var_out = saturate_o (L_sum, Overflow); +#else /* BASOP_NOGLOB */ var_out = saturate (L_sum); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].add++; @@ -247,6 +286,12 @@ Word16 add (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 add (Word16 var1, Word16 var2) { + return add_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -281,12 +326,20 @@ Word16 add (Word16 var1, Word16 var2) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 sub_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 sub (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_diff; L_diff = (Word32) var1 - var2; +#ifdef BASOP_NOGLOB + var_out = saturate_o (L_diff, Overflow); +#else /* BASOP_NOGLOB */ var_out = saturate (L_diff); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].sub++; @@ -294,6 +347,12 @@ Word16 sub (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 sub (Word16 var1, Word16 var2) { + return sub_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -376,7 +435,11 @@ Word16 abs_s (Word16 var1) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 shl_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 shl (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 result; @@ -393,7 +456,11 @@ Word16 shl (Word16 var1, Word16 var2) { result = (Word32) var1 *((Word32) 1 << var2); if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = (var1 > 0) ? MAX_16 : MIN_16; } else { var_out = extract_l (result); @@ -410,6 +477,13 @@ Word16 shl (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 shl (Word16 var1, Word16 var2) { + return shl_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + + /*___________________________________________________________________________ | | @@ -445,14 +519,22 @@ Word16 shl (Word16 var1, Word16 var2) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 shr_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 shr (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; if (var2 < 0) { if (var2 < -16) var2 = -16; var2 = -var2; +#ifdef BASOP_NOGLOB + var_out = shl_o (var1, var2, Overflow); +#else /* BASOP_NOGLOB */ var_out = shl (var1, var2); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].shl--; @@ -475,6 +557,12 @@ Word16 shr (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 shr (Word16 var1, Word16 var2) { + return shr_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -510,7 +598,11 @@ Word16 shr (Word16 var1, Word16 var2) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 mult_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 mult (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_product; @@ -521,7 +613,11 @@ Word16 mult (Word16 var1, Word16 var2) { if (L_product & (Word32) 0x00010000L) L_product = L_product | (Word32) 0xffff0000L; +#ifdef BASOP_NOGLOB + var_out = saturate_o (L_product, Overflow); +#else /* BASOP_NOGLOB */ var_out = saturate (L_product); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].mult++; @@ -529,6 +625,12 @@ Word16 mult (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 mult (Word16 var1, Word16 var2) { + return mult_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -564,7 +666,11 @@ Word16 mult (Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_mult_o (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_mult (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = (Word32) var1 *(Word32) var2; @@ -572,7 +678,11 @@ Word32 L_mult (Word16 var1, Word16 var2) { if (L_var_out != (Word32) 0x40000000L) { L_var_out *= 2; } else { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; } @@ -582,6 +692,12 @@ Word32 L_mult (Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_mult (Word16 var1, Word16 var2) { + return L_mult_o (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -731,11 +847,19 @@ Word16 extract_l (Word32 L_var1) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 round_fx_o (Word32 L_var1, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 round_fx (Word32 L_var1) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_rounded; +#ifdef BASOP_NOGLOB + L_rounded = L_add_o (L_var1, (Word32) 0x00008000L, Overflow); +#else /* BASOP_NOGLOB */ L_rounded = L_add (L_var1, (Word32) 0x00008000L); +#endif /* BASOP_NOGLOB */ var_out = extract_h (L_rounded); #if (WMOPS) @@ -746,6 +870,12 @@ Word16 round_fx (Word32 L_var1) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 round_fx (Word32 L_var1) { + return round_fx_o (L_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -783,12 +913,21 @@ Word16 round_fx (Word32 L_var1) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word32 L_product; +#ifdef BASOP_NOGLOB + L_product = L_mult_o (var1, var2, Overflow); + L_var_out = L_add_o (L_var3, L_product, Overflow); +#else /* BASOP_NOGLOB */ L_product = L_mult (var1, var2); L_var_out = L_add (L_var3, L_product); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_mult--; @@ -798,6 +937,12 @@ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) { + return L_mac_o (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -835,12 +980,21 @@ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word32 L_product; +#ifdef BASOP_NOGLOB + L_product = L_mult_o (var1, var2, Overflow); + L_var_out = L_sub_o (L_var3, L_product, Overflow); +#else /* BASOP_NOGLOB */ L_product = L_mult (var1, var2); L_var_out = L_sub (L_var3, L_product); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_mult--; @@ -850,6 +1004,12 @@ Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) { + return L_msu_o (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -889,15 +1049,27 @@ Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) { | | | Caution : | | | +#ifdef BASOP_NOGLOB + | In some cases the BASOP_Carry flag has to be cleared or set before using | +#else | In some cases the Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_macNs_co (Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = L_mult (var1, var2); +#ifdef BASOP_NOGLOB + L_var_out = L_add_co (L_var3, L_var_out, Carry, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_add_c (L_var3, L_var_out); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_mult--; @@ -907,6 +1079,11 @@ Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) { + return L_macNs_co (L_var3, var1, var2, NULL, NULL); +} +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -946,15 +1123,27 @@ Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) { | | | Caution : | | | +#ifdef BASOP_NOGLOB + | In some cases the BASOP_Carry flag has to be cleared or set before using | +#else | In some cases the Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_msuNs_co (Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = L_mult (var1, var2); +#ifdef BASOP_NOGLOB + L_var_out = L_sub_co (L_var3, L_var_out, Carry, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_sub_c (L_var3, L_var_out); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_mult--; @@ -965,6 +1154,12 @@ Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) { + return L_msuNs_co (L_var3, var1, var2, NULL, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -997,7 +1192,11 @@ Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_add (Word32 L_var1, Word32 L_var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = L_var1 + L_var2; @@ -1005,7 +1204,11 @@ Word32 L_add (Word32 L_var1, Word32 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; +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } #if (WMOPS) @@ -1014,6 +1217,12 @@ Word32 L_add (Word32 L_var1, Word32 L_var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_add (Word32 L_var1, Word32 L_var2) { + return L_add_o (L_var1, L_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1046,7 +1255,11 @@ Word32 L_add (Word32 L_var1, Word32 L_var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_sub (Word32 L_var1, Word32 L_var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = L_var1 - L_var2; @@ -1054,7 +1267,11 @@ Word32 L_sub (Word32 L_var1, Word32 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; +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } #if (WMOPS) @@ -1063,6 +1280,12 @@ Word32 L_sub (Word32 L_var1, Word32 L_var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_sub (Word32 L_var1, Word32 L_var2) { + return L_sub_o (L_var1, L_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1071,7 +1294,11 @@ Word32 L_sub (Word32 L_var1, Word32 L_var2) { | Purpose : | | | | Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)| +#ifdef BASOP_NOGLOB + | with carry. No saturation. Generate carry and BASOP_Overflow values. The car- | +#else | with carry. No saturation. Generate carry and Overflow values. The car- | +#endif | ry and overflow values are binary variables which can be tested and as- | | signed values. | | | @@ -1097,55 +1324,108 @@ Word32 L_sub (Word32 L_var1, Word32 L_var2) { | | | Caution : | | | +#ifdef BASOP_NOGLOB + | In some cases the BASOP_Carry flag has to be cleared or set before using | +#else | In some cases the Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_add_co (Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_add_c (Word32 L_var1, Word32 L_var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word32 L_test; Flag carry_int = 0; +#ifdef BASOP_NOGLOB + L_var_out = L_var1 + L_var2 + get_flag (Carry); +#else /* BASOP_NOGLOB */ L_var_out = L_var1 + L_var2 + Carry; +#endif /* BASOP_NOGLOB */ L_test = L_var1 + L_var2; if ((L_var1 > 0) && (L_var2 > 0) && (L_test < 0)) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ carry_int = 0; } else { if ((L_var1 < 0) && (L_var2 < 0)) { if (L_test >= 0) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ carry_int = 1; } else { +#ifdef BASOP_NOGLOB + unset_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 0; +#endif /* BASOP_NOGLOB */ carry_int = 1; } } else { if (((L_var1 ^ L_var2) < 0) && (L_test >= 0)) { +#ifdef BASOP_NOGLOB + unset_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 0; +#endif /* BASOP_NOGLOB */ carry_int = 1; } else { +#ifdef BASOP_NOGLOB + unset_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 0; +#endif /* BASOP_NOGLOB */ carry_int = 0; } } } +#ifdef BASOP_NOGLOB + if (get_flag (Carry)) { +#else /* BASOP_NOGLOB */ if (Carry) { +#endif /* BASOP_NOGLOB */ if (L_test == MAX_32) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + carry_int ? set_flag (Carry) : unset_flag (Carry); +#else /* BASOP_NOGLOB */ Overflow = 1; Carry = carry_int; +#endif /* BASOP_NOGLOB */ } else { if (L_test == (Word32) 0xFFFFFFFFL) { +#ifdef BASOP_NOGLOB + set_flag (Carry); +#else /* BASOP_NOGLOB */ Carry = 1; +#endif /* BASOP_NOGLOB */ } else { +#ifdef BASOP_NOGLOB + carry_int ? set_flag (Carry) : unset_flag (Carry); +#else /* BASOP_NOGLOB */ Carry = carry_int; +#endif /* BASOP_NOGLOB */ } } } else { +#ifdef BASOP_NOGLOB + carry_int ? set_flag (Carry) : unset_flag (Carry); +#else /* BASOP_NOGLOB */ Carry = carry_int; +#endif /* BASOP_NOGLOB */ } #if (WMOPS) @@ -1154,6 +1434,12 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_add_c (Word32 L_var1, Word32 L_var2) { + return L_add_co (L_var1, L_var2, NULL, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1162,7 +1448,11 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2) { | Purpose : | | | | Performs 32 bits subtraction of the two 32 bits variables with carry | + #ifdef BASOP_NOGLOB + | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and BASOP_Overflow | +#else | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow | +#endif | values. The carry and overflow values are binary variables which can | | be tested and assigned values. | | | @@ -1188,27 +1478,48 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2) { | | | Caution : | | | + #ifdef BASOP_NOGLOB + | In some cases the BASOP_Carry flag has to be cleared or set before using | +#else | In some cases the Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_sub_co (Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_sub_c (Word32 L_var1, Word32 L_var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word32 L_test; Flag carry_int = 0; +#ifdef BASOP_NOGLOB + if (get_flag (Carry)) { + unset_flag (Carry); +#else /* BASOP_NOGLOB */ if (Carry) { Carry = 0; +#endif /* BASOP_NOGLOB */ if (L_var2 != MIN_32) { +#ifdef BASOP_NOGLOB + L_var_out = L_add_co (L_var1, -L_var2, Carry, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_add_c (L_var1, -L_var2); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_add_c--; #endif } else { L_var_out = L_var1 - L_var2; if (L_var1 > 0L) { +#ifdef BASOP_NOGLOB + unset_flag (Carry); +#else /* BASOP_NOGLOB */ Overflow = 1; Carry = 0; +#endif /* BASOP_NOGLOB */ } } } else { @@ -1216,20 +1527,34 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2) { L_test = L_var1 - L_var2; if ((L_test < 0) && (L_var1 > 0) && (L_var2 < 0)) { +#ifndef BASOP_NOGLOB Overflow = 1; +#endif /* BASOP_NOGLOB */ carry_int = 0; } else if ((L_test > 0) && (L_var1 < 0) && (L_var2 > 0)) { +#ifndef BASOP_NOGLOB Overflow = 1; +#endif /* BASOP_NOGLOB */ carry_int = 1; } else if ((L_test > 0) && ((L_var1 ^ L_var2) > 0)) { +#ifndef BASOP_NOGLOB Overflow = 0; +#endif /* BASOP_NOGLOB */ carry_int = 1; } if (L_test == MIN_32) { +#ifdef BASOP_NOGLOB + carry_int ? set_flag (Carry) : unset_flag (Carry); +#else /* BASOP_NOGLOB */ Overflow = 1; Carry = carry_int; +#endif /* BASOP_NOGLOB */ } else { +#ifdef BASOP_NOGLOB + carry_int ? set_flag (Carry) : unset_flag (Carry); +#else /* BASOP_NOGLOB */ Carry = carry_int; +#endif /* BASOP_NOGLOB */ } } @@ -1239,6 +1564,12 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_sub_c (Word32 L_var1, Word32 L_var2) { + return L_sub_co (L_var1, L_var2, NULL, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1312,7 +1643,11 @@ Word32 L_negate (Word32 L_var1) { | range : 0x8000 <= var_out <= 0x7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 mult_ro (Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 mult_r (Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_product_arr; @@ -1324,7 +1659,11 @@ Word16 mult_r (Word16 var1, Word16 var2) { if (L_product_arr & (Word32) 0x00010000L) { /* sign extend when necessary */ L_product_arr |= (Word32) 0xffff0000L; } +#ifdef BASOP_NOGLOB + var_out = saturate_o (L_product_arr, Overflow); +#else /* BASOP_NOGLOB */ var_out = saturate (L_product_arr); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].mult_r++; @@ -1332,6 +1671,12 @@ Word16 mult_r (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 mult_r (Word16 var1, Word16 var2) { + return mult_ro (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1366,7 +1711,11 @@ Word16 mult_r (Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_shl (Word32 L_var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out = 0L; @@ -1381,12 +1730,20 @@ Word32 L_shl (Word32 L_var1, Word16 var2) { } else { for (; var2 > 0; var2--) { if (L_var1 > (Word32) 0X3fffffffL) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; break; } else { if (L_var1 < (Word32) 0xc0000000L) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MIN_32; break; } @@ -1401,6 +1758,12 @@ Word32 L_shl (Word32 L_var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_shl (Word32 L_var1, Word16 var2) { + return L_shl_o (L_var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1435,14 +1798,22 @@ Word32 L_shl (Word32 L_var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_shr_o (Word32 L_var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_shr (Word32 L_var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; if (var2 < 0) { if (var2 < -32) var2 = -32; var2 = -var2; +#ifdef BASOP_NOGLOB + L_var_out = L_shl_o (L_var1, var2, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_shl (L_var1, var2); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_shl--; #endif @@ -1463,6 +1834,12 @@ Word32 L_shr (Word32 L_var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_shr (Word32 L_var1, Word16 var2) { + return L_shr_o (L_var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1505,7 +1882,11 @@ Word32 L_shr (Word32 L_var1, Word16 var2) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 shr_ro (Word16 var1, Word16 var2, Flag *Overflow) { +#else Word16 shr_r (Word16 var1, Word16 var2) { +#endif Word16 var_out; if (var2 > 15) { @@ -1530,6 +1911,11 @@ Word16 shr_r (Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 shr_r (Word16 var1, Word16 var2) { + return shr_ro (var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1569,11 +1955,20 @@ Word16 shr_r (Word16 var1, Word16 var2) { | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 mac_ro (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; +#ifdef BASOP_NOGLOB + L_var3 = L_mac_o (L_var3, var1, var2, Overflow); + L_var3 = L_add_o (L_var3, (Word32) 0x00008000L, Overflow); +#else /* BASOP_NOGLOB */ L_var3 = L_mac (L_var3, var1, var2); L_var3 = L_add (L_var3, (Word32) 0x00008000L); +#endif /* BASOP_NOGLOB */ var_out = extract_h (L_var3); #if (WMOPS) @@ -1585,6 +1980,12 @@ Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) { + return mac_ro (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1624,11 +2025,20 @@ Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) { | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 msu_ro (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word16 var_out; +#ifdef BASOP_NOGLOB + L_var3 = L_msu_o (L_var3, var1, var2, Overflow); + L_var3 = L_add_o (L_var3, (Word32) 0x00008000L, Overflow); +#else /* BASOP_NOGLOB */ L_var3 = L_msu (L_var3, var1, var2); L_var3 = L_add (L_var3, (Word32) 0x00008000L); +#endif /* BASOP_NOGLOB */ var_out = extract_h (L_var3); #if (WMOPS) @@ -1640,6 +2050,12 @@ Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) { return (var_out); } +#ifdef BASOP_NOGLOB +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) { + return msu_ro (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1865,7 +2281,11 @@ Word32 L_abs (Word32 L_var1) { | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_sat_co (Word32 L_var1, Flag Carry, Flag Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_sat (Word32 L_var1) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; L_var_out = L_var1; @@ -1878,8 +2298,10 @@ Word32 L_sat (Word32 L_var1) { L_var_out = MAX_32; } +#ifndef BASOP_NOGLOB Carry = 0; Overflow = 0; +#endif /* BASOP_NOGLOB */ } #if (WMOPS) multiCounter[currCounter].L_sat++; @@ -1887,6 +2309,12 @@ Word32 L_sat (Word32 L_var1) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_sat (Word32 L_var1) { + assert (0); /* Overflow and Carry are no longer global, must be passed as parameters */ + return L_sat_co (L_var1, 0, 0); +} +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -2134,13 +2562,21 @@ Word16 norm_l (Word32 L_var1) { | | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 L_mls_o (Word32 Lv, Word16 v, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_mls (Word32 Lv, Word16 v) { +#endif /* BASOP_NOGLOB */ Word32 Temp; Temp = Lv & (Word32) 0x0000ffff; Temp = Temp * (Word32) v; Temp = L_shr (Temp, (Word16) 15); +#ifdef BASOP_NOGLOB + Temp = L_mac_o (Temp, v, extract_h (Lv), Overflow); +#else /* BASOP_NOGLOB */ Temp = L_mac (Temp, v, extract_h (Lv)); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_shr--; @@ -2152,6 +2588,12 @@ Word32 L_mls (Word32 Lv, Word16 v) { return Temp; } +#ifdef BASOP_NOGLOB +Word32 L_mls (Word32 Lv, Word16 v) { + return L_mls_o (Lv, v, NULL); +} +#endif /* BASOP_NOGLOB */ + /*__________________________________________________________________________ | | @@ -2202,12 +2644,20 @@ Word16 div_l (Word32 L_num, Word16 den) { if (den == (Word16) 0) { printf ("Division by 0 in div_l, Fatal error \n"); +#ifdef BASOP_NOGLOB + abort (); +#else /* BASOP_NOGLOB */ exit (0); +#endif /* BASOP_NOGLOB */ } if ((L_num < (Word32) 0) || (den < (Word16) 0)) { printf ("Division Error in div_l, Fatal error \n"); +#ifdef BASOP_NOGLOB + abort (); +#else /* BASOP_NOGLOB */ exit (0); +#endif /* BASOP_NOGLOB */ } L_den = L_deposit_h (den); @@ -2364,12 +2814,21 @@ Word32 L_mult0 (Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ +#ifdef BASOP_NOGLOB +Word32 L_mac0_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ + Word32 L_var_out; Word32 L_product; L_product = L_mult0 (var1, var2); +#ifdef BASOP_NOGLOB + L_var_out = L_add_o (L_var3, L_product, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_add (L_var3, L_product); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_mac0++; @@ -2379,6 +2838,13 @@ Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2) { + return L_mac0_o (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + + /*___________________________________________________________________________ | @@ -2410,12 +2876,20 @@ Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ +#ifdef BASOP_NOGLOB +Word32 L_msu0_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word32 L_product; L_product = L_mult0 (var1, var2); +#ifdef BASOP_NOGLOB + L_var_out = L_sub_o (L_var3, L_product, Overflow); +#else /* BASOP_NOGLOB */ L_var_out = L_sub (L_var3, L_product); +#endif /* BASOP_NOGLOB */ #if (WMOPS) multiCounter[currCounter].L_msu0++; @@ -2425,5 +2899,11 @@ Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2) { + return L_msu0_o (L_var3, var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /* end of file */ diff --git a/src/basop/basop32.h b/src/basop/basop32.h index 62a44ed..44dcda6 100644 --- a/src/basop/basop32.h +++ b/src/basop/basop32.h @@ -44,6 +44,10 @@ #ifndef _BASIC_OP_H #define _BASIC_OP_H +#ifdef BASOP_NOGLOB +#include +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -51,8 +55,16 @@ | $Id $ |___________________________________________________________________________| */ -extern Flag Overflow; +#ifdef BASOP_NOGLOB +/* DISABLED TO AVOID GLOBAL VARIABLES */ +/* +extern Flag BASOP_Overflow, BASOP_Overflow2; +extern Flag BASOP_Carry; +*/ +#else /* BASOP_NOGLOB */ +extern Flag Overflow, Overflow2; extern Flag Carry; +#endif /* BASOP_NOGLOB */ #define MAX_32 (Word32)0x7fffffffL #define MIN_32 (Word32)0x80000000L @@ -60,6 +72,12 @@ extern Flag Carry; #define MAX_16 (Word16)0x7fff #define MIN_16 (Word16)0x8000 +#ifdef BASOP_NOGLOB +static inline void set_flag(Flag* flag) { if (flag) *flag = 1; else assert(0); } +static inline void unset_flag(Flag* flag) { if (flag) *flag = 0; else assert(0); } +static inline Flag get_flag(Flag* flag) { if (flag) return *flag; else assert(0); } +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | | Prototypes for basic arithmetic operators | @@ -117,6 +135,36 @@ 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 */ +#ifdef BASOP_NOGLOB +/* + * Overflowing operators + */ +Word16 add_o (Word16 var1, Word16 var2, Flag * Overflow); +Word16 sub_o (Word16 var1, Word16 var2, Flag * Overflow); +Word16 shl_o (Word16 var1, Word16 var2, Flag * Overflow); +Word16 shr_o (Word16 var1, Word16 var2, Flag * Overflow); +Word16 shr_ro(Word16 var1, Word16 var2, Flag* Overflow); +Word16 mult_o (Word16 var1, Word16 var2, Flag * Overflow); +Word32 L_mult_o (Word16 var1, Word16 var2, Flag * Overflow); +Word16 round_fx_o (Word32 L_var1, Flag * Overflow); +Word32 L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word32 L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word32 L_macNs_co (Word32 L_var3, Word16 var1, Word16 var2, Flag * Carry, Flag* Overflow); +Word32 L_msuNs_co (Word32 L_var3, Word16 var1, Word16 var2, Flag * Carry, Flag* Overflow); +Word32 L_add_o (Word32 L_var1, Word32 L_var2, Flag * Overflow); +Word32 L_sub_o (Word32 L_var1, Word32 L_var2, Flag * Overflow); +Word32 L_add_co (Word32 L_var1, Word32 L_var2, Flag * Carry, Flag *Overflow); +Word32 L_sub_co (Word32 L_var1, Word32 L_var2, Flag * Carry, Flag *Overflow); +Word32 L_shr_o (Word32 L_var1, Word16 var2, Flag * Overflow); +Word32 L_shl_o (Word32 L_var1, Word16 var2, Flag * Overflow); +Word32 L_mls_o (Word32 Lv, Word16 v, Flag * Overflow); +Word32 L_mac0_o (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word32 L_msu0_o (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word16 mult_ro (Word16 var1, Word16 var2, Flag * Overflow); +Word16 mac_ro (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word16 msu_ro (Word32 L_var3, Word16 var1, Word16 var2, Flag * Overflow); +Word32 L_sat_co (Word32 L_var1, Flag Carry, Flag Overflow); +#endif /* BASOP_NOGLOB */ #endif /* ifndef _BASIC_OP_H */ diff --git a/src/basop/enh40.c b/src/basop/enh40.c index a72a243..c75fa61 100644 --- a/src/basop/enh40.c +++ b/src/basop/enh40.c @@ -63,6 +63,9 @@ #include #include #include "stl.h" +#ifdef BASOP_NOGLOB +#include +#endif /* BASOP_NOGLOB */ #if (WMOPS) extern BASIC_OP multiCounter[MAXCOUNTERS]; @@ -124,7 +127,11 @@ extern int currCounter; * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifdef BASOP_NOGLOB +Word40 L40_shl_o (Word40 L40_var1, Word16 var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word40 L40_shl (Word40 L40_var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word40 L40_var_out; Word40 L40_constant = L40_set (0xc000000000); @@ -143,12 +150,22 @@ Word40 L40_shl (Word40 L40_var1, Word16 var2) { for (; var2 > 0; var2--) { if (L40_var_out > 0x003fffffffff) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MAX_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_OVERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ break; } else if (L40_var_out < L40_constant) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MIN_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_UNDERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ break; } @@ -166,6 +183,12 @@ Word40 L40_shl (Word40 L40_var1, Word16 var2) { return (L40_var_out); } +#ifdef BASOP_NOGLOB +Word40 L40_shl (Word40 L40_var1, Word16 var2) { + return L40_shl_o (L40_var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /***************************************************************************** * @@ -295,7 +318,11 @@ Word40 L40_negate (Word40 L40_var1) { * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifdef BASOP_NOGLOB +Word40 L40_add_o (Word40 L40_var1, Word40 L40_var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word40 L40_add (Word40 L40_var1, Word40 L40_var2) { +#endif /* BASOP_NOGLOB */ Word40 L40_var_out; L40_var_out = L40_var1 + L40_var2; @@ -303,12 +330,22 @@ Word40 L40_add (Word40 L40_var1, Word40 L40_var2) { if ((((L40_var1 & 0x8000000000) >> 39) != 0) && (((L40_var2 & 0x8000000000) >> 39) != 0) && (((L40_var_out & 0x8000000000) >> 39) == 0)) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MIN_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_UNDERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ } else if ((((L40_var1 & 0x8000000000) >> 39) == 0) && (((L40_var2 & 0x8000000000) >> 39) == 0) && (((L40_var_out & 0x8000000000) >> 39) != 0)) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MAX_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_OVERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ } #if (WMOPS) multiCounter[currCounter].L40_add++; @@ -317,6 +354,12 @@ Word40 L40_add (Word40 L40_var1, Word40 L40_var2) { return (L40_var_out); } +#ifdef BASOP_NOGLOB +Word40 L40_add (Word40 L40_var1, Word40 L40_var2) { + return L40_add_o (L40_var1, L40_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /***************************************************************************** * @@ -348,7 +391,11 @@ Word40 L40_add (Word40 L40_var1, Word40 L40_var2) { * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifdef BASOP_NOGLOB +Word40 L40_sub_o (Word40 L40_var1, Word40 L40_var2, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word40 L40_sub (Word40 L40_var1, Word40 L40_var2) { +#endif /* BASOP_NOGLOB */ Word40 L40_var_out; L40_var_out = L40_var1 - L40_var2; @@ -356,12 +403,22 @@ Word40 L40_sub (Word40 L40_var1, Word40 L40_var2) { if ((((L40_var1 & 0x8000000000) >> 39) != 0) && (((L40_var2 & 0x8000000000) >> 39) == 0) && (((L40_var_out & 0x8000000000) >> 39) == 0)) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MIN_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_UNDERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ } else if ((((L40_var1 & 0x8000000000) >> 39) == 0) && (((L40_var2 & 0x8000000000) >> 39) != 0) && (((L40_var_out & 0x8000000000) >> 39) != 0)) { +#ifdef BASOP_NOGLOB + set_flag (Overflow); + L40_var_out = MAX_40; +#else /* BASOP_NOGLOB */ L40_var_out = L40_OVERFLOW_OCCURED (L40_var_out); +#endif /* BASOP_NOGLOB */ } #if (WMOPS) multiCounter[currCounter].L40_sub++; @@ -370,6 +427,12 @@ Word40 L40_sub (Word40 L40_var1, Word40 L40_var2) { return (L40_var_out); } +#ifdef BASOP_NOGLOB +Word40 L40_sub (Word40 L40_var1, Word40 L40_var2) { + return L40_sub_o (L40_var1, L40_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /***************************************************************************** * @@ -537,7 +600,11 @@ Word40 L40_min (Word40 L40_var1, Word40 L40_var2) { * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ +#ifdef BASOP_NOGLOB +Word32 L_saturate40_o (Word40 L40_var1, Flag *Overflow) { +#else /* BASOP_NOGLOB */ Word32 L_saturate40 (Word40 L40_var1) { +#endif /* BASOP_NOGLOB */ Word32 L_var_out; Word40 UNDER_L40_var2 = (Word40) ~ ((((Word40) 1) << 31) - (Word40) 1); @@ -545,12 +612,20 @@ Word32 L_saturate40 (Word40 L40_var1) { if (L40_var1 < UNDER_L40_var2) { L40_var1 = UNDER_L40_var2; +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } if (L40_var1 > OVER_L40_var2) { L40_var1 = OVER_L40_var2; +#ifdef BASOP_NOGLOB + set_flag (Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } L_var_out = L_Extract40 (L40_var1); @@ -563,6 +638,12 @@ Word32 L_saturate40 (Word40 L40_var1) { return (L_var_out); } +#ifdef BASOP_NOGLOB +Word32 L_saturate40 (Word40 L40_var1) { + return L_saturate40_o (L40_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /***************************************************************************** * diff --git a/src/basop/enh40.h b/src/basop/enh40.h index faa8663..da4de40 100644 --- a/src/basop/enh40.h +++ b/src/basop/enh40.h @@ -25,6 +25,10 @@ #include "stl.h" +#ifdef BASOP_NOGLOB +#define MAX_40 ( 0x0000007fffffffff ) +#define MIN_40 ( 0xffffff8000000000 ) +#endif /* BASOP_NOGLOB */ #ifdef WMOPS extern BASIC_OP multiCounter[MAXCOUNTERS]; @@ -44,6 +48,7 @@ extern int currCounter; +#ifndef BASOP_NOGLOB /***************************************************************************** * * Macros for 40 bit arithmetic overflow management : @@ -53,6 +58,7 @@ extern int currCounter; *****************************************************************************/ #define L40_OVERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(1), L40_var1) #define L40_UNDERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(2), L40_var1) +#endif /* BASOP_NOGLOB */ @@ -104,6 +110,15 @@ Word40 L40_min (Word40 L40_var1, Word40 L40_var2); Word32 L_saturate40 (Word40 L40_var1); Word16 norm_L40 (Word40 L40_var1); +#ifdef BASOP_NOGLOB +/* + * Overflowing operators + */ +Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ); +Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); +Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); +Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ /***************************************************************************** * diff --git a/src/basop/enh64.c b/src/basop/enh64.c index 37a408b..5aabb45 100755 --- a/src/basop/enh64.c +++ b/src/basop/enh64.c @@ -163,7 +163,11 @@ Word64 W_sub_nosat (Word64 L64_var1, Word64 L64_var2) { | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_shl_o (Word64 L64_var1, Word16 var2, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_shl (Word64 L64_var1, Word16 var2) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out = 0LL; @@ -176,13 +180,21 @@ Word64 W_shl (Word64 L64_var1, Word16 var2) { else { for (; var2 > 0; var2--) { if (L64_var1 > (Word64) 0X3fffffffffffffffLL) { +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ L64_var_out = (Word64) 0X7fffffffffffffffLL; break; } else { if (L64_var1 < (Word64) 0xc000000000000000LL) { +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ L64_var_out = (Word64)0x8000000000000000LL; break; } @@ -200,6 +212,12 @@ Word64 W_shl (Word64 L64_var1, Word16 var2) { return (L64_var_out); } +#ifdef BASOP_NOGLOB +Word64 W_shl (Word64 L64_var1, Word16 var2) { + return W_shl_o(L64_var1, var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1088,7 +1106,11 @@ Word32 W_shl_sat_l (Word64 L64_var, Word32 n) { | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |__________________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word32 W_round48_L_o (Word64 L64_var1, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word32 W_round48_L (Word64 L64_var1) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; Word32 L_result; @@ -1103,7 +1125,11 @@ Word32 W_round48_L (Word64 L64_var1) { if ( ( (L64_var1 ^ L64_var2) & L64_MIN) == 0) { if ( (L64_var_out ^ L64_var1) & L64_MIN) { L64_var_out = (L64_var1 < 0) ? L64_MIN : L64_MAX; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } L_result = W_extract_h (L64_var_out); @@ -1116,6 +1142,12 @@ Word32 W_round48_L (Word64 L64_var1) { return (L_result); } +#ifdef BASOP_NOGLOB +Word32 W_round48_L (Word64 L64_var1) { + return W_round48_L_o(L64_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*__________________________________________________________________________________ | | | Function Name : W_round32_s | @@ -1143,7 +1175,11 @@ Word32 W_round48_L (Word64 L64_var1) { | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |__________________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 W_round32_s_o (Word64 L64_var1, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word16 W_round32_s (Word64 L64_var1) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; Word32 L_var; Word16 var_out; @@ -1159,7 +1195,11 @@ Word16 W_round32_s (Word64 L64_var1) { if (((L64_var1 ^ L64_var2) & L64_MIN) == 0) { if ((L64_var_out ^ L64_var1) & L64_MIN) { L64_var_out = (L64_var1 < 0) ? L64_MIN : L64_MAX; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } L_var = W_extract_h (L64_var_out); @@ -1173,6 +1213,13 @@ Word16 W_round32_s (Word64 L64_var1) { return (var_out); } + +#ifdef BASOP_NOGLOB +Word16 W_round32_s (Word64 L64_var1) { + return W_round32_s_o(L64_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | | Function Name : W_norm | @@ -1258,7 +1305,11 @@ Word16 W_norm (Word64 L64_var1) { | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_add_o (Word64 L64_var1, Word64 L64_var2, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_add (Word64 L64_var1, Word64 L64_var2) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; L64_var_out = L64_var1 + L64_var2; @@ -1266,7 +1317,11 @@ Word64 W_add (Word64 L64_var1, Word64 L64_var2) { if (((L64_var1 ^ L64_var2) & MIN_64) == 0) { if ((L64_var_out ^ L64_var1) & MIN_64) { L64_var_out = (L64_var1 < 0) ? MIN_64 : MAX_64; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } @@ -1276,6 +1331,12 @@ Word64 W_add (Word64 L64_var1, Word64 L64_var2) { return L64_var_out; } +#ifdef BASOP_NOGLOB +Word64 W_add (Word64 L64_var1, Word64 L64_var2) { + return W_add_o(L64_var1, L64_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*______________________________________________________________________________ | | | Function Name : W_sub | @@ -1307,7 +1368,11 @@ Word64 W_add (Word64 L64_var1, Word64 L64_var2) { | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_sub_o (Word64 L64_var1, Word64 L64_var2, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_sub (Word64 L64_var1, Word64 L64_var2) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; L64_var_out = L64_var1 - L64_var2; @@ -1315,7 +1380,11 @@ Word64 W_sub (Word64 L64_var1, Word64 L64_var2) { if (((L64_var1 ^ L64_var2) & MIN_64) != 0) { if ((L64_var_out ^ L64_var1) & MIN_64) { L64_var_out = (L64_var1 < 0) ? MIN_64 : MAX_64; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } } @@ -1325,6 +1394,12 @@ Word64 W_sub (Word64 L64_var1, Word64 L64_var2) { return L64_var_out; } +#ifdef BASOP_NOGLOB +Word64 W_sub (Word64 L64_var1, Word64 L64_var2) { + return W_sub_o(L64_var1, L64_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*______________________________________________________________________________ | | @@ -1353,12 +1428,20 @@ Word64 W_sub (Word64 L64_var1, Word64 L64_var2) { | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_neg_o (Word64 L64_var1, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_neg (Word64 L64_var1) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; if (L64_var1 == MIN_64) { L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } else { L64_var_out = -L64_var1; @@ -1372,6 +1455,12 @@ Word64 W_neg (Word64 L64_var1) { } +#ifdef BASOP_NOGLOB +Word64 W_neg (Word64 L64_var1) { + return W_neg_o(L64_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -1400,12 +1489,20 @@ Word64 W_neg (Word64 L64_var1) { | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_abs_o (Word64 L64_var1, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_abs (Word64 L64_var1) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; if (L64_var1 == MIN_64) { L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } else { if (L64_var1 < 0) { @@ -1423,6 +1520,12 @@ Word64 W_abs (Word64 L64_var1) { return (L64_var_out); } +#ifdef BASOP_NOGLOB +Word64 W_abs (Word64 L64_var1) { + return W_abs_o(L64_var1, NULL); +} +#endif /* BASOP_NOGLOB */ + /*_________________________________________________________________________________________________ | | | Function Name : W_mult_32_32 | @@ -1455,12 +1558,20 @@ Word64 W_abs (Word64 L64_var1) { | range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | |_________________________________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word64 W_mult_32_32_o(Word32 L_var1, Word32 L_var2, Flag* Overflow) { +#else /* BASOP_NOGLOB */ Word64 W_mult_32_32(Word32 L_var1, Word32 L_var2) { +#endif /* BASOP_NOGLOB */ Word64 L64_var_out; if ((L_var1 == MIN_32) && (L_var2 == MIN_32)) { L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_flag(Overflow); +#else /* BASOP_NOGLOB */ Overflow = 1; +#endif /* BASOP_NOGLOB */ } else { L64_var_out = ((Word64 )L_var1*L_var2) << 1; @@ -1472,6 +1583,12 @@ Word64 W_mult_32_32(Word32 L_var1, Word32 L_var2) { return L64_var_out; } +#ifdef BASOP_NOGLOB +Word64 W_mult_32_32(Word32 L_var1, Word32 L_var2) { + return W_mult_32_32_o(L_var1, L_var2, NULL); +} +#endif /* BASOP_NOGLOB */ + /*_________________________________________________________________________________________________ | | | Function Name : W_mult0_32_32 | diff --git a/src/basop/enh64.h b/src/basop/enh64.h index ac15ffd..9364c25 100755 --- a/src/basop/enh64.h +++ b/src/basop/enh64.h @@ -63,6 +63,20 @@ UWord64 W_lshl (UWord64 L64_var1, Word16 var2); UWord64 W_lshr (UWord64 L64_var1, Word16 var2); Word32 W_round64_L (Word64 L64_var1) ; +#ifdef BASOP_NOGLOB +/* + * Overflowing operators + */ +Word64 W_shl_o (Word64 L64_var1, Word16 var2, Flag* Overflow); +Word32 W_round48_L_o (Word64 L64_var1, Flag* Overflow); +Word16 W_round32_s_o (Word64 L64_var1, Flag* Overflow); +Word64 W_add_o (Word64 L64_var1, Word64 L64_var2, Flag* Overflow); +Word64 W_sub_o (Word64 L64_var1, Word64 L64_var2, Flag* Overflow); +Word64 W_neg_o (Word64 L64_var1, Flag* Overflow); +Word64 W_abs_o (Word64 L64_var1, Flag* Overflow); +Word64 W_mult_32_32_o(Word32 L_var1, Word32 L_var2, Flag* Overflow); +#endif /* BASOP_NOGLOB */ + #endif /* #ifdef ENH_64_BIT_OPERATOR */ #endif /*_ENH64_H*/ diff --git a/src/basop/test_framework/CMakeLists.txt b/src/basop/test_framework/CMakeLists.txt index 61cf933..c2ada4c 100644 --- a/src/basop/test_framework/CMakeLists.txt +++ b/src/basop/test_framework/CMakeLists.txt @@ -5,7 +5,7 @@ file(GLOB BASOP_TEST_SRC ./src/*.c ./test/*.c) include_directories( ./ ../ ./src ) add_executable(basop_test ${BASOP_SRC} ${BASOP_TEST_SRC}) -target_compile_definitions(basop_test PUBLIC ENH_64_BIT_OPERATOR ENH_32_BIT_OPERATOR COMPLEX_OPERATOR ALLOW_ENH_UL32 IDENTICAL_FLOAT_INP) +target_compile_definitions(basop_test PUBLIC ENH_64_BIT_OPERATOR ENH_32_BIT_OPERATOR COMPLEX_OPERATOR ALLOW_ENH_UL32 IDENTICAL_FLOAT_INP BASOP_NOGLOB) target_link_libraries(basop_test ${M_LIBRARY}) diff --git a/src/g722/funcg722.c b/src/g722/funcg722.c index 4e2cb4f..41b3a36 100644 --- a/src/g722/funcg722.c +++ b/src/g722/funcg722.c @@ -1227,6 +1227,9 @@ Word16 scaleh (Word16 nbph) { */ void uppol1 (Word16 al[], Word16 plt[]) { Word16 sg0, sg1, wd1, wd2, wd3, apl1; +#ifdef BASOP_NOGLOB + Flag Overflow; +#endif /* BASOP_NOGLOB */ sg0 = shr (plt[0], 15); sg1 = shr (plt[1], 15); @@ -1243,14 +1246,22 @@ void uppol1 (Word16 al[], Word16 plt[]) { wd2 = mult (al[1], 32640); apl1 = add (wd1, wd2); wd3 = sub (15360, al[2]); +#ifdef BASOP_NOGLOB + if (sub_o (apl1, wd3, &Overflow) > 0) { +#else /* BASOP_NOGLOB */ if (sub (apl1, wd3) > 0) { +#endif /* BASOP_NOGLOB */ apl1 = wd3; #ifdef WMOPS move16 (); #endif } ELSE { +#ifdef BASOP_NOGLOB + if (add_o (apl1, wd3, &Overflow) < 0) { +#else /* BASOP_NOGLOB */ if (add (apl1, wd3) < 0) { +#endif /* BASOP_NOGLOB */ apl1 = negate (wd3); } } @@ -1291,14 +1302,25 @@ void uppol1 (Word16 al[], Word16 plt[]) { */ void uppol2 (Word16 al[], Word16 plt[]) { Word16 sg0, sg1, sg2, wd1, wd2, wd3, wd4, wd5, apl2; +#ifdef BASOP_NOGLOB + Flag Overflow; +#endif /* BASOP_NOGLOB */ sg0 = shr (plt[0], 15); sg1 = shr (plt[1], 15); sg2 = shr (plt[2], 15); +#ifdef BASOP_NOGLOB + wd1 = shl_o (al[1], 2, &Overflow); +#else /* BASOP_NOGLOB */ wd1 = shl (al[1], 2); +#endif /* BASOP_NOGLOB */ wd2 = add (0, wd1); if (sub (sg0, sg1) == 0) { +#ifdef BASOP_NOGLOB + wd2 = sub_o (0, wd1, &Overflow); +#else /* BASOP_NOGLOB */ wd2 = sub (0, wd1); +#endif /* BASOP_NOGLOB */ } wd2 = shr (wd2, 7); wd3 = -128;