diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj
index fba796c7c63e8a6e1e913f76203477e3326ce4e0..29658b452400064cfec17a459957e1e6ac7f12dd 100644
--- a/Workspace_msvc/lib_com.vcxproj
+++ b/Workspace_msvc/lib_com.vcxproj
@@ -283,7 +283,6 @@
-
diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters
index 7a8f8e013bc27c7ca256c1f5945d88fd49176f28..6bc0ffe04b5362a5a229d50458d96bcc95108214 100644
--- a/Workspace_msvc/lib_com.vcxproj.filters
+++ b/Workspace_msvc/lib_com.vcxproj.filters
@@ -489,9 +489,6 @@
common_h
-
- common_h
-
common_h
diff --git a/apps/decoder.c b/apps/decoder.c
index 9b5619ceacba661f4e0663c2380c127782665ae4..f893346623b046fdce936098229051de268b7c39 100644
--- a/apps/decoder.c
+++ b/apps/decoder.c
@@ -3503,3 +3503,5 @@ static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec(
return IVAS_DEC_FORCE_REND_UNDEFINED;
}
#endif
+
+#undef WMC_TOOL_SKIP
diff --git a/apps/encoder.c b/apps/encoder.c
index 9229cc64143e4475f56dd0505f9dc452612093e4..ef1e7c1c85232c081010bba22e3f4b9537f5e4dc 100644
--- a/apps/encoder.c
+++ b/apps/encoder.c
@@ -2117,3 +2117,5 @@ static ivas_error readForcedMode(
return IVAS_ERR_OK;
}
#endif
+
+#undef WMC_TOOL_SKIP
diff --git a/apps/renderer.c b/apps/renderer.c
index 7f5af747d530f6f1059e802fcd2e979faf7f6f6c..1ee499fbea1512e4683a59f74a642211055f98e5 100644
--- a/apps/renderer.c
+++ b/apps/renderer.c
@@ -4072,3 +4072,5 @@ static void convertOutputBuffer(
return;
}
+
+#undef WMC_TOOL_SKIP
diff --git a/lib_com/basop32.c b/lib_com/basop32.c
index 3e608e4a6506c626dca99b99daf1d223d7d057c7..a407ff72d40b0fcd774572f770b764b254fa88e0 100644
--- a/lib_com/basop32.c
+++ b/lib_com/basop32.c
@@ -261,6 +261,9 @@ static Word16 saturate_o( Word32 L_var1, Flag *Overflow )
else
{
var_out = extract_l( L_var1 );
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+#endif
}
BASOP_CHECK();
@@ -286,6 +289,9 @@ static Word16 saturate( Word32 L_var1 )
else
{
var_out = extract_l( L_var1 );
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+#endif
}
BASOP_CHECK();
@@ -336,7 +342,9 @@ Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow )
L_sum = (Word32) var1 + var2;
var_out = saturate_o( L_sum, Overflow );
-
+#ifdef WMOPS
+ multiCounter[currCounter].add++;
+#endif
return ( var_out );
}
@@ -349,7 +357,9 @@ Word16 add( Word16 var1, Word16 var2 )
L_sum = (Word32) var1 + var2;
var_out = saturate( L_sum );
-
+#ifdef WMOPS
+ multiCounter[currCounter].add++;
+#endif
return ( var_out );
}
@@ -396,6 +406,9 @@ Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow )
L_diff = (Word32) var1 - var2;
var_out = saturate_o( L_diff, Overflow );
+#ifdef WMOPS
+ multiCounter[currCounter].sub++;
+#endif
return ( var_out );
}
@@ -408,6 +421,9 @@ Word16 sub( Word16 var1, Word16 var2 )
L_diff = (Word32) var1 - var2;
var_out = saturate( L_diff );
+#ifdef WMOPS
+ multiCounter[currCounter].sub++;
+#endif
return ( var_out );
}
@@ -459,6 +475,9 @@ Word16 abs_s( Word16 var1 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].abs_s++;
+#endif
BASOP_CHECK();
@@ -515,6 +534,10 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow )
var2 = -16;
var2 = -var2;
var_out = shr( var1, var2 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].shr--;
+#endif
}
else
{
@@ -532,9 +555,17 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow )
else
{
var_out = extract_l( result );
+
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+#endif
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].shl++;
+#endif
+
BASOP_CHECK();
@@ -553,6 +584,10 @@ Word16 shl( Word16 var1, Word16 var2 )
var2 = -16;
var2 = -var2;
var_out = shr( var1, var2 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].shr--;
+#endif
}
else
{
@@ -566,9 +601,16 @@ Word16 shl( Word16 var1, Word16 var2 )
else
{
var_out = extract_l( result );
+
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+#endif
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].shl++;
+#endif
BASOP_CHECK();
@@ -623,6 +665,10 @@ Word16 shr( Word16 var1, Word16 var2 )
var2 = -16;
var2 = -var2;
var_out = shl( var1, var2 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].shl--;
+#endif
}
else
{
@@ -643,6 +689,10 @@ Word16 shr( Word16 var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].shr++;
+#endif
+
BASOP_CHECK();
@@ -699,6 +749,9 @@ Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow )
var_out = saturate_o( L_product, Overflow );
+#ifdef WMOPS
+ multiCounter[currCounter].mult++;
+#endif
return ( var_out );
}
@@ -718,7 +771,9 @@ Word16 mult( Word16 var1, Word16 var2 )
var_out = saturate( L_product );
-
+#ifdef WMOPS
+ multiCounter[currCounter].mult++;
+#endif
return ( var_out );
}
@@ -781,6 +836,10 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow )
L_var_out = MAX_32;
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult++;
+#endif
+
BASOP_CHECK();
return ( L_var_out );
@@ -803,6 +862,10 @@ Word32 L_mult( Word16 var1, Word16 var2 )
L_var_out = MAX_32;
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult++;
+#endif
+
BASOP_CHECK();
return ( L_var_out );
@@ -844,6 +907,10 @@ Word16 negate( Word16 var1 )
var_out = ( var1 == MIN_16 ) ? MAX_16 : -var1;
+#ifdef WMOPS
+ multiCounter[currCounter].negate++;
+#endif
+
BASOP_CHECK();
@@ -884,6 +951,10 @@ Word16 extract_h( Word32 L_var1 )
var_out = (Word16) ( L_var1 >> 16 );
+#ifdef WMOPS
+ multiCounter[currCounter].extract_h++;
+#endif
+
BASOP_CHECK();
@@ -924,6 +995,10 @@ Word16 extract_l( Word32 L_var1 )
var_out = (Word16) L_var1;
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l++;
+#endif
+
BASOP_CHECK();
@@ -972,6 +1047,12 @@ Word16 round_fx_o( Word32 L_var1, Flag *Overflow )
BASOP_SATURATE_WARNING_ON
var_out = extract_h( L_rounded );
+#ifdef WMOPS
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].round++;
+#endif
+
BASOP_CHECK();
return ( var_out );
@@ -988,6 +1069,11 @@ Word16 round_fx( Word32 L_var1 )
BASOP_SATURATE_WARNING_ON
var_out = extract_h( L_rounded );
+#ifdef WMOPS
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].round++;
+#endif
BASOP_CHECK();
return ( var_out );
@@ -1039,7 +1125,11 @@ Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_product = L_mult_o( var1, var2, Overflow );
L_var_out = L_add_o( L_var3, L_product, Overflow );
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].L_mac++;
+#endif
return ( L_var_out );
}
@@ -1053,6 +1143,11 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 )
L_product = L_mult( var1, var2 );
L_var_out = L_add( L_var3, L_product );
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].L_mac++;
+#endif
BASOP_CHECK();
return ( L_var_out );
@@ -1104,7 +1199,11 @@ Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_product = L_mult_o( var1, var2, Overflow );
L_var_out = L_sub_o( L_var3, L_product, Overflow );
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_sub--;
+ multiCounter[currCounter].L_msu++;
+#endif
return ( L_var_out );
}
@@ -1118,6 +1217,11 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 )
L_product = L_mult( var1, var2 );
L_var_out = L_sub( L_var3, L_product );
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_sub--;
+ multiCounter[currCounter].L_msu++;
+#endif
BASOP_CHECK();
return ( L_var_out );
@@ -1185,6 +1289,12 @@ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry )
L_var_out = DEPR_L_add_c( L_var3, L_var_out, Carry );
#endif /* BASOP_NOGLOB */
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_add_c--;
+ multiCounter[currCounter].L_macNs++;
+#endif
+
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
@@ -1253,8 +1363,13 @@ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry )
L_var_out = DEPR_L_sub_c( L_var3, L_var_out, Carry );
#endif /* BASOP_NOGLOB */
- /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult--;
+ multiCounter[currCounter].L_sub_c--;
+ multiCounter[currCounter].L_msuNs++;
+#endif
+ /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
return ( L_var_out );
}
@@ -1314,6 +1429,10 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_add++;
+#endif
+
BASOP_CHECK();
@@ -1336,6 +1455,9 @@ Word32 L_add( Word32 L_var1, Word32 L_var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_add++;
+#endif
return ( L_var_out );
}
#endif /* BASOP_NOGLOB */
@@ -1394,6 +1516,10 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_sub++;
+#endif
+
BASOP_CHECK();
return ( L_var_out );
@@ -1415,6 +1541,9 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_sub++;
+#endif
BASOP_CHECK();
return ( L_var_out );
@@ -1573,6 +1702,10 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry )
#endif /* BASOP_NOGLOB */
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_add_c++;
+#endif
+
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
@@ -1653,6 +1786,9 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry )
#else /* BASOP_NOGLOB */
L_var_out = DEPR_L_add_c( L_var1, -L_var2, Carry );
#endif /* BASOP_NOGLOB */
+#ifdef WMOPS
+ multiCounter[currCounter].L_add_c--;
+#endif
}
else
{
@@ -1713,6 +1849,10 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_sub_c++;
+#endif
+
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
@@ -1753,6 +1893,11 @@ Word32 L_negate( Word32 L_var1 )
L_var_out = ( L_var1 == MIN_32 ) ? MAX_32 : -L_var1;
+
+#ifdef WMOPS
+ multiCounter[currCounter].L_negate++;
+#endif
+
BASOP_CHECK();
return ( L_var_out );
@@ -1809,6 +1954,9 @@ Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow )
}
var_out = saturate_o( L_product_arr, Overflow );
+#ifdef WMOPS
+ multiCounter[currCounter].mult_r++;
+#endif
return ( var_out );
}
@@ -1830,7 +1978,9 @@ Word16 mult_r( Word16 var1, Word16 var2 )
}
var_out = saturate( L_product_arr );
-
+#ifdef WMOPS
+ multiCounter[currCounter].mult_r++;
+#endif
return ( var_out );
}
@@ -1883,6 +2033,9 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow )
var2 = -32;
var2 = -var2;
L_var_out = L_shr( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr--;
+#endif
}
else
{
@@ -1916,6 +2069,10 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl++;
+#endif
+
BASOP_CHECK();
@@ -1934,6 +2091,9 @@ Word32 L_shl( Word32 L_var1, Word16 var2 )
var2 = -32;
var2 = -var2;
L_var_out = L_shr( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr--;
+#endif
}
else
{
@@ -1959,6 +2119,9 @@ Word32 L_shl( Word32 L_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl++;
+#endif
BASOP_CHECK();
@@ -2010,6 +2173,9 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow )
var2 = -32;
var2 = -var2;
L_var_out = L_shl_o( L_var1, var2, Overflow );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl--;
+#endif
}
else
{
@@ -2030,6 +2196,10 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr++;
+#endif
+
BASOP_CHECK();
@@ -2047,6 +2217,9 @@ Word32 L_shr( Word32 L_var1, Word16 var2 )
var2 = -32;
var2 = -var2;
L_var_out = L_shl( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl--;
+#endif
}
else
{
@@ -2067,6 +2240,9 @@ Word32 L_shr( Word32 L_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr++;
+#endif
BASOP_CHECK();
@@ -2127,6 +2303,9 @@ Word16 shr_r( Word16 var1, Word16 var2 )
{
var_out = shr( var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].shr--;
+#endif
if ( var2 > 0 )
{
if ( ( var1 & ( (Word16) 1 << ( var2 - 1 ) ) ) != 0 )
@@ -2136,6 +2315,10 @@ Word16 shr_r( Word16 var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].shr_r++;
+#endif
+
BASOP_CHECK();
return ( var_out );
@@ -2189,6 +2372,13 @@ Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_var3 = L_add_o( L_var3, (Word32) 0x00008000L, Overflow );
var_out = extract_h( L_var3 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_mac--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].mac_r++;
+#endif
+
BASOP_CHECK();
@@ -2204,6 +2394,13 @@ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 )
L_var3 = L_add( L_var3, (Word32) 0x00008000L );
var_out = extract_h( L_var3 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_mac--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].mac_r++;
+#endif
+
BASOP_CHECK();
@@ -2258,6 +2455,12 @@ Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_var3 = L_add_o( L_var3, (Word32) 0x00008000L, Overflow );
var_out = extract_h( L_var3 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_msu--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].msu_r++;
+#endif
BASOP_CHECK();
return ( var_out );
@@ -2272,6 +2475,12 @@ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 )
L_var3 = L_add( L_var3, (Word32) 0x00008000L );
var_out = extract_h( L_var3 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_msu--;
+ multiCounter[currCounter].L_add--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].msu_r++;
+#endif
BASOP_CHECK();
return ( var_out );
@@ -2312,6 +2521,10 @@ Word32 L_deposit_h( Word16 var1 )
L_var_out = (Word32) var1 << 16;
+#ifdef WMOPS
+ multiCounter[currCounter].L_deposit_h++;
+#endif
+
BASOP_CHECK();
@@ -2353,6 +2566,10 @@ Word32 L_deposit_l( Word16 var1 )
L_var_out = (Word32) var1;
+#ifdef WMOPS
+ multiCounter[currCounter].L_deposit_l++;
+#endif
+
BASOP_CHECK();
@@ -2413,6 +2630,9 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 )
{
L_var_out = L_shr( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr--;
+#endif
if ( var2 > 0 )
{
if ( ( L_var1 & ( (Word32) 1 << ( var2 - 1 ) ) ) != 0 )
@@ -2422,6 +2642,10 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr_r++;
+#endif
+
BASOP_CHECK();
@@ -2477,6 +2701,10 @@ Word32 L_abs( Word32 L_var1 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_abs++;
+#endif
+
BASOP_CHECK();
@@ -2542,6 +2770,10 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry )
#endif /* ! BASOP_NOGLOB */
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_sat++;
+#endif
+
BASOP_CHECK();
@@ -2608,6 +2840,10 @@ Word16 norm_s( Word16 var1 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].norm_s++;
+#endif
+
BASOP_CHECK();
@@ -2685,6 +2921,11 @@ Word16 div_s( Word16 var1, Word16 var2 )
L_num = L_deposit_l( var1 );
L_denom = L_deposit_l( var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_deposit_l--;
+ multiCounter[currCounter].L_deposit_l--;
+#endif
+
for ( iteration = 0; iteration < 15; iteration++ )
{
var_out <<= 1;
@@ -2694,11 +2935,19 @@ Word16 div_s( Word16 var1, Word16 var2 )
{
L_num = L_sub( L_num, L_denom );
var_out = add( var_out, 1 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_sub--;
+ multiCounter[currCounter].add--;
+#endif
}
}
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].div_s++;
+#endif
+
BASOP_CHECK();
@@ -2765,6 +3014,10 @@ Word16 norm_l( Word32 L_var1 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].norm_l++;
+#endif
+
BASOP_CHECK();
@@ -2827,6 +3080,13 @@ Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow )
Temp = L_shr( Temp, (Word16) 15 );
Temp = L_mac_o( Temp, v, extract_h( Lv ), Overflow );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr--;
+ multiCounter[currCounter].L_mac--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].L_mls++;
+#endif
+
BASOP_CHECK();
return Temp;
@@ -2842,6 +3102,13 @@ Word32 L_mls( Word32 Lv, Word16 v )
Temp = L_shr( Temp, (Word16) 15 );
Temp = L_mac( Temp, v, extract_h( Lv ) );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr--;
+ multiCounter[currCounter].L_mac--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].L_mls++;
+#endif
+
BASOP_CHECK();
return Temp;
@@ -2892,6 +3159,9 @@ Word16 div_l( Word32 L_num, Word16 den )
Word32 L_den;
Word16 iteration;
+#ifdef WMOPS
+ multiCounter[currCounter].div_l++;
+#endif
if ( den == (Word16) 0 )
{
@@ -2906,6 +3176,9 @@ Word16 div_l( Word32 L_num, Word16 den )
}
L_den = L_deposit_h( den );
+#ifdef WMOPS
+ multiCounter[currCounter].L_deposit_h--;
+#endif
if ( L_num >= L_den )
{
@@ -2918,14 +3191,25 @@ Word16 div_l( Word32 L_num, Word16 den )
{
L_num = L_shr( L_num, (Word16) 1 );
L_den = L_shr( L_den, (Word16) 1 );
+#ifdef 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 );
+#ifdef 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 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_sub--;
+ multiCounter[currCounter].add--;
+#endif
}
}
@@ -2977,6 +3261,9 @@ Word16 DEPR_i_mult( Word16 a, Word16 b )
return a * b;
#else
Word32 /*register*/ c = a * b;
+#ifdef WMOPS
+ multiCounter[currCounter].i_mult++;
+#endif
return saturate( c );
#endif
}
@@ -3022,7 +3309,9 @@ Word32 L_mult0( Word16 var1, Word16 var2 )
L_var_out = (Word32) var1 * (Word32) var2;
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_mult0++;
+#endif
return ( L_var_out );
@@ -3068,8 +3357,13 @@ Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_product = L_mult0( var1, var2 );
L_var_out = L_add_o( L_var3, L_product, Overflow );
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_mac0++;
+ multiCounter[currCounter].L_mult0--;
+ multiCounter[currCounter].L_add--;
+#endif
+ BASOP_CHECK();
return ( L_var_out );
}
@@ -3083,6 +3377,12 @@ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 )
L_product = L_mult0( var1, var2 );
L_var_out = L_add( L_var3, L_product );
+#ifdef WMOPS
+ multiCounter[currCounter].L_mac0++;
+ multiCounter[currCounter].L_mult0--;
+ multiCounter[currCounter].L_add--;
+#endif
+
BASOP_CHECK();
@@ -3129,8 +3429,13 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow )
L_product = L_mult0( var1, var2 );
L_var_out = L_sub_o( L_var3, L_product, Overflow );
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_msu0++;
+ multiCounter[currCounter].L_mult0--;
+ multiCounter[currCounter].L_sub--;
+#endif
+ BASOP_CHECK();
return ( L_var_out );
}
@@ -3144,6 +3449,12 @@ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 )
L_product = L_mult0( var1, var2 );
L_var_out = L_sub( L_var3, L_product );
+#ifdef WMOPS
+ multiCounter[currCounter].L_msu0++;
+ multiCounter[currCounter].L_mult0--;
+ multiCounter[currCounter].L_sub--;
+#endif
+
BASOP_CHECK();
diff --git a/lib_com/basop_lsf_tools.c b/lib_com/basop_lsf_tools.c
index eddce99e83929a2ae105b6117512512f20fd1880..103fe7000207e24f8ef78003bfb965b32a55b9ed 100644
--- a/lib_com/basop_lsf_tools.c
+++ b/lib_com/basop_lsf_tools.c
@@ -38,7 +38,6 @@
#include
#include "options.h"
#include "basop_proto_func.h"
-#include "control.h"
#include "basop_util.h"
#define WMC_TOOL_SKIP
diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c
index 09ccc44ae6b3866ce969499625683790b2046d07..0a168852b0a95b8cbc243a9563d19e9bf06a9907 100644
--- a/lib_com/basop_util.c
+++ b/lib_com/basop_util.c
@@ -44,7 +44,7 @@
#include "rom_com.h"
#include "basop_settings.h"
#include "basop_mpy.h"
-#include "control.h"
+#include "stl.h"
#include "cnst.h"
#define WMC_TOOL_SKIP
diff --git a/lib_com/control.h b/lib_com/control.h
deleted file mode 100644
index 725163728dc88ec26e8cee3d1f0b2c7c28e5721e..0000000000000000000000000000000000000000
--- a/lib_com/control.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/******************************************************************************************************
-
- (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository. All Rights Reserved.
-
- This software is protected by copyright law and by international treaties.
- The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository retain full ownership rights in their respective contributions in
- the software. This notice grants no license of any kind, including but not limited to patent
- license, nor is any license granted by implication, estoppel or otherwise.
-
- Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
- contributions.
-
- This software is provided "AS IS", without any express or implied warranties. The software is in the
- development stage. It is intended exclusively for experts who have experience with such software and
- solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
- and fitness for a particular purpose are hereby disclaimed and excluded.
-
- Any dispute, controversy or claim arising under or in relation to providing this software shall be
- submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
- accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
- the United Nations Convention on Contracts on the International Sales of Goods.
-
-*******************************************************************************************************/
-
-/*====================================================================================
- EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
- ====================================================================================*/
-
-#ifndef _CONTROL_H
-#define _CONTROL_H
-
-/* BASOP -> FLC brigde: flow control instructions */
-
-#include "stl.h"
-
-#define FOR( a ) \
- if ( incrFor(), 0 ) \
- ; \
- else \
- for ( a )
-static __inline void incrFor( void )
-{
-}
-
-#define WHILE( a ) \
- if ( incrFlcWhile(), 0 ) \
- ; \
- else \
- while ( a )
-static __inline void incrFlcWhile( void )
-{
-}
-
-#define DO do
-
-#define IF( a ) if ( incrIf(), a )
-static __inline void incrIf( void )
-{
-}
-
-#define ELSE else
-
-#define SWITCH( a ) switch ( incrSwitch(), a )
-static __inline void incrSwitch( void )
-{
-}
-
-#define CONTINUE continue
-
-#define BREAK break
-
-#define GOTO goto
-
-#endif /* _CONTROL_H */
diff --git a/lib_com/enh1632.c b/lib_com/enh1632.c
index 1dd192faaa7d9c2d0190c781c3a18af3cdda27db..4e53ba695ef8685f163abaa25869a35cfb4edc5c 100644
--- a/lib_com/enh1632.c
+++ b/lib_com/enh1632.c
@@ -145,6 +145,9 @@ Word16 lshl( Word16 var1, Word16 var2 )
{
var2 = -var2;
var_out = lshr( var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].lshr--;
+#endif
}
else
{
@@ -162,6 +165,10 @@ Word16 lshl( Word16 var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].lshl++;
+#endif
+
BASOP_CHECK();
@@ -208,6 +215,9 @@ Word16 lshr( Word16 var1, Word16 var2 )
{
var2 = -var2;
var_out = lshl( var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].lshl--;
+#endif
}
else
{
@@ -227,6 +237,10 @@ Word16 lshr( Word16 var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].lshr++;
+#endif
+
BASOP_CHECK();
@@ -274,6 +288,9 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 )
{
var2 = -var2;
L_var_out = L_lshr( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_lshr--;
+#endif
}
else
{
@@ -291,8 +308,11 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 )
}
}
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L_lshl++;
+#endif
+ BASOP_CHECK();
return ( L_var_out );
}
@@ -338,6 +358,9 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 )
{
var2 = -var2;
L_var_out = L_lshl( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_lshl--;
+#endif
}
else
{
@@ -357,6 +380,10 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_lshr++;
+#endif
+
BASOP_CHECK();
@@ -400,13 +427,22 @@ Word16 shl_r( Word16 var1, Word16 var2 )
if ( var2 >= 0 )
{
var_out = shl( var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].shl--;
+#endif
}
else
{
var2 = -var2;
var_out = shr_r( var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].shr_r--;
+#endif
}
+#ifdef WMOPS
+ multiCounter[currCounter].shl_r++;
+#endif
return ( var_out );
}
@@ -448,13 +484,22 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2 )
if ( var2 >= 0 )
{
var_out = L_shl( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl--;
+#endif
}
else
{
var2 = -var2;
var_out = L_shr_r( L_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_shr_r--;
+#endif
}
+#ifdef WMOPS
+ multiCounter[currCounter].L_shl_r++;
+#endif
return ( var_out );
}
@@ -497,6 +542,13 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 )
*var3 = s_and( var1, 0x1 );
var_out = s_or( lshr( var1, 1 ), lshl( var2, 15 ) );
+#ifdef WMOPS
+ multiCounter[currCounter].s_and--;
+ multiCounter[currCounter].lshl--;
+ multiCounter[currCounter].lshr--;
+ multiCounter[currCounter].s_or--;
+ multiCounter[currCounter].rotr++;
+#endif
return ( var_out );
}
@@ -540,6 +592,13 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 )
var_out = s_or( lshl( var1, 1 ), s_and( var2, 0x1 ) );
+#ifdef WMOPS
+ multiCounter[currCounter].lshr--;
+ multiCounter[currCounter].s_and--;
+ multiCounter[currCounter].lshl--;
+ multiCounter[currCounter].s_or--;
+ multiCounter[currCounter].rotl++;
+#endif
return ( var_out );
}
@@ -583,6 +642,15 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 )
L_var_out = L_or( L_lshr( L_var1, 1 ), L_lshl( L_deposit_l( var2 ), 31 ) );
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+ multiCounter[currCounter].s_and--;
+ multiCounter[currCounter].L_deposit_l--;
+ multiCounter[currCounter].L_lshl--;
+ multiCounter[currCounter].L_lshr--;
+ multiCounter[currCounter].L_or--;
+ multiCounter[currCounter].L_rotr++;
+#endif
return ( L_var_out );
}
@@ -626,6 +694,15 @@ Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3 )
L_var_out = L_or( L_lshl( L_var1, 1 ), L_deposit_l( s_and( var2, 0x1 ) ) );
+#ifdef WMOPS
+ multiCounter[currCounter].L_lshr--;
+ multiCounter[currCounter].extract_l--;
+ multiCounter[currCounter].s_and--;
+ multiCounter[currCounter].L_deposit_l--;
+ multiCounter[currCounter].L_lshl--;
+ multiCounter[currCounter].L_or--;
+ multiCounter[currCounter].L_rotl++;
+#endif
return ( L_var_out );
}
diff --git a/lib_com/enh1632.h b/lib_com/enh1632.h
index 9216ea6c201a3b63690723318b65ea19367445c2..8e943d42f07c872a607517aa3b202a4985486831 100644
--- a/lib_com/enh1632.h
+++ b/lib_com/enh1632.h
@@ -131,6 +131,9 @@ static __inline Word16 s_max( Word16 var1, Word16 var2 )
else
var_out = var2;
+#ifdef WMOPS
+ multiCounter[currCounter].s_max++;
+#endif
return ( var_out );
}
@@ -173,6 +176,9 @@ static __inline Word16 s_min( Word16 var1, Word16 var2 )
else
var_out = var2;
+#ifdef WMOPS
+ multiCounter[currCounter].s_min++;
+#endif
return ( var_out );
}
@@ -215,6 +221,9 @@ static __inline Word32 L_max( Word32 L_var1, Word32 L_var2 )
else
L_var_out = L_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L_max++;
+#endif
return ( L_var_out );
}
@@ -257,6 +266,9 @@ static __inline Word32 L_min( Word32 L_var1, Word32 L_var2 )
else
L_var_out = L_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L_min++;
+#endif
return ( L_var_out );
}
@@ -297,6 +309,9 @@ static __inline Word16 s_and( Word16 var1, Word16 var2 )
var_out = var1 & var2;
+#ifdef WMOPS
+ multiCounter[currCounter].s_and++;
+#endif
return ( var_out );
}
@@ -337,6 +352,9 @@ static __inline Word32 L_and( Word32 L_var1, Word32 L_var2 )
L_var_out = L_var1 & L_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L_and++;
+#endif
return ( L_var_out );
}
@@ -377,6 +395,9 @@ static __inline Word16 s_or( Word16 var1, Word16 var2 )
var_out = var1 | var2;
+#ifdef WMOPS
+ multiCounter[currCounter].s_or++;
+#endif
return ( var_out );
}
@@ -418,6 +439,9 @@ static __inline Word32 L_or( Word32 L_var1, Word32 L_var2 )
L_var_out = L_var1 | L_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L_or++;
+#endif
return ( L_var_out );
}
@@ -458,6 +482,9 @@ static __inline Word16 s_xor( Word16 var1, Word16 var2 )
var_out = var1 ^ var2;
+#ifdef WMOPS
+ multiCounter[currCounter].s_xor++;
+#endif
return ( var_out );
}
@@ -498,6 +525,9 @@ static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2 )
L_var_out = L_var1 ^ L_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L_xor++;
+#endif
return ( L_var_out );
}
diff --git a/lib_com/enh40.c b/lib_com/enh40.c
index 8a48cece39bed8b7e709fedb9bd8c9b40c5354a0..d77e23b23c679532cd66bdafde845f4b9f258f5b 100644
--- a/lib_com/enh40.c
+++ b/lib_com/enh40.c
@@ -225,8 +225,11 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow )
}
}
- BASOP_CHECK();
+#ifdef WMOPS
+ multiCounter[currCounter].L40_shl++;
+#endif
+ BASOP_CHECK();
return ( L40_var_out );
}
@@ -281,6 +284,10 @@ Word40 L40_shl( Word40 L40_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L40_shl++;
+#endif
+
BASOP_CHECK();
@@ -336,6 +343,9 @@ Word40 L40_shr( Word40 L40_var1, Word16 var2 )
L40_var_out = L40_var1 >> var2;
}
+#ifdef WMOPS
+ multiCounter[currCounter].L40_shr++;
+#endif
return ( L40_var_out );
}
@@ -374,6 +384,10 @@ Word40 L40_negate( Word40 L40_var1 )
L40_var_out = L40_add( ~L40_var1, 0x01 );
+#ifdef WMOPS
+ multiCounter[currCounter].L40_negate++;
+#endif
+
return ( L40_var_out );
}
@@ -440,6 +454,11 @@ Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
}
#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_add++;
+#endif
+
+
BASOP_CHECK();
@@ -501,6 +520,10 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 )
}
#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_add++;
+#endif
+
BASOP_CHECK();
@@ -596,6 +619,10 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
}
#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_sub++;
+#endif
+
BASOP_CHECK();
@@ -633,6 +660,10 @@ Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 )
}
#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_sub++;
+#endif
+
BASOP_CHECK();
@@ -680,6 +711,9 @@ Word40 L40_abs( Word40 L40_var1 )
L40_var_out = L40_var1;
}
+#ifdef WMOPS
+ multiCounter[currCounter].L40_abs++;
+#endif
return ( L40_var_out );
}
@@ -723,6 +757,9 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 )
else
L40_var_out = L40_var1;
+#ifdef WMOPS
+ multiCounter[currCounter].L40_max++;
+#endif
return ( L40_var_out );
}
@@ -766,6 +803,9 @@ Word40 L40_min( Word40 L40_var1, Word40 L40_var2 )
else
L40_var_out = L40_var2;
+#ifdef WMOPS
+ multiCounter[currCounter].L40_min++;
+#endif
return ( L40_var_out );
}
@@ -832,6 +872,10 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow )
L_var_out = L_Extract40( L40_var1 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_saturate40++;
+#endif
+
BASOP_CHECK();
@@ -860,6 +904,10 @@ Word32 L_saturate40( Word40 L40_var1 )
L_var_out = L_Extract40( L40_var1 );
+#ifdef WMOPS
+ multiCounter[currCounter].L_saturate40++;
+#endif
+
BASOP_CHECK();
@@ -928,8 +976,20 @@ void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varo
L40_var1 = L40_mac( L40_var1, var2, var1_h );
*L_varout_h = L_Extract40( L40_var1 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].Extract40_L--;
+ multiCounter[currCounter].L40_shr--;
+ multiCounter[currCounter].L40_mac--;
+ multiCounter[currCounter].L_Extract40--;
+#endif
}
+#ifdef WMOPS
+ multiCounter[currCounter].Mpy_32_16_ss++;
+#endif
return;
}
@@ -1004,8 +1064,20 @@ void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_
L40_var1 = L40_mac( L40_var1, var1_h, var2_h );
*L_varout_h = L_Extract40( L40_var1 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].extract_l -= 2;
+ multiCounter[currCounter].extract_h -= 2;
+ multiCounter[currCounter].L_Extract40 -= 3;
+ multiCounter[currCounter].L40_shr -= 2;
+ multiCounter[currCounter].L40_add -= 2;
+ multiCounter[currCounter].L40_mac--;
+#endif
}
+#ifdef WMOPS
+ multiCounter[currCounter].Mpy_32_32_ss++;
+#endif
return;
}
@@ -1039,7 +1111,7 @@ void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_
*
* Return Value :
*
- * L40_var_out 40 bit long signed integer (Word40) whose value falls in
+ * L_var_out 32 bit long unsigned integer (UWord32) whose value falls in
* the range : MIN_40 <= L40_var_out <= MAX_40.
*
*****************************************************************************/
@@ -1051,6 +1123,9 @@ Word40 L40_lshl( Word40 L40_var1, Word16 var2 )
{
var2 = -var2;
L40_var_out = L40_lshr( L40_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L40_lshr--;
+#endif
}
else
{
@@ -1063,6 +1138,10 @@ Word40 L40_lshl( Word40 L40_var1, Word16 var2 )
L40_var_out = L40_set( L40_var_out );
}
+#ifdef WMOPS
+ multiCounter[currCounter].L40_lshl++;
+#endif
+
BASOP_CHECK();
@@ -1110,6 +1189,9 @@ Word40 L40_lshr( Word40 L40_var1, Word16 var2 )
{
var2 = -var2;
L40_var_out = L40_lshl( L40_var1, var2 );
+#ifdef WMOPS
+ multiCounter[currCounter].L40_lshl--;
+#endif
}
else
{
@@ -1125,6 +1207,10 @@ Word40 L40_lshr( Word40 L40_var1, Word16 var2 )
}
}
+#ifdef WMOPS
+ multiCounter[currCounter].L40_lshr++;
+#endif
+
BASOP_CHECK();
diff --git a/lib_com/enh40.h b/lib_com/enh40.h
index a55bd925e9da5ca2408aa43f18f787a3ae32be64..8c34ec36ac7a3a76f120cbbcb9a453bf250be752 100644
--- a/lib_com/enh40.h
+++ b/lib_com/enh40.h
@@ -54,7 +54,6 @@
#ifndef _ENH40_H
#define _ENH40_H
-
#include "stl.h"
#if defined( BASOP_NOGLOB ) || defined( _MSC_VER )
@@ -62,11 +61,9 @@
#define MIN_40 ( 0xffffff8000000000 )
#endif
-
#define L40_OVERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 1 ), L40_var1 )
#define L40_UNDERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 2 ), L40_var1 )
-
/*****************************************************************************
*
* Prototypes for enhanced 40 bit arithmetic operators
@@ -114,7 +111,6 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 );
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
@@ -124,7 +120,6 @@ 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 */
-
/*#ifdef _MSC_VER*/
static __inline Word40 L40_set( Word40 L40_var1 )
{
@@ -142,6 +137,9 @@ static __inline Word40 L40_set( Word40 L40_var1 )
L40_var_out = L40_var_out | 0xffffff0000000000LL;
#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set++;
+#endif
return ( L40_var_out );
}
@@ -154,6 +152,9 @@ static __inline UWord16 Extract40_H( Word40 L40_var1 )
var_out = (UWord16) ( L40_var1 >> 16 );
+#ifdef WMOPS
+ multiCounter[currCounter].Extract40_H++;
+#endif
return ( var_out );
}
@@ -165,6 +166,9 @@ static __inline UWord16 Extract40_L( Word40 L40_var1 )
var_out = (UWord16) ( L40_var1 );
+#ifdef WMOPS
+ multiCounter[currCounter].Extract40_L++;
+#endif
return ( var_out );
}
@@ -176,6 +180,9 @@ static __inline UWord32 L_Extract40( Word40 L40_var1 )
L_var_out = (UWord32) L40_var1;
+#ifdef WMOPS
+ multiCounter[currCounter].L_Extract40++;
+#endif
return ( L_var_out );
}
@@ -191,13 +198,25 @@ static __inline Word40 L40_deposit_h( Word16 var1 )
if ( var1 & 0x8000 )
{
L40_var_out = L40_set( L40_var_out | 0xff00000000 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
+#endif
+ }
#else
if ( var1 & 0x8000 )
{
L40_var_out = L40_set( L40_var_out | 0xff00000000LL );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
#endif
}
+#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_deposit_h++;
+#endif
return ( L40_var_out );
}
@@ -213,13 +232,25 @@ static __inline Word40 L40_deposit_l( Word16 var1 )
if ( var1 & 0x8000 )
{
L40_var_out = L40_set( L40_var_out | 0xffffff0000 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
+#endif
+ }
#else
if ( var1 & 0x8000 )
{
L40_var_out = L40_set( L40_var_out | 0xffffff0000LL );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
#endif
}
+#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_deposit_l++;
+#endif
return ( L40_var_out );
}
@@ -235,13 +266,25 @@ static __inline Word40 L40_deposit32( Word32 L_var1 )
if ( L_var1 & 0x80000000 )
{
L40_var_out = L40_set( L40_var_out | 0xff00000000 );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
+#endif
+ }
#else
if ( L_var1 & 0x80000000 )
{
L40_var_out = L40_set( L40_var_out | 0xff00000000LL );
+
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
#endif
}
+#endif
+#ifdef WMOPS
+ multiCounter[currCounter].L40_deposit32++;
+#endif
return ( L40_var_out );
}
@@ -261,6 +304,11 @@ static __inline Word40 L40_round( Word40 L40_var1 )
L40_var_out = L40_add( 0x8000, L40_var1 );
L40_var_out = L40_var_out & L40_constant;
+#ifdef WMOPS
+ multiCounter[currCounter].L40_set--;
+ multiCounter[currCounter].L40_add--;
+ multiCounter[currCounter].L40_round++;
+#endif
return ( L40_var_out );
}
@@ -272,6 +320,12 @@ static __inline Word16 round40( Word40 L40_var1 )
var_out = extract_h( L_saturate40( L40_round( L40_var1 ) ) );
+#ifdef WMOPS
+ multiCounter[currCounter].L40_round--;
+ multiCounter[currCounter].L_saturate40--;
+ multiCounter[currCounter].extract_h--;
+ multiCounter[currCounter].round40++;
+#endif
return ( var_out );
}
@@ -288,6 +342,9 @@ static __inline Word40 L40_mult( Word16 var1, Word16 var2 )
/* Below line can not overflow, so we can use << instead of L40_shl. */
L40_var_out = L40_var_out << 1;
+#ifdef WMOPS
+ multiCounter[currCounter].L40_mult++;
+#endif
return ( L40_var_out );
}
@@ -300,6 +357,9 @@ static __inline Word40 L40_mac( Word40 L40_var1, Word16 var2, Word16 var3 )
L40_var_out = L40_mult( var2, var3 );
L40_var_out = L40_add( L40_var1, L40_var_out );
+#ifdef WMOPS
+ multiCounter[currCounter].L40_mac++;
+#endif
return ( L40_var_out );
}
diff --git a/lib_com/move.h b/lib_com/move.h
index c7bee82cd41d3669da2a06759116db869ce61c29..becc9314d2c42a205771aa236b0d6d3536b17ac8 100644
--- a/lib_com/move.h
+++ b/lib_com/move.h
@@ -39,29 +39,41 @@
/* BASOP -> FLC brigde: data move counting */
-#include "stl.h"
-
static __inline void move16( void )
{
+#ifdef WMOPS
+ multiCounter[currCounter].move16++;
+#endif
}
static __inline void move32( void )
{
+#ifdef WMOPS
+ multiCounter[currCounter].move32++;
+#endif
}
static __inline void test( void )
{
+#ifdef WMOPS
+ multiCounter[currCounter].Test++;
+#endif
}
static __inline void logic16( void )
{
+#ifdef WMOPS
+ multiCounter[currCounter].Logic16++;
+#endif
}
static __inline void logic32( void )
{
+#ifdef WMOPS
+ multiCounter[currCounter].Logic32++;
+#endif
}
-
/*-------- legacy ----------*/
#define data_move() move16()
#define L_data_move() move32()
diff --git a/lib_com/stl.h b/lib_com/stl.h
index c9ca42280642ae4ba91cc65258d8a567b04a195c..be5722630e76b3c12ba828d6ec9b149c7e4702e7 100644
--- a/lib_com/stl.h
+++ b/lib_com/stl.h
@@ -60,8 +60,8 @@
#include "options.h" /* note: needed until BASOP_NOGLOB is accepted */
#include "typedef.h"
#include "basop32.h"
+#include "wmc_auto.h"
#include "move.h"
-#include "control.h"
#include "enh1632.h"
#include "enh40.h"
diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c
index 029640a1dba8bce33cafd82907ef5bb5e5d5dabe..6ee30fd269f1f90fd2437c941c2b2d01b8964e8c 100644
--- a/lib_debug/wmc_auto.c
+++ b/lib_debug/wmc_auto.c
@@ -28,7 +28,6 @@
#include "options.h"
#include "wmc_auto.h"
-
#define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */
#ifdef WMOPS
@@ -37,23 +36,26 @@
* Complexity counting tool
*--------------------------------------------------------------------*/
-#define MAX_RECORDS 1024
-#define MAX_CHAR 64
-#define MAX_STACK 64
-#define DOUBLE_MAX 0x80000000
+#define MAX_FUNCTION_NAME_LENGTH 50 /* Maximum length of the function name */
+#define MAX_PARAMS_LENGTH 50 /* Maximum length of the function parameter string */
+#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> mightb be increased during runtime, if needed */
+#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */
+#define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */
+#define DOUBLE_MAX 0x80000000
-struct wmops_record
+typedef struct
{
- char label[MAX_CHAR];
+ char label[MAX_FUNCTION_NAME_LENGTH];
long call_number;
long update_cnt;
- int call_tree[MAX_RECORDS];
+ int call_tree[MAX_CALL_TREE_DEPTH];
+ long LastWOper;
double start_selfcnt;
double current_selfcnt;
double max_selfcnt;
double min_selfcnt;
double tot_selfcnt;
- double start_cnt; /* The following take into account the decendants */
+ double start_cnt;
double current_cnt;
double max_cnt;
double min_cnt;
@@ -64,16 +66,14 @@ struct wmops_record
double wc_selfcnt;
int32_t wc_call_number;
#endif
-};
+} wmops_record;
double ops_cnt;
double prom_cnt;
double inst_cnt[NUM_INST];
-static struct wmops_record wmops[MAX_RECORDS];
-static int stack[MAX_STACK];
-static int sptr;
-static int num_records;
+static wmops_record *wmops = NULL;
+static int num_wmops_records, max_num_wmops_records;
static int current_record;
static long update_cnt;
static double start_cnt;
@@ -81,20 +81,56 @@ static double max_cnt;
static double min_cnt;
static double inst_cnt_wc[NUM_INST];
static long fnum_cnt_wc;
-
+static int *wmops_caller_stack = NULL, wmops_caller_stack_index, max_wmops_caller_stack_index = 0;
static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0;
-
void reset_wmops( void )
{
int i, j;
+ unsigned int *ptr;
+
+ num_wmops_records = 0;
+ max_num_wmops_records = MAX_NUM_RECORDS;
+ current_record = -1;
+ update_cnt = 0;
+
+ max_cnt = 0.0;
+ min_cnt = DOUBLE_MAX;
+ start_cnt = 0.0;
+ ops_cnt = 0.0;
+
+ /* allocate the list of wmops records */
+ if ( wmops == NULL )
+ {
+ wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) );
+ }
+
+ if ( wmops == NULL )
+ {
+ fprintf( stderr, "Error: Unable to Allocate List of WMOPS Records!" );
+ exit( -1 );
+ }
+
+ /* allocate the BASOP WMOPS counter */
+ if ( multiCounter == NULL )
+ {
+ multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) );
+ }
+
+ if ( multiCounter == NULL )
+ {
+ fprintf( stderr, "Error: Unable to Allocate the BASOP WMOPS counter!" );
+ exit( -1 );
+ }
- for ( i = 0; i < MAX_RECORDS; i++ )
+ /* initilize the list of wmops records */
+ /* initilize the BASOP WMOPS counters */
+ for ( i = 0; i < max_num_wmops_records; i++ )
{
strcpy( &wmops[i].label[0], "\0" );
wmops[i].call_number = 0;
wmops[i].update_cnt = 0;
- for ( j = 0; j < MAX_RECORDS; j++ )
+ for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ )
{
wmops[i].call_tree[j] = -1;
}
@@ -112,22 +148,42 @@ void reset_wmops( void )
wmops[i].wc_cnt = 0.0;
wmops[i].wc_selfcnt = 0.0;
wmops[i].current_call_number = 0;
+ wmops[i].wc_call_number = -1;
#endif
+
+ /* clear all BASOP operation counters */
+ ptr = (unsigned int*) &multiCounter[i];
+ for ( j = 0; j < (int) ( sizeof(BASIC_OP ) / sizeof( unsigned int ) ); j++ )
+ {
+ *ptr++ = 0;
+ }
+ wmops[i].LastWOper = 0;
}
- for ( i = 0; i < MAX_STACK; i++ )
+ /* allocate the list of wmops callers to track the sequence of function calls */
+ wmops_caller_stack_index = 0;
+ max_wmops_caller_stack_index = MAX_NUM_RECORDS;
+ if ( wmops_caller_stack == NULL )
{
- stack[i] = -1;
+ wmops_caller_stack = malloc( max_wmops_caller_stack_index * sizeof( int ) );
}
- sptr = 0;
- num_records = 0;
- current_record = -1;
- update_cnt = 0;
- max_cnt = 0.0;
- min_cnt = DOUBLE_MAX;
- start_cnt = 0.0;
- ops_cnt = 0.0;
+ if ( wmops_caller_stack == NULL )
+ {
+ fprintf( stderr, "Error: Unable to Allocate List of WMOPS Callers!" );
+ exit( -1 );
+ }
+
+ for ( i = 0; i < max_wmops_caller_stack_index; i++ )
+ {
+ wmops_caller_stack[i] = -1;
+ }
+
+ /* initialize auxiliary BASOP WMOPS variables */
+ call_occurred = 1;
+ funcId_where_last_call_to_else_occurred = INT_MAX;
+
+ return;
}
@@ -136,9 +192,9 @@ void push_wmops( const char *label )
int new_flag;
int i, j;
- /* Check if new function record label */
+ /* Check, if this is a new function label */
new_flag = 1;
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
if ( strcmp( wmops[i].label, label ) == 0 )
{
@@ -147,33 +203,38 @@ void push_wmops( const char *label )
}
}
- /* Configure new record */
+ /* Create a new record in the list */
if ( new_flag )
{
- if ( num_records >= MAX_RECORDS )
+ if ( num_wmops_records >= max_num_wmops_records )
{
- fprintf( stdout, "push_wmops(): exceeded MAX_RECORDS count.\n\n" );
- exit( -1 );
+ /* There is no room for a new wmops record -> reallocate the list */
+ max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP;
+ wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) );
+ multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) );
}
+
strcpy( wmops[i].label, label );
- num_records++;
+
+ num_wmops_records++;
}
- /* Push current context onto stack */
+ /* Push the current context info to the new record */
if ( current_record >= 0 )
{
- if ( sptr >= MAX_STACK )
+ if ( wmops_caller_stack_index >= max_wmops_caller_stack_index )
{
- fprintf( stdout, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n" );
- exit( -1 );
+ /* There is no room for a new record -> reallocate the list */
+ max_wmops_caller_stack_index += MAX_NUM_RECORDS_REALLOC_STEP;
+ wmops_caller_stack = realloc( wmops_caller_stack, max_wmops_caller_stack_index * sizeof( int ) );
}
- stack[sptr++] = current_record;
+ wmops_caller_stack[wmops_caller_stack_index++] = current_record;
/* accumulate op counts */
wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt;
/* update call tree */
- for ( j = 0; j < MAX_RECORDS; j++ )
+ for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ )
{
if ( wmops[i].call_tree[j] == current_record )
{
@@ -187,7 +248,7 @@ void push_wmops( const char *label )
}
}
- /* init current record */
+ /* update the current context info */
current_record = i;
wmops[current_record].start_selfcnt = ops_cnt;
wmops[current_record].start_cnt = ops_cnt;
@@ -196,12 +257,16 @@ void push_wmops( const char *label )
wmops[current_record].current_call_number++;
#endif
+ /* set the ID of BASOP functions counters */
+ Set_BASOP_WMOPS_counter( current_record );
+
return;
}
void pop_wmops( void )
{
+ long tot;
/* Check for underflow */
if ( current_record < 0 )
@@ -210,21 +275,29 @@ void pop_wmops( void )
exit( -1 );
}
- /* update count of current record */
+ /* add the BASOP complexity to the counter */
+ tot = DeltaWeightedOperation();
+ ops_cnt += tot;
+
+ /* update count of current record */
wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt;
wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt;
/* Get back previous context from stack */
- if ( sptr > 0 )
+ if ( wmops_caller_stack_index > 0 )
{
- current_record = stack[--sptr];
+ current_record = wmops_caller_stack[--wmops_caller_stack_index];
wmops[current_record].start_selfcnt = ops_cnt;
+
+ /* set the ID of the previous BASOP counter */
+ Set_BASOP_WMOPS_counter( current_record );
}
else
{
current_record = -1;
}
+
return;
}
@@ -239,9 +312,9 @@ void update_wmops( void )
float tmpF;
#endif
- if ( sptr != 0 )
+ if ( wmops_caller_stack_index != 0 )
{
- fprintf( stdout, "update_wmops(): Stack must be empty!\n" );
+ fprintf( stdout, "update_wmops(): WMOPS caller stack corrupted - check that all push_wmops() are matched with pop_wmops()!\n" );
exit( -1 );
}
@@ -266,7 +339,7 @@ void update_wmops( void )
#ifdef WMOPS_WC_FRAME_ANALYSIS
if ( ops_cnt - start_cnt > max_cnt )
{
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
wmops[i].wc_cnt = wmops[i].current_cnt;
wmops[i].wc_selfcnt = wmops[i].current_selfcnt;
@@ -275,7 +348,7 @@ void update_wmops( void )
}
#endif
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
wmops[i].tot_selfcnt += wmops[i].current_selfcnt;
wmops[i].tot_cnt += wmops[i].current_cnt;
@@ -302,6 +375,7 @@ void update_wmops( void )
wmops[i].max_cnt = wmops[i].current_cnt;
}
+
if ( wmops[i].current_cnt < wmops[i].min_cnt )
{
wmops[i].min_cnt = wmops[i].current_cnt;
@@ -314,6 +388,10 @@ void update_wmops( void )
#ifdef WMOPS_WC_FRAME_ANALYSIS
wmops[i].current_call_number = 0;
#endif
+
+ /* update the WC of all BASOP counters */
+ Set_BASOP_WMOPS_counter( i );
+ Reset_BASOP_WMOPS_counter();
}
current_cnt = ops_cnt - start_cnt;
@@ -350,28 +428,40 @@ void update_wmops( void )
void print_wmops( void )
{
- int i;
+ int i, label_len, max_label_len;
- char *sfmts = "%20s %8s %8s %7s %7s\n";
- char *dfmts = "%20s %8.2f %8.3f %7.3f %7.3f\n";
- char *sfmt = "%20s %8s %8s %7s %7s %7s %7s %7s\n";
- char *dfmt = "%20s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n";
+ char *sfmts = "%*s %8s %8s %7s %7s\n";
+ char *dfmts = "%*s %8.2f %8.3f %7.3f %7.3f\n";
+ char *sfmt = "%*s %8s %8s %7s %7s %7s %7s %7s\n";
+ char *dfmt = "%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n";
#ifdef WMOPS_WC_FRAME_ANALYSIS
- int j, label_len, max_label_len;
+ int j;
char *sfmtt = "%20s %4s %15s\n";
char *dfmtt = "%20s %4d ";
#endif
- fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" );
+ /* calculate maximum label length for compact prinout */
+ max_label_len = 0;
+ for ( i = 0; i < num_wmops_records; i++ )
+ {
+ label_len = strlen( wmops[i].label );
+ if ( label_len > max_label_len )
+ {
+ max_label_len = label_len;
+ }
+ }
+ max_label_len += 4;
- fprintf( stdout, "%54s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" );
- fprintf( stdout, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " );
- fprintf( stdout, sfmt, "---------------", "------", "------", "------", "------", "------", "------", "------" );
+ fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" );
+
+ fprintf( stdout, "%*s %33s %23s\n", max_label_len, "", "|------ SELF ------|", "|--- CUMULATIVE ---|" );
+ fprintf( stdout, sfmt, max_label_len, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " );
+ fprintf( stdout, sfmt, max_label_len, "---------------", "------", "------", "------", "------", "------", "------", "------" );
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
- fprintf( stdout, dfmt, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt,
+ fprintf( stdout, dfmt, max_label_len, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt,
wmops[i].min_selfcnt == DOUBLE_MAX ? 0 : FAC * wmops[i].min_selfcnt,
FAC * wmops[i].max_selfcnt,
wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_selfcnt / wmops[i].update_cnt,
@@ -380,54 +470,47 @@ void print_wmops( void )
wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_cnt / wmops[i].update_cnt );
}
- fprintf( stdout, sfmts, "---------------", "------", "------", "------", "------" );
- fprintf( stdout, dfmts, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt );
+ fprintf( stdout, sfmts, max_label_len, "---------------", "------", "------", "------", "------" );
+ fprintf( stdout, dfmts, max_label_len, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt );
fprintf( stdout, "\n" );
#ifdef WMOPS_WC_FRAME_ANALYSIS
- /* calculate maximum label length for compact prinout */
- max_label_len = 0;
- for ( i = 0; i < num_records; i++ )
- {
- label_len = strlen( wmops[i].label );
- if ( label_len > max_label_len )
- {
- max_label_len = label_len;
- }
- }
- max_label_len += 4;
-
- fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n", fnum_cnt_wc );
- fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" );
+ fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc );
+ fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" );
fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" );
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
- fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt );
+ if ( wmops[i].wc_call_number > 0 )
+ {
+ fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt );
+ }
}
- fprintf( stdout, "\nCall Tree:\n\n" );
- fprintf( stdout, sfmtt, " function", "num", "called by: " );
+ fprintf( stdout, "\nCall tree for the worst-case frame %ld:\n\n", fnum_cnt_wc );
+ fprintf( stdout, sfmtt, " function", "num", "called by " );
fprintf( stdout, sfmtt, "---------------", "---", "--------------" );
- for ( i = 0; i < num_records; i++ )
+ for ( i = 0; i < num_wmops_records; i++ )
{
- fprintf( stdout, dfmtt, wmops[i].label, i );
- for ( j = 0; wmops[i].call_tree[j] != -1; j++ )
+ if ( wmops[i].wc_call_number > 0 )
{
- if ( j != 0 )
+ fprintf( stdout, dfmtt, wmops[i].label, i );
+ for ( j = 0; wmops[i].call_tree[j] != -1 && j < MAX_CALL_TREE_DEPTH; j++ )
{
- fprintf( stdout, ", " );
+ if ( j != 0 )
+ {
+ fprintf( stdout, ", " );
+ }
+ fprintf( stdout, "%d", wmops[i].call_tree[j] );
}
- fprintf( stdout, "%d", wmops[i].call_tree[j] );
+ fprintf( stdout, "\n" );
}
- fprintf( stdout, "\n" );
}
- fprintf( stdout, sfmtt, "---------------", "---", "--------------" );
fprintf( stdout, "\n\n" );
- fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); /* added -- JPA */
+ fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc );
for ( i = 0; i < NUM_INST; i++ )
{
switch ( (enum instructions) i )
@@ -498,6 +581,24 @@ void print_wmops( void )
}
#endif
+ /* De-allocate the list of wmops record */
+ if ( wmops != NULL )
+ {
+ free( wmops );
+ }
+
+ /* De-allocate the list of wmops caller functions */
+ if ( wmops_caller_stack != NULL )
+ {
+ free( wmops_caller_stack );
+ }
+
+ /* De-allocate the BASOP WMOPS counter */
+ if ( multiCounter != NULL )
+ {
+ free( multiCounter );
+ }
+
return;
}
@@ -524,12 +625,6 @@ void print_wmops( void )
* #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free().
*--------------------------------------------------------------------*/
-#define MAX_RECORDABLE_CALLS 100
-#define MAX_FUNCTION_NAME_LENGTH 35 /* Maximum length that the function string will be truncated to */
-#define MAX_PARAMS_LENGTH 50 /* Maximum length that the parameter string will be truncated to */
-#define MAX_NUM_RECORDS 300 /* Initial maximum number of memory records -> mightb be increased during runtime, if needed */
-#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of memory records, increase the number of records by this number */
-
/* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using
a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */
#ifdef MEM_ALIGN_64BITS
@@ -539,15 +634,13 @@ void print_wmops( void )
#endif
#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) )
+#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) )
#define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */
#define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */
#define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */
#define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */
-#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) )
-#define IS_CALLOC( str ) ( str[0] == 'c' )
-
#ifdef MEM_COUNT_DETAILS
const char *csv_filename = "mem_analysis.csv";
static FILE *fid_csv_filename = NULL;
@@ -559,8 +652,16 @@ typedef struct
int16_t *stack_ptr;
} caller_info;
-caller_info stack_callers[2][MAX_RECORDABLE_CALLS];
+static caller_info *stack_callers[2] = {NULL, NULL};
+
+static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */
+static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */
+static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */
+static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */
+static int current_calls = 0, max_num_calls = MAX_NUM_RECORDS;
+static char location_max_stack[256] = "undefined";
+/* Heap-related variables */
typedef struct
{
char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */
@@ -580,18 +681,12 @@ typedef struct
allocator_record *allocation_list = NULL;
-static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */
-static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */
-static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */
-static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */
-static int32_t wc_ram_size, wc_ram_frame;
-static int32_t current_heap_size;
-static int current_calls = 0;
-static char location_max_stack[256] = "undefined";
static int Num_Records, Max_Num_Records;
static size_t Stat_Cnt_Size = USE_BYTES;
static const char *Count_Unit[] = { "bytes", "words", "words" };
+static int32_t wc_ram_size, wc_ram_frame;
+static int32_t current_heap_size;
static int *list_wc_intra_frame_heap, n_items_wc_intra_frame_heap, max_items_wc_intra_frame_heap, size_wc_intra_frame_heap, location_wc_intra_frame_heap;
static int *list_current_inter_frame_heap, n_items_current_inter_frame_heap, max_items_current_inter_frame_heap, size_current_inter_frame_heap;
static int *list_wc_inter_frame_heap, n_items_wc_inter_frame_heap, max_items_wc_inter_frame_heap, size_wc_inter_frame_heap, location_wc_inter_frame_heap;
@@ -612,11 +707,28 @@ void reset_mem( Counting_Size cnt_size )
int16_t something;
size_t tmp_size;
+ /* initialize list of stack records */
+ if ( stack_callers[0] == NULL )
+ {
+ stack_callers[0] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) );
+ stack_callers[1] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) );
+ }
+
+ if ( stack_callers[0] == NULL || stack_callers[1] == NULL )
+ {
+ fprintf( stderr, "Error: Unable to Allocate List of Stack Records!" );
+ exit( -1 );
+ }
+
+ current_calls = 0;
+ max_num_calls = MAX_NUM_RECORDS;
+
/* initialize stack pointers */
ptr_base_stack = &something;
ptr_max_stack = ptr_base_stack;
ptr_current_stack = ptr_base_stack;
+ /* initialize the unit of memory block size */
Stat_Cnt_Size = cnt_size;
/* Check, if sizeof(int32_t) is 4 bytes */
@@ -742,11 +854,12 @@ int push_stack( const char *filename, const char *fctname )
(void) *filename; /* to avoid compilation warning */
- /* Is there room to save the caller's information? */
- if ( current_calls >= MAX_RECORDABLE_CALLS )
- { /* No */
- fprintf( stderr, "No more room to store call stack info. Please increase MAX_RECORDABLE_CALLS" );
- exit( -1 );
+ if ( current_calls >= max_num_calls )
+ {
+ /* There is no room for a new record -> reallocate the list */
+ max_num_calls += MAX_NUM_RECORDS_REALLOC_STEP;
+ stack_callers[0] = realloc( stack_callers[0], max_num_calls * sizeof( caller_info ) );
+ stack_callers[1] = realloc( stack_callers[1], max_num_calls * sizeof( caller_info ) );
}
/* Valid Function Name? */
@@ -763,7 +876,7 @@ int push_stack( const char *filename, const char *fctname )
/* Save the Stack Pointer */
stack_callers[0][current_calls].stack_ptr = ptr_current_stack;
- /* Increase Stack Calling Tree Level */
+ /* Increase the Number of Calls in the List */
current_calls++;
/* Is this the First Time or the Worst Case? */
@@ -772,15 +885,17 @@ int push_stack( const char *filename, const char *fctname )
/* Save Info about it */
ptr_max_stack = ptr_current_stack;
- wc_stack_frame = update_cnt; /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */
+ /* save the worst-case frame number */
+ /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */
+ wc_stack_frame = update_cnt;
strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 );
location_max_stack[sizeof( location_max_stack ) - 1] = '\0';
/* Save Call Tree */
memmove( stack_callers[1], stack_callers[0], sizeof( caller_info ) * current_calls );
- /* Terminate the List (Unless Full) */
- if ( current_calls < MAX_RECORDABLE_CALLS )
+ /* Terminate the List with 0 (for printing purposes) */
+ if ( current_calls < max_num_calls )
{
stack_callers[1][current_calls].function_name[0] = 0;
}
@@ -816,13 +931,13 @@ int pop_stack( const char *filename, const char *fctname )
(void) *filename; /* to avoid compilation warning */
- /* Decrease Stack Calling */
+ /* Decrease the Number of Records */
current_calls--;
/* Get Pointer to Caller Information */
caller_info_ptr = &stack_callers[0][current_calls];
- /* Check, if Names Match */
+ /* Check, if the Function Names Match */
if ( strncmp( caller_info_ptr->function_name, fctname, MAX_FUNCTION_NAME_LENGTH ) != 0 )
{
fprintf( stderr, "Invalid usage of pop_stack()" );
@@ -861,7 +976,7 @@ static void print_stack_call_tree( void )
fprintf( stdout, "\nList of functions when maximum stack size is reached:\n\n" );
caller_info_ptr = &stack_callers[1][0];
- for ( call_level = 0; call_level < MAX_RECORDABLE_CALLS; call_level++ )
+ for ( call_level = 0; call_level < max_num_calls; call_level++ )
{
/* Done? */
if ( caller_info_ptr->function_name[0] == 0 )
@@ -1060,7 +1175,7 @@ static void *mem_alloc_block( size_t size, const char *size_str )
/* Fill Memory Block with Magic Value or 0 */
fill_value = MAGIC_VALUE_USED;
- if ( IS_CALLOC( size_str ) )
+ if ( size_str[0] == 'c' )
{
fill_value = 0x00000000;
}
@@ -1887,6 +2002,17 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] )
free( allocation_list );
}
+ /* De-allocate list of stack records */
+ if ( stack_callers[0] != NULL )
+ {
+ free( stack_callers[0] );
+ }
+
+ if ( stack_callers[1] != NULL )
+ {
+ free( stack_callers[1] );
+ }
+
/* De-allocate heap allocation call tree */
if ( heap_allocation_call_tree != NULL )
{
@@ -1924,3 +2050,105 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] )
#ifndef WMOPS
int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */
#endif
+
+#ifdef WMOPS
+/* Global counter for the calculation of BASOP complexity */
+BASIC_OP *multiCounter = NULL;
+int currCounter = 0;
+int funcId_where_last_call_to_else_occurred;
+long funcid_total_wmops_at_last_call_to_else;
+int call_occurred = 1;
+
+BASIC_OP op_weight = {
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 1,
+ 1, 1, 1, 3, 1,
+
+ 1, 1, 1, 3, 1,
+ 4, 1, 18, 1, 1,
+ 2, 1, 2, 2, 1,
+ 1, 1, 1, 1, 1,
+ 3, 3, 3, 3, 1,
+
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 2,
+ 1, 2, 2, 4, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 3,
+ 3, 3, 3, 3, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 4,
+ 4, 8, 3, 4, 4,
+
+ 5, 32, 3
+};
+
+/* Set the counter group to use, default is zero */
+void Set_BASOP_WMOPS_counter( int counterId )
+{
+ if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) )
+ {
+ currCounter = 0;
+ return;
+ }
+ currCounter = counterId;
+ call_occurred = 1;
+}
+
+extern int32_t frame;
+
+long TotalWeightedOperation()
+{
+ int i;
+ unsigned int *ptr, *ptr2;
+ long tot;
+
+ tot = 0;
+ ptr = (unsigned int *) &multiCounter[currCounter];
+ ptr2 = (unsigned int *) &op_weight;
+
+ for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ )
+ {
+ tot += ( ( *ptr++ ) * ( *ptr2++ ) );
+ }
+
+ return ( tot );
+}
+
+long DeltaWeightedOperation( void )
+{
+ long NewWOper, delta;
+
+ NewWOper = TotalWeightedOperation();
+
+ delta = NewWOper - wmops[currCounter].LastWOper;
+ wmops[currCounter].LastWOper = NewWOper;
+
+ return ( delta );
+}
+
+/* Resets the current BASOP WMOPS counter */
+void Reset_BASOP_WMOPS_counter( void )
+{
+ int i;
+ long *ptr;
+
+ /* clear the current BASOP operation counter before new frame begins */
+ ptr = (long *) &multiCounter[currCounter];
+ for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( long ) ); i++ )
+ {
+ *ptr++ = 0;
+ }
+
+ wmops[currCounter].LastWOper = 0;
+
+ return;
+}
+
+#endif
+
+
diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h
index 9e20a4c7c8162126ead7cf45fbc8aab5f506c435..0a13cb7020557d6727304cfc3ac5efc8c11225e9 100644
--- a/lib_debug/wmc_auto.h
+++ b/lib_debug/wmc_auto.h
@@ -1,5 +1,5 @@
/*
- * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved.
+ * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved.
*
* This software is protected by copyright law and by international treaties. The source code, and all of its derivations,
* is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file
@@ -29,13 +29,14 @@
#pragma GCC system_header
#endif
+#ifndef INT_MAX
+#define INT_MAX 32767
+#endif
+
/* Real-time relationships */
-#define FRAMES_PER_SECOND 50.0
-#define MILLION_CYCLES 1e6
+#define FRAMES_PER_SECOND 50.0
#define WMOPS_BOOST_FAC ( 1.0f ) /* scaling factor for equalizing the difference between automatic and manual instrumentation */
-#define FAC ( FRAMES_PER_SECOND / MILLION_CYCLES * WMOPS_BOOST_FAC )
-#define NUM_INST 20 /* Total number of instruction types (in enum below) */
-
+#define FAC ( FRAMES_PER_SECOND / 1e6 * WMOPS_BOOST_FAC )
#ifdef WMOPS
enum instructions
@@ -59,7 +60,8 @@ enum instructions
_TEST,
_POWER,
_LOG,
- _MISC
+ _MISC,
+ NUM_INST
};
#define _ADD_C 1
@@ -561,7 +563,6 @@ enum instructions
extern double ops_cnt;
extern double prom_cnt;
extern double inst_cnt[NUM_INST];
-extern int ops_cnt_activ;
void reset_wmops( void );
void push_wmops( const char *label );
@@ -1012,7 +1013,7 @@ int push_stack( const char *filename, const char *fctname );
int pop_stack( const char *filename, const char *fctname );
#ifdef WMOPS_DETAIL
-#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */
+#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ " [WMC_AUTO]" ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */
#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */
#else
#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ )
@@ -1036,4 +1037,405 @@ void reset_stack( void );
#endif
+
+/* Global counter variable for calculation of complexity weight */
+typedef struct
+{
+ unsigned int add; /* Complexity Weight of 1 */
+ unsigned int sub; /* Complexity Weight of 1 */
+ unsigned int abs_s; /* Complexity Weight of 1 */
+ unsigned int shl; /* Complexity Weight of 1 */
+ unsigned int shr; /* Complexity Weight of 1 */
+
+ unsigned int extract_h; /* Complexity Weight of 1 */
+ unsigned int extract_l; /* Complexity Weight of 1 */
+ unsigned int mult; /* Complexity Weight of 1 */
+ unsigned int L_mult; /* Complexity Weight of 1 */
+ unsigned int negate; /* Complexity Weight of 1 */
+
+ unsigned int round; /* Complexity Weight of 1 */
+ unsigned int L_mac; /* Complexity Weight of 1 */
+ unsigned int L_msu; /* Complexity Weight of 1 */
+ unsigned int L_macNs; /* Complexity Weight of 1 */
+ unsigned int L_msuNs; /* Complexity Weight of 1 */
+
+ unsigned int L_add; /* Complexity Weight of 1 */
+ unsigned int L_sub; /* Complexity Weight of 1 */
+ unsigned int L_add_c; /* Complexity Weight of 2 */
+ unsigned int L_sub_c; /* Complexity Weight of 2 */
+ unsigned int L_negate; /* Complexity Weight of 1 */
+
+ unsigned int L_shl; /* Complexity Weight of 1 */
+ unsigned int L_shr; /* Complexity Weight of 1 */
+ unsigned int mult_r; /* Complexity Weight of 1 */
+ unsigned int shr_r; /* Complexity Weight of 3 */
+ unsigned int mac_r; /* Complexity Weight of 1 */
+
+ unsigned int msu_r; /* Complexity Weight of 1 */
+ unsigned int L_deposit_h; /* Complexity Weight of 1 */
+ unsigned int L_deposit_l; /* Complexity Weight of 1 */
+ unsigned int L_shr_r; /* Complexity Weight of 3 */
+ unsigned int L_abs; /* Complexity Weight of 1 */
+
+ unsigned int L_sat; /* Complexity Weight of 4 */
+ unsigned int norm_s; /* Complexity Weight of 1 */
+ unsigned int div_s; /* Complexity Weight of 18 */
+ unsigned int norm_l; /* Complexity Weight of 1 */
+ unsigned int move16; /* Complexity Weight of 1 */
+
+ unsigned int move32; /* Complexity Weight of 2 */
+ unsigned int Logic16; /* Complexity Weight of 1 */
+ unsigned int Logic32; /* Complexity Weight of 2 */
+ unsigned int Test; /* Complexity Weight of 2 */
+ unsigned int s_max; /* Complexity Weight of 1 */
+
+ unsigned int s_min; /* Complexity Weight of 1 */
+ unsigned int L_max; /* Complexity Weight of 1 */
+ unsigned int L_min; /* Complexity Weight of 1 */
+ unsigned int L40_max; /* Complexity Weight of 1 */
+ unsigned int L40_min; /* Complexity Weight of 1 */
+
+ unsigned int shl_r; /* Complexity Weight of 3 */
+ unsigned int L_shl_r; /* Complexity Weight of 3 */
+ unsigned int L40_shr_r; /* Complexity Weight of 3 */
+ unsigned int L40_shl_r; /* Complexity Weight of 3 */
+ unsigned int norm_L40; /* Complexity Weight of 1 */
+
+ unsigned int L40_shl; /* Complexity Weight of 1 */
+ unsigned int L40_shr; /* Complexity Weight of 1 */
+ unsigned int L40_negate; /* Complexity Weight of 1 */
+ unsigned int L40_add; /* Complexity Weight of 1 */
+ unsigned int L40_sub; /* Complexity Weight of 1 */
+
+ unsigned int L40_abs; /* Complexity Weight of 1 */
+ unsigned int L40_mult; /* Complexity Weight of 1 */
+ unsigned int L40_mac; /* Complexity Weight of 1 */
+ unsigned int mac_r40; /* Complexity Weight of 2 */
+
+ unsigned int L40_msu; /* Complexity Weight of 1 */
+ unsigned int msu_r40; /* Complexity Weight of 2 */
+ unsigned int Mpy_32_16_ss; /* Complexity Weight of 2 */
+ unsigned int Mpy_32_32_ss; /* Complexity Weight of 4 */
+ unsigned int L_mult0; /* Complexity Weight of 1 */
+
+ unsigned int L_mac0; /* Complexity Weight of 1 */
+ unsigned int L_msu0; /* Complexity Weight of 1 */
+ unsigned int lshl; /* Complexity Weight of 1 */
+ unsigned int lshr; /* Complexity Weight of 1 */
+ unsigned int L_lshl; /* Complexity Weight of 1 */
+
+ unsigned int L_lshr; /* Complexity Weight of 1 */
+ unsigned int L40_lshl; /* Complexity Weight of 1 */
+ unsigned int L40_lshr; /* Complexity Weight of 1 */
+ unsigned int s_and; /* Complexity Weight of 1 */
+ unsigned int s_or; /* Complexity Weight of 1 */
+
+ unsigned int s_xor; /* Complexity Weight of 1 */
+ unsigned int L_and; /* Complexity Weight of 1 */
+ unsigned int L_or; /* Complexity Weight of 1 */
+ unsigned int L_xor; /* Complexity Weight of 1 */
+ unsigned int rotl; /* Complexity Weight of 3 */
+
+ unsigned int rotr; /* Complexity Weight of 3 */
+ unsigned int L_rotl; /* Complexity Weight of 3 */
+ unsigned int L_rotr; /* Complexity Weight of 3 */
+ unsigned int L40_set; /* Complexity Weight of 3 */
+ unsigned int L40_deposit_h; /* Complexity Weight of 1 */
+
+ unsigned int L40_deposit_l; /* Complexity Weight of 1 */
+ unsigned int L40_deposit32; /* Complexity Weight of 1 */
+ unsigned int Extract40_H; /* Complexity Weight of 1 */
+ unsigned int Extract40_L; /* Complexity Weight of 1 */
+ unsigned int L_Extract40; /* Complexity Weight of 1 */
+
+ unsigned int L40_round; /* Complexity Weight of 1 */
+ unsigned int L_saturate40; /* Complexity Weight of 1 */
+ unsigned int round40; /* Complexity Weight of 1 */
+ unsigned int If; /* Complexity Weight of 4 */
+ unsigned int Goto; /* Complexity Weight of 4 */
+
+ unsigned int Break; /* Complexity Weight of 4 */
+ unsigned int Switch; /* Complexity Weight of 8 */
+ unsigned int For; /* Complexity Weight of 3 */
+ unsigned int While; /* Complexity Weight of 4 */
+ unsigned int Continue; /* Complexity Weight of 4 */
+
+ unsigned int L_mls; /* Complexity Weight of 6 */
+ unsigned int div_l; /* Complexity Weight of 32 */
+ unsigned int i_mult; /* Complexity Weight of 3 */
+} BASIC_OP;
+
+#ifdef WMOPS
+extern BASIC_OP *multiCounter;
+extern int currCounter;
+
+/* Technical note :
+ * The following 3 variables are only used for correct complexity
+ * evaluation of the following structure :
+ * IF{
+ * ...
+ * } ELSE IF {
+ * ...
+ * } ELSE IF {
+ * ...
+ * }
+ * ...
+ * } ELSE {
+ * ...
+ * }
+ */
+extern int funcId_where_last_call_to_else_occurred;
+extern long funcid_total_wmops_at_last_call_to_else;
+extern int call_occurred;
+
+extern long TotalWeightedOperation( void );
+long DeltaWeightedOperation( void );
+
+void Set_BASOP_WMOPS_counter( int counterId );
+void Reset_BASOP_WMOPS_counter( void );
+
+#endif
+
+/*****************************************************************************
+ *
+ * Function Name : FOR
+ *
+ * Purpose :
+ *
+ * The macro FOR should be used instead of the 'for' C statement.
+ * The complexity is independent of the number of loop iterations that are
+ * performed.
+ *
+ * Complexity weight : 3 (regardless of number of iterations).
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define FOR( a) for( a)
+
+#else
+#define FOR( a) if( incrFor(), 0); else for( a)
+
+static __inline void incrFor( void) {
+ multiCounter[currCounter].For++;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : WHILE
+ *
+ * Purpose :
+ *
+ * The macro WHILE should be used instead of the 'while' C statement.
+ * The complexity is proportional to the number of loop iterations that
+ * are performed.
+ *
+ * Complexity weight : 4 x 'number of loop iterations'.
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define WHILE( a) while( a)
+
+#else
+#define WHILE( a) while( incrWhile(), a)
+
+static __inline void incrWhile( void) {
+ multiCounter[currCounter].While++;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : DO
+ *
+ * Purpose :
+ *
+ * The macro DO should be used instead of the 'do' C statement.
+ *
+ * Complexity weight : 0 (complexity counted by WHILE macro).
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define DO do
+
+#else
+#define DO do
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : IF
+ *
+ * Purpose :
+ *
+ * The macro IF should :
+ *
+ * - not be used when :
+ * - the 'if' structure does not have any 'else if' nor 'else' statement
+ * - and it conditions only one DSP basic operations.
+ *
+ * - be used instead of the 'if' C statement in every other case :
+ * - when there is an 'else' or 'else if' statement,
+ * - or when the 'if' conditions several DSP basic operations,
+ * - or when the 'if' conditions a function call.
+ *
+ * Complexity weight : 4
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define IF( a) if( a)
+
+#else
+#define IF( a) if( incrIf(), a)
+
+static __inline void incrIf( void) {
+ /* Technical note :
+ * If the "IF" operator comes just after an "ELSE", its counter
+ * must not be incremented.
+ */
+ if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) )
+ {
+ multiCounter[currCounter].If++;
+ }
+
+ call_occurred = 0;
+ funcId_where_last_call_to_else_occurred = INT_MAX;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : ELSE
+ *
+ * Purpose :
+ *
+ * The macro ELSE should be used instead of the 'else' C statement.
+ *
+ * Complexity weight : 4
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define ELSE else
+
+#else
+#define ELSE else if( incrElse(), 0) ; else
+
+static __inline void incrElse( void) {
+ multiCounter[currCounter].If++;
+
+ /* We keep track of the funcId of the last function
+ * which used ELSE {...} structure.
+ */
+ funcId_where_last_call_to_else_occurred = currCounter;
+
+ /* We keep track of the number of WMOPS of this funcId
+ * when the ELSE macro was called.
+ */
+ funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation();
+
+ /* call_occurred is set to 0, in order to count the next IF (if necessary)
+ */
+ call_occurred = 0;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : SWITCH
+ *
+ * Purpose :
+ *
+ * The macro SWITCH should be used instead of the 'switch' C statement.
+ *
+ * Complexity weight : 8
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define SWITCH( a) switch( a)
+
+#else
+#define SWITCH( a) switch( incrSwitch(), a)
+
+static __inline void incrSwitch( void) {
+ multiCounter[currCounter].Switch++;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : CONTINUE
+ *
+ * Purpose :
+ *
+ * The macro CONTINUE should be used instead of the 'continue' C statement.
+ *
+ * Complexity weight : 4
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define CONTINUE continue
+
+#else
+#define CONTINUE if( incrContinue(), 0); else continue
+
+static __inline void incrContinue( void) {
+ multiCounter[currCounter].Continue++;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : BREAK
+ *
+ * Purpose :
+ *
+ * The macro BREAK should be used instead of the 'break' C statement.
+ *
+ * Complexity weight : 4
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define BREAK break
+
+#else
+#define BREAK if( incrBreak(), 0) break; else break
+
+static __inline void incrBreak( void) {
+ multiCounter[currCounter].Break++;
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function Name : GOTO
+ *
+ * Purpose :
+ *
+ * The macro GOTO should be used instead of the 'goto' C statement.
+ *
+ * Complexity weight : 4
+ *
+ *****************************************************************************/
+#ifndef WMOPS
+#define GOTO goto
+
+#else
+#define GOTO if( incrGoto(), 0); else goto
+
+static __inline void incrGoto( void) {
+ multiCounter[currCounter].Goto++;
+}
+#endif
+
#endif /* WMOPS_H */
+
+
diff --git a/scripts/tools/Darwin/wmc_tool b/scripts/tools/Darwin/wmc_tool
index 1393aaa77f752e4595dfb5898a5a0b8a3e010ede..a9b10dcfb2d32c87dd9c7cc40884ae675f3e4fa0 100755
Binary files a/scripts/tools/Darwin/wmc_tool and b/scripts/tools/Darwin/wmc_tool differ
diff --git a/scripts/tools/Linux/wmc_tool b/scripts/tools/Linux/wmc_tool
index fa197f0647c5d4fc951fc688cd07695c6b66f1cd..effbba41d676161b03519714eaeef2453c9fbff4 100755
Binary files a/scripts/tools/Linux/wmc_tool and b/scripts/tools/Linux/wmc_tool differ
diff --git a/scripts/tools/Win32/wmc_tool.exe b/scripts/tools/Win32/wmc_tool.exe
index 2c4859e0e56c4b5f62dc92e2427095aa94fe99be..ae48b8dbd08c0a4823d8abbd7b655a3825f81f5e 100755
--- a/scripts/tools/Win32/wmc_tool.exe
+++ b/scripts/tools/Win32/wmc_tool.exe
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:85947566be9633b14ed4c2cf0b822333a2820ce02a3675ab837bc32b791790dc
-size 176128
+oid sha256:6569149c60e810a6f2aaed8cd003766e2e1374bd69692eb140bef4c531bb2bfc
+size 381952