diff --git a/doc/manual/wmc_tool.tex b/doc/manual/wmc_tool.tex index a4c85a95..17ab327e 100644 --- a/doc/manual/wmc_tool.tex +++ b/doc/manual/wmc_tool.tex @@ -612,7 +612,7 @@ \subsection{Instrumentation of program and constant data ROM} } \end{Verbatim} -Note, that the declaration of the function \verb|PROM_Size_pre_echo_mask()| is visible in all project files that include \verb|wmc_auto.h|. During the instrumentation process the WMC tool will process all \verb|.c| files according to their command-line specification and will automatically sum up the program ROM size. Thus, if the user specifies e.g. \verb|lib_enc/*.c| on the command-line the WMC tool will calculate the total program ROM size of the \verb|lib_enc| library. This information may be inserted in a user-specified \verb|.c| file with the \verb|-m| command-line option and printed with the \verb|print_mem()| system function. Detailed instructions on how to print memory consumption is explained in section \ref{ch:printing_statistics_about_memory_consumption} of this document. +Note, that the declaration of the function \verb|PROM_Size_pre_echo_mask()| is visible in all project files that include \verb|wmc_auto.h|. During the instrumentation process the WMC tool will process all \verb|.c| files according to their command-line specification and will automatically sum up the program ROM size. This includes couting of both, the instrumentation added by the WMC tool for the floating point code as well as all BASOP operators and keywords. Thus, if the user specifies e.g. \verb|lib_enc/*.c| on the command-line the WMC tool will calculate the total program ROM size of the \verb|lib_enc| library. This information may be inserted in a user-specified \verb|.c| file with the \verb|-m| command-line option and printed with the \verb|print_mem()| system function. Detailed instructions on how to print memory consumption is explained in section \ref{ch:printing_statistics_about_memory_consumption} of this document. The Data (Table) ROM is estimated by counting the total size of all constant variables in each \verb|.c| source file. The WMC tool parses all global variables declared with the \verb|const| qualifier in each \verb|.c| source file and inserts the following instrumentation information in the declaration of each variable. diff --git a/src/wmc_tool/CMakeLists.txt b/src/wmc_tool/CMakeLists.txt index 858ee70c..ae47bdd5 100644 --- a/src/wmc_tool/CMakeLists.txt +++ b/src/wmc_tool/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project(wmc_tool) include(CTest) @@ -10,8 +10,8 @@ if(WIN32) ) endif() -add_executable(wmc_tool c_parser.cpp output.cpp text_utils.cpp wmc_tool.cpp) -find_package(PythonInterp) +add_executable(wmc_tool parsing_defs.h c_parser.h c_parser.cpp output.h output.cpp text_utils.h text_utils.cpp constants.h wmc_tool.h wmc_tool.cpp) +find_package (Python COMPONENTS Interpreter) # Testing file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_data TEST_DIR) @@ -19,16 +19,16 @@ file(TO_CMAKE_PATH ${TEST_DIR}/test_wmc_tool.py TEST_WMC_TOOL_SCRIPT) add_test(NAME wmc_tool_dry_run COMMAND wmc_tool -h) add_test(NAME wmc_tool_dry_run2 COMMAND wmc_tool -i) -add_test(NAME wmc_tool_test_single_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -s src -r ref -o out -v test_file1.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_single_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ test_file2.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_multiple_files COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_file*.c test_g728durb.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_basop_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_basop_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop32.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_rom_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main1.c test_rom.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_rom_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main2.c test*.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_desinstrument_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_file1.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_desinstrument_rom_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_rom.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_wmc_auto_files COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -c ${TEST_DIR} test_file3.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_single_file COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -s src -r ref -o out -v test_file1.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_single_file2 COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ test_file2.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_multiple_files COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_file*.c test_g728durb.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_basop_file COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_basop_file2 COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop32.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_rom_file COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main1.c test_rom.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_rom_file2 COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main2.c test*.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_desinstrument_file COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_file1.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_desinstrument_rom_file COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_rom.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_wmc_auto_files COMMAND ${Python_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -c ${TEST_DIR} test_file3.c WORKING_DIRECTORY ${TEST_DIR}) diff --git a/src/wmc_tool/HISTORY.md b/src/wmc_tool/HISTORY.md index 456511f3..f2bbe707 100644 --- a/src/wmc_tool/HISTORY.md +++ b/src/wmc_tool/HISTORY.md @@ -66,4 +66,26 @@ * export information about all dynamic allocations/de-allocations occuring during the runtime of the codec to a `.csv` file * added an exemplary Python script `mem_analysis.py` for graphical analysis and profiling of dynamic memory alloations based on the generated `.csv` file * added support for counting complexity and PROM size of BASOP operations and BASOP functions within floating-point source code + +## v1.5.1 + + * added the -s (--skip_cmplx_instrumentation) command-line option, which avoids the instrumentation of function bodies. The func_start_ and return_ keywords, along with the remaining functionality, remain unchanged. + +## v1.6 + + * fixed instrumentation issues in encoder.c of the 3GPP EVS codec where malloc() is instrumented and print_mem() is present as well + * when #undef WMC_TOOL_SKIP is missing, automatically assume end of file, but before the last automatically instrumented segment + * the function DesInstrument_ROM() is called in all regular files as well as the file pointed to with the -m command-line argument + +## v1.7 + * major udate of BASOP operators, corrections to the BASOP complexity counting mechanism + * update of recognized BASOP operators that should NOT be instrumented as regular functions + * introduction of the WMOPS_DISABLE_FCN_CALL_PENALIZATION macro allowing the user to skip the counting of complexity of function calls + * fix the defition of FRAMES_PER_SECOND + +## v1.8 + * fix the counting of PROM of BASOP operators appearing inside function arguments + + + \ No newline at end of file diff --git a/src/wmc_tool/README.md b/src/wmc_tool/README.md index 4731e71b..23e8647e 100644 --- a/src/wmc_tool/README.md +++ b/src/wmc_tool/README.md @@ -51,9 +51,9 @@ cmake .. make ``` -The binary file `wmc_tool` shall be created in the top-level directory. +The binary file `wmc_tool` shall be created in the top-level directory. -### Windows system +### Windows system To build the project on MS Windows use the `cmake` command with `-G` option specifying the target platform. For example, to build project files for 64-bit MSVC 2019, invoke the following commands from the top-level directory containing the file `CMakeLists.txt`: @@ -61,10 +61,10 @@ To build the project on MS Windows use the `cmake` command with `-G` option spec md build cd build cmake -G "Visual Studio 16 2019" -A "x64" .. -msbuild wmc_tool.sln +cmake --build . --config Release ``` -The executable file `wmc_tool.exe` shall be created in the top-level directory. Note, that it is recommended to run these commands from the `Developer Command Prompt for VS2019` opened in `Administrator` mode. This ensures that all paths to libraries including the SDK can be found by the `cmake` command. This can also be verified with the `vswhere` command. +In the script above `Visual Studio 16 2019` specifies the Visual Studio version, `x64` refers to the host architecture and `Release` specified the build type. The executable file `wmc_tool.exe` shall be created in the top-level directory. Note, that it is recommended to run these commands from the `Developer Command Prompt for VS2019` opened in `Administrator` mode. This ensures that all paths to libraries including the SDK can be found by the `cmake` command. This can also be verified with the `vswhere` command. ### Mac OS X system diff --git a/src/wmc_tool/c_parser.cpp b/src/wmc_tool/c_parser.cpp index 79f11010..a7a43c7e 100644 --- a/src/wmc_tool/c_parser.cpp +++ b/src/wmc_tool/c_parser.cpp @@ -142,17 +142,38 @@ "_round round round_f roundf " \ "set_min set_max " +/* Note: the following set of intrinsic BASOP operators has been extracted with */ +/* ctags - x --c - kinds = f move.h control.h control.c complex_basop.h complex_basop.c basop32.h basop32.c enh32.h enh32.c enh40.h enh40.c + enh64.h enh64.c enh1632.h enh1632.c enhUL32.h enhUL32.c math_32.h */ #define BASOP_FUNCTS_STRING \ - "add sub abs_s shl shr extract_h extract_l mult L_mult negate round " \ - "L_mac L_msu L_macNs L_msuNs L_add L_sub L_add_c L_sub_c L_negate L_shl L_shr " \ - "mult_r shr_r mac_r msu_r L_deposit_h L_deposit_l L_shr_r L_abs L_sat norm_s div_s " \ - "norm_l move16 move32 Logic16 Logic32 Test s_max s_min L_max L_min L40_max " \ - "L40_min shl_r L_shl_r L40_shr_r L40_shl_r norm_L40 L40_shl L40_shr L40_negate " \ - "L40_add L40_sub L40_abs L40_mult L40_mac mac_r40 L40_msu msu_r40 Mpy_32_16_ss " \ - "Mpy_32_32_ss L_mult0 L_mac0 L_msu0 lshl lshr L_lshl L_lshr L40_lshl L40_lshr " \ - "s_and s_or s_xor L_and L_or L_xor rotl rotr L_rotl L_rotr L40_set L40_deposit_h " \ - "L40_deposit_l L40_deposit32 Extract40_H Extract40_L L_Extract40 L40_round " \ - "L_saturate40 round40 If Goto Break Switch For While Continue L_mls div_l i_mult " +"Break CL_Extract_imag CL_Extract_imag CL_Extract_real CL_Extract_real CL_add CL_add CL_conjugate CL_conjugate CL_dscale CL_dscale CL_dscale_32 CL_dscale_32" \ +"CL_form CL_form CL_mac_j CL_mac_j CL_move CL_move CL_msu_j CL_msu_j CL_mul_j CL_mul_j CL_multr_32x16 CL_multr_32x16 CL_multr_32x32 CL_multr_32x32 CL_negate" \ +"CL_negate CL_round32_16 CL_round32_16 CL_scale CL_scale CL_scale_32 CL_scale_32 CL_shl CL_shl CL_shr CL_shr CL_sub CL_sub CL_swap_real_imag CL_swap_real_imag" \ +"C_Extract_imag C_Extract_imag C_Extract_real C_Extract_real C_add C_add C_conjugate C_conjugate C_form C_form C_mac_r C_mac_r C_msu_r C_msu_r C_mul_j C_mul_j" \ +"C_multr C_multr C_negate C_negate C_scale C_scale C_shl C_shl C_shr C_shr C_sub C_sub Continue EQ_16 EQ_32 EQ_64 Extract40_H Extract40_L For GE_16 GE_16 GE_32" \ +"GE_32 GE_64 GE_64 GT_16 GT_16 GT_32 GT_32 GT_64 GT_64 Goto If L40_abs L40_abs L40_add L40_add L40_add_o L40_deposit32 L40_deposit32 L40_deposit_h L40_deposit_h" \ +"L40_deposit_l L40_deposit_l L40_lshl L40_lshl L40_lshr L40_lshr L40_mac L40_mac L40_max L40_max L40_min L40_min L40_msu L40_msu L40_mult L40_mult L40_negate" \ +"L40_negate L40_round L40_round L40_set L40_set L40_shl L40_shl L40_shl_o L40_shl_r L40_shl_r L40_shr L40_shr L40_shr_r L40_shr_r L40_sub L40_sub L40_sub_o" \ +"LE_16 LE_16 LE_32 LE_32 LE_64 LE_64 LT_16 LT_16 LT_32 LT_32 LT_64 LT_64 L_Extract40 L_abs L_abs L_add L_add L_add_c L_add_c L_add_co L_add_o L_add_sat L_and" \ +"L_and L_deposit_h L_deposit_h L_deposit_l L_deposit_l L_lshl L_lshl L_lshr L_lshr L_mac L_mac L_mac0 L_mac0 L_mac0_o L_mac0_sat L_macNs L_macNs L_macNs_co" \ +"L_macNs_sat L_mac_o L_mac_sat L_max L_max L_min L_min L_mls L_mls L_mls_o L_mls_sat L_msu L_msu L_msu0 L_msu0 L_msu0_o L_msu0_sat L_msuNs L_msuNs L_msuNs_co" \ +"L_msuNs_sat L_msu_o L_msu_sat L_mult L_mult L_mult0 L_mult0 L_mult_o L_mult_sat L_negate L_negate L_or L_or L_rotl L_rotl L_rotr L_rotr L_sat L_sat L_sat_co" \ +"L_saturate40 L_saturate40 L_saturate40_o L_shl L_shl L_shl_o L_shl_r L_shl_r L_shl_sat L_shr L_shr L_shr_o L_shr_r L_shr_r L_shr_r_sat L_shr_ro L_shr_sat L_sub" \ +"L_sub L_sub_c L_sub_c L_sub_co L_sub_o L_sub_sat L_xor L_xor Logic16 Logic32 Madd_32_16 Madd_32_16 Madd_32_16_r Madd_32_16_r Madd_32_32 Madd_32_32 Madd_32_32_r" \ +"Madd_32_32_r Mpy_32_16_1 Mpy_32_16_1 Mpy_32_16_r Mpy_32_16_r Mpy_32_16_ss Mpy_32_16_ss Mpy_32_16_uu Mpy_32_16_uu Mpy_32_32 Mpy_32_32 Mpy_32_32_r Mpy_32_32_r" \ +"Mpy_32_32_ss Mpy_32_32_ss Mpy_32_32_uu Mpy_32_32_uu Msub_32_16 Msub_32_16 Msub_32_16_r Msub_32_16_r Msub_32_32 Msub_32_32 Msub_32_32_r Msub_32_32_r NE_16 NE_16" \ +"NE_32 NE_32 NE_64 NE_64 Switch Test UL_Mpy_32_32 UL_Mpy_32_32 UL_addNs UL_addNs UL_addNsD UL_and UL_deposit_h UL_deposit_l UL_deposit_l UL_lshl UL_lshr UL_or" \ +"UL_subNs UL_subNs UL_subNsD UL_xor W_abs W_abs W_abs_o W_add W_add W_add_nosat W_add_nosat W_add_o W_deposit32_h W_deposit32_h W_deposit32_l W_deposit32_l" \ +"W_extract_h W_extract_h W_extract_l W_extract_l W_lshl W_lshl W_lshr W_lshr W_mac0_16_16 W_mac0_16_16 W_mac_16_16 W_mac_16_16 W_mac_32_16 W_mac_32_16" \ +"W_mac_32_32 W_msu0_16_16 W_msu0_16_16 W_msu_16_16 W_msu_16_16 W_msu_32_16 W_msu_32_16 W_mult0_16_16 W_mult0_16_16 W_mult0_32_32 W_mult0_32_32 W_mult_16_16" \ +"W_mult_16_16 W_mult_32_16 W_mult_32_16 W_mult_32_32 W_mult_32_32 W_mult_32_32_o W_neg W_neg W_neg_o W_norm W_norm W_round32_s W_round32_s W_round32_s_o" \ +"W_round48_L W_round48_L W_round48_L_o W_round64_L W_round64_L W_sat_l W_sat_l W_sat_m W_sat_m W_shl W_shl W_shl_nosat W_shl_nosat W_shl_o W_shl_sat_l" \ +"W_shl_sat_l W_shr W_shr W_shr_nosat W_shr_nosat W_sub W_sub W_sub_nosat W_sub_nosat W_sub_o While abs_s abs_s add add add_o add_sat div_l div_l div_s div_s" \ +"extract_h extract_h extract_l extract_l get_carry i_mult i_mult i_mult_o i_mult_sat logic16 logic32 lshl lshr mac_r mac_r40 mac_r_sat mac_ro move16 move16" \ +"move32 move32 move64 move64 msu_r msu_r msu_r40 msu_r40 msu_r_sat msu_ro mult mult mult_o mult_r mult_r mult_r_sat mult_ro mult_sat negate negate norm_L40" \ +"norm_L40 norm_l norm_l norm_s norm_s norm_ul_float rotl rotl rotr rotr round round40 round40 round_fx round_fx_o round_fx_sat s_and s_and s_max s_max s_min" \ +"s_min s_or s_or s_xor s_xor saturate saturate_o set_carry set_overflow shl shl shl_o shl_r shl_r shl_ro shl_sat shr shr shr_o shr_r shr_r shr_r_sat shr_ro" \ +"shr_sat sub sub sub_o sub_sat test u_extract_h u_extract_l unset_carry unset_overflow" #define WMOPS_LIB_INCLUDE_STRING \ "wmc_auto.h" @@ -180,13 +201,6 @@ #define FUNC_START_STRING FUNC_COUNTING_MACRO_STRING "start" WORD_INSTRUMENT_STRING -/***************************************** - * Function Exit - *****************************************/ - -#define RETURN_KW_STRING "return" - - /*-------------------------------------------------------------------* * Local Typedefs *-------------------------------------------------------------------*/ @@ -250,7 +264,7 @@ static const struct { "break", false, NUL_CHAR, ITEM_KEYWORD_BREAK, 0 }, { "continue", false, NUL_CHAR, ITEM_KEYWORD_CONTINUE | ITEM_WARNING, 0 }, /* 'return' now Instrumented for enter/leave function Mechanism */ - { RETURN_KW_STRING, false, NUL_CHAR, ITEM_KEYWORD_RETURN | ITEM_RETURN } + { "return", false, NUL_CHAR, ITEM_KEYWORD_RETURN | ITEM_RETURN } }; static const char * const Conditionnal_Directives[] = { "ifdef", "ifndef", "if", "else", "elif", "endif", NULL }; @@ -1657,7 +1671,7 @@ static bool Is_Constant( UpperChar = Total = 0; do { - if ( IS_UPPER_CHAR( *ptr ) ) + if ( !IS_LOWER_CHAR( *ptr ) ) UpperChar += 100; Total++; ptr++; @@ -2584,6 +2598,7 @@ static TOOL_ERROR Find_Keywords( } /* Reset Parameter End */ pe = NULL; + /* Reset Delimiter Position */ dp = NULL; /* Keyword has an Argument? */ @@ -3549,6 +3564,46 @@ static TOOL_ERROR Find_Preproc_Instrumentation( } } + /* Mark all lines preceded by AddedByWMC_Tool as Instrumentation */ + + /* Start at Beginning */ + ptr = ParseCtx_ptr->File.Data; + + /* Search for AddedBy_WMC_Tool string which has not been marked as instrumentation yet */ + while ((ptr = Find_Identifier(ptr, ADDED_TOOL_INFO_STRING, ParseTbl_ptr, ITEM_COMMENT, ITEM_INSTRUMENTATION, &idx)) != NULL) + { + /* Get Record */ + ParseRec_ptr = &ParseTbl_ptr->Data[idx]; + + /* Mark as Instrumentation */ + ParseRec_ptr->item_type |= ITEM_INSTRUMENTATION; + + ptr = ParseRec_ptr->item_end; + + /* check, if is followed by #ifdef or #endif statement */ + if ((idx = Find_Region(ptr, ParseTbl_ptr, ITEM_PREPROC_CMD | ITEM_PREPROC_COND)) > 0) + { + /* Get Record */ + ParseRec_ptr = &ParseTbl_ptr->Data[idx]; + + /* Mark as Instrumentation */ + ParseRec_ptr->item_type |= ITEM_INSTRUMENTATION; + + if (memwordcmp(ptr, "#if #ifdef #ifndef #elif") != NULL) + { + /* Get the next record - should be Preprocessor Directive Arguments */ + ParseRec_ptr = &ParseTbl_ptr->Data[idx + 1]; + + /* Mark as Instrumentation */ + ParseRec_ptr->item_type |= ITEM_INSTRUMENTATION; + } + + /* Advance pointer to the end of Preprocessor Arguments (Skip Spaces and Comments Only) */ + ptr = Skip_Chars(ParseRec_ptr->item_end, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_COMMENT); + } + } + + return ErrCode; } @@ -4323,8 +4378,7 @@ static TOOL_ERROR Find_Calls( if ( item_type != ITEM_NONE ) { /* Add Function Call Name Region */ - if ( ( ErrCode = Add_Region( ParseTbl_ptr, item_type | ITEM_CALL, - ns, ne + 1 ) ) != NO_ERR ) + if ( ( ErrCode = Add_Region( ParseTbl_ptr, item_type | ITEM_CALL, ns, ne + 1 ) ) != NO_ERR ) { goto ret; } @@ -4334,12 +4388,14 @@ static TOOL_ERROR Find_Calls( ErrCode = Parentheses_Error( ps, ')' ); goto ret; } + /* Add Function Arguments Region (Arguments are never Marked as Instrumented) */ - if ( ( ErrCode = Add_Region( ParseTbl_ptr, ( item_type | ITEM_CALL_ARGS ) & ~ITEM_INSTRUMENTED, - ps, pe + 1 ) ) != NO_ERR ) + //if ((ErrCode = Add_Region(ParseTbl_ptr, (item_type | ITEM_CALL_ARGS) & ~ITEM_INSTRUMENTED, ps, pe + 1)) != NO_ERR) + if ( ( ErrCode = Add_Region( ParseTbl_ptr, ( item_type | ITEM_CALL_ARGS ) & ~ITEM_INSTRUMENTED & ~ITEM_INSTRUMENTATION_OFF, ps, pe + 1 ) ) != NO_ERR ) { goto ret; } + /* Counting Macro, Couting Function or BASOP Function? */ if ( item_type & ( ITEM_FUNC_COUNTERS | ITEM_FUNC_COUNT_LIB | ITEM_FUNC_BASOP ) ) { /* Yes */ @@ -4349,7 +4405,8 @@ static TOOL_ERROR Find_Calls( not Preprocessor Lines */ /* Skip Blanks to the Right (this cannot fail) */ - ps = Skip_Chars( pe + 1, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_COMMENT ); + //ps = Skip_Chars( pe + 1, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_COMMENT ); + /* It is the End of Statement? */ if ( *ps == ';' ) { /* Yes */ @@ -4667,7 +4724,8 @@ static TOOL_ERROR Instrument_Switch( * Instrument_Keywords *-------------------------------------------------------------------*/ static TOOL_ERROR Instrument_Keywords( - Parse_Context_def *ParseCtx_ptr ) + Parse_Context_def *ParseCtx_ptr, + bool skip_cmplx_instrum) { TOOL_ERROR ErrCode = NO_ERR; @@ -4696,88 +4754,104 @@ static TOOL_ERROR Instrument_Keywords( item_type = ParseRec_ptr->item_type; /* Skipped? */ - unless( item_type & ITEM_SKIPPED ) + if( !(item_type & ITEM_SKIPPED) ) { /* No */ - /* In Skipped or Non-Instrumented Region? */ - if ( Find_Region( ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED | ITEM_INSTRUMENTATION_OFF ) < 0 - /* 'return' always gets Instrumented (even in Manual Regions) */ - || ( item_type == ITEM_KEYWORD_RETURN - /* 'return not' Instrumented in Skipped Regions */ - && Find_Region( ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED ) < 0 - && Find_Region( ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK ) < 0 && Find_Region( ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK | ITEM_FUNC_MATH ) < 0 && Find_Region( ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK | ITEM_FUNC_SYSTEM ) < 0 ) ) - { /* No */ - /* Instrument After (by default) */ - ptr = ParseRec_ptr->item_end; - /* Is it a 'while' that is part of a 'do' Block? */ - /* Insert Instrumentation Character */ - if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, ptr, WORD_INSTRUMENT_STRING ) ) != NO_ERR ) - { - goto ret; - } + /* Skip the instrumentation if the user specified so on the command-line */ + /* with the exception of the 'return' keywords */ + if (!skip_cmplx_instrum || item_type == ITEM_KEYWORD_RETURN) + { + /* In Skipped or Non-Instrumented Region? */ + if (Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED | ITEM_INSTRUMENTATION_OFF) < 0 + /* 'return' always gets Instrumented (even in Manual Regions) */ + || (item_type == ITEM_KEYWORD_RETURN + /* 'return not' Instrumented in Skipped Regions */ + && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED) < 0 + && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK) < 0 + && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK | ITEM_FUNC_MATH) < 0 + && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_FUNC_BLOCK | ITEM_FUNC_SYSTEM) < 0)) + { /* No */ - /* Is it a 'while'? - Auto Instrumentation Macro for 'while' in a 'do' Block - can handle multiple Condition. */ - if ( item_type == ITEM_KEYWORD_WHILE - /* 'while' from 'do/while' now Needs Extra () for Multiple Condition*/ - || item_type == ITEM_KEYWORD_WHILE2 - ) - { /* Yes */ - /* Advance to Parameters Record */ - ParseRec_ptr++; - /* More than one Condition? */ - if ( Count_Args( ParseRec_ptr->item_start, - ParseRec_ptr->item_end - 1, - ParseTbl_ptr ) > 1 ) + //if (skip_cmplx_instrum && item_type != ITEM_KEYWORD_RETURN) + //{ + // /* skip the instrumentation if the user specified so on the command-line */ + // /* with the exception of the 'return' keywords */ + // continue; + //} + + /* Instrument After (by default) */ + ptr = ParseRec_ptr->item_end; + + /* Insert Instrumentation Character '_' */ + if ((ErrCode = Add_Insertion(&ParseCtx_ptr->InsertTbl, ptr, WORD_INSTRUMENT_STRING)) != NO_ERR) + { + goto ret; + } + + /* Is it a 'while'? + Auto Instrumentation Macro for 'while' in a 'do' Block + can handle multiple Condition. */ + if (item_type == ITEM_KEYWORD_WHILE + /* 'while' from 'do/while' now Needs Extra () for Multiple Condition*/ + || item_type == ITEM_KEYWORD_WHILE2) { /* Yes */ - /* Must Add Extra () */ - if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, - ParseRec_ptr->item_start, - "(" ) ) != NO_ERR ) - { - goto ret; - } + /* Advance to Parameters Record */ + ParseRec_ptr++; + /* More than one Condition? */ + if (Count_Args(ParseRec_ptr->item_start, + ParseRec_ptr->item_end - 1, + ParseTbl_ptr) > 1) + { /* Yes */ + /* Must Add Extra () */ + if ((ErrCode = Add_Insertion(&ParseCtx_ptr->InsertTbl, + ParseRec_ptr->item_start, + "(")) != NO_ERR) + { + goto ret; + } + + if ((ErrCode = Add_Insertion(&ParseCtx_ptr->InsertTbl, + ParseRec_ptr->item_end, + ")")) != NO_ERR) + { + goto ret; + } - if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, - ParseRec_ptr->item_end, - ")" ) ) != NO_ERR ) + /* Add Warning */ + ParseRec_ptr->item_type |= ITEM_WARNING; + } + } + /* Is it a switch? */ + else if (item_type == ITEM_KEYWORD_SWITCH) + { /* Yes */ + if ((ErrCode = Instrument_Switch(ParseCtx_ptr, idx, + &ParseCtx_ptr->PROMSize, + prom_ops_weights_ptr)) != NO_ERR) { goto ret; } - - /* Add Warning */ - ParseRec_ptr->item_type |= ITEM_WARNING; } - } - /* Is it a switch? */ - else if ( item_type == ITEM_KEYWORD_SWITCH ) - { /* Yes */ - if ( ( ErrCode = Instrument_Switch( ParseCtx_ptr, idx, - &ParseCtx_ptr->PROMSize, - prom_ops_weights_ptr ) ) != NO_ERR ) - { - goto ret; - } - } - /* Count Program Memory */ - //if ( item_type == ITEM_KEYWORD_FOR ) - // loops++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->loop; - //else if ( item_type == ITEM_KEYWORD_WHILE ) - // whiles++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch * 2; - //else if ( item_type & ( ITEM_KEYWORD_CONTROL | ITEM_KEYWORD_IS_JUMP ) ) - // jumps++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch; + ///* Count Program Memory */ + //if ( item_type == ITEM_KEYWORD_FOR ) + // loops++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->loop; + //else if ( item_type == ITEM_KEYWORD_WHILE ) + // whiles++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch * 2; + //else if ( item_type & ( ITEM_KEYWORD_CONTROL | ITEM_KEYWORD_IS_JUMP ) ) + // jumps++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch; + } } /* Count Program Memory */ /* !!! VM: Moved to this place to count PROM size even for non-instrumented keywords */ - if ( Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED) < 0 ) + //if ( Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED) < 0 ) + if (!IS_RESERVED_CHAR(*(ParseRec_ptr->item_start))) { - if (item_type == ITEM_KEYWORD_FOR) + /* Note, that the construct (item_type & ~ITEM_INSTRUMENTATION_OFF) has been added to be able to use == instead of &*/ + if ((item_type & ~ITEM_INSTRUMENTATION_OFF) == ITEM_KEYWORD_FOR) loops++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->loop; - else if (item_type == ITEM_KEYWORD_WHILE) + else if ((item_type & ~ITEM_INSTRUMENTATION_OFF) == ITEM_KEYWORD_WHILE) whiles++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch * 2; - else if (item_type & (ITEM_KEYWORD_CONTROL | ITEM_KEYWORD_IS_JUMP)) + else if ((item_type & ~ITEM_INSTRUMENTATION_OFF) & (ITEM_KEYWORD_CONTROL | ITEM_KEYWORD_IS_JUMP)) jumps++, ParseCtx_ptr->PROMSize += prom_ops_weights_ptr->branch; } } @@ -5889,7 +5963,7 @@ static TOOL_ERROR Instrument_Calls( } /* System Allocation Function */ /* !! VM: Added && Find_Region(.) to avoid instrumentation of malloc() calls within WMC_TOOL_SKIP segments */ - if ( (item_type & ITEM_FUNC_SYSTEM) && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED | ITEM_INSTRUMENTATION_OFF) < 0 ) + if ((item_type & ITEM_FUNC_SYSTEM) && Find_Region(ParseRec_ptr->item_start, ParseTbl_ptr, ITEM_SKIPPED) < 0) { /* Yes */ /* Insert Instrumentation */ if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, end, WORD_INSTRUMENT_STRING ) ) != NO_ERR ) @@ -6454,13 +6528,46 @@ TOOL_ERROR Setup_Regions( ITEM_PREPROC_ARGS | ITEM_PREPROC_UNDEF, ITEM_ENCLOSED, &idx ) ) == NULL ) { /* No */ - /* Error - #undef WMC_TOOL_SKIP missing ! */ - ErrCode = ERR_EXPECTED_EOS; - Error("Unable to find matching #undef %s!", ErrCode, WMC_TOOL_SKIP_STRING); - goto ret; + ///* Error - #undef WMC_TOOL_SKIP missing ! */ + //ErrCode = ERR_EXPECTED_EOS; + //Error("Unable to find matching #undef %s!", ErrCode, WMC_TOOL_SKIP_STRING); + //goto ret; + + /* Go to EOF */ + end = file_ptr->Data + file_ptr->Size; - /* Skipped Region will End at EOF */ - //end = file_ptr->Data + file_ptr->Size; + /* Go back by skipping all lines preceded by AddedByWMC_Tool */ + + /* Go back to the beginning of the line */ + end = Skip_Chars(end, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + end = Goto_Chars(end, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + end++; + + /* Check, if line starts with "AddedByWMC_Tool */ + while (strncmp(end, ADDED_TOOL_INFO_STRING, strlen(ADDED_TOOL_INFO_STRING)) == 0) + { + /* Go back to the beginning of the previous line */ + end = Skip_Chars(end - 1, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + end = Goto_Chars(end, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + end++; + } + + /* Go to the end of the current line */ + end = Goto_Chars(end, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); + + if (end == NULL) + { + /* reached the end of file */ + end = file_ptr->Data + file_ptr->Size; + } + else if (IS_EOL_SEQ(end)) + { + end += 2; + } + else + { + end++; + } } else { /* Yes */ @@ -6475,7 +6582,7 @@ TOOL_ERROR Setup_Regions( } /* Add Non-Instrumented Region */ - if ( ( ErrCode = Add_Region( ParseTbl_ptr, ITEM_INSTRUMENTATION_OFF, ptr, end ) ) != NO_ERR ) + if ( ( ErrCode = Add_Region( ParseTbl_ptr, ITEM_SKIPPED | ITEM_INSTRUMENTATION_OFF, ptr, end ) ) != NO_ERR ) { goto ret; } @@ -7335,13 +7442,13 @@ TOOL_ERROR DesInstrument( } - /*-------------------------------------------------------------------* * DesInstrument_ROM *-------------------------------------------------------------------*/ TOOL_ERROR DesInstrument_ROM( - Parse_Context_def* ParseCtx_ptr) + Parse_Context_def* ParseCtx_ptr +) { TOOL_ERROR ErrCode = NO_ERR; @@ -7353,13 +7460,6 @@ TOOL_ERROR DesInstrument_ROM( start_const_data_prom_table = NULL; end_const_data_prom_table = NULL; - /* Check Previous State */ - if (ParseCtx_ptr->State != SETUP_OK) - { - ErrCode = Internal_Error(__FUNCTION__); - goto ret; - } - /* Set State Failure (by default) */ ParseCtx_ptr->State = DI_FAILED; @@ -7386,31 +7486,103 @@ TOOL_ERROR DesInstrument_ROM( Delete(start, tmp); } } - - /* 'Const_Data_PROM_Table' Declaration? */ + /* Data Declaration? */ else if (ParseRec_ptr->item_type & ITEM_DATA_DECL) { /* Yes */ - /* Check if this ROM_Size_Lookup_Table declaration */ + /* Check if this is ROM_Size_Lookup_Table declaration */ if (strnistr(start, "ROM_Size_Lookup_Table", strlen("ROM_Size_Lookup_Table")) != NULL) { - /* Save the pointers - will be used later to check, if it was enclosed in #ifdef WMOPS .. #endif pair */ - start_const_data_prom_table = start; - end_const_data_prom_table = tmp; - } + /* Go back to the beginning of the line */ + start = Goto_Chars(start, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + start++; - /* Delete it */ - Delete(start, tmp); + /* Check, if line starts with "AddedByWMC_Tool */ + while (strncmp(start, ADDED_TOOL_INFO_STRING, strlen(ADDED_TOOL_INFO_STRING)) == 0) + { + /* check, if line continues with "#ifdef WMOPS" */ + if (strncmp(start + strlen(ADDED_TOOL_INFO_STRING), "#ifdef WMOPS", strlen("#ifdef WMOPS")) == 0) + { + start_const_data_prom_table = start; + break; + } + else + { + /* Go back to the beginning of the previous line */ + start = Skip_Chars(start - 1, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + start = Goto_Chars(start, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); + start++; + } + } - } + if (!IS_EOL_CHAR(PREV_CHAR(tmp))) + { + /* Go to the beginning of the next line */ + tmp = Goto_Chars(tmp, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); + tmp = Skip_Chars(tmp, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); + } + + /* Check, if line starts with "AddedByWMC_Tool */ + while (strncmp(tmp, ADDED_TOOL_INFO_STRING, strlen(ADDED_TOOL_INFO_STRING)) == 0) + { + /* check, if line continues with "#endif" */ + if (strncmp(tmp + strlen(ADDED_TOOL_INFO_STRING), "#endif", strlen("#endif")) == 0) + { + /* Go to the end this line */ + tmp = Goto_Chars(tmp, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); - /* One of the ROM counting functions, e.g. 'Const_Data_Size_Func(...)'? */ + /* Go past the EOL */ + if (IS_EOL_SEQ(tmp)) + { + /* One Extra step, if it's CR+LF */ + tmp++; + } + tmp++; + + end_const_data_prom_table = tmp; + break; + } + else + { + /* Go to the beginning of the next line */ + tmp = Goto_Chars(tmp, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); + tmp = Skip_Chars(tmp, EOL_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, FORWARD); + } + } + + if (start_const_data_prom_table != NULL && end_const_data_prom_table != NULL) + { + /* Delete the whole segment */ + Delete(start, tmp); + } + + /* Item is no Longer a Declaration */ + ParseRec_ptr->item_type ^= ITEM_DATA_DECL; + + /* Item is no Longer Instrumentation */ + ParseRec_ptr->item_type ^= ITEM_INSTRUMENTATION; + } + } + /* One of the 'Const_Data_Size_Func(...)' counting functions? */ else if (ParseRec_ptr->item_type & ITEM_FUNC_DEF) { /* Yes */ /* Is function prototype or block followed by some blank chars? -> delete them as well */ if (ParseRec_ptr->item_type & (ITEM_FUNC_PROTO | ITEM_FUNC_BLOCK)) { - tmp = Skip_Chars(tmp, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_COMMENT, FORWARD); + /* Skip all SPACE chars, if any */ + tmp = Skip_Chars(tmp, SPACE_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_COMMENT, FORWARD); + + /* Go past the EOL, if present */ + if (IS_EOL_SEQ(tmp)) + { + /* Two chars, in case of CR+LF */ + tmp += 2; + } + else if (IS_EOL_CHAR(*tmp)) + { + /* One char, if only LF */ + tmp++; + } } /* Delete it */ @@ -7436,62 +7608,11 @@ TOOL_ERROR DesInstrument_ROM( /* Item is no Longer a Function Name/Proto/Block */ ParseRec_ptr->item_type &= ~ITEM_FUNC_DEF; - } - /* Item is no Longer Instrumentation */ - ParseRec_ptr->item_type ^= ITEM_INSTRUMENTATION; - } - - /* Check, if Const_Data_PROM_Table[] was enclosed in #ifdef WMOPS .. #endif pair */ - if (start_const_data_prom_table != NULL && end_const_data_prom_table != NULL) - { - /* Go back to the first word preceding Const_Data_PROM_Table[] */ - start = Skip_Chars(start_const_data_prom_table - 1, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE, BACKWARDS); - - /* Proceed to the beginning of the line */ - while (!IS_EOL_CHAR(PREV_CHAR(start))) - { - start--; - } - - /* Check if line contains "#ifdef WMOPS" */ - if ( (tmp = stristr(memstr(start, start_const_data_prom_table), "#ifdef")) != NULL) - { - tmp = Skip_Identifier(tmp, FORWARD); - tmp = Skip_Chars(tmp + 1, SPACE_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE); - if (strncmp(tmp, "WMOPS", strlen("WMOPS")) == 0) - { - /* Delete the whole line */ - Delete(start, start_const_data_prom_table); - } + /* Item is no Longer Instrumentation */ + ParseRec_ptr->item_type ^= ITEM_INSTRUMENTATION; } - /* Go to the first word after Const_Data_PROM_Table[] */ - end = Skip_Chars(end_const_data_prom_table, BLANK_CHARS, ParseTbl_ptr, ITEM_ANY, ITEM_NONE); - - /* Check if line contains "#endif" */ - while (!IS_EOL_CHAR(NEXT_CHAR(end))) - { - if (*end == '#') - { - /* Found '#' */ - if (strncmp(end, "#endif", strlen("#endif")) == 0) - { - /* Go to EOL */ - while (*end != LF_CHAR) - { - end++; - } - - /* Delete the whole line */ - Delete(end_const_data_prom_table, end); - - break; - } - } - - end++; - } } /* Find the print_mem() function */ @@ -7521,7 +7642,7 @@ TOOL_ERROR DesInstrument_ROM( /* Set State Success */ ParseCtx_ptr->State = DESINSTRUMENTED; -ret: +//ret: return ErrCode; } @@ -8112,7 +8233,9 @@ TOOL_ERROR Include_Header( TOOL_ERROR Instrument( Parse_Context_def *ParseCtx_ptr, - bool instrument_ROM ) + bool instrument_ROM, + bool skip_cmplx_instrum +) { TOOL_ERROR ErrCode = NO_ERR; @@ -8122,6 +8245,7 @@ TOOL_ERROR Instrument( ErrCode = Internal_Error( __FUNCTION__ ); goto ret; } + /* Set State Failure (by default) */ ParseCtx_ptr->State = INS_FAILED; @@ -8149,7 +8273,7 @@ TOOL_ERROR Instrument( /* Erase Function Call Table */ ParseCtx_ptr->FctCallTbl.Size = 0; - if ( ( ErrCode = Instrument_Calls( ParseCtx_ptr ) ) != NO_ERR ) + if ((ErrCode = Instrument_Calls(ParseCtx_ptr)) != NO_ERR) { goto ret; } @@ -8170,7 +8294,7 @@ TOOL_ERROR Instrument( } is_function_present = 0; - if (idx > 0) + if ( idx > 0 ) { is_function_present = 1; } @@ -8263,17 +8387,20 @@ TOOL_ERROR Instrument( /* $(...) inserted on same Line as #pragma message for Skipped Region */ } - if ( ( ErrCode = Instrument_Operators( ParseCtx_ptr ) ) != NO_ERR ) + if (!skip_cmplx_instrum) { - goto ret; + if ((ErrCode = Instrument_Operators(ParseCtx_ptr)) != NO_ERR) + { + goto ret; + } } - if ( ( ErrCode = Instrument_Keywords( ParseCtx_ptr ) ) != NO_ERR ) + if ((ErrCode = Instrument_Keywords(ParseCtx_ptr, skip_cmplx_instrum)) != NO_ERR) { goto ret; } - if ( instrument_ROM && is_cnst_data_present) + if ( instrument_ROM && is_cnst_data_present ) { if ( ( ErrCode = Instrument_ROM( ParseCtx_ptr) ) != NO_ERR ) { @@ -8389,7 +8516,6 @@ TOOL_ERROR Instrument( } /* Insert PROM_Size_Func() function */ - //if (is_function_present) if (ParseCtx_ptr->PROMSize > 0) { if ((ErrCode = Instrument_PROM(ParseCtx_ptr)) != NO_ERR) @@ -8432,7 +8558,7 @@ TOOL_ERROR Instrument( } ptr3 = NULL; /* Find Last 'return' keyword in this Function (this is used for the Function Leave Mechanism) */ - while ( ( ptr = Find_String( memstr( ptr, ptr2 ), RETURN_KW_STRING, ParseTbl_ptr, ITEM_KEYWORD_RETURN ) ) != NULL ) + while ( ( ptr = Find_String( memstr( ptr, ptr2 ), "return", ParseTbl_ptr, ITEM_KEYWORD_RETURN ) ) != NULL ) { /* Copy and Advance */ ptr3 = ptr++; @@ -8548,7 +8674,7 @@ TOOL_ERROR Instrument( } /* Add 'return' keyword */ - if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, ptr, RETURN_KW_STRING WORD_INSTRUMENT_STRING ADDED_TOOL_INFO_STRING ";" ) ) != NO_ERR ) + if ( ( ErrCode = Add_Insertion( &ParseCtx_ptr->InsertTbl, ptr, "return_" ADDED_TOOL_INFO_STRING ";" ) ) != NO_ERR ) { goto ret; } diff --git a/src/wmc_tool/c_parser.h b/src/wmc_tool/c_parser.h index fcdf8106..4c51e943 100644 --- a/src/wmc_tool/c_parser.h +++ b/src/wmc_tool/c_parser.h @@ -31,7 +31,7 @@ void Free_Pointer_Table_Memory( Pointer_Tbl_def *PointerTable_ptr ); TOOL_ERROR Setup_Regions( Parse_Context_def *ParseContext_ptr, bool verbose ); TOOL_ERROR DesInstrument( Parse_Context_def *ParseContext_ptr, bool keep_manual ); TOOL_ERROR DesInstrument_ROM(Parse_Context_def* ParseCtx_ptr); -TOOL_ERROR Instrument(Parse_Context_def* ParseContext_ptr, bool instr_const); +TOOL_ERROR Instrument(Parse_Context_def* ParseContext_ptr, bool instr_const, bool skip_cmplx_instrum); TOOL_ERROR Instrument_Const_Data_PROM_Table( Parse_Context_def *ParseContext_ptr, T_FILE_BOOK file_book[], int nRecords ); TOOL_ERROR Finalize( Parse_Context_def *ParseContext_ptr ); TOOL_ERROR Include_Header(Parse_Context_def* ParseContext_ptr, char** ptr_end_preproc_block ); diff --git a/src/wmc_tool/parsing_defs.h b/src/wmc_tool/parsing_defs.h index 99949148..04361436 100644 --- a/src/wmc_tool/parsing_defs.h +++ b/src/wmc_tool/parsing_defs.h @@ -196,8 +196,9 @@ #define ITEM_LABEL 0x02 #define ITEM_DATA 0x04 /* typedef or Declaration*/ -#define ITEM_INSTRUMENTED 0x02000000 -#define ITEM_INSTRUMENTATION 0x04000000 +#define ITEM_INSTRUMENTATION_OFF 0x10000000 +#define ITEM_INSTRUMENTED 0x02000000 +#define ITEM_INSTRUMENTATION 0x04000000 #define ITEM_MOVED_OVER ( ITEM_COMMENT | ITEM_PREPROC_LINE ) #define ITEM_NOT_SEARCHED ( ITEM_SKIPPED | ITEM_ENCLOSED | ITEM_PREPROC_LINE | ITEM_DATA_DECL ) @@ -212,8 +213,6 @@ #define ITEM_CSTE_SUFFIX 0x40 #define ITEM_CSTE_ERROR 0x80 -#define ITEM_INSTRUMENTATION_OFF 0x10000000 - #define ITEM_CONSTANT 0x20000000 #define ITEM_SKIPPED 0x40000000 #define ITEM_WARNING 0x80000000 diff --git a/src/wmc_tool/test_data/ref/main2.c b/src/wmc_tool/test_data/ref/main2.c index e77f327c..7ba9dc2e 100644 --- a/src/wmc_tool/test_data/ref/main2.c +++ b/src/wmc_tool/test_data/ref/main2.c @@ -20,7 +20,7 @@ /*AddedByWMC_Tool*/} /*AddedByWMC_Tool*/ROM_Size_Lookup_Table Const_Data_PROM_Table[] = /*AddedByWMC_Tool*/{ -/*AddedByWMC_Tool*/ { "out/test*.c", 291, Get_Const_Data_Size_out_test_c }, +/*AddedByWMC_Tool*/ { "out/test*.c", 302, Get_Const_Data_Size_out_test_c }, /*AddedByWMC_Tool*/ { "", -1, NULL } /*AddedByWMC_Tool*/}; /*AddedByWMC_Tool*/#endif diff --git a/src/wmc_tool/test_data/ref/test_basop.c b/src/wmc_tool/test_data/ref/test_basop.c index dd20ac35..7cb71518 100644 --- a/src/wmc_tool/test_data/ref/test_basop.c +++ b/src/wmc_tool/test_data/ref/test_basop.c @@ -55,4 +55,4 @@ void weight_coef_a( const Word16 *a, Word16 *b, const Word16 ght ) } #undef WMC_TOOL_SKIP -/*AddedByWMC_Tool*/ int PROM_Size_Func( test_basop ) { return 15; } +/*AddedByWMC_Tool*/ int PROM_Size_Func( test_basop ) { return 24; } diff --git a/src/wmc_tool/test_data/ref/test_basop32.c b/src/wmc_tool/test_data/ref/test_basop32.c index 9fcdf1e7..380e1247 100644 --- a/src/wmc_tool/test_data/ref/test_basop32.c +++ b/src/wmc_tool/test_data/ref/test_basop32.c @@ -2430,4 +2430,4 @@ Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2) { #undef WMC_TOOL_SKIP /* end of file */ -/*AddedByWMC_Tool*/ int PROM_Size_Func( test_basop32 ) { return 157; } +/*AddedByWMC_Tool*/ int PROM_Size_Func( test_basop32 ) { return 159; } diff --git a/src/wmc_tool/test_data/ref/wmc_auto.c b/src/wmc_tool/test_data/ref/wmc_auto.c index 7dfcf8bf..2e10db8c 100644 --- a/src/wmc_tool/test_data/ref/wmc_auto.c +++ b/src/wmc_tool/test_data/ref/wmc_auto.c @@ -1,5 +1,5 @@ /* - * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2024 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 @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include #ifndef _MSC_VER #include @@ -25,27 +27,29 @@ #include #endif -#include "options.h" #include "wmc_auto.h" #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ -#ifdef WMOPS +#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 /*-------------------------------------------------------------------* * Complexity counting tool *--------------------------------------------------------------------*/ -#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_FUNCTION_NAME_LENGTH 200 /* Maximum length of the function name */ +#define MAX_PARAMS_LENGTH 200 /* Maximum length of the function parameter string */ +#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> might 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 -#define FAC ( FRAMES_PER_SECOND / 1e6 ) - +#define FRAMES_PER_SECOND 50.0 #define FAC ( FRAMES_PER_SECOND / 1e6 ) +#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ -typedef struct +typedef struct { char label[MAX_FUNCTION_NAME_LENGTH]; long call_number; @@ -57,7 +61,7 @@ typedef struct double max_selfcnt; double min_selfcnt; double tot_selfcnt; - double start_cnt; + double start_cnt; /* The following take into account the decendants */ double current_cnt; double max_cnt; double min_cnt; @@ -71,7 +75,6 @@ typedef struct } wmops_record; double ops_cnt; -double prom_cnt; double inst_cnt[NUM_INST]; static wmops_record *wmops = NULL; @@ -86,10 +89,73 @@ 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; +static 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, 2, 1, + + 1, 1, 1, 2, 1, + 1, 1, 18, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 2, 2, 2, 2, 1, + + 1, 1, 1, 1, 1, + 1, 1, 1, 2, + 1, 2, 2, 2, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 3, + 3, 3, 3, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 3, 2, + 2, 6, 3, 3, 2, + + 1, 32, 1 + +/* New complex basops */ +#ifdef COMPLEX_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1 + + , + 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1 + +#endif /* #ifdef COMPLEX_OPERATOR */ + +#ifdef ENH_64_BIT_OPERATOR + /* Weights of new 64 bit basops */ + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + , + 1, 1, 1, 2, 2, 1, 1 +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef CONTROL_CODE_OPS */ +}; + +BASIC_OP *multiCounter = NULL; +unsigned int currCounter = 0; +long funcid_total_wmops_at_last_call_to_else; +char func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH + 1]; + void reset_wmops( void ) { int i, j; - unsigned int *ptr; num_wmops_records = 0; max_num_wmops_records = MAX_NUM_RECORDS; @@ -101,10 +167,10 @@ void reset_wmops( void ) start_cnt = 0.0; ops_cnt = 0.0; - /* allocate the list of wmops records */ + /* allocate the list of WMOPS records */ if ( wmops == NULL ) { - wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) ); + wmops = (wmops_record *) malloc( max_num_wmops_records * sizeof( wmops_record ) ); } if ( wmops == NULL ) @@ -113,7 +179,7 @@ void reset_wmops( void ) exit( -1 ); } - /* allocate the BASOP WMOPS counter */ + /* allocate the list of BASOP WMOPS records */ if ( multiCounter == NULL ) { multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) ); @@ -125,8 +191,8 @@ void reset_wmops( void ) exit( -1 ); } - /* initilize the list of wmops records */ - /* initilize the BASOP WMOPS counters */ + /* initilize the list of WMOPS records */ + /* initilize BASOP operation counters */ for ( i = 0; i < max_num_wmops_records; i++ ) { strcpy( &wmops[i].label[0], "\0" ); @@ -153,13 +219,8 @@ void reset_wmops( void ) 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; + /* Reset BASOP operation counter */ + Reset_BASOP_WMOPS_counter( i ); } /* allocate the list of wmops callers to track the sequence of function calls */ @@ -181,47 +242,83 @@ void reset_wmops( void ) wmops_caller_stack[i] = -1; } - /* initialize auxiliary BASOP WMOPS variables */ - call_occurred = 1; - funcId_where_last_call_to_else_occurred = INT_MAX; - return; } - -void push_wmops( const char *label ) +void push_wmops_fct( const char *label, ... ) { int new_flag; - int i, j; + int i, j, index_record; + long tot; + va_list arg; + char func_name[MAX_FUNCTION_NAME_LENGTH] = ""; + + /* concatenate all function name labels into a single string */ + va_start( arg, label ); + while ( label ) + { + strcat( func_name, label ); + label = va_arg( arg, const char * ); + } + va_end( arg ); /* Check, if this is a new function label */ new_flag = 1; for ( i = 0; i < num_wmops_records; i++ ) { - if ( strcmp( wmops[i].label, label ) == 0 ) + if ( strcmp( wmops[i].label, func_name ) == 0 ) { new_flag = 0; break; } } + index_record = i; - /* Create a new record in the list */ + /* Create a new WMOPS record in the list */ if ( new_flag ) { if ( num_wmops_records >= max_num_wmops_records ) { - /* There is no room for a new wmops record -> reallocate the list */ + /* 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 ); + /* initilize the new WMOPS record */ + strcpy( &wmops[index_record].label[0], "\0" ); + wmops[index_record].call_number = 0; + wmops[index_record].update_cnt = 0; + for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) + { + wmops[index_record].call_tree[j] = -1; + } + wmops[index_record].start_selfcnt = 0.0; + wmops[index_record].current_selfcnt = 0.0; + wmops[index_record].max_selfcnt = 0.0; + wmops[index_record].min_selfcnt = DOUBLE_MAX; + wmops[index_record].tot_selfcnt = 0.0; + wmops[index_record].start_cnt = 0.0; + wmops[index_record].current_cnt = 0.0; + wmops[index_record].max_cnt = 0.0; + wmops[index_record].min_cnt = DOUBLE_MAX; + wmops[index_record].tot_cnt = 0.0; +#ifdef WMOPS_WC_FRAME_ANALYSIS + wmops[index_record].wc_cnt = 0.0; + wmops[index_record].wc_selfcnt = 0.0; + wmops[index_record].current_call_number = 0; + wmops[index_record].wc_call_number = -1; +#endif + + /* Reset BASOP operation counter */ + Reset_BASOP_WMOPS_counter( index_record ); + + strcpy( wmops[index_record].label, func_name ); num_wmops_records++; } - /* Push the current context info to the new record */ + /* Update the WMOPS context info of the old record before switching to the new one */ if ( current_record >= 0 ) { if ( wmops_caller_stack_index >= max_wmops_caller_stack_index ) @@ -232,40 +329,48 @@ void push_wmops( const char *label ) } wmops_caller_stack[wmops_caller_stack_index++] = current_record; - /* accumulate op counts */ + /* add the BASOP complexity to the counter and update the old WMOPS counter */ + tot = DeltaWeightedOperation( current_record ); + ops_cnt += tot; wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; /* update call tree */ for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) { - if ( wmops[i].call_tree[j] == current_record ) + if ( wmops[index_record].call_tree[j] == current_record ) { break; } - else if ( wmops[i].call_tree[j] == -1 ) + else if ( wmops[index_record].call_tree[j] == -1 ) { - wmops[i].call_tree[j] = current_record; + wmops[index_record].call_tree[j] = current_record; break; } } } - /* update the current context info */ - current_record = i; - wmops[current_record].start_selfcnt = ops_cnt; - wmops[current_record].start_cnt = ops_cnt; - wmops[current_record].call_number++; + /* Need to reset the BASOP operation counter of the 0th record in every push_wmops() */ + /* because currCounter can never be -1 */ + if ( current_record == -1 && index_record == 0 ) + { + wmops[index_record].LastWOper = TotalWeightedOperation( index_record ); + } + + /* switch to the new record */ + current_record = index_record; + wmops[index_record].start_selfcnt = ops_cnt; + wmops[index_record].start_cnt = ops_cnt; + wmops[index_record].call_number++; #ifdef WMOPS_WC_FRAME_ANALYSIS - wmops[current_record].current_call_number++; + wmops[index_record].current_call_number++; #endif - /* set the ID of BASOP functions counters */ - Set_BASOP_WMOPS_counter( current_record ); + /* set the ID of the current BASOP operations counter */ + currCounter = index_record; return; } - void pop_wmops( void ) { long tot; @@ -278,10 +383,10 @@ void pop_wmops( void ) } /* add the BASOP complexity to the counter */ - tot = DeltaWeightedOperation(); + tot = DeltaWeightedOperation( currCounter ); ops_cnt += tot; - /* update count of current record */ + /* 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; @@ -290,15 +395,21 @@ void pop_wmops( void ) { 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; } + /* set the ID of the previous BASOP operations counter */ + if ( current_record == -1 ) + { + currCounter = 0; /* Note: currCounter cannot be set to -1 because it's defined as unsigned int ! */ + } + else + { + currCounter = current_record; + } return; } @@ -391,9 +502,8 @@ void update_wmops( void ) wmops[i].current_call_number = 0; #endif - /* update the WC of all BASOP counters */ - Set_BASOP_WMOPS_counter( i ); - Reset_BASOP_WMOPS_counter(); + /* reset the BASOP operations counter */ + Reset_BASOP_WMOPS_counter( i ); } current_cnt = ops_cnt - start_cnt; @@ -427,15 +537,14 @@ void update_wmops( void ) return; } - void print_wmops( void ) { int i, label_len, max_label_len; 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"; + 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; @@ -456,7 +565,7 @@ void print_wmops( void ) max_label_len += 4; 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, "---------------", "------", "------", "------", "------", "------", "------", "------" ); @@ -478,7 +587,7 @@ void print_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS 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 %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); for ( i = 0; i < num_wmops_records; i++ ) @@ -512,7 +621,7 @@ void print_wmops( void ) fprintf( stdout, "\n\n" ); - fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); + 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 ) @@ -604,7 +713,6 @@ void print_wmops( void ) return; } - /*-------------------------------------------------------------------* * Memory counting tool measuring RAM usage (stack and heap) * @@ -627,6 +735,7 @@ void print_wmops( void ) * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free(). *--------------------------------------------------------------------*/ + /* 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 @@ -636,12 +745,14 @@ 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 OOB_START 0x1 /* int indicating out-of-bounds access before memory block */ +#define OOB_END 0x2 /* int 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"; @@ -654,7 +765,7 @@ typedef struct int16_t *stack_ptr; } caller_info; -static caller_info *stack_callers[2] = {NULL, NULL}; +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 */ @@ -663,7 +774,6 @@ static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case 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 */ @@ -889,7 +999,7 @@ int push_stack( const char *filename, const char *fctname ) /* 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; + wc_stack_frame = update_cnt; strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 ); location_max_stack[sizeof( location_max_stack ) - 1] = '\0'; @@ -904,7 +1014,7 @@ int push_stack( const char *filename, const char *fctname ) } /* Check, if This is the New Worst-Case RAM (stack + heap) */ - current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); if ( current_stack_size < 0 ) { @@ -1097,7 +1207,7 @@ void *mem_alloc( #ifdef MEM_COUNT_DETAILS /* Export heap memory allocation record to the .csv file */ - fprintf( fid_csv_filename, "A,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); + fprintf( fid_csv_filename, "A,%ld,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); #endif if ( ptr_record->frame_allocated != -1 ) @@ -1112,7 +1222,7 @@ void *mem_alloc( current_heap_size += ptr_record->block_size; /* Check, if this is the new Worst-Case RAM (stack + heap) */ - current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); if ( current_stack_size + current_heap_size > wc_ram_size ) { wc_ram_size = current_stack_size + current_heap_size; @@ -1395,8 +1505,8 @@ allocator_record *get_mem_record( unsigned long *hash, const char *func_name, in /*-------------------------------------------------------------------* * mem_free() * - * This function de-allocatesd the memory block and frees the mphysical memory with free(). - * It also updates actual and average usage of the memory block. + * This function de-allocates memory blocks and frees physical memory with free(). + * It also updates the actual and average usage of memory blocks. * * Note: The record is not removed from the list and may be reused later on in mem_alloc()! *--------------------------------------------------------------------*/ @@ -1437,7 +1547,7 @@ void mem_free( const char *func_name, int func_lineno, void *ptr ) #ifdef MEM_COUNT_DETAILS /* Export heap memory de-allocation record to the .csv file */ - fprintf( fid_csv_filename, "D,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); + fprintf( fid_csv_filename, "D,%ld,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); #endif /* De-Allocate Memory Block */ @@ -1697,7 +1807,7 @@ static void mem_count_summary( void ) allocator_record *ptr_record, *ptr; /* Prepare format string */ - sprintf( format_str, "%%-%ds %%5s %%6s %%-%ds %%20s %%6s ", MAX_FUNCTION_NAME_LENGTH, MAX_PARAMS_LENGTH ); + sprintf( format_str, "%%-%d.%ds %%5.5s %%6.6s %%-%d.%ds %%20.20s %%6.6s ", 50, 50, 50, 50 ); if ( n_items_wc_intra_frame_heap > 0 ) { @@ -2064,109 +2174,339 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) #endif /* WMOPS */ -#ifndef WMOPS -int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ +#ifdef CONTROL_CODE_OPS + +int LT_16( short var1, short var2 ) +{ + int F_ret = 0; + + if ( var1 < var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_16++; #endif + return F_ret; +} + +int GT_16( short var1, short var2 ) +{ + int F_ret = 0; + if ( var1 > var2 ) + { + F_ret = 1; + } #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; + multiCounter[currCounter].GT_16++; +#endif + return F_ret; +} -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, +int LE_16( short var1, short var2 ) +{ + int F_ret = 0; - 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, + if ( var1 <= var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_16++; +#endif + return F_ret; +} - 1, 1, 1, 1, 1, - 1, 1, 1, 2, - 1, 2, 2, 4, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, +int GE_16( short var1, short var2 ) +{ + int F_ret = 0; - 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, + if ( var1 >= var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_16++; +#endif + return F_ret; +} - 5, 32, 3 -}; +int EQ_16( short var1, short var2 ) +{ + int F_ret = 0; + + if ( var1 == var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_16++; +#endif + return F_ret; +} -/* Set the counter group to use, default is zero */ -void Set_BASOP_WMOPS_counter( int counterId ) +int NE_16( short var1, short var2 ) { - if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) ) + int F_ret = 0; + + if ( var1 != var2 ) { - currCounter = 0; - return; + F_ret = 1; } - currCounter = counterId; - call_occurred = 1; +#ifdef WMOPS + multiCounter[currCounter].NE_16++; +#endif + return F_ret; +} + +int LT_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 < L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_32++; +#endif + return F_ret; +} + +int GT_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 > L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GT_32++; +#endif + return F_ret; +} + +int LE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 <= L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_32++; +#endif + return F_ret; +} + +int GE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 >= L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_32++; +#endif + return F_ret; +} + +int EQ_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 == L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_32++; +#endif + return F_ret; +} + +int NE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 != L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].NE_32++; +#endif + return F_ret; +} + +int LT_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 < L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_64++; +#endif + return F_ret; +} + +int GT_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 > L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GT_64++; +#endif + return F_ret; +} + +int LE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 <= L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_64++; +#endif + return F_ret; +} +int GE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 >= L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_64++; +#endif + return F_ret; } -extern int32_t frame; +int EQ_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; -long TotalWeightedOperation() + if ( L64_var1 == L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_64++; +#endif + return F_ret; +} +int NE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 != L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].NE_64++; +#endif + return F_ret; +} + +#endif /* #ifdef CONTROL_CODE_OPS */ + +#ifdef WMOPS + +void incrIf( const char *func_name ) +{ + /* Technical note: If the "IF" operator comes just after an "ELSE", its counter must not be incremented */ + /* The following auxiliary variables are used to check if the "IF" operator doesn't immediately follow an "ELSE" operator */ + if ( ( strncmp( func_name, func_name_where_last_call_to_else_occurred, MAX_FUNCTION_NAME_LENGTH ) != 0 ) || ( TotalWeightedOperation( currCounter ) != funcid_total_wmops_at_last_call_to_else ) ) + { + + multiCounter[currCounter].If++; + } + + func_name_where_last_call_to_else_occurred[0] = '\0'; +} + +void incrElse( const char *func_name ) +{ + multiCounter[currCounter].If++; + + /* Save the BASOP comeplxity in the last call of the ELSE() statement */ + funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation( currCounter ); + + /* We keep track of the name of the last calling function when the ELSE macro was called */ + strncpy( func_name_where_last_call_to_else_occurred, func_name, MAX_FUNCTION_NAME_LENGTH ); + func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH] = '\0'; +} + +long TotalWeightedOperation( unsigned int CounterId ) { int i; unsigned int *ptr, *ptr2; - long tot; + long tot; tot = 0; - ptr = (unsigned int *) &multiCounter[currCounter]; + ptr = (unsigned int *) &multiCounter[CounterId]; ptr2 = (unsigned int *) &op_weight; - for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) + for ( i = 0; i < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); i++ ) { + if ( *ptr == UINT_MAX ) + { + printf( "\nError in BASOP complexity counters: multiCounter[%d][%d] = %d !!!\n", CounterId, i, *ptr ); + exit( -1 ); + } + tot += ( ( *ptr++ ) * ( *ptr2++ ) ); } return ( tot ); } -long DeltaWeightedOperation( void ) +long DeltaWeightedOperation( unsigned int CounterId ) { long NewWOper, delta; - NewWOper = TotalWeightedOperation(); + NewWOper = TotalWeightedOperation( CounterId ); - delta = NewWOper - wmops[currCounter].LastWOper; - wmops[currCounter].LastWOper = NewWOper; + delta = NewWOper - wmops[CounterId].LastWOper; + wmops[CounterId].LastWOper = NewWOper; return ( delta ); } -/* Resets the current BASOP WMOPS counter */ -void Reset_BASOP_WMOPS_counter( void ) +/* Resets BASOP operation counter */ +void Reset_BASOP_WMOPS_counter( unsigned int counterId ) { int i; - long *ptr; + unsigned int *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++ ) + /* reset the current BASOP operation counter */ + ptr = (unsigned int *) &multiCounter[counterId]; + for ( i = 0; i < (int) (sizeof(BASIC_OP) / sizeof(unsigned int)); i++ ) { *ptr++ = 0; } - wmops[currCounter].LastWOper = 0; + wmops[counterId].LastWOper = 0; return; } #endif - - - diff --git a/src/wmc_tool/test_data/ref/wmc_auto.h b/src/wmc_tool/test_data/ref/wmc_auto.h index 3dae42b6..ba006919 100644 --- a/src/wmc_tool/test_data/ref/wmc_auto.h +++ b/src/wmc_tool/test_data/ref/wmc_auto.h @@ -1,5 +1,5 @@ /* - * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2024 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 @@ -23,18 +23,17 @@ #include /* stdio is needed for fprintf() */ #endif - /* To Prevent "warning: '$' in identifier or number" message under GCC */ #ifdef __GNUC__ #pragma GCC system_header #endif -#ifndef INT_MAX -#define INT_MAX 32767 -#endif - -#define FRAMES_PER_SECOND 50.0 -#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ +#define ENH_32_BIT_OPERATOR +#define ENH_64_BIT_OPERATOR +#define ENH_U_32_BIT_OPERATOR +#define COMPLEX_OPERATOR +#define CONTROL_CODE_OPS /* enable control code operators such as LT_16, GT_16, ... */ +/* #define WMOPS_DISABLE_FCN_CALL_PENALIZATION*/ /* do not count the complexity of function calls */ #ifdef WMOPS enum instructions @@ -62,6 +61,30 @@ enum instructions NUM_INST }; +extern double ops_cnt; +extern double inst_cnt[NUM_INST]; + +/******************************************************************/ +/* NOTES: */ +/* The 'wmc_flag_' flag is global to avoid declaration in every */ +/* function and 'static' to avoid clashing with other modules */ +/* that include this header file. */ +/* */ +/* The declarations of 'wmc_flag_' and 'wops_' in this header */ +/* file prevent the addition of a 'C' file to the Project. */ +/******************************************************************/ + +/* General Purpose Global int */ +static int wmc_flag_ = 0; + +#define push_wmops( ... ) push_wmops_fct( __VA_ARGS__, NULL ) +void push_wmops_fct( const char *label, ... ); +void pop_wmops( void ); +void reset_wmops( void ); +void print_wmops( void ); +void update_wmops( void ); +void update_mem( void ); + #define _ADD_C 1 #define _ABS_C 1 #define _MULT_C 1 @@ -83,501 +106,167 @@ enum instructions #define _LOG_C 25 #define _MISC_C 1 -#define _ADD_P 1 -#define _ABS_P 1 -#define _MULT_P 1 -#define _MAC_P 1 -#define _MOVE_P 1 -#define _STORE_P 0 -#define _LOGIC_P 1 -#define _SHIFT_P 1 -#define _BRANCH_P 2 -#define _DIV_P 2 -#define _SQRT_P 2 -#define _TRANS_P 2 -#define _FUNC_P 2 /* need to add number of arguments */ -#define _LOOP_P 1 -#define _INDIRECT_P 2 -#define _PTR_INIT_P 1 -#define _TEST_P 1 -#define _POWER_P 2 -#define _LOG_P 2 -#define _MISC_P 1 - -#define ADD( x ) \ - { \ - { \ - ops_cnt += ( _ADD_C * ( x ) ); \ - inst_cnt[_ADD] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ADD_P * ( x ) ); \ - } \ - } \ - } \ +#define ADD( x ) \ + { \ + ops_cnt += ( _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ } -#define ABS( x ) \ - { \ - { \ - ops_cnt += ( _ABS_C * ( x ) ); \ - inst_cnt[_ABS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ABS_P * ( x ) ); \ - } \ - } \ - } \ +#define ABS( x ) \ + { \ + ops_cnt += ( _ABS_C * ( x ) ); \ + inst_cnt[_ABS] += ( x ); \ } -#define MULT( x ) \ - { \ - { \ - ops_cnt += ( _MULT_C * ( x ) ); \ - inst_cnt[_MULT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MULT_P * ( x ) ); \ - } \ - } \ - } \ +#define MULT( x ) \ + { \ + ops_cnt += ( _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ } -#define MAC( x ) \ - { \ - { \ - ops_cnt += ( _MAC_C * ( x ) ); \ - inst_cnt[_MAC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MAC_P * ( x ) ); \ - } \ - } \ - } \ +#define MAC( x ) \ + { \ + ops_cnt += ( _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ } -#define MOVE( x ) \ - { \ - { \ - ops_cnt += ( _MOVE_C * ( x ) ); \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define MOVE( x ) \ + { \ + ops_cnt += ( _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ } -#define STORE( x ) \ - { \ - { \ - ops_cnt += ( _STORE_C * ( x ) ); \ - inst_cnt[_STORE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _STORE_P * ( x ) ); \ - } \ - } \ - } \ +#define STORE( x ) \ + { \ + ops_cnt += ( _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ } -#define LOGIC( x ) \ - { \ - { \ - ops_cnt += ( _LOGIC_C * ( x ) ); \ - inst_cnt[_LOGIC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOGIC_P * ( x ) ); \ - } \ - } \ - } \ +#define LOGIC( x ) \ + { \ + ops_cnt += ( _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ } -#define SHIFT( x ) \ - { \ - { \ - ops_cnt += ( _SHIFT_C * ( x ) ); \ - inst_cnt[_SHIFT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SHIFT_P * ( x ) ); \ - } \ - } \ - } \ +#define SHIFT( x ) \ + { \ + ops_cnt += ( _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ } -#define BRANCH( x ) \ - { \ - { \ - ops_cnt += ( _BRANCH_C * ( x ) ); \ - inst_cnt[_BRANCH] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _BRANCH_P * ( x ) ); \ - } \ - } \ - } \ +#define BRANCH( x ) \ + { \ + ops_cnt += ( _BRANCH_C * ( x ) ); \ + inst_cnt[_BRANCH] += ( x ); \ } -#define DIV( x ) \ - { \ - { \ - ops_cnt += ( _DIV_C * ( x ) ); \ - inst_cnt[_DIV] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _DIV_P * ( x ) ); \ - } \ - } \ - } \ +#define DIV( x ) \ + { \ + ops_cnt += ( _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ } -#define SQRT( x ) \ - { \ - { \ - ops_cnt += ( _SQRT_C * ( x ) ); \ - inst_cnt[_SQRT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SQRT_P * ( x ) ); \ - } \ - } \ - } \ +#define SQRT( x ) \ + { \ + ops_cnt += ( _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ } -#define TRANS( x ) \ - { \ - { \ - ops_cnt += ( _TRANS_C * ( x ) ); \ - inst_cnt[_TRANS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TRANS_P * ( x ) ); \ - } \ - } \ - } \ +#define TRANS( x ) \ + { \ + ops_cnt += ( _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ } -#define LOOP( x ) \ - { \ - { \ - ops_cnt += ( _LOOP_C * ( x ) ); \ - inst_cnt[_LOOP] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOOP_P * ( x ) ); \ - } \ - } \ - } \ +#define LOOP( x ) \ + { \ + ops_cnt += ( _LOOP_C * ( x ) ); \ + inst_cnt[_LOOP] += ( x ); \ } -#define INDIRECT( x ) \ - { \ - { \ - ops_cnt += ( _INDIRECT_C * ( x ) ); \ - inst_cnt[_INDIRECT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _INDIRECT_P * ( x ) ); \ - } \ - } \ - } \ +#define INDIRECT( x ) \ + { \ + ops_cnt += ( _INDIRECT_C * ( x ) ); \ + inst_cnt[_INDIRECT] += ( x ); \ } -#define PTR_INIT( x ) \ - { \ - { \ - ops_cnt += ( _PTR_INIT_C * ( x ) ); \ - inst_cnt[_PTR_INIT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _PTR_INIT_P * ( x ) ); \ - } \ - } \ - } \ +#define PTR_INIT( x ) \ + { \ + ops_cnt += ( _PTR_INIT_C * ( x ) ); \ + inst_cnt[_PTR_INIT] += ( x ); \ } -#define TEST( x ) \ - { \ - { \ - ops_cnt += ( _TEST_C * ( x ) ); \ - inst_cnt[_TEST] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TEST_P * ( x ) ); \ - } \ - } \ - } \ +#define TEST( x ) \ + { \ + ops_cnt += ( _TEST_C * ( x ) ); \ + inst_cnt[_TEST] += ( x ); \ } -#define POWER( x ) \ - { \ - { \ - ops_cnt += ( _POWER_C * ( x ) ); \ - inst_cnt[_POWER] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _POWER_P * ( x ) ); \ - } \ - } \ - } \ +#define POWER( x ) \ + { \ + ops_cnt += ( _POWER_C * ( x ) ); \ + inst_cnt[_POWER] += ( x ); \ } -#define LOG( x ) \ - { \ - { \ - ops_cnt += ( _LOG_C * ( x ) ); \ - inst_cnt[_LOG] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOG_P * ( x ) ); \ - } \ - } \ - } \ +#define LOG( x ) \ + { \ + ops_cnt += ( _LOG_C * ( x ) ); \ + inst_cnt[_LOG] += ( x ); \ } -#define MISC( x ) \ - { \ - { \ - ops_cnt += ( _MISC_C * ( x ) ); \ - inst_cnt[_MISC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MISC_P * ( x ) ); \ - } \ - } \ - } \ +#define MISC( x ) \ + { \ + ops_cnt += ( _MISC_C * ( x ) ); \ + inst_cnt[_MISC] += ( x ); \ } - -#define FUNC( x ) \ - { \ - { \ - ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \ - inst_cnt[_FUNC]++; \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _FUNC_P + _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define FUNC( x ) \ + { \ + ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \ + inst_cnt[_FUNC]++; \ + inst_cnt[_MOVE] += ( x ); \ } - -#define DADD( x ) \ - { \ - { \ - ops_cnt += ( 2 * _ADD_C * ( x ) ); \ - inst_cnt[_ADD] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ADD_P * ( x ) ); \ - } \ - } \ - } \ +#define DADD( x ) \ + { \ + ops_cnt += ( 2 * _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ } -#define DMULT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MULT_C * ( x ) ); \ - inst_cnt[_MULT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MULT_P * ( x ) ); \ - } \ - } \ - } \ +#define DMULT( x ) \ + { \ + ops_cnt += ( 2 * _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ } -#define DMAC( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MAC_C * ( x ) ); \ - inst_cnt[_MAC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MAC_P * ( x ) ); \ - } \ - } \ - } \ +#define DMAC( x ) \ + { \ + ops_cnt += ( 2 * _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ } -#define DMOVE( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MOVE_C * ( x ) ); \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define DMOVE( x ) \ + { \ + ops_cnt += ( 2 * _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ } -#define DSTORE( x ) \ - { \ - { \ - ops_cnt += ( 2 * _STORE_C * ( x ) ); \ - inst_cnt[_STORE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _STORE_P * ( x ) ); \ - } \ - } \ - } \ +#define DSTORE( x ) \ + { \ + ops_cnt += ( 2 * _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ } -#define DLOGIC( x ) \ - { \ - { \ - ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \ - inst_cnt[_LOGIC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOGIC_P * ( x ) ); \ - } \ - } \ - } \ +#define DLOGIC( x ) \ + { \ + ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ } -#define DSHIFT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \ - inst_cnt[_SHIFT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SHIFT_P * ( x ) ); \ - } \ - } \ - } \ +#define DSHIFT( x ) \ + { \ + ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ } -#define DDIV( x ) \ - { \ - { \ - ops_cnt += ( 2 * _DIV_C * ( x ) ); \ - inst_cnt[_DIV] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _DIV_P * ( x ) ); \ - } \ - } \ - } \ +#define DDIV( x ) \ + { \ + ops_cnt += ( 2 * _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ } -#define DSQRT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _SQRT_C * ( x ) ); \ - inst_cnt[_SQRT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SQRT_P * ( x ) ); \ - } \ - } \ - } \ +#define DSQRT( x ) \ + { \ + ops_cnt += ( 2 * _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ } -#define DTRANS( x ) \ - { \ - { \ - ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ - inst_cnt[_TRANS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TRANS_P * ( x ) ); \ - } \ - } \ - } \ +#define DTRANS( x ) \ + { \ + ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ } -extern double ops_cnt; -extern double prom_cnt; -extern double inst_cnt[NUM_INST]; - -void reset_wmops( void ); -void push_wmops( const char *label ); -void pop_wmops( void ); -void update_wmops( void ); -void update_mem( void ); -void print_wmops( void ); - -#else /* WMOPS counting disabled */ +#else -#define reset_wmops() extern int cntr_push_pop; #define push_wmops( x ) ( cntr_push_pop++ ) #define pop_wmops() ( cntr_push_pop-- ) -#define update_wmops() ( assert( cntr_push_pop == 0 ) ) -#define update_mem() +#define reset_wmops() #define print_wmops() +#define update_wmops() ( assert( cntr_push_pop == 0 ) ) +#define update_mem() #define ADD( x ) #define ABS( x ) @@ -628,24 +317,8 @@ extern int cntr_push_pop; #else -/* '*ops_cnt_ptr' is Used to Avoid: "warning: operation on 'ops_cnt' may be undefined" with Cygwin gcc Compiler */ -static double *ops_cnt_ptr = &ops_cnt; -#define OP_COUNT_( op, x ) ( *ops_cnt_ptr += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) ) - -/******************************************************************/ -/* NOTES: */ -/* The 'wmc_flag_' flag is global to avoid declaration in every */ -/* function and 'static' to avoid clashing with other modules */ -/* that include this header file. */ -/* */ -/* The declarations of 'wmc_flag_' and 'wops_' in this header */ -/* file prevent the addition of a 'C' file to the Project. */ -/******************************************************************/ - -/* General Purpose Global Flag */ -static int wmc_flag_ = 0; - /* Operation Counter Wrappers */ +#define OP_COUNT_( op, x ) ( ops_cnt += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) ) #define OP_COUNT_WRAPPER1_( op, val ) ( op, val ) #define OP_COUNT_WRAPPER2_( expr ) \ if ( expr, 0 ) \ @@ -677,8 +350,12 @@ static int wmc_flag_ = 0; #define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) ) #define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) ) #define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) ) -#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) -#define MISC_( x ) ABS_( x ) +#ifdef WMOPS_DISABLE_FCN_CALL_PENALIZATION +#define FUNC_( x ) ( x ) +#else +#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) +#endif +#define MISC_( x ) ABS_( x ) /* Math Operations */ #define abs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), abs ) @@ -723,8 +400,8 @@ static int wmc_flag_ = 0; #define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf ) /* the macros below are instrumented versions of user-defined macros that might be used in the source code -/* representing some well-known and recognized mathematical operations (that are not defined in math.h) */ -/* Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ + representing some well-known and recognized mathematical operations (that are not defined in math.h) + Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ #define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) ) #define max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), max( ( a ), ( b ) ) ) @@ -744,8 +421,8 @@ static int wmc_flag_ = 0; #define inv_sqrt_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrt( ( x ) ) ) #define inv_sqrtf_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrtf( ( x ) ) ) #define log_base_2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log_base_2( ( x ) ) ) -#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) ) -#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) ) +#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) ) +#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) ) #define log2_f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2_f( ( x ) ) ) #define _round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, _round( ( x ) ) ) #define round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, round( ( x ) ) ) @@ -795,7 +472,6 @@ static int wmc_flag_ = 0; #define return_ \ OP_COUNT_WRAPPER2_( ( wmc_flag_ = stack_tree_level_, STACK_DEPTH_FCT_RETURN ) ) \ return - #define switch_ \ OP_COUNT_WRAPPER2_( ( BRANCH_( 1 ), wmc_flag_ = 1 ) ) \ switch @@ -911,7 +587,6 @@ static void wops_( const char *ops ) /* This Shouldn't Happen */ /* These are Used to Avoid: "warning: 'name' defined but not used" with Cygwin gcc Compiler */ wmc_flag_ = wmc_flag_; - ops_cnt_ptr = ops_cnt_ptr; fct( "" ); error: default: @@ -973,7 +648,7 @@ typedef struct ROM_Size_Lookup_Table * ROM_Size_Lookup_Table Const_Data_PROM_Table[] = * { * {"../lib_enc/rom_enc.c", 0, NULL}, - * {"../lib_com/*.c", 0, NULL}, + * {"../lib_com/[star].c", 0, NULL}, * {"", -1, NULL} * }; * #endif @@ -986,22 +661,9 @@ typedef enum { USE_BYTES = 0, USE_16BITS = 1, - USE_32BITS = 2, - USE_64BITS = 3 + USE_32BITS = 2 } Counting_Size; -#if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) ) -#define __func__ __FUNCTION__ -#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ < 199901L -#if ( __GNUC__ >= 2 ) -#define __func__ __FUNCTION__ -#else -#define __func__ "" -#endif -#elif defined( __GNUC__ ) -#define __func__ __extension__ __FUNCTION__ -#endif - #ifdef WMOPS @@ -1019,11 +681,11 @@ 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__ " [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 */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ #else -#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) -#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __FUNCTION__ ) +#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __func__ ) +#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ ) #endif void reset_stack( void ); @@ -1043,7 +705,6 @@ void reset_stack( void ); #endif - /* Global counter variable for calculation of complexity weight */ typedef struct { @@ -1101,10 +762,10 @@ typedef struct 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 shl_r; /* Complexity Weight of 2 */ + unsigned int L_shl_r; /* Complexity Weight of 2 */ + unsigned int L40_shr_r; /* Complexity Weight of 2 */ + unsigned int L40_shl_r; /* Complexity Weight of 2 */ unsigned int norm_L40; /* Complexity Weight of 1 */ unsigned int L40_shl; /* Complexity Weight of 1 */ @@ -1121,7 +782,7 @@ typedef struct 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 Mpy_32_32_ss; /* Complexity Weight of 2 */ unsigned int L_mult0; /* Complexity Weight of 1 */ unsigned int L_mac0; /* Complexity Weight of 1 */ @@ -1145,7 +806,7 @@ typedef struct 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_set; /* Complexity Weight of 1 */ unsigned int L40_deposit_h; /* Complexity Weight of 1 */ unsigned int L40_deposit_l; /* Complexity Weight of 1 */ @@ -1157,48 +818,158 @@ typedef struct 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 If; /* Complexity Weight of 3 */ + unsigned int Goto; /* Complexity Weight of 2 */ - unsigned int Break; /* Complexity Weight of 4 */ - unsigned int Switch; /* Complexity Weight of 8 */ + unsigned int Break; /* Complexity Weight of 2 */ + unsigned int Switch; /* Complexity Weight of 6 */ unsigned int For; /* Complexity Weight of 3 */ - unsigned int While; /* Complexity Weight of 4 */ - unsigned int Continue; /* Complexity Weight of 4 */ + unsigned int While; /* Complexity Weight of 3 */ + unsigned int Continue; /* Complexity Weight of 2 */ - unsigned int L_mls; /* Complexity Weight of 6 */ + unsigned int L_mls; /* Complexity Weight of 1 */ unsigned int div_l; /* Complexity Weight of 32 */ - unsigned int i_mult; /* Complexity Weight of 3 */ + unsigned int i_mult; /* Complexity Weight of 1 */ + +/* New complex basic operators */ +#ifdef COMPLEX_OPERATOR + unsigned int CL_shr; /* Complexity Weight of 1 */ + unsigned int CL_shl; /* Complexity Weight of 1 */ + unsigned int CL_add; /* Complexity Weight of 1 */ + unsigned int CL_sub; /* Complexity Weight of 1 */ + unsigned int CL_scale; /* Complexity Weight of 1 */ + unsigned int CL_dscale; /* Complexity Weight of 1 */ + unsigned int CL_msu_j; /* Complexity Weight of 1 */ + unsigned int CL_mac_j; /* Complexity Weight of 1 */ + unsigned int CL_move; /* Complexity Weight of 1 */ + unsigned int CL_Extract_real; /* Complexity Weight of 1 */ + unsigned int CL_Extract_imag; /* Complexity Weight of 1 */ + unsigned int CL_form; /* Complexity Weight of 1 */ + unsigned int CL_multr_32x16; /* Complexity Weight of 2 */ + unsigned int CL_negate; /* Complexity Weight of 1 */ + unsigned int CL_conjugate; /* Complexity Weight of 1 */ + unsigned int CL_mul_j; /* Complexity Weight of 1 */ + unsigned int CL_swap_real_imag; /* Complexity Weight of 1 */ + unsigned int C_add; /* Complexity Weight of 1 */ + unsigned int C_sub; /* Complexity Weight of 1 */ + unsigned int C_mul_j; /* Complexity Weight of 1 */ + unsigned int C_multr; /* Complexity Weight of 2 */ + unsigned int C_form; /* Complexity Weight of 1 */ + + unsigned int C_scale; /* Complexity Weight of 1 */ + unsigned int CL_round32_16; /* Complexity Weight of 1 */ + unsigned int CL_scale_32; /* Complexity Weight of 1 */ + unsigned int CL_dscale_32; /* Complexity Weight of 1 */ + unsigned int CL_multr_32x32; /* Complexity Weight of 2 */ + unsigned int C_mac_r; /* Complexity Weight of 2 */ + unsigned int C_msu_r; /* Complexity Weight of 2 */ + unsigned int C_Extract_real; /* Complexity Weight of 1 */ + unsigned int C_Extract_imag; /* Complexity Weight of 1 */ + unsigned int C_negate; /* Complexity Weight of 1 */ + unsigned int C_conjugate; /* Complexity Weight of 1 */ + unsigned int C_shr; /* Complexity Weight of 1 */ + unsigned int C_shl; /* Complexity Weight of 1 */ + +#endif /* #ifdef COMPLEX_OPERATOR */ + +/* New 64 bit basops */ +#ifdef ENH_64_BIT_OPERATOR + unsigned int move64; /* Complexity Weight of 1 */ + unsigned int W_add_nosat; /* Complexity Weight of 1 */ + unsigned int W_sub_nosat; /* Complexity Weight of 1 */ + unsigned int W_shl; /* Complexity Weight of 1 */ + unsigned int W_shr; /* Complexity Weight of 1 */ + unsigned int W_shl_nosat; /* Complexity Weight of 1 */ + unsigned int W_shr_nosat; /* Complexity Weight of 1 */ + unsigned int W_mac_32_16; /* Complexity Weight of 1 */ + unsigned int W_msu_32_16; /* Complexity Weight of 1 */ + unsigned int W_mult_32_16; /* Complexity Weight of 1 */ + unsigned int W_mult0_16_16; /* Complexity Weight of 1 */ + unsigned int W_mac0_16_16; /* Complexity Weight of 1 */ + unsigned int W_msu0_16_16; /* Complexity Weight of 1 */ + unsigned int W_mult_16_16; /* Complexity Weight of 1 */ + unsigned int W_mac_16_16; /* Complexity Weight of 1 */ + unsigned int W_msu_16_16; /* Complexity Weight of 1 */ + unsigned int W_shl_sat_l; /* Complexity Weight of 1 */ + unsigned int W_sat_l; /* Complexity Weight of 1 */ + unsigned int W_sat_m; /* Complexity Weight of 1 */ + unsigned int W_deposit32_l; /* Complexity Weight of 1 */ + unsigned int W_deposit32_h; /* Complexity Weight of 1 */ + unsigned int W_extract_l; /* Complexity Weight of 1 */ + unsigned int W_extract_h; /* Complexity Weight of 1 */ + unsigned int W_round48_L; /* Complexity Weight of 1 */ + unsigned int W_round32_s; /* Complexity Weight of 1 */ + unsigned int W_norm; /* Complexity Weight of 1 */ + + unsigned int W_add; /* Complexity Weight of 1 */ + unsigned int W_sub; /* Complexity Weight of 1 */ + unsigned int W_neg; /* Complexity Weight of 1 */ + unsigned int W_abs; /* Complexity Weight of 1 */ + unsigned int W_mult_32_32; /* Complexity Weight of 1 */ + unsigned int W_mult0_32_32; /* Complexity Weight of 1 */ + unsigned int W_lshl; /* Complexity Weight of 1 */ + unsigned int W_lshr; /* Complexity Weight of 1 */ + unsigned int W_round64_L; /* Complexity Weight of 1 */ + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + unsigned int Mpy_32_16_1; /* Complexity Weight of 1 */ + unsigned int Mpy_32_16_r; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32_r; /* Complexity Weight of 1 */ + unsigned int Madd_32_16; /* Complexity Weight of 1 */ + unsigned int Madd_32_16_r; /* Complexity Weight of 1 */ + unsigned int Msub_32_16; /* Complexity Weight of 1 */ + unsigned int Msub_32_16_r; /* Complexity Weight of 1 */ + unsigned int Madd_32_32; /* Complexity Weight of 1 */ + unsigned int Madd_32_32_r; /* Complexity Weight of 1 */ + unsigned int Msub_32_32; /* Complexity Weight of 1 */ + unsigned int Msub_32_32_r; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + unsigned int UL_addNs; /* Complexity Weight of 1 */ + unsigned int UL_subNs; /* Complexity Weight of 1 */ + unsigned int UL_Mpy_32_32; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32_uu; /* Complexity Weight of 2 */ + unsigned int Mpy_32_16_uu; /* Complexity Weight of 2 */ + unsigned int norm_ul_float; /* Complexity Weight of 1 */ + unsigned int UL_deposit_l; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + unsigned int LT_16; /* Complexity Weight of 1 */ + unsigned int GT_16; /* Complexity Weight of 1 */ + unsigned int LE_16; /* Complexity Weight of 1 */ + unsigned int GE_16; /* Complexity Weight of 1 */ + unsigned int EQ_16; /* Complexity Weight of 1 */ + unsigned int NE_16; /* Complexity Weight of 1 */ + unsigned int LT_32; /* Complexity Weight of 1 */ + unsigned int GT_32; /* Complexity Weight of 1 */ + unsigned int LE_32; /* Complexity Weight of 1 */ + unsigned int GE_32; /* Complexity Weight of 1 */ + unsigned int EQ_32; /* Complexity Weight of 1 */ + unsigned int NE_32; /* Complexity Weight of 1 */ + unsigned int LT_64; /* Complexity Weight of 1 */ + unsigned int GT_64; /* Complexity Weight of 1 */ + unsigned int LE_64; /* Complexity Weight of 1 */ + unsigned int GE_64; /* Complexity Weight of 1 */ + unsigned int EQ_64; /* Complexity Weight of 1 */ + unsigned int NE_64; /* Complexity Weight of 1 */ + +#endif /* #ifdef CONTROL_CODE_OPS */ } 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 unsigned int currCounter; extern long funcid_total_wmops_at_last_call_to_else; -extern int call_occurred; +extern char func_name_where_last_call_to_else_occurred[]; -extern long TotalWeightedOperation( void ); -long DeltaWeightedOperation( void ); - -void Set_BASOP_WMOPS_counter( int counterId ); -void Reset_BASOP_WMOPS_counter( void ); +long TotalWeightedOperation( unsigned int counterId ); +long DeltaWeightedOperation( unsigned int counterId ); +void Reset_BASOP_WMOPS_counter( unsigned int counterId ); #endif @@ -1216,15 +987,20 @@ void Reset_BASOP_WMOPS_counter( void ); * *****************************************************************************/ #ifndef WMOPS -#define FOR( a) for( a) +#define FOR( a ) for ( a ) -#else -#define FOR( a) if( incrFor(), 0); else for( a) +#else /* ifndef WMOPS */ +#define FOR( a ) \ + if ( incrFor(), 0 ) \ + ; \ + else \ + for ( a ) -static __inline void incrFor( void) { - multiCounter[currCounter].For++; +static __inline void incrFor( void ) +{ + multiCounter[currCounter].For++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1241,15 +1017,16 @@ static __inline void incrFor( void) { * *****************************************************************************/ #ifndef WMOPS -#define WHILE( a) while( a) +#define WHILE( a ) while ( a ) -#else -#define WHILE( a) while( incrWhile(), a) +#else /* ifndef WMOPS */ +#define WHILE( a ) while ( incrWhile(), a ) -static __inline void incrWhile( void) { - multiCounter[currCounter].While++; +static __inline void incrWhile( void ) +{ + multiCounter[currCounter].While++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1266,10 +1043,10 @@ static __inline void incrWhile( void) { #ifndef WMOPS #define DO do -#else +#else /* ifndef WMOPS */ #define DO do -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1289,29 +1066,16 @@ static __inline void incrWhile( void) { * - or when the 'if' conditions several DSP basic operations, * - or when the 'if' conditions a function call. * - * Complexity weight : 4 + * Complexity weight : 3 * *****************************************************************************/ -#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 +#ifndef WMOPS +#define IF( a ) if ( a ) +#else /* ifndef WMOPS */ +#define IF( a ) if ( incrIf( __func__ ), a ) +void incrIf( const char *func_name ); +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1322,33 +1086,18 @@ static __inline void incrIf( void) { * * The macro ELSE should be used instead of the 'else' C statement. * - * Complexity weight : 4 + * Complexity weight : 3 * *****************************************************************************/ + #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 +#else /* ifndef WMOPS */ +#define ELSE \ + else if ( incrElse( __func__ ), 0 ); \ + else +void incrElse( const char *func_name ); +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1359,19 +1108,20 @@ static __inline void incrElse( void) { * * The macro SWITCH should be used instead of the 'switch' C statement. * - * Complexity weight : 8 + * Complexity weight : 6 * *****************************************************************************/ #ifndef WMOPS -#define SWITCH( a) switch( a) +#define SWITCH( a ) switch ( a ) -#else -#define SWITCH( a) switch( incrSwitch(), a) +#else /* ifndef WMOPS */ +#define SWITCH( a ) switch ( incrSwitch(), a ) -static __inline void incrSwitch( void) { - multiCounter[currCounter].Switch++; +static __inline void incrSwitch( void ) +{ + multiCounter[currCounter].Switch++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1382,19 +1132,24 @@ static __inline void incrSwitch( void) { * * The macro CONTINUE should be used instead of the 'continue' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define CONTINUE continue -#else -#define CONTINUE if( incrContinue(), 0); else continue +#else /* ifndef WMOPS */ +#define CONTINUE \ + if ( incrContinue(), 0 ) \ + ; \ + else \ + continue -static __inline void incrContinue( void) { - multiCounter[currCounter].Continue++; +static __inline void incrContinue( void ) +{ + multiCounter[currCounter].Continue++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1405,19 +1160,24 @@ static __inline void incrContinue( void) { * * The macro BREAK should be used instead of the 'break' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define BREAK break -#else -#define BREAK if( incrBreak(), 0) break; else break +#else /* ifndef WMOPS */ +#define BREAK \ + if ( incrBreak(), 0 ) \ + ; \ + else \ + break -static __inline void incrBreak( void) { - multiCounter[currCounter].Break++; +static __inline void incrBreak( void ) +{ + multiCounter[currCounter].Break++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1428,21 +1188,50 @@ static __inline void incrBreak( void) { * * The macro GOTO should be used instead of the 'goto' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define GOTO goto -#else -#define GOTO if( incrGoto(), 0); else goto +#else /* ifndef WMOPS */ +#define GOTO \ + if ( incrGoto(), 0 ) \ + ; \ + else \ + goto -static __inline void incrGoto( void) { - multiCounter[currCounter].Goto++; +static __inline void incrGoto( void ) +{ + multiCounter[currCounter].Goto++; } -#endif +#endif /* ifndef WMOPS */ -#endif /* WMOPS_H */ +#ifdef CONTROL_CODE_OPS +extern int LT_16( short var1, short var2 ); +extern int GT_16( short var1, short var2 ); +extern int LE_16( short var1, short var2 ); +extern int GE_16( short var1, short var2 ); +extern int EQ_16( short var1, short var2 ); +extern int NE_16( short var1, short var2 ); +extern int LT_32( int L_var1, int L_var2 ); +extern int GT_32( int L_var1, int L_var2 ); +extern int LE_32( int L_var1, int L_var2 ); +extern int GE_32( int L_var1, int L_var2 ); +extern int EQ_32( int L_var1, int L_var2 ); +extern int NE_32( int L_var1, int L_var2 ); + +extern int LT_64( long long int L64_var1, long long int L64_var2 ); +extern int GT_64( long long int L64_var1, long long int L64_var2 ); +extern int LE_64( long long int L64_var1, long long int L64_var2 ); +extern int GE_64( long long int L64_var1, long long int L64_var2 ); +extern int EQ_64( long long int L64_var1, long long int L64_var2 ); +extern int NE_64( long long int L64_var1, long long int L64_var2 ); + +#endif /* #ifdef CONTROL_CODE_OPS */ + + +#endif /* WMOPS_H */ diff --git a/src/wmc_tool/wmc_auto_c.txt b/src/wmc_tool/wmc_auto_c.txt index 1b3b85e0..3f5c54bc 100644 --- a/src/wmc_tool/wmc_auto_c.txt +++ b/src/wmc_tool/wmc_auto_c.txt @@ -1,5 +1,5 @@ "/*\r\n", -" * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved.\r\n", +" * (C) 2024 copyright VoiceAge Corporation. All Rights Reserved.\r\n", " *\r\n", " * This software is protected by copyright law and by international treaties. The source code, and all of its derivations,\r\n", " * is provided by VoiceAge Corporation under the \"ITU-T Software Tools' General Public License\". Please, read the license file\r\n", @@ -16,7 +16,9 @@ "#include \r\n", "#include \r\n", "#include \r\n", +"#include \r\n", "#include \r\n", +"#include \r\n", "\r\n", "#ifndef _MSC_VER\r\n", "#include \r\n", @@ -25,27 +27,30 @@ "#include \r\n", "#endif\r\n", "\r\n", -"#include \"options.h\"\r\n", "#include \"wmc_auto.h\"\r\n", "\r\n", "#define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */\r\n", "\r\n", -"#ifdef WMOPS\r\n", +"#ifndef WMOPS\r\n", +"int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */\r\n", +"#endif\r\n", "\r\n", +"#ifdef WMOPS\r\n", "/*-------------------------------------------------------------------*\r\n", " * Complexity counting tool\r\n", " *--------------------------------------------------------------------*/\r\n", "\r\n", -"#define MAX_FUNCTION_NAME_LENGTH 50 /* Maximum length of the function name */\r\n", -"#define MAX_PARAMS_LENGTH 50 /* Maximum length of the function parameter string */\r\n", -"#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> mightb be increased during runtime, if needed */\r\n", +"#define MAX_FUNCTION_NAME_LENGTH 200 /* Maximum length of the function name */\r\n", +"#define MAX_PARAMS_LENGTH 200 /* Maximum length of the function parameter string */\r\n", +"#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> might be increased during runtime, if needed */\r\n", "#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */\r\n", "#define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */\r\n", "#define DOUBLE_MAX 0x80000000\r\n", +"#define FRAMES_PER_SECOND 50.0\r\n", "#define FAC ( FRAMES_PER_SECOND / 1e6 )\r\n", +"#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */\r\n", "\r\n", -"\r\n", -"typedef struct \r\n", +"typedef struct\r\n", "{\r\n", " char label[MAX_FUNCTION_NAME_LENGTH];\r\n", " long call_number;\r\n", @@ -57,7 +62,7 @@ " double max_selfcnt;\r\n", " double min_selfcnt;\r\n", " double tot_selfcnt;\r\n", -" double start_cnt; \r\n", +" double start_cnt; /* The following take into account the decendants */\r\n", " double current_cnt;\r\n", " double max_cnt;\r\n", " double min_cnt;\r\n", @@ -71,7 +76,6 @@ "} wmops_record;\r\n", "\r\n", "double ops_cnt;\r\n", -"double prom_cnt;\r\n", "double inst_cnt[NUM_INST];\r\n", "\r\n", "static wmops_record *wmops = NULL;\r\n", @@ -86,10 +90,73 @@ "static int *wmops_caller_stack = NULL, wmops_caller_stack_index, max_wmops_caller_stack_index = 0;\r\n", "static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0;\r\n", "\r\n", +"static BASIC_OP op_weight = {\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 2, 2, 1,\r\n", +" 1, 1, 1, 2, 1,\r\n", +"\r\n", +" 1, 1, 1, 2, 1,\r\n", +" 1, 1, 18, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 2, 2, 2, 2, 1,\r\n", +"\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 2,\r\n", +" 1, 2, 2, 2, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +"\r\n", +" 1, 1, 1, 1, 3,\r\n", +" 3, 3, 3, 1, 1,\r\n", +" 1, 1, 1, 1, 1,\r\n", +" 1, 1, 1, 3, 2,\r\n", +" 2, 6, 3, 3, 2,\r\n", +"\r\n", +" 1, 32, 1\r\n", +"\r\n", +"/* New complex basops */\r\n", +"#ifdef COMPLEX_OPERATOR\r\n", +" ,\r\n", +" 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1\r\n", +"\r\n", +" ,\r\n", +" 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1\r\n", +"\r\n", +"#endif /* #ifdef COMPLEX_OPERATOR */\r\n", +"\r\n", +"#ifdef ENH_64_BIT_OPERATOR\r\n", +" /* Weights of new 64 bit basops */\r\n", +" ,\r\n", +" 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\r\n", +"#endif /* #ifdef ENH_64_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef ENH_32_BIT_OPERATOR\r\n", +" ,\r\n", +" 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\r\n", +"#endif /* #ifdef ENH_32_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef ENH_U_32_BIT_OPERATOR\r\n", +" ,\r\n", +" 1, 1, 1, 2, 2, 1, 1\r\n", +"#endif /* #ifdef ENH_U_32_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef CONTROL_CODE_OPS\r\n", +" ,\r\n", +" 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\r\n", +"#endif /* #ifdef CONTROL_CODE_OPS */\r\n", +"};\r\n", +"\r\n", +"BASIC_OP *multiCounter = NULL;\r\n", +"unsigned int currCounter = 0;\r\n", +"long funcid_total_wmops_at_last_call_to_else;\r\n", +"char func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH + 1];\r\n", +"\r\n", "void reset_wmops( void )\r\n", "{\r\n", " int i, j;\r\n", -" unsigned int *ptr;\r\n", "\r\n", " num_wmops_records = 0;\r\n", " max_num_wmops_records = MAX_NUM_RECORDS;\r\n", @@ -101,10 +168,10 @@ " start_cnt = 0.0;\r\n", " ops_cnt = 0.0;\r\n", "\r\n", -" /* allocate the list of wmops records */\r\n", +" /* allocate the list of WMOPS records */\r\n", " if ( wmops == NULL )\r\n", " {\r\n", -" wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) );\r\n", +" wmops = (wmops_record *) malloc( max_num_wmops_records * sizeof( wmops_record ) );\r\n", " }\r\n", "\r\n", " if ( wmops == NULL )\r\n", @@ -113,7 +180,7 @@ " exit( -1 );\r\n", " }\r\n", "\r\n", -" /* allocate the BASOP WMOPS counter */\r\n", +" /* allocate the list of BASOP WMOPS records */\r\n", " if ( multiCounter == NULL )\r\n", " {\r\n", " multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) );\r\n", @@ -125,8 +192,8 @@ " exit( -1 );\r\n", " }\r\n", "\r\n", -" /* initilize the list of wmops records */\r\n", -" /* initilize the BASOP WMOPS counters */\r\n", +" /* initilize the list of WMOPS records */\r\n", +" /* initilize BASOP operation counters */\r\n", " for ( i = 0; i < max_num_wmops_records; i++ )\r\n", " {\r\n", " strcpy( &wmops[i].label[0], \"\\0\" );\r\n", @@ -153,13 +220,8 @@ " wmops[i].wc_call_number = -1;\r\n", "#endif\r\n", "\r\n", -" /* clear all BASOP operation counters */\r\n", -" ptr = (unsigned int*) &multiCounter[i];\r\n", -" for ( j = 0; j < (int) ( sizeof(BASIC_OP ) / sizeof( unsigned int ) ); j++ )\r\n", -" {\r\n", -" *ptr++ = 0;\r\n", -" }\r\n", -" wmops[i].LastWOper = 0;\r\n", +" /* Reset BASOP operation counter */\r\n", +" Reset_BASOP_WMOPS_counter( i );\r\n", " }\r\n", "\r\n", " /* allocate the list of wmops callers to track the sequence of function calls */\r\n", @@ -181,47 +243,83 @@ " wmops_caller_stack[i] = -1;\r\n", " }\r\n", "\r\n", -" /* initialize auxiliary BASOP WMOPS variables */\r\n", -" call_occurred = 1;\r\n", -" funcId_where_last_call_to_else_occurred = INT_MAX;\r\n", -"\r\n", " return;\r\n", "}\r\n", "\r\n", -"\r\n", -"void push_wmops( const char *label )\r\n", +"void push_wmops_fct( const char *label, ... )\r\n", "{\r\n", " int new_flag;\r\n", -" int i, j;\r\n", +" int i, j, index_record;\r\n", +" long tot;\r\n", +" va_list arg;\r\n", +" char func_name[MAX_FUNCTION_NAME_LENGTH] = \"\";\r\n", +"\r\n", +" /* concatenate all function name labels into a single string */\r\n", +" va_start( arg, label );\r\n", +" while ( label )\r\n", +" {\r\n", +" strcat( func_name, label );\r\n", +" label = va_arg( arg, const char * );\r\n", +" }\r\n", +" va_end( arg );\r\n", "\r\n", " /* Check, if this is a new function label */\r\n", " new_flag = 1;\r\n", " for ( i = 0; i < num_wmops_records; i++ )\r\n", " {\r\n", -" if ( strcmp( wmops[i].label, label ) == 0 )\r\n", +" if ( strcmp( wmops[i].label, func_name ) == 0 )\r\n", " {\r\n", " new_flag = 0;\r\n", " break;\r\n", " }\r\n", " }\r\n", +" index_record = i;\r\n", "\r\n", -" /* Create a new record in the list */\r\n", +" /* Create a new WMOPS record in the list */\r\n", " if ( new_flag )\r\n", " {\r\n", " if ( num_wmops_records >= max_num_wmops_records )\r\n", " {\r\n", -" /* There is no room for a new wmops record -> reallocate the list */\r\n", +" /* There is no room for a new WMOPS record -> reallocate the list */\r\n", " max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP;\r\n", " wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) );\r\n", " multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) );\r\n", " }\r\n", "\r\n", -" strcpy( wmops[i].label, label );\r\n", +" /* initilize the new WMOPS record */\r\n", +" strcpy( &wmops[index_record].label[0], \"\\0\" );\r\n", +" wmops[index_record].call_number = 0;\r\n", +" wmops[index_record].update_cnt = 0;\r\n", +" for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ )\r\n", +" {\r\n", +" wmops[index_record].call_tree[j] = -1;\r\n", +" }\r\n", +" wmops[index_record].start_selfcnt = 0.0;\r\n", +" wmops[index_record].current_selfcnt = 0.0;\r\n", +" wmops[index_record].max_selfcnt = 0.0;\r\n", +" wmops[index_record].min_selfcnt = DOUBLE_MAX;\r\n", +" wmops[index_record].tot_selfcnt = 0.0;\r\n", +" wmops[index_record].start_cnt = 0.0;\r\n", +" wmops[index_record].current_cnt = 0.0;\r\n", +" wmops[index_record].max_cnt = 0.0;\r\n", +" wmops[index_record].min_cnt = DOUBLE_MAX;\r\n", +" wmops[index_record].tot_cnt = 0.0;\r\n", +"#ifdef WMOPS_WC_FRAME_ANALYSIS\r\n", +" wmops[index_record].wc_cnt = 0.0;\r\n", +" wmops[index_record].wc_selfcnt = 0.0;\r\n", +" wmops[index_record].current_call_number = 0;\r\n", +" wmops[index_record].wc_call_number = -1;\r\n", +"#endif\r\n", +"\r\n", +" /* Reset BASOP operation counter */\r\n", +" Reset_BASOP_WMOPS_counter( index_record );\r\n", +"\r\n", +" strcpy( wmops[index_record].label, func_name );\r\n", "\r\n", " num_wmops_records++;\r\n", " }\r\n", "\r\n", -" /* Push the current context info to the new record */\r\n", +" /* Update the WMOPS context info of the old record before switching to the new one */\r\n", " if ( current_record >= 0 )\r\n", " {\r\n", " if ( wmops_caller_stack_index >= max_wmops_caller_stack_index )\r\n", @@ -232,40 +330,48 @@ " }\r\n", " wmops_caller_stack[wmops_caller_stack_index++] = current_record;\r\n", "\r\n", -" /* accumulate op counts */\r\n", +" /* add the BASOP complexity to the counter and update the old WMOPS counter */\r\n", +" tot = DeltaWeightedOperation( current_record );\r\n", +" ops_cnt += tot;\r\n", " wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt;\r\n", "\r\n", " /* update call tree */\r\n", " for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ )\r\n", " {\r\n", -" if ( wmops[i].call_tree[j] == current_record )\r\n", +" if ( wmops[index_record].call_tree[j] == current_record )\r\n", " {\r\n", " break;\r\n", " }\r\n", -" else if ( wmops[i].call_tree[j] == -1 )\r\n", +" else if ( wmops[index_record].call_tree[j] == -1 )\r\n", " {\r\n", -" wmops[i].call_tree[j] = current_record;\r\n", +" wmops[index_record].call_tree[j] = current_record;\r\n", " break;\r\n", " }\r\n", " }\r\n", " }\r\n", "\r\n", -" /* update the current context info */\r\n", -" current_record = i;\r\n", -" wmops[current_record].start_selfcnt = ops_cnt;\r\n", -" wmops[current_record].start_cnt = ops_cnt;\r\n", -" wmops[current_record].call_number++;\r\n", +" /* Need to reset the BASOP operation counter of the 0th record in every push_wmops() */\r\n", +" /* because currCounter can never be -1 */\r\n", +" if ( current_record == -1 && index_record == 0 )\r\n", +" {\r\n", +" wmops[index_record].LastWOper = TotalWeightedOperation( index_record );\r\n", +" }\r\n", +"\r\n", +" /* switch to the new record */\r\n", +" current_record = index_record;\r\n", +" wmops[index_record].start_selfcnt = ops_cnt;\r\n", +" wmops[index_record].start_cnt = ops_cnt;\r\n", +" wmops[index_record].call_number++;\r\n", "#ifdef WMOPS_WC_FRAME_ANALYSIS\r\n", -" wmops[current_record].current_call_number++;\r\n", +" wmops[index_record].current_call_number++;\r\n", "#endif\r\n", "\r\n", -" /* set the ID of BASOP functions counters */\r\n", -" Set_BASOP_WMOPS_counter( current_record );\r\n", +" /* set the ID of the current BASOP operations counter */\r\n", +" currCounter = index_record;\r\n", "\r\n", " return;\r\n", "}\r\n", "\r\n", -"\r\n", "void pop_wmops( void )\r\n", "{\r\n", " long tot;\r\n", @@ -278,10 +384,10 @@ " }\r\n", "\r\n", " /* add the BASOP complexity to the counter */\r\n", -" tot = DeltaWeightedOperation();\r\n", +" tot = DeltaWeightedOperation( currCounter );\r\n", " ops_cnt += tot;\r\n", "\r\n", -" /* update count of current record */\r\n", +" /* update count of current record */\r\n", " wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt;\r\n", " wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt;\r\n", "\r\n", @@ -290,15 +396,21 @@ " {\r\n", " current_record = wmops_caller_stack[--wmops_caller_stack_index];\r\n", " wmops[current_record].start_selfcnt = ops_cnt;\r\n", -"\r\n", -" /* set the ID of the previous BASOP counter */\r\n", -" Set_BASOP_WMOPS_counter( current_record );\r\n", " }\r\n", " else\r\n", " {\r\n", " current_record = -1;\r\n", " }\r\n", "\r\n", +" /* set the ID of the previous BASOP operations counter */\r\n", +" if ( current_record == -1 )\r\n", +" {\r\n", +" currCounter = 0; /* Note: currCounter cannot be set to -1 because it's defined as unsigned int ! */\r\n", +" }\r\n", +" else\r\n", +" {\r\n", +" currCounter = current_record;\r\n", +" }\r\n", "\r\n", " return;\r\n", "}\r\n", @@ -391,9 +503,8 @@ " wmops[i].current_call_number = 0;\r\n", "#endif\r\n", "\r\n", -" /* update the WC of all BASOP counters */\r\n", -" Set_BASOP_WMOPS_counter( i );\r\n", -" Reset_BASOP_WMOPS_counter();\r\n", +" /* reset the BASOP operations counter */\r\n", +" Reset_BASOP_WMOPS_counter( i );\r\n", " }\r\n", "\r\n", " current_cnt = ops_cnt - start_cnt;\r\n", @@ -427,15 +538,14 @@ " return;\r\n", "}\r\n", "\r\n", -"\r\n", "void print_wmops( void )\r\n", "{\r\n", " int i, label_len, max_label_len;\r\n", "\r\n", " char *sfmts = \"%*s %8s %8s %7s %7s\\n\";\r\n", " char *dfmts = \"%*s %8.2f %8.3f %7.3f %7.3f\\n\";\r\n", -" char *sfmt = \"%*s %8s %8s %7s %7s %7s %7s %7s\\n\";\r\n", -" char *dfmt = \"%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\\n\";\r\n", +" char *sfmt = \"%*s %8s %8s %7s %7s %7s %7s %7s\\n\";\r\n", +" char *dfmt = \"%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\\n\";\r\n", "\r\n", "#ifdef WMOPS_WC_FRAME_ANALYSIS\r\n", " int j;\r\n", @@ -456,7 +566,7 @@ " max_label_len += 4;\r\n", "\r\n", " fprintf( stdout, \"\\n\\n --- Complexity analysis [WMOPS] --- \\n\\n\" );\r\n", -" \r\n", +"\r\n", " fprintf( stdout, \"%*s %33s %23s\\n\", max_label_len, \"\", \"|------ SELF ------|\", \"|--- CUMULATIVE ---|\" );\r\n", " fprintf( stdout, sfmt, max_label_len, \" routine\", \" calls\", \" min \", \" max \", \" avg \", \" min \", \" max \", \" avg \" );\r\n", " fprintf( stdout, sfmt, max_label_len, \"---------------\", \"------\", \"------\", \"------\", \"------\", \"------\", \"------\", \"------\" );\r\n", @@ -478,7 +588,7 @@ "\r\n", "#ifdef WMOPS_WC_FRAME_ANALYSIS\r\n", " fprintf( stdout, \"\\nComplexity analysis for the worst-case frame %ld:\\n\\n\", fnum_cnt_wc );\r\n", -" fprintf( stdout, \"%*s %8s %10s %12s\\n\", max_label_len, \" routine\", \" calls\", \" SELF\", \" CUMULATIVE\" );\r\n", +" fprintf( stdout, \"%*s %8s %10s %12s\\n\", max_label_len, \" routine\", \" calls\", \" SELF\", \" CUMULATIVE\" );\r\n", " fprintf( stdout, \"%*s %8s %10s %10s\\n\", max_label_len, \"---------------\", \"------\", \"------\", \"----------\" );\r\n", "\r\n", " for ( i = 0; i < num_wmops_records; i++ )\r\n", @@ -512,7 +622,7 @@ "\r\n", " fprintf( stdout, \"\\n\\n\" );\r\n", "\r\n", -" fprintf( stdout, \"\\nInstruction type analysis for the worst-case frame %ld:\\n\\n\", fnum_cnt_wc ); \r\n", +" fprintf( stdout, \"\\nInstruction type analysis for the worst-case frame %ld:\\n\\n\", fnum_cnt_wc );\r\n", " for ( i = 0; i < NUM_INST; i++ )\r\n", " {\r\n", " switch ( (enum instructions) i )\r\n", @@ -604,7 +714,6 @@ " return;\r\n", "}\r\n", "\r\n", -"\r\n", "/*-------------------------------------------------------------------*\r\n", " * Memory counting tool measuring RAM usage (stack and heap)\r\n", " *\r\n", @@ -627,6 +736,7 @@ " * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free().\r\n", " *--------------------------------------------------------------------*/\r\n", "\r\n", +"\r\n", "/* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using\r\n", " a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */\r\n", "#ifdef MEM_ALIGN_64BITS\r\n", @@ -636,12 +746,14 @@ "#endif\r\n", "\r\n", "#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) )\r\n", -"#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) )\r\n", "\r\n", "#define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */\r\n", "#define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */\r\n", -"#define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */\r\n", -"#define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */\r\n", +"#define OOB_START 0x1 /* int indicating out-of-bounds access before memory block */\r\n", +"#define OOB_END 0x2 /* int indicating out-of-bounds access after memory block */\r\n", +"\r\n", +"#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) )\r\n", +"#define IS_CALLOC( str ) ( str[0] == 'c' )\r\n", "\r\n", "#ifdef MEM_COUNT_DETAILS\r\n", "const char *csv_filename = \"mem_analysis.csv\";\r\n", @@ -654,7 +766,7 @@ " int16_t *stack_ptr;\r\n", "} caller_info;\r\n", "\r\n", -"static caller_info *stack_callers[2] = {NULL, NULL};\r\n", +"static caller_info *stack_callers[2] = { NULL, NULL };\r\n", "\r\n", "static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */\r\n", "static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */\r\n", @@ -663,7 +775,6 @@ "static int current_calls = 0, max_num_calls = MAX_NUM_RECORDS;\r\n", "static char location_max_stack[256] = \"undefined\";\r\n", "\r\n", -"/* Heap-related variables */\r\n", "typedef struct\r\n", "{\r\n", " char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */\r\n", @@ -706,7 +817,6 @@ "\r\n", "void reset_mem( Counting_Size cnt_size )\r\n", "{\r\n", -" int16_t something;\r\n", " size_t tmp_size;\r\n", "\r\n", " /* initialize list of stack records */\r\n", @@ -726,7 +836,13 @@ " max_num_calls = MAX_NUM_RECORDS;\r\n", "\r\n", " /* initialize stack pointers */\r\n", +"#if defined( __GNUC__ ) || defined( __clang__ )\r\n", +" /* GCC/Clang: use builtin (works for many targets) */\r\n", +" ptr_base_stack = __builtin_frame_address( 0 );\r\n", +"#else\r\n", +" int16_t something;\r\n", " ptr_base_stack = &something;\r\n", +"#endif\r\n", " ptr_max_stack = ptr_base_stack;\r\n", " ptr_current_stack = ptr_base_stack;\r\n", "\r\n", @@ -831,10 +947,14 @@ "\r\n", "void reset_stack( void )\r\n", "{\r\n", -" int16_t something;\r\n", -"\r\n", " /* initialize/reset stack pointers */\r\n", +"#if defined( __GNUC__ ) || defined( __clang__ )\r\n", +" /* GCC/Clang: use builtin (works for many targets) */\r\n", +" ptr_base_stack = __builtin_frame_address( 0 );\r\n", +"#else\r\n", +" int16_t something;\r\n", " ptr_base_stack = &something;\r\n", +"#endif\r\n", " ptr_max_stack = ptr_base_stack;\r\n", " ptr_current_stack = ptr_base_stack;\r\n", "\r\n", @@ -849,10 +969,15 @@ "\r\n", "int push_stack( const char *filename, const char *fctname )\r\n", "{\r\n", -" int16_t something;\r\n", " int32_t current_stack_size;\r\n", "\r\n", -" ptr_current_stack = &something;\r\n", +"#if defined( __GNUC__ ) || defined( __clang__ )\r\n", +" /* GCC/Clang: use builtin (works for many targets) */\r\n", +" ptr_base_stack = __builtin_frame_address( 0 );\r\n", +"#else\r\n", +" int16_t something;\r\n", +" ptr_base_stack = &something;\r\n", +"#endif\r\n", "\r\n", " (void) *filename; /* to avoid compilation warning */\r\n", "\r\n", @@ -889,7 +1014,7 @@ "\r\n", " /* save the worst-case frame number */\r\n", " /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */\r\n", -" wc_stack_frame = update_cnt; \r\n", +" wc_stack_frame = update_cnt;\r\n", " strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 );\r\n", " location_max_stack[sizeof( location_max_stack ) - 1] = '\\0';\r\n", "\r\n", @@ -904,7 +1029,7 @@ " }\r\n", "\r\n", " /* Check, if This is the New Worst-Case RAM (stack + heap) */\r\n", -" current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) );\r\n", +" current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) );\r\n", "\r\n", " if ( current_stack_size < 0 )\r\n", " {\r\n", @@ -1097,7 +1222,7 @@ "\r\n", "#ifdef MEM_COUNT_DETAILS\r\n", " /* Export heap memory allocation record to the .csv file */\r\n", -" fprintf( fid_csv_filename, \"A,%d,%s,%d,%d\\n\", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size );\r\n", +" fprintf( fid_csv_filename, \"A,%ld,%s,%d,%d\\n\", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size );\r\n", "#endif\r\n", "\r\n", " if ( ptr_record->frame_allocated != -1 )\r\n", @@ -1112,7 +1237,7 @@ " current_heap_size += ptr_record->block_size;\r\n", "\r\n", " /* Check, if this is the new Worst-Case RAM (stack + heap) */\r\n", -" current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) );\r\n", +" current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) );\r\n", " if ( current_stack_size + current_heap_size > wc_ram_size )\r\n", " {\r\n", " wc_ram_size = current_stack_size + current_heap_size;\r\n", @@ -1395,8 +1520,8 @@ "/*-------------------------------------------------------------------*\r\n", " * mem_free()\r\n", " *\r\n", -" * This function de-allocatesd the memory block and frees the mphysical memory with free().\r\n", -" * It also updates actual and average usage of the memory block.\r\n", +" * This function de-allocates memory blocks and frees physical memory with free().\r\n", +" * It also updates the actual and average usage of memory blocks.\r\n", " *\r\n", " * Note: The record is not removed from the list and may be reused later on in mem_alloc()!\r\n", " *--------------------------------------------------------------------*/\r\n", @@ -1437,7 +1562,7 @@ "\r\n", "#ifdef MEM_COUNT_DETAILS\r\n", " /* Export heap memory de-allocation record to the .csv file */\r\n", -" fprintf( fid_csv_filename, \"D,%d,%s,%d,%d\\n\", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size );\r\n", +" fprintf( fid_csv_filename, \"D,%ld,%s,%d,%d\\n\", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size );\r\n", "#endif\r\n", "\r\n", " /* De-Allocate Memory Block */\r\n", @@ -1697,7 +1822,7 @@ " allocator_record *ptr_record, *ptr;\r\n", "\r\n", " /* Prepare format string */\r\n", -" sprintf( format_str, \"%%-%ds %%5s %%6s %%-%ds %%20s %%6s \", MAX_FUNCTION_NAME_LENGTH, MAX_PARAMS_LENGTH );\r\n", +" sprintf( format_str, \"%%-%d.%ds %%5.5s %%6.6s %%-%d.%ds %%20.20s %%6.6s \", 50, 50, 50, 50 );\r\n", "\r\n", " if ( n_items_wc_intra_frame_heap > 0 )\r\n", " {\r\n", @@ -1916,8 +2041,10 @@ " {\r\n", " fprintf( stdout, \"Error: Cannot retrieve or calculate Table ROM size of (%s)!\\n\", Const_Data_PROM_Table[i].file_spec );\r\n", " }\r\n", -"\r\n", -" fprintf( stdout, \"Table ROM (const data) size (%s): %d %s\\n\", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].Get_Const_Data_Size_Func() >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] );\r\n", +" else\r\n", +" {\r\n", +" fprintf( stdout, \"Table ROM (const data) size (%s): %d %s\\n\", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].Get_Const_Data_Size_Func() >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] );\r\n", +" }\r\n", " }\r\n", " }\r\n", " else\r\n", @@ -2064,109 +2191,339 @@ "\r\n", "#endif /* WMOPS */\r\n", "\r\n", -"#ifndef WMOPS\r\n", -"int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */\r\n", +"#ifdef CONTROL_CODE_OPS\r\n", +"\r\n", +"int LT_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( var1 < var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LT_16++;\r\n", "#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", +"int GT_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( var1 > var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", "#ifdef WMOPS\r\n", -"/* Global counter for the calculation of BASOP complexity */\r\n", -"BASIC_OP *multiCounter = NULL;\r\n", -"int currCounter = 0;\r\n", -"int funcId_where_last_call_to_else_occurred;\r\n", -"long funcid_total_wmops_at_last_call_to_else;\r\n", -"int call_occurred = 1;\r\n", +" multiCounter[currCounter].GT_16++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", -"BASIC_OP op_weight = {\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 2, 2, 1,\r\n", -" 1, 1, 1, 3, 1,\r\n", +"int LE_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", "\r\n", -" 1, 1, 1, 3, 1,\r\n", -" 4, 1, 18, 1, 1,\r\n", -" 2, 1, 2, 2, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 3, 3, 3, 3, 1,\r\n", +" if ( var1 <= var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LE_16++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 1, 2,\r\n", -" 1, 2, 2, 4, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", +"int GE_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", "\r\n", -" 1, 1, 1, 1, 3,\r\n", -" 3, 3, 3, 3, 1,\r\n", -" 1, 1, 1, 1, 1,\r\n", -" 1, 1, 1, 4, 4,\r\n", -" 4, 8, 3, 4, 4,\r\n", +" if ( var1 >= var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].GE_16++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", -" 5, 32, 3\r\n", -"};\r\n", +"int EQ_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( var1 == var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].EQ_16++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int NE_16( short var1, short var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( var1 != var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].NE_16++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int LT_32( int L_var1, int L_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 < L_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LT_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int GT_32( int L_var1, int L_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 > L_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].GT_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", -"/* Set the counter group to use, default is zero */\r\n", -"void Set_BASOP_WMOPS_counter( int counterId )\r\n", +"int LE_32( int L_var1, int L_var2 )\r\n", "{\r\n", -" if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) )\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 <= L_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LE_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int GE_32( int L_var1, int L_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 >= L_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].GE_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int EQ_32( int L_var1, int L_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 == L_var2 )\r\n", " {\r\n", -" currCounter = 0;\r\n", -" return;\r\n", +" F_ret = 1;\r\n", " }\r\n", -" currCounter = counterId;\r\n", -" call_occurred = 1;\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].EQ_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", "}\r\n", "\r\n", -"extern int32_t frame;\r\n", +"int NE_32( int L_var1, int L_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L_var1 != L_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].NE_32++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", "\r\n", -"long TotalWeightedOperation()\r\n", +"int LT_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 < L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LT_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int GT_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 > L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].GT_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int LE_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 <= L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].LE_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"int GE_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 >= L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].GE_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"int EQ_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 == L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].EQ_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"int NE_64( long long int L64_var1, long long int L64_var2 )\r\n", +"{\r\n", +" int F_ret = 0;\r\n", +"\r\n", +" if ( L64_var1 != L64_var2 )\r\n", +" {\r\n", +" F_ret = 1;\r\n", +" }\r\n", +"#ifdef WMOPS\r\n", +" multiCounter[currCounter].NE_64++;\r\n", +"#endif\r\n", +" return F_ret;\r\n", +"}\r\n", +"\r\n", +"#endif /* #ifdef CONTROL_CODE_OPS */\r\n", +"\r\n", +"#ifdef WMOPS\r\n", +"\r\n", +"void incrIf( const char *func_name )\r\n", +"{\r\n", +" /* Technical note: If the \"IF\" operator comes just after an \"ELSE\", its counter must not be incremented */\r\n", +" /* The following auxiliary variables are used to check if the \"IF\" operator doesn't immediately follow an \"ELSE\" operator */\r\n", +" if ( ( strncmp( func_name, func_name_where_last_call_to_else_occurred, MAX_FUNCTION_NAME_LENGTH ) != 0 ) || ( TotalWeightedOperation( currCounter ) != funcid_total_wmops_at_last_call_to_else ) )\r\n", +" {\r\n", +"\r\n", +" multiCounter[currCounter].If++;\r\n", +" }\r\n", +"\r\n", +" func_name_where_last_call_to_else_occurred[0] = '\\0';\r\n", +"}\r\n", +"\r\n", +"void incrElse( const char *func_name )\r\n", +"{\r\n", +" multiCounter[currCounter].If++;\r\n", +"\r\n", +" /* Save the BASOP comeplxity in the last call of the ELSE() statement */\r\n", +" funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation( currCounter );\r\n", +"\r\n", +" /* We keep track of the name of the last calling function when the ELSE macro was called */\r\n", +" strncpy( func_name_where_last_call_to_else_occurred, func_name, MAX_FUNCTION_NAME_LENGTH );\r\n", +" func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH] = '\\0';\r\n", +"}\r\n", +"\r\n", +"long TotalWeightedOperation( unsigned int CounterId )\r\n", "{\r\n", " int i;\r\n", " unsigned int *ptr, *ptr2;\r\n", -" long tot; \r\n", +" long tot;\r\n", "\r\n", " tot = 0;\r\n", -" ptr = (unsigned int *) &multiCounter[currCounter];\r\n", +" ptr = (unsigned int *) &multiCounter[CounterId];\r\n", " ptr2 = (unsigned int *) &op_weight;\r\n", "\r\n", -" for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ )\r\n", +" for ( i = 0; i < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); i++ )\r\n", " {\r\n", +" if ( *ptr == UINT_MAX )\r\n", +" {\r\n", +" printf( \"\\nError in BASOP complexity counters: multiCounter[%d][%d] = %d !!!\\n\", CounterId, i, *ptr );\r\n", +" exit( -1 );\r\n", +" }\r\n", +"\r\n", " tot += ( ( *ptr++ ) * ( *ptr2++ ) );\r\n", " }\r\n", "\r\n", " return ( tot );\r\n", "}\r\n", "\r\n", -"long DeltaWeightedOperation( void )\r\n", +"long DeltaWeightedOperation( unsigned int CounterId )\r\n", "{\r\n", " long NewWOper, delta;\r\n", "\r\n", -" NewWOper = TotalWeightedOperation();\r\n", +" NewWOper = TotalWeightedOperation( CounterId );\r\n", "\r\n", -" delta = NewWOper - wmops[currCounter].LastWOper;\r\n", -" wmops[currCounter].LastWOper = NewWOper;\r\n", +" delta = NewWOper - wmops[CounterId].LastWOper;\r\n", +" wmops[CounterId].LastWOper = NewWOper;\r\n", "\r\n", " return ( delta );\r\n", "}\r\n", "\r\n", -"/* Resets the current BASOP WMOPS counter */\r\n", -"void Reset_BASOP_WMOPS_counter( void )\r\n", +"/* Resets BASOP operation counter */\r\n", +"void Reset_BASOP_WMOPS_counter( unsigned int counterId )\r\n", "{\r\n", " int i;\r\n", -" long *ptr;\r\n", +" unsigned int *ptr;\r\n", "\r\n", -" /* clear the current BASOP operation counter before new frame begins */\r\n", -" ptr = (long *) &multiCounter[currCounter];\r\n", -" for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( long ) ); i++ )\r\n", +" /* reset the current BASOP operation counter */\r\n", +" ptr = (unsigned int *) &multiCounter[counterId];\r\n", +" for ( i = 0; i < (int) (sizeof(BASIC_OP) / sizeof(unsigned int)); i++ )\r\n", " {\r\n", " *ptr++ = 0;\r\n", " }\r\n", "\r\n", -" wmops[currCounter].LastWOper = 0;\r\n", +" wmops[counterId].LastWOper = 0;\r\n", "\r\n", " return;\r\n", "}\r\n", "\r\n", "#endif\r\n", -"\r\n", -"\r\n", -"\r\n", \ No newline at end of file diff --git a/src/wmc_tool/wmc_auto_h.txt b/src/wmc_tool/wmc_auto_h.txt index caed2709..a6963abf 100644 --- a/src/wmc_tool/wmc_auto_h.txt +++ b/src/wmc_tool/wmc_auto_h.txt @@ -1,5 +1,5 @@ "/*\r\n", -" * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved.\r\n", +" * (C) 2024 copyright VoiceAge Corporation. All Rights Reserved.\r\n", " *\r\n", " * This software is protected by copyright law and by international treaties. The source code, and all of its derivations,\r\n", " * is provided by VoiceAge Corporation under the \"ITU-T Software Tools' General Public License\". Please, read the license file\r\n", @@ -23,18 +23,17 @@ "#include /* stdio is needed for fprintf() */\r\n", "#endif\r\n", "\r\n", -"\r\n", "/* To Prevent \"warning: '$' in identifier or number\" message under GCC */\r\n", "#ifdef __GNUC__\r\n", "#pragma GCC system_header\r\n", "#endif\r\n", "\r\n", -"#ifndef INT_MAX\r\n", -"#define INT_MAX 32767\r\n", -"#endif\r\n", -"\r\n", -"#define FRAMES_PER_SECOND 50.0 \r\n", -"#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */\r\n", +"#define ENH_32_BIT_OPERATOR\r\n", +"#define ENH_64_BIT_OPERATOR\r\n", +"#define ENH_U_32_BIT_OPERATOR\r\n", +"#define COMPLEX_OPERATOR\r\n", +"#define CONTROL_CODE_OPS /* enable control code operators such as LT_16, GT_16, ... */\r\n", +"/* #define WMOPS_DISABLE_FCN_CALL_PENALIZATION*/ /* do not count the complexity of function calls */\r\n", "\r\n", "#ifdef WMOPS\r\n", "enum instructions\r\n", @@ -62,6 +61,30 @@ " NUM_INST\r\n", "};\r\n", "\r\n", +"extern double ops_cnt;\r\n", +"extern double inst_cnt[NUM_INST];\r\n", +"\r\n", +"/******************************************************************/\r\n", +"/* NOTES: */\r\n", +"/* The 'wmc_flag_' flag is global to avoid declaration in every */\r\n", +"/* function and 'static' to avoid clashing with other modules */\r\n", +"/* that include this header file. */\r\n", +"/* */\r\n", +"/* The declarations of 'wmc_flag_' and 'wops_' in this header */\r\n", +"/* file prevent the addition of a 'C' file to the Project. */\r\n", +"/******************************************************************/\r\n", +"\r\n", +"/* General Purpose Global int */\r\n", +"static int wmc_flag_ = 0;\r\n", +"\r\n", +"#define push_wmops( ... ) push_wmops_fct( __VA_ARGS__, NULL )\r\n", +"void push_wmops_fct( const char *label, ... );\r\n", +"void pop_wmops( void );\r\n", +"void reset_wmops( void );\r\n", +"void print_wmops( void );\r\n", +"void update_wmops( void );\r\n", +"void update_mem( void );\r\n", +"\r\n", "#define _ADD_C 1\r\n", "#define _ABS_C 1\r\n", "#define _MULT_C 1\r\n", @@ -83,501 +106,167 @@ "#define _LOG_C 25\r\n", "#define _MISC_C 1\r\n", "\r\n", -"#define _ADD_P 1\r\n", -"#define _ABS_P 1\r\n", -"#define _MULT_P 1\r\n", -"#define _MAC_P 1\r\n", -"#define _MOVE_P 1\r\n", -"#define _STORE_P 0\r\n", -"#define _LOGIC_P 1\r\n", -"#define _SHIFT_P 1\r\n", -"#define _BRANCH_P 2\r\n", -"#define _DIV_P 2\r\n", -"#define _SQRT_P 2\r\n", -"#define _TRANS_P 2\r\n", -"#define _FUNC_P 2 /* need to add number of arguments */\r\n", -"#define _LOOP_P 1\r\n", -"#define _INDIRECT_P 2\r\n", -"#define _PTR_INIT_P 1\r\n", -"#define _TEST_P 1\r\n", -"#define _POWER_P 2\r\n", -"#define _LOG_P 2\r\n", -"#define _MISC_P 1\r\n", -"\r\n", -"#define ADD( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _ADD_C * ( x ) ); \\\r\n", -" inst_cnt[_ADD] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _ADD_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define ADD( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _ADD_C * ( x ) ); \\\r\n", +" inst_cnt[_ADD] += ( x ); \\\r\n", " }\r\n", -"#define ABS( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _ABS_C * ( x ) ); \\\r\n", -" inst_cnt[_ABS] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _ABS_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define ABS( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _ABS_C * ( x ) ); \\\r\n", +" inst_cnt[_ABS] += ( x ); \\\r\n", " }\r\n", -"#define MULT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _MULT_C * ( x ) ); \\\r\n", -" inst_cnt[_MULT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MULT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define MULT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _MULT_C * ( x ) ); \\\r\n", +" inst_cnt[_MULT] += ( x ); \\\r\n", " }\r\n", -"#define MAC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _MAC_C * ( x ) ); \\\r\n", -" inst_cnt[_MAC] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MAC_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define MAC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _MAC_C * ( x ) ); \\\r\n", +" inst_cnt[_MAC] += ( x ); \\\r\n", " }\r\n", -"#define MOVE( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _MOVE_C * ( x ) ); \\\r\n", -" inst_cnt[_MOVE] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MOVE_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define MOVE( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _MOVE_C * ( x ) ); \\\r\n", +" inst_cnt[_MOVE] += ( x ); \\\r\n", " }\r\n", -"#define STORE( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _STORE_C * ( x ) ); \\\r\n", -" inst_cnt[_STORE] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _STORE_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define STORE( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _STORE_C * ( x ) ); \\\r\n", +" inst_cnt[_STORE] += ( x ); \\\r\n", " }\r\n", -"#define LOGIC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _LOGIC_C * ( x ) ); \\\r\n", -" inst_cnt[_LOGIC] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _LOGIC_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define LOGIC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _LOGIC_C * ( x ) ); \\\r\n", +" inst_cnt[_LOGIC] += ( x ); \\\r\n", " }\r\n", -"#define SHIFT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _SHIFT_C * ( x ) ); \\\r\n", -" inst_cnt[_SHIFT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _SHIFT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define SHIFT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _SHIFT_C * ( x ) ); \\\r\n", +" inst_cnt[_SHIFT] += ( x ); \\\r\n", " }\r\n", -"#define BRANCH( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _BRANCH_C * ( x ) ); \\\r\n", -" inst_cnt[_BRANCH] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _BRANCH_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define BRANCH( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _BRANCH_C * ( x ) ); \\\r\n", +" inst_cnt[_BRANCH] += ( x ); \\\r\n", " }\r\n", -"#define DIV( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _DIV_C * ( x ) ); \\\r\n", -" inst_cnt[_DIV] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _DIV_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DIV( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _DIV_C * ( x ) ); \\\r\n", +" inst_cnt[_DIV] += ( x ); \\\r\n", " }\r\n", -"#define SQRT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _SQRT_C * ( x ) ); \\\r\n", -" inst_cnt[_SQRT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _SQRT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define SQRT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _SQRT_C * ( x ) ); \\\r\n", +" inst_cnt[_SQRT] += ( x ); \\\r\n", " }\r\n", -"#define TRANS( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _TRANS_C * ( x ) ); \\\r\n", -" inst_cnt[_TRANS] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _TRANS_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define TRANS( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _TRANS_C * ( x ) ); \\\r\n", +" inst_cnt[_TRANS] += ( x ); \\\r\n", " }\r\n", -"#define LOOP( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _LOOP_C * ( x ) ); \\\r\n", -" inst_cnt[_LOOP] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _LOOP_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define LOOP( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _LOOP_C * ( x ) ); \\\r\n", +" inst_cnt[_LOOP] += ( x ); \\\r\n", " }\r\n", -"#define INDIRECT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _INDIRECT_C * ( x ) ); \\\r\n", -" inst_cnt[_INDIRECT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _INDIRECT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define INDIRECT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _INDIRECT_C * ( x ) ); \\\r\n", +" inst_cnt[_INDIRECT] += ( x ); \\\r\n", " }\r\n", -"#define PTR_INIT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _PTR_INIT_C * ( x ) ); \\\r\n", -" inst_cnt[_PTR_INIT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _PTR_INIT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define PTR_INIT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _PTR_INIT_C * ( x ) ); \\\r\n", +" inst_cnt[_PTR_INIT] += ( x ); \\\r\n", " }\r\n", -"#define TEST( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _TEST_C * ( x ) ); \\\r\n", -" inst_cnt[_TEST] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _TEST_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define TEST( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _TEST_C * ( x ) ); \\\r\n", +" inst_cnt[_TEST] += ( x ); \\\r\n", " }\r\n", -"#define POWER( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _POWER_C * ( x ) ); \\\r\n", -" inst_cnt[_POWER] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _POWER_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define POWER( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _POWER_C * ( x ) ); \\\r\n", +" inst_cnt[_POWER] += ( x ); \\\r\n", " }\r\n", -"#define LOG( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _LOG_C * ( x ) ); \\\r\n", -" inst_cnt[_LOG] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _LOG_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define LOG( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _LOG_C * ( x ) ); \\\r\n", +" inst_cnt[_LOG] += ( x ); \\\r\n", " }\r\n", -"#define MISC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _MISC_C * ( x ) ); \\\r\n", -" inst_cnt[_MISC] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MISC_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define MISC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _MISC_C * ( x ) ); \\\r\n", +" inst_cnt[_MISC] += ( x ); \\\r\n", " }\r\n", -"\r\n", -"#define FUNC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \\\r\n", -" inst_cnt[_FUNC]++; \\\r\n", -" inst_cnt[_MOVE] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _FUNC_P + _MOVE_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define FUNC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \\\r\n", +" inst_cnt[_FUNC]++; \\\r\n", +" inst_cnt[_MOVE] += ( x ); \\\r\n", " }\r\n", -"\r\n", -"#define DADD( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _ADD_C * ( x ) ); \\\r\n", -" inst_cnt[_ADD] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _ADD_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DADD( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _ADD_C * ( x ) ); \\\r\n", +" inst_cnt[_ADD] += ( x ); \\\r\n", " }\r\n", -"#define DMULT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _MULT_C * ( x ) ); \\\r\n", -" inst_cnt[_MULT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MULT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DMULT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _MULT_C * ( x ) ); \\\r\n", +" inst_cnt[_MULT] += ( x ); \\\r\n", " }\r\n", -"#define DMAC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _MAC_C * ( x ) ); \\\r\n", -" inst_cnt[_MAC] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MAC_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DMAC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _MAC_C * ( x ) ); \\\r\n", +" inst_cnt[_MAC] += ( x ); \\\r\n", " }\r\n", -"#define DMOVE( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _MOVE_C * ( x ) ); \\\r\n", -" inst_cnt[_MOVE] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _MOVE_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DMOVE( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _MOVE_C * ( x ) ); \\\r\n", +" inst_cnt[_MOVE] += ( x ); \\\r\n", " }\r\n", -"#define DSTORE( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _STORE_C * ( x ) ); \\\r\n", -" inst_cnt[_STORE] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _STORE_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DSTORE( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _STORE_C * ( x ) ); \\\r\n", +" inst_cnt[_STORE] += ( x ); \\\r\n", " }\r\n", -"#define DLOGIC( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \\\r\n", -" inst_cnt[_LOGIC] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _LOGIC_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DLOGIC( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \\\r\n", +" inst_cnt[_LOGIC] += ( x ); \\\r\n", " }\r\n", -"#define DSHIFT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \\\r\n", -" inst_cnt[_SHIFT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _SHIFT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DSHIFT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \\\r\n", +" inst_cnt[_SHIFT] += ( x ); \\\r\n", " }\r\n", -"#define DDIV( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _DIV_C * ( x ) ); \\\r\n", -" inst_cnt[_DIV] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _DIV_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DDIV( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _DIV_C * ( x ) ); \\\r\n", +" inst_cnt[_DIV] += ( x ); \\\r\n", " }\r\n", -"#define DSQRT( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _SQRT_C * ( x ) ); \\\r\n", -" inst_cnt[_SQRT] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _SQRT_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DSQRT( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _SQRT_C * ( x ) ); \\\r\n", +" inst_cnt[_SQRT] += ( x ); \\\r\n", " }\r\n", -"#define DTRANS( x ) \\\r\n", -" { \\\r\n", -" { \\\r\n", -" ops_cnt += ( 2 * _TRANS_C * ( x ) ); \\\r\n", -" inst_cnt[_TRANS] += ( x ); \\\r\n", -" { \\\r\n", -" static int pcnt; \\\r\n", -" if ( !pcnt ) \\\r\n", -" { \\\r\n", -" pcnt = 1; \\\r\n", -" prom_cnt += ( _TRANS_P * ( x ) ); \\\r\n", -" } \\\r\n", -" } \\\r\n", -" } \\\r\n", +"#define DTRANS( x ) \\\r\n", +" { \\\r\n", +" ops_cnt += ( 2 * _TRANS_C * ( x ) ); \\\r\n", +" inst_cnt[_TRANS] += ( x ); \\\r\n", " }\r\n", "\r\n", -"extern double ops_cnt;\r\n", -"extern double prom_cnt;\r\n", -"extern double inst_cnt[NUM_INST];\r\n", -"\r\n", -"void reset_wmops( void );\r\n", -"void push_wmops( const char *label );\r\n", -"void pop_wmops( void );\r\n", -"void update_wmops( void );\r\n", -"void update_mem( void );\r\n", -"void print_wmops( void );\r\n", -"\r\n", -"#else /* WMOPS counting disabled */\r\n", +"#else\r\n", "\r\n", -"#define reset_wmops()\r\n", "extern int cntr_push_pop;\r\n", "#define push_wmops( x ) ( cntr_push_pop++ )\r\n", "#define pop_wmops() ( cntr_push_pop-- )\r\n", -"#define update_wmops() ( assert( cntr_push_pop == 0 ) )\r\n", -"#define update_mem()\r\n", +"#define reset_wmops()\r\n", "#define print_wmops()\r\n", +"#define update_wmops() ( assert( cntr_push_pop == 0 ) )\r\n", +"#define update_mem()\r\n", "\r\n", "#define ADD( x )\r\n", "#define ABS( x )\r\n", @@ -628,24 +317,8 @@ "\r\n", "#else\r\n", "\r\n", -"/* '*ops_cnt_ptr' is Used to Avoid: \"warning: operation on 'ops_cnt' may be undefined\" with Cygwin gcc Compiler */\r\n", -"static double *ops_cnt_ptr = &ops_cnt;\r\n", -"#define OP_COUNT_( op, x ) ( *ops_cnt_ptr += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) )\r\n", -"\r\n", -"/******************************************************************/\r\n", -"/* NOTES: */\r\n", -"/* The 'wmc_flag_' flag is global to avoid declaration in every */\r\n", -"/* function and 'static' to avoid clashing with other modules */\r\n", -"/* that include this header file. */\r\n", -"/* */\r\n", -"/* The declarations of 'wmc_flag_' and 'wops_' in this header */\r\n", -"/* file prevent the addition of a 'C' file to the Project. */\r\n", -"/******************************************************************/\r\n", -"\r\n", -"/* General Purpose Global Flag */\r\n", -"static int wmc_flag_ = 0;\r\n", -"\r\n", "/* Operation Counter Wrappers */\r\n", +"#define OP_COUNT_( op, x ) ( ops_cnt += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) )\r\n", "#define OP_COUNT_WRAPPER1_( op, val ) ( op, val )\r\n", "#define OP_COUNT_WRAPPER2_( expr ) \\\r\n", " if ( expr, 0 ) \\\r\n", @@ -677,8 +350,12 @@ "#define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) )\r\n", "#define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) )\r\n", "#define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) )\r\n", -"#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) )\r\n", -"#define MISC_( x ) ABS_( x )\r\n", +"#ifdef WMOPS_DISABLE_FCN_CALL_PENALIZATION\r\n", +"#define FUNC_( x ) ( x )\r\n", +"#else\r\n", +"#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) )\r\n", +"#endif\r\n", +"#define MISC_( x ) ABS_( x )\r\n", "\r\n", "/* Math Operations */\r\n", "#define abs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), abs )\r\n", @@ -723,8 +400,8 @@ "#define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf )\r\n", "\r\n", "/* the macros below are instrumented versions of user-defined macros that might be used in the source code \r\n", -"/* representing some well-known and recognized mathematical operations (that are not defined in math.h) */\r\n", -"/* Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */\r\n", +" representing some well-known and recognized mathematical operations (that are not defined in math.h) \r\n", +" Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */\r\n", "\r\n", "#define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) )\r\n", "#define max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), max( ( a ), ( b ) ) )\r\n", @@ -744,8 +421,8 @@ "#define inv_sqrt_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrt( ( x ) ) )\r\n", "#define inv_sqrtf_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrtf( ( x ) ) )\r\n", "#define log_base_2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log_base_2( ( x ) ) )\r\n", -"#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) )\r\n", -"#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) )\r\n", +"#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) )\r\n", +"#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) )\r\n", "#define log2_f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2_f( ( x ) ) )\r\n", "#define _round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, _round( ( x ) ) )\r\n", "#define round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, round( ( x ) ) )\r\n", @@ -795,7 +472,6 @@ "#define return_ \\\r\n", " OP_COUNT_WRAPPER2_( ( wmc_flag_ = stack_tree_level_, STACK_DEPTH_FCT_RETURN ) ) \\\r\n", " return\r\n", -"\r\n", "#define switch_ \\\r\n", " OP_COUNT_WRAPPER2_( ( BRANCH_( 1 ), wmc_flag_ = 1 ) ) \\\r\n", " switch\r\n", @@ -911,7 +587,6 @@ " /* This Shouldn't Happen */\r\n", " /* These are Used to Avoid: \"warning: 'name' defined but not used\" with Cygwin gcc Compiler */\r\n", " wmc_flag_ = wmc_flag_;\r\n", -" ops_cnt_ptr = ops_cnt_ptr;\r\n", " fct( \"\" );\r\n", " error:\r\n", " default:\r\n", @@ -973,7 +648,7 @@ " * ROM_Size_Lookup_Table Const_Data_PROM_Table[] =\r\n", " * {\r\n", " * {\"../lib_enc/rom_enc.c\", 0, NULL},\r\n", -" * {\"../lib_com/*.c\", 0, NULL},\r\n", +" * {\"../lib_com/[star].c\", 0, NULL},\r\n", " * {\"\", -1, NULL}\r\n", " * };\r\n", " * #endif\r\n", @@ -986,22 +661,9 @@ "{\r\n", " USE_BYTES = 0,\r\n", " USE_16BITS = 1,\r\n", -" USE_32BITS = 2,\r\n", -" USE_64BITS = 3\r\n", +" USE_32BITS = 2\r\n", "} Counting_Size;\r\n", "\r\n", -"#if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) )\r\n", -"#define __func__ __FUNCTION__\r\n", -"#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ < 199901L\r\n", -"#if ( __GNUC__ >= 2 )\r\n", -"#define __func__ __FUNCTION__\r\n", -"#else\r\n", -"#define __func__ \"\"\r\n", -"#endif\r\n", -"#elif defined( __GNUC__ )\r\n", -"#define __func__ __extension__ __FUNCTION__\r\n", -"#endif\r\n", -"\r\n", "\r\n", "#ifdef WMOPS\r\n", "\r\n", @@ -1019,11 +681,11 @@ "int pop_stack( const char *filename, const char *fctname );\r\n", "\r\n", "#ifdef WMOPS_DETAIL\r\n", -"#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ \" [WMC_AUTO]\" ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */\r\n", -"#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */\r\n", +"#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, \"[WMC_AUTO]\" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */\r\n", +"#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */\r\n", "#else\r\n", -"#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ )\r\n", -"#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __FUNCTION__ )\r\n", +"#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __func__ )\r\n", +"#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ )\r\n", "#endif\r\n", "\r\n", "void reset_stack( void );\r\n", @@ -1043,7 +705,6 @@ "\r\n", "#endif\r\n", "\r\n", -"\r\n", "/* Global counter variable for calculation of complexity weight */\r\n", "typedef struct\r\n", "{\r\n", @@ -1101,10 +762,10 @@ " unsigned int L40_max; /* Complexity Weight of 1 */\r\n", " unsigned int L40_min; /* Complexity Weight of 1 */\r\n", "\r\n", -" unsigned int shl_r; /* Complexity Weight of 3 */\r\n", -" unsigned int L_shl_r; /* Complexity Weight of 3 */\r\n", -" unsigned int L40_shr_r; /* Complexity Weight of 3 */\r\n", -" unsigned int L40_shl_r; /* Complexity Weight of 3 */\r\n", +" unsigned int shl_r; /* Complexity Weight of 2 */\r\n", +" unsigned int L_shl_r; /* Complexity Weight of 2 */\r\n", +" unsigned int L40_shr_r; /* Complexity Weight of 2 */\r\n", +" unsigned int L40_shl_r; /* Complexity Weight of 2 */\r\n", " unsigned int norm_L40; /* Complexity Weight of 1 */\r\n", "\r\n", " unsigned int L40_shl; /* Complexity Weight of 1 */\r\n", @@ -1121,7 +782,7 @@ " unsigned int L40_msu; /* Complexity Weight of 1 */\r\n", " unsigned int msu_r40; /* Complexity Weight of 2 */\r\n", " unsigned int Mpy_32_16_ss; /* Complexity Weight of 2 */\r\n", -" unsigned int Mpy_32_32_ss; /* Complexity Weight of 4 */\r\n", +" unsigned int Mpy_32_32_ss; /* Complexity Weight of 2 */\r\n", " unsigned int L_mult0; /* Complexity Weight of 1 */\r\n", "\r\n", " unsigned int L_mac0; /* Complexity Weight of 1 */\r\n", @@ -1145,7 +806,7 @@ " unsigned int rotr; /* Complexity Weight of 3 */\r\n", " unsigned int L_rotl; /* Complexity Weight of 3 */\r\n", " unsigned int L_rotr; /* Complexity Weight of 3 */\r\n", -" unsigned int L40_set; /* Complexity Weight of 3 */\r\n", +" unsigned int L40_set; /* Complexity Weight of 1 */\r\n", " unsigned int L40_deposit_h; /* Complexity Weight of 1 */\r\n", "\r\n", " unsigned int L40_deposit_l; /* Complexity Weight of 1 */\r\n", @@ -1157,48 +818,158 @@ " unsigned int L40_round; /* Complexity Weight of 1 */\r\n", " unsigned int L_saturate40; /* Complexity Weight of 1 */\r\n", " unsigned int round40; /* Complexity Weight of 1 */\r\n", -" unsigned int If; /* Complexity Weight of 4 */\r\n", -" unsigned int Goto; /* Complexity Weight of 4 */\r\n", +" unsigned int If; /* Complexity Weight of 3 */\r\n", +" unsigned int Goto; /* Complexity Weight of 2 */\r\n", "\r\n", -" unsigned int Break; /* Complexity Weight of 4 */\r\n", -" unsigned int Switch; /* Complexity Weight of 8 */\r\n", +" unsigned int Break; /* Complexity Weight of 2 */\r\n", +" unsigned int Switch; /* Complexity Weight of 6 */\r\n", " unsigned int For; /* Complexity Weight of 3 */\r\n", -" unsigned int While; /* Complexity Weight of 4 */\r\n", -" unsigned int Continue; /* Complexity Weight of 4 */\r\n", +" unsigned int While; /* Complexity Weight of 3 */\r\n", +" unsigned int Continue; /* Complexity Weight of 2 */\r\n", "\r\n", -" unsigned int L_mls; /* Complexity Weight of 6 */\r\n", +" unsigned int L_mls; /* Complexity Weight of 1 */\r\n", " unsigned int div_l; /* Complexity Weight of 32 */\r\n", -" unsigned int i_mult; /* Complexity Weight of 3 */\r\n", +" unsigned int i_mult; /* Complexity Weight of 1 */\r\n", +"\r\n", +"/* New complex basic operators */\r\n", +"#ifdef COMPLEX_OPERATOR\r\n", +" unsigned int CL_shr; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_shl; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_add; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_sub; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_scale; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_dscale; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_msu_j; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_mac_j; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_move; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_Extract_real; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_Extract_imag; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_form; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_multr_32x16; /* Complexity Weight of 2 */\r\n", +" unsigned int CL_negate; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_conjugate; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_mul_j; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_swap_real_imag; /* Complexity Weight of 1 */\r\n", +" unsigned int C_add; /* Complexity Weight of 1 */\r\n", +" unsigned int C_sub; /* Complexity Weight of 1 */\r\n", +" unsigned int C_mul_j; /* Complexity Weight of 1 */\r\n", +" unsigned int C_multr; /* Complexity Weight of 2 */\r\n", +" unsigned int C_form; /* Complexity Weight of 1 */\r\n", +"\r\n", +" unsigned int C_scale; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_round32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_scale_32; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_dscale_32; /* Complexity Weight of 1 */\r\n", +" unsigned int CL_multr_32x32; /* Complexity Weight of 2 */\r\n", +" unsigned int C_mac_r; /* Complexity Weight of 2 */\r\n", +" unsigned int C_msu_r; /* Complexity Weight of 2 */\r\n", +" unsigned int C_Extract_real; /* Complexity Weight of 1 */\r\n", +" unsigned int C_Extract_imag; /* Complexity Weight of 1 */\r\n", +" unsigned int C_negate; /* Complexity Weight of 1 */\r\n", +" unsigned int C_conjugate; /* Complexity Weight of 1 */\r\n", +" unsigned int C_shr; /* Complexity Weight of 1 */\r\n", +" unsigned int C_shl; /* Complexity Weight of 1 */\r\n", +"\r\n", +"#endif /* #ifdef COMPLEX_OPERATOR */\r\n", +"\r\n", +"/* New 64 bit basops */\r\n", +"#ifdef ENH_64_BIT_OPERATOR\r\n", +" unsigned int move64; /* Complexity Weight of 1 */\r\n", +" unsigned int W_add_nosat; /* Complexity Weight of 1 */\r\n", +" unsigned int W_sub_nosat; /* Complexity Weight of 1 */\r\n", +" unsigned int W_shl; /* Complexity Weight of 1 */\r\n", +" unsigned int W_shr; /* Complexity Weight of 1 */\r\n", +" unsigned int W_shl_nosat; /* Complexity Weight of 1 */\r\n", +" unsigned int W_shr_nosat; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mac_32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_msu_32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mult_32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mult0_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mac0_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_msu0_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mult_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mac_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_msu_16_16; /* Complexity Weight of 1 */\r\n", +" unsigned int W_shl_sat_l; /* Complexity Weight of 1 */\r\n", +" unsigned int W_sat_l; /* Complexity Weight of 1 */\r\n", +" unsigned int W_sat_m; /* Complexity Weight of 1 */\r\n", +" unsigned int W_deposit32_l; /* Complexity Weight of 1 */\r\n", +" unsigned int W_deposit32_h; /* Complexity Weight of 1 */\r\n", +" unsigned int W_extract_l; /* Complexity Weight of 1 */\r\n", +" unsigned int W_extract_h; /* Complexity Weight of 1 */\r\n", +" unsigned int W_round48_L; /* Complexity Weight of 1 */\r\n", +" unsigned int W_round32_s; /* Complexity Weight of 1 */\r\n", +" unsigned int W_norm; /* Complexity Weight of 1 */\r\n", +"\r\n", +" unsigned int W_add; /* Complexity Weight of 1 */\r\n", +" unsigned int W_sub; /* Complexity Weight of 1 */\r\n", +" unsigned int W_neg; /* Complexity Weight of 1 */\r\n", +" unsigned int W_abs; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mult_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int W_mult0_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int W_lshl; /* Complexity Weight of 1 */\r\n", +" unsigned int W_lshr; /* Complexity Weight of 1 */\r\n", +" unsigned int W_round64_L; /* Complexity Weight of 1 */\r\n", +"\r\n", +"#endif /* #ifdef ENH_64_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef ENH_32_BIT_OPERATOR\r\n", +" unsigned int Mpy_32_16_1; /* Complexity Weight of 1 */\r\n", +" unsigned int Mpy_32_16_r; /* Complexity Weight of 1 */\r\n", +" unsigned int Mpy_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int Mpy_32_32_r; /* Complexity Weight of 1 */\r\n", +" unsigned int Madd_32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int Madd_32_16_r; /* Complexity Weight of 1 */\r\n", +" unsigned int Msub_32_16; /* Complexity Weight of 1 */\r\n", +" unsigned int Msub_32_16_r; /* Complexity Weight of 1 */\r\n", +" unsigned int Madd_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int Madd_32_32_r; /* Complexity Weight of 1 */\r\n", +" unsigned int Msub_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int Msub_32_32_r; /* Complexity Weight of 1 */\r\n", +"#endif /* #ifdef ENH_32_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef ENH_U_32_BIT_OPERATOR\r\n", +" unsigned int UL_addNs; /* Complexity Weight of 1 */\r\n", +" unsigned int UL_subNs; /* Complexity Weight of 1 */\r\n", +" unsigned int UL_Mpy_32_32; /* Complexity Weight of 1 */\r\n", +" unsigned int Mpy_32_32_uu; /* Complexity Weight of 2 */\r\n", +" unsigned int Mpy_32_16_uu; /* Complexity Weight of 2 */\r\n", +" unsigned int norm_ul_float; /* Complexity Weight of 1 */\r\n", +" unsigned int UL_deposit_l; /* Complexity Weight of 1 */\r\n", +"#endif /* #ifdef ENH_U_32_BIT_OPERATOR */\r\n", +"\r\n", +"#ifdef CONTROL_CODE_OPS\r\n", +" unsigned int LT_16; /* Complexity Weight of 1 */\r\n", +" unsigned int GT_16; /* Complexity Weight of 1 */\r\n", +" unsigned int LE_16; /* Complexity Weight of 1 */\r\n", +" unsigned int GE_16; /* Complexity Weight of 1 */\r\n", +" unsigned int EQ_16; /* Complexity Weight of 1 */\r\n", +" unsigned int NE_16; /* Complexity Weight of 1 */\r\n", +" unsigned int LT_32; /* Complexity Weight of 1 */\r\n", +" unsigned int GT_32; /* Complexity Weight of 1 */\r\n", +" unsigned int LE_32; /* Complexity Weight of 1 */\r\n", +" unsigned int GE_32; /* Complexity Weight of 1 */\r\n", +" unsigned int EQ_32; /* Complexity Weight of 1 */\r\n", +" unsigned int NE_32; /* Complexity Weight of 1 */\r\n", +" unsigned int LT_64; /* Complexity Weight of 1 */\r\n", +" unsigned int GT_64; /* Complexity Weight of 1 */\r\n", +" unsigned int LE_64; /* Complexity Weight of 1 */\r\n", +" unsigned int GE_64; /* Complexity Weight of 1 */\r\n", +" unsigned int EQ_64; /* Complexity Weight of 1 */\r\n", +" unsigned int NE_64; /* Complexity Weight of 1 */\r\n", +"\r\n", +"#endif /* #ifdef CONTROL_CODE_OPS */\r\n", "} BASIC_OP;\r\n", "\r\n", "#ifdef WMOPS\r\n", "extern BASIC_OP *multiCounter;\r\n", -"extern int currCounter;\r\n", -"\r\n", -"/* Technical note :\r\n", -" * The following 3 variables are only used for correct complexity\r\n", -" * evaluation of the following structure :\r\n", -" * IF{\r\n", -" * ...\r\n", -" * } ELSE IF {\r\n", -" * ...\r\n", -" * } ELSE IF {\r\n", -" * ...\r\n", -" * }\r\n", -" * ...\r\n", -" * } ELSE {\r\n", -" * ...\r\n", -" * }\r\n", -" */\r\n", -"extern int funcId_where_last_call_to_else_occurred;\r\n", +"extern unsigned int currCounter;\r\n", "extern long funcid_total_wmops_at_last_call_to_else;\r\n", -"extern int call_occurred;\r\n", -"\r\n", -"extern long TotalWeightedOperation( void );\r\n", -"long DeltaWeightedOperation( void );\r\n", +"extern char func_name_where_last_call_to_else_occurred[];\r\n", "\r\n", -"void Set_BASOP_WMOPS_counter( int counterId );\r\n", -"void Reset_BASOP_WMOPS_counter( void );\r\n", +"long TotalWeightedOperation( unsigned int counterId );\r\n", +"long DeltaWeightedOperation( unsigned int counterId );\r\n", +"void Reset_BASOP_WMOPS_counter( unsigned int counterId );\r\n", "\r\n", "#endif\r\n", "\r\n", @@ -1216,15 +987,20 @@ " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", -"#define FOR( a) for( a)\r\n", +"#define FOR( a ) for ( a )\r\n", "\r\n", -"#else \r\n", -"#define FOR( a) if( incrFor(), 0); else for( a)\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define FOR( a ) \\\r\n", +" if ( incrFor(), 0 ) \\\r\n", +" ; \\\r\n", +" else \\\r\n", +" for ( a )\r\n", "\r\n", -"static __inline void incrFor( void) {\r\n", -" multiCounter[currCounter].For++;\r\n", +"static __inline void incrFor( void )\r\n", +"{\r\n", +" multiCounter[currCounter].For++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1241,15 +1017,16 @@ " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", -"#define WHILE( a) while( a)\r\n", +"#define WHILE( a ) while ( a )\r\n", "\r\n", -"#else \r\n", -"#define WHILE( a) while( incrWhile(), a)\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define WHILE( a ) while ( incrWhile(), a )\r\n", "\r\n", -"static __inline void incrWhile( void) {\r\n", -" multiCounter[currCounter].While++;\r\n", +"static __inline void incrWhile( void )\r\n", +"{\r\n", +" multiCounter[currCounter].While++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1266,10 +1043,10 @@ "#ifndef WMOPS\r\n", "#define DO do\r\n", "\r\n", -"#else \r\n", +"#else /* ifndef WMOPS */\r\n", "#define DO do\r\n", "\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1289,29 +1066,16 @@ " * - or when the 'if' conditions several DSP basic operations,\r\n", " * - or when the 'if' conditions a function call.\r\n", " *\r\n", -" * Complexity weight : 4\r\n", +" * Complexity weight : 3\r\n", " *\r\n", " *****************************************************************************/\r\n", -"#ifndef WMOPS\r\n", -"#define IF( a) if( a)\r\n", -"\r\n", -"#else \r\n", -"#define IF( a) if( incrIf(), a)\r\n", -"\r\n", -"static __inline void incrIf( void) {\r\n", -" /* Technical note :\r\n", -" * If the \"IF\" operator comes just after an \"ELSE\", its counter\r\n", -" * must not be incremented.\r\n", -" */\r\n", -" if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) )\r\n", -" {\r\n", -" multiCounter[currCounter].If++;\r\n", -" }\r\n", "\r\n", -" call_occurred = 0;\r\n", -" funcId_where_last_call_to_else_occurred = INT_MAX;\r\n", -"}\r\n", -"#endif \r\n", +"#ifndef WMOPS\r\n", +"#define IF( a ) if ( a )\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define IF( a ) if ( incrIf( __func__ ), a )\r\n", +"void incrIf( const char *func_name );\r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1322,33 +1086,18 @@ " *\r\n", " * The macro ELSE should be used instead of the 'else' C statement.\r\n", " *\r\n", -" * Complexity weight : 4\r\n", +" * Complexity weight : 3\r\n", " *\r\n", " *****************************************************************************/\r\n", +"\r\n", "#ifndef WMOPS\r\n", "#define ELSE else\r\n", -"\r\n", -"#else \r\n", -"#define ELSE else if( incrElse(), 0) ; else\r\n", -"\r\n", -"static __inline void incrElse( void) {\r\n", -" multiCounter[currCounter].If++;\r\n", -"\r\n", -" /* We keep track of the funcId of the last function\r\n", -" * which used ELSE {...} structure.\r\n", -" */\r\n", -" funcId_where_last_call_to_else_occurred = currCounter;\r\n", -"\r\n", -" /* We keep track of the number of WMOPS of this funcId\r\n", -" * when the ELSE macro was called.\r\n", -" */\r\n", -" funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation();\r\n", -"\r\n", -" /* call_occurred is set to 0, in order to count the next IF (if necessary)\r\n", -" */\r\n", -" call_occurred = 0;\r\n", -"}\r\n", -"#endif \r\n", +"#else /* ifndef WMOPS */\r\n", +"#define ELSE \\\r\n", +" else if ( incrElse( __func__ ), 0 ); \\\r\n", +" else\r\n", +"void incrElse( const char *func_name );\r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1359,19 +1108,20 @@ " *\r\n", " * The macro SWITCH should be used instead of the 'switch' C statement.\r\n", " *\r\n", -" * Complexity weight : 8\r\n", +" * Complexity weight : 6\r\n", " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", -"#define SWITCH( a) switch( a)\r\n", +"#define SWITCH( a ) switch ( a )\r\n", "\r\n", -"#else \r\n", -"#define SWITCH( a) switch( incrSwitch(), a)\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define SWITCH( a ) switch ( incrSwitch(), a )\r\n", "\r\n", -"static __inline void incrSwitch( void) {\r\n", -" multiCounter[currCounter].Switch++;\r\n", +"static __inline void incrSwitch( void )\r\n", +"{\r\n", +" multiCounter[currCounter].Switch++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1382,19 +1132,24 @@ " *\r\n", " * The macro CONTINUE should be used instead of the 'continue' C statement.\r\n", " *\r\n", -" * Complexity weight : 4\r\n", +" * Complexity weight : 2\r\n", " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", "#define CONTINUE continue\r\n", "\r\n", -"#else \r\n", -"#define CONTINUE if( incrContinue(), 0); else continue\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define CONTINUE \\\r\n", +" if ( incrContinue(), 0 ) \\\r\n", +" ; \\\r\n", +" else \\\r\n", +" continue\r\n", "\r\n", -"static __inline void incrContinue( void) {\r\n", -" multiCounter[currCounter].Continue++;\r\n", +"static __inline void incrContinue( void )\r\n", +"{\r\n", +" multiCounter[currCounter].Continue++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1405,19 +1160,24 @@ " *\r\n", " * The macro BREAK should be used instead of the 'break' C statement.\r\n", " *\r\n", -" * Complexity weight : 4\r\n", +" * Complexity weight : 2\r\n", " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", "#define BREAK break\r\n", "\r\n", -"#else \r\n", -"#define BREAK if( incrBreak(), 0) break; else break\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define BREAK \\\r\n", +" if ( incrBreak(), 0 ) \\\r\n", +" ; \\\r\n", +" else \\\r\n", +" break\r\n", "\r\n", -"static __inline void incrBreak( void) {\r\n", -" multiCounter[currCounter].Break++;\r\n", +"static __inline void incrBreak( void )\r\n", +"{\r\n", +" multiCounter[currCounter].Break++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", "\r\n", "/*****************************************************************************\r\n", @@ -1428,21 +1188,50 @@ " *\r\n", " * The macro GOTO should be used instead of the 'goto' C statement.\r\n", " *\r\n", -" * Complexity weight : 4\r\n", +" * Complexity weight : 2\r\n", " *\r\n", " *****************************************************************************/\r\n", "#ifndef WMOPS\r\n", "#define GOTO goto\r\n", "\r\n", -"#else \r\n", -"#define GOTO if( incrGoto(), 0); else goto\r\n", +"#else /* ifndef WMOPS */\r\n", +"#define GOTO \\\r\n", +" if ( incrGoto(), 0 ) \\\r\n", +" ; \\\r\n", +" else \\\r\n", +" goto\r\n", "\r\n", -"static __inline void incrGoto( void) {\r\n", -" multiCounter[currCounter].Goto++;\r\n", +"static __inline void incrGoto( void )\r\n", +"{\r\n", +" multiCounter[currCounter].Goto++;\r\n", "}\r\n", -"#endif \r\n", +"#endif /* ifndef WMOPS */\r\n", "\r\n", -"#endif /* WMOPS_H */\r\n", "\r\n", +"#ifdef CONTROL_CODE_OPS\r\n", +"\r\n", +"extern int LT_16( short var1, short var2 );\r\n", +"extern int GT_16( short var1, short var2 );\r\n", +"extern int LE_16( short var1, short var2 );\r\n", +"extern int GE_16( short var1, short var2 );\r\n", +"extern int EQ_16( short var1, short var2 );\r\n", +"extern int NE_16( short var1, short var2 );\r\n", "\r\n", -"\r\n", \ No newline at end of file +"extern int LT_32( int L_var1, int L_var2 );\r\n", +"extern int GT_32( int L_var1, int L_var2 );\r\n", +"extern int LE_32( int L_var1, int L_var2 );\r\n", +"extern int GE_32( int L_var1, int L_var2 );\r\n", +"extern int EQ_32( int L_var1, int L_var2 );\r\n", +"extern int NE_32( int L_var1, int L_var2 );\r\n", +"\r\n", +"extern int LT_64( long long int L64_var1, long long int L64_var2 );\r\n", +"extern int GT_64( long long int L64_var1, long long int L64_var2 );\r\n", +"extern int LE_64( long long int L64_var1, long long int L64_var2 );\r\n", +"extern int GE_64( long long int L64_var1, long long int L64_var2 );\r\n", +"extern int EQ_64( long long int L64_var1, long long int L64_var2 );\r\n", +"extern int NE_64( long long int L64_var1, long long int L64_var2 );\r\n", +"\r\n", +"#endif /* #ifdef CONTROL_CODE_OPS */\r\n", +"\r\n", +"\r\n", +"#endif /* WMOPS_H */\r\n", diff --git a/src/wmc_tool/wmc_tool.cpp b/src/wmc_tool/wmc_tool.cpp index dac4c482..6c497ff6 100644 --- a/src/wmc_tool/wmc_tool.cpp +++ b/src/wmc_tool/wmc_tool.cpp @@ -54,10 +54,11 @@ #define DESINSTRUMENT_ONLY 0x001 #define REMOVE_MANUAL_INSTR 0x002 #define VERBOSE 0x004 +#define SKIP_CMPLX_INSTRUM 0x010 #define NO_BACKUP 0x020 #define INSTR_INFO_ONLY 0x040 -#define OUTPUT_WMOPS_FILES 0x080 #define INSTRUMENT_ROM 0x100 +#define OUTPUT_WMOPS_FILES 0x200 /* Other Constants */ #define BACKUP_SUFFIX ".bak" @@ -77,6 +78,7 @@ static void usage() "Options:\n" " -h [--help]: print help\n" " -v [--verbose]: print warnings and other information messages\n" + " -s [--skip-cmplx-instrumentation]: skip complexity instrumentation\n" " -i [--info-only]: only print instrumentation information\n" " -d [--desinstrument]: desintrument only\n" " -m filename [--rom filename]: add statistics about ROM and RAM consumption\n" @@ -191,6 +193,10 @@ static TOOL_ERROR Parse_Command_Line( { *Operation |= INSTR_INFO_ONLY; } + else if (_stricmp(arg_name, "s") == 0 || _stricmp(arg_name, "skip-cmplx-instrumentation") == 0) + { + *Operation |= SKIP_CMPLX_INSTRUM; + } else if (_stricmp(arg_name, "c") == 0 || _stricmp(arg_name, "generate-wmc-files") == 0) { /* get the next argument - must be an existing direectory */ @@ -231,12 +237,19 @@ static TOOL_ERROR Parse_Command_Line( i++; /* get the value */ - if ((*frames_per_sec = strtof(args[i], NULL)) <= 0.0 ) + if ((*frames_per_sec = strtof(args[i], NULL)) <= 0.0) { fprintf(stderr, "Incorrect number of frames per second specified: %s!\n\n", args[i]); return ERR_CMD_LINE; } } + else + { + /* unknown command-line option */ + usage(); + fprintf(stderr, "Unknown command-line option: %s!\n\n", args[i]); + return ERR_CMD_LINE; + } /* Move to the next argument */ i++; @@ -989,11 +1002,18 @@ static TOOL_ERROR Process_File( return ErrCode; } + /* DesInstrument Const_Data_Size_XXX Functions */ + if ( ( ErrCode = DesInstrument_ROM( ParseCtx_ptr ) ) != NO_ERR ) + { + fprintf(stdout, "\n"); + return ErrCode; + } + /* Instrument */ if ( !( Operation & DESINSTRUMENT_ONLY ) ) { /* Yes */ /* Instrument */ - if ((ErrCode = Instrument(ParseCtx_ptr, (Operation & INSTRUMENT_ROM) != 0)) != NO_ERR) + if ((ErrCode = Instrument(ParseCtx_ptr, (Operation & INSTRUMENT_ROM) != 0, (Operation & SKIP_CMPLX_INSTRUM) != 0)) != NO_ERR) { fprintf(stdout, "\n"); return ErrCode; @@ -1154,6 +1174,7 @@ int main( int argc, char *argv[] ) char Const_Data_PROM_File[MAX_PATH] = ""; char wmops_output_dir[MAX_PATH]; float frames_per_sec; + bool Const_Data_PROM_File_already_reinstrumented = 0; T_FILE_BOOK file_book[MAX_RECORDS]; struct stat s; Parse_Context_def ParseContext; @@ -1238,7 +1259,14 @@ int main( int argc, char *argv[] ) if (!(Operation & DESINSTRUMENT_ONLY)) { - fprintf(stdout, "- instrumenting all functions and table (const) data memory\n"); + if (Operation & SKIP_CMPLX_INSTRUM) + { + fprintf(stdout, "- skipping instrumentation of functions\n"); + } + else + { + fprintf(stdout, "- instrumenting all functions and table (const) data memory\n"); + } } if (Operation & OUTPUT_WMOPS_FILES) @@ -1421,6 +1449,12 @@ int main( int argc, char *argv[] ) /* Process File */ ErrCode = Process_File(LongFileName, Operation, &ParseContext, MaxFnLength, (Operation & NO_BACKUP) == 0, j * 100.0f / file_book[i].nFiles); + /* Check if the processed file is the same as */ + if (strcmp(LongFileName, Const_Data_PROM_File) == 0) + { + Const_Data_PROM_File_already_reinstrumented = 1; + } + /* Update # of Bytes Processed */ nBytesProcessed += ParseContext.File.Size; @@ -1513,10 +1547,13 @@ int main( int argc, char *argv[] ) goto ret; } - /* DesInstrument Const_Data_Size_XXX Functions */ - if ((ErrCode = DesInstrument_ROM(&ParseContext)) != NO_ERR) + /* DesInstrument Const_Data_PROM_Table[] */ + if (!Const_Data_PROM_File_already_reinstrumented) { - goto ret; + if ((ErrCode = DesInstrument_ROM(&ParseContext)) != NO_ERR) + { + goto ret; + } } /* Check, if "wmc_auto.h" is included */ diff --git a/src/wmc_tool/wmc_tool.h b/src/wmc_tool/wmc_tool.h index 95d961ef..2b1e9800 100644 --- a/src/wmc_tool/wmc_tool.h +++ b/src/wmc_tool/wmc_tool.h @@ -19,7 +19,7 @@ * Switches *-------------------------------------------------------------------*/ -#define WMC_TOOL_VERSION_NO "1.5" /* Current version */ +#define WMC_TOOL_VERSION_NO "1.8" /* Current version */ /*#define DEBUG_PRINT*/ /* For debugging purposes */ /*-------------------------------------------------------------------*