diff --git a/ctest/athrill_setup.cpp b/ctest/athrill_setup.cpp index 98ef55a..bd9403f 100644 --- a/ctest/athrill_setup.cpp +++ b/ctest/athrill_setup.cpp @@ -8,15 +8,20 @@ #include "dt16x2_mcdhelper.hpp" #include "dt32x1_mcdhelper.hpp" -void setup_decoders() +namespace mcdhelper { - arm::mcdhelper::setup_decoder(); - ab::mcdhelper::setup_decoder(); - at::mcdhelper::setup_decoder(); - atb::mcdhelper::setup_decoder(); - riscv::mcdhelper::setup_decoder(); - pc::mcdhelper::setup_decoder(); - cc::mcdhelper::setup_decoder(); - dt16x2::mcdhelper::setup_decoder(); - dt32x1::mcdhelper::setup_decoder(); + +void SetupDecoders() +{ + arm::mcdhelper::SetupDecoder(); + ab::mcdhelper::SetupDecoder(); + at::mcdhelper::SetupDecoder(); + atb::mcdhelper::SetupDecoder(); + riscv::mcdhelper::SetupDecoder(); + pc::mcdhelper::SetupDecoder(); + cc::mcdhelper::SetupDecoder(); + dt16x2::mcdhelper::SetupDecoder(); + dt32x1::mcdhelper::SetupDecoder(); } + +} // namespace mcdhelper diff --git a/ctest/features/step_definitions/mcdecoder_steps.cpp b/ctest/features/step_definitions/mcdecoder_steps.cpp index a74bee7..418c909 100644 --- a/ctest/features/step_definitions/mcdecoder_steps.cpp +++ b/ctest/features/step_definitions/mcdecoder_steps.cpp @@ -12,15 +12,13 @@ using cucumber::ScenarioScope; struct McdCtx { std::string decoder_name; - bool result_code; + bool succeeded; mcdhelper::DecodeResult result; }; -extern void setup_decoders(); - BEFORE_ALL() { - setup_decoders(); + mcdhelper::SetupDecoders(); } GIVEN("^decoding instructions with the decoder \"([^\"]+)\"$") @@ -38,36 +36,36 @@ WHEN("^I decode \"([^\"]+)\"$") // Get the byte length of code // In hex string, 2 characters correspond to 1 byte - const int byte_char_len = 2; - int byte_length = std::min((int)(code_str.length() / byte_char_len), 4); + const int kByteCharLen = 2; + int byte_length = std::min((int)(code_str.length() / kByteCharLen), 4); // Convert hex string to integer array uint8_t codes[4]; for (int i = 0; i < byte_length; i++) { - codes[i] = std::stoul(code_str.substr(i * byte_char_len, byte_char_len), nullptr, 16); + codes[i] = std::stoul(code_str.substr(i * kByteCharLen, kByteCharLen), nullptr, 16); } // Decode mcdhelper::DecodeRequest request; request.decoder_name = context->decoder_name; - request.codes = (const uint8_t *)&codes[0]; + request.codes = (const uint8_t*)&codes[0]; - context->result_code = mcdhelper::decode_instruction(request, &context->result); + context->succeeded = mcdhelper::DecodeInstruction(request, &context->result); } THEN("^the decoding should be succeeded$") { ScenarioScope context; - EXPECT_TRUE(context->result_code); + EXPECT_TRUE(context->succeeded); } THEN("^the decoding should be failed$") { ScenarioScope context; - EXPECT_FALSE(context->result_code); + EXPECT_FALSE(context->succeeded); } THEN("^the instruction should be \"([^\"]+)\"$") @@ -97,8 +95,8 @@ THEN("^the fields \"([^\"]+)\" should be \"([^\"]+)\"$") // Test the fields for (int i = 0; i < fields.size(); i++) { - const std::string &field = fields[i]; - const std::string &str_expected_value = str_expected_values[i]; + const std::string& field = fields[i]; + const std::string& str_expected_value = str_expected_values[i]; uint32_t expected_value = std::stoul(str_expected_value, nullptr, 16); EXPECT_EQ(expected_value, context->result.fields[field]); diff --git a/ctest/mcdecoder_setup.cpp b/ctest/mcdecoder_setup.cpp index 98ef55a..bd9403f 100644 --- a/ctest/mcdecoder_setup.cpp +++ b/ctest/mcdecoder_setup.cpp @@ -8,15 +8,20 @@ #include "dt16x2_mcdhelper.hpp" #include "dt32x1_mcdhelper.hpp" -void setup_decoders() +namespace mcdhelper { - arm::mcdhelper::setup_decoder(); - ab::mcdhelper::setup_decoder(); - at::mcdhelper::setup_decoder(); - atb::mcdhelper::setup_decoder(); - riscv::mcdhelper::setup_decoder(); - pc::mcdhelper::setup_decoder(); - cc::mcdhelper::setup_decoder(); - dt16x2::mcdhelper::setup_decoder(); - dt32x1::mcdhelper::setup_decoder(); + +void SetupDecoders() +{ + arm::mcdhelper::SetupDecoder(); + ab::mcdhelper::SetupDecoder(); + at::mcdhelper::SetupDecoder(); + atb::mcdhelper::SetupDecoder(); + riscv::mcdhelper::SetupDecoder(); + pc::mcdhelper::SetupDecoder(); + cc::mcdhelper::SetupDecoder(); + dt16x2::mcdhelper::SetupDecoder(); + dt32x1::mcdhelper::SetupDecoder(); } + +} // namespace mcdhelper diff --git a/ctest/mcdhelper.cpp b/ctest/mcdhelper.cpp index ac6c810..c8e6d4a 100644 --- a/ctest/mcdhelper.cpp +++ b/ctest/mcdhelper.cpp @@ -3,15 +3,15 @@ namespace mcdhelper { -#pragma region Global variables +#pragma region Internal global variables static std::map decoders; -#pragma endregion Global variables +#pragma endregion Internal global variables #pragma region External functions -bool decode_instruction(const DecodeRequest &request, DecodeResult *result) +bool DecodeInstruction(const DecodeRequest& request, DecodeResult* result) { std::map::iterator pair = decoders.find(request.decoder_name); if (pair == decoders.end()) @@ -22,7 +22,7 @@ bool decode_instruction(const DecodeRequest &request, DecodeResult *result) return pair->second.decode_function(request, result); } -void regist_decoder(const Decoder &decoder) +void RegistDecoder(const Decoder& decoder) { decoders[decoder.decoder_name] = decoder; } diff --git a/ctest/mcdhelper.hpp b/ctest/mcdhelper.hpp index 9ce3638..d66d16a 100644 --- a/ctest/mcdhelper.hpp +++ b/ctest/mcdhelper.hpp @@ -5,34 +5,60 @@ namespace mcdhelper { -#pragma region Data types +#pragma region Types -typedef struct +/** Decoding request */ +struct DecodeRequest { - std::string decoder_name; // Name of a decoder - const uint8_t *codes; // Codes to be input -} DecodeRequest; + std::string decoder_name; /** Name of a decoder */ + const uint8_t* codes; /** Codes to be input */ +}; -typedef struct +/** Decoding result */ +struct DecodeResult { - std::string instruction_name; // Name of a matched instruction - std::map fields; // Decoded field values -} DecodeResult; + std::string instruction_name; /** Name of a matched instruction */ + std::map fields; /** Decoded field values */ +}; -typedef bool (*DecodeFunction)(const DecodeRequest &request, DecodeResult *result); +/** + * Decoding function + * + * @param request Decoding request + * @param result Decoding result + * @return True if decoding succeeded. False otherwise + */ +typedef bool (*DecodeFunction)(const DecodeRequest& request, DecodeResult* result); -typedef struct +/** Decoder information */ +struct Decoder { - std::string decoder_name; // Name of a decoder - DecodeFunction decode_function; // Function to decode an instruction -} Decoder; + std::string decoder_name; /** Name of a decoder */ + DecodeFunction decode_function; /** Function to decode an instruction */ +}; -#pragma endregion Data types +#pragma endregion Types #pragma region Functions -extern bool decode_instruction(const DecodeRequest &request, DecodeResult *result); -extern void regist_decoder(const Decoder &decoder); +/** + * Decode an instruction + * + * @param request Decoding request + * @param result Decoding result + * @return True if decoding succeeded. False otherwise + */ +extern bool DecodeInstruction(const DecodeRequest& request, DecodeResult* result); + +/** + * Register a decoder + * + * @param decoder Decoder to be registered + */ +extern void RegistDecoder(const Decoder& decoder); + +/** Hook to setup decoders */ +extern void SetupDecoders(); #pragma endregion Functions diff --git a/ctest/templates/athrill_helper/{{ns}}mcdhelper.cpp b/ctest/templates/athrill_helper/{{ns}}mcdhelper.cpp index ba73d72..15b4821 100644 --- a/ctest/templates/athrill_helper/{{ns}}mcdhelper.cpp +++ b/ctest/templates/athrill_helper/{{ns}}mcdhelper.cpp @@ -1,3 +1,5 @@ +#include "{{ ns }}mcdhelper.hpp" + #include "mcdhelper.hpp" extern "C" { @@ -10,7 +12,7 @@ namespace mcdhelper { #pragma region Internal functions {% for inst in instruction_decoders %} - static void convert_result_{{ inst.name }}(const {{ ns }}OpDecodedCodeType& decoded_code, ::mcdhelper::DecodeResult* result) { + static void ConvertResult_{{ inst.name }}(const {{ ns }}OpDecodedCodeType& decoded_code, ::mcdhelper::DecodeResult* result) { result->instruction_name = "{{ inst.name }}"; {% for field in inst.field_decoders %} result->fields["{{ field.name }}"] = decoded_code.code.{{ inst.name }}.{{ field.name }}; @@ -18,18 +20,17 @@ namespace mcdhelper { } {% endfor %} -static bool decode_instruction(const ::mcdhelper::DecodeRequest& request, ::mcdhelper::DecodeResult* result) { +static bool DecodeInstruction(const ::mcdhelper::DecodeRequest& request, ::mcdhelper::DecodeResult* result) { {{ ns }}uint16* code = ({{ ns }}uint16*) request.codes; {{ ns }}OpDecodedCodeType decoded_code; {{ ns }}OperationCodeType optype; - int result_code; - result_code = {{ ns }}op_parse(code, &decoded_code, &optype); + int result_code = {{ ns }}op_parse(code, &decoded_code, &optype); switch (optype.code_id) { {% for inst in instruction_decoders %} case {{ ns }}OpCodeId_{{ inst.name }}: - convert_result_{{ inst.name }}(decoded_code, result); + ConvertResult_{{ inst.name }}(decoded_code, result); break; {% endfor %} } @@ -41,13 +42,13 @@ static bool decode_instruction(const ::mcdhelper::DecodeRequest& request, ::mcdh #pragma region External functions -void setup_decoder(void) { +void SetupDecoder(void) { ::mcdhelper::Decoder decoder = { "{{ mcdecoder.namespace }}", - decode_instruction, + DecodeInstruction, }; - ::mcdhelper::regist_decoder(decoder); + ::mcdhelper::RegistDecoder(decoder); } #pragma endregion External functions diff --git a/ctest/templates/athrill_helper/{{ns}}mcdhelper.hpp b/ctest/templates/athrill_helper/{{ns}}mcdhelper.hpp index b546c35..f7de2f6 100644 --- a/ctest/templates/athrill_helper/{{ns}}mcdhelper.hpp +++ b/ctest/templates/athrill_helper/{{ns}}mcdhelper.hpp @@ -3,7 +3,8 @@ namespace mcdhelper { #pragma region Functions - extern void setup_decoder(void); +/** Setup a decoder */ +extern void SetupDecoder(void); #pragma endregion Functions diff --git a/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.cpp b/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.cpp index 26b26f3..8c60929 100644 --- a/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.cpp +++ b/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.cpp @@ -12,7 +12,7 @@ namespace mcdhelper { #pragma region Internal functions {% for inst in instruction_decoders -%} - static void convert_result_{{ inst.name }}(const {{ ns }}DecodeResult& concrete_result, ::mcdhelper::DecodeResult* result) { + static void ConvertResult_{{ inst.name }}(const {{ ns }}DecodeResult& concrete_result, ::mcdhelper::DecodeResult* result) { result->instruction_name = "{{ inst.name }}"; {% for field in inst.field_decoders -%} result->fields["{{ field.name }}"] = concrete_result.instruction.{{ inst.name }}.{{ field.name }}; @@ -20,37 +20,35 @@ namespace mcdhelper { } {% endfor %} -static bool decode_instruction(const ::mcdhelper::DecodeRequest& request, ::mcdhelper::DecodeResult* result) { +static bool DecodeInstruction(const ::mcdhelper::DecodeRequest& request, ::mcdhelper::DecodeResult* result) { {{ ns }}DecodeRequest concrete_request; - {{ ns }}DecodeResult concrete_result; - int result_code; - concrete_request.codes = request.codes; - result_code = {{ ns }}decode_instruction(&concrete_request, &concrete_result); + {{ ns }}DecodeResult concrete_result; + bool succeeded = {{ ns }}DecodeInstruction(&concrete_request, &concrete_result); switch (concrete_result.instruction_id) { {% for inst in instruction_decoders -%} case {{ ns }}InstructionId_k_{{ inst.name }}: - convert_result_{{ inst.name }}(concrete_result, result); + ConvertResult_{{ inst.name }}(concrete_result, result); break; {% endfor %} } - return result_code; + return succeeded; } #pragma endregion Internal functions #pragma region External functions -void setup_decoder(void) { +void SetupDecoder(void) { ::mcdhelper::Decoder decoder = { "{{ mcdecoder.namespace }}", - decode_instruction, + DecodeInstruction, }; - ::mcdhelper::regist_decoder(decoder); + ::mcdhelper::RegistDecoder(decoder); } #pragma endregion External functions diff --git a/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.hpp b/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.hpp index b546c35..f7de2f6 100644 --- a/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.hpp +++ b/ctest/templates/mcdecoder_helper/{{ns}}mcdhelper.hpp @@ -3,7 +3,8 @@ namespace mcdhelper { #pragma region Functions - extern void setup_decoder(void); +/** Setup a decoder */ +extern void SetupDecoder(void); #pragma endregion Functions diff --git a/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.c b/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.c index 4e0bd70..f1fc53c 100755 --- a/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.c +++ b/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.c @@ -4,7 +4,7 @@ {%- if object.element_index is none -%} context->result->instruction.{{ instruction.name }}.{{ object.field }} {%- else -%} - bit_element(context->result->instruction.{{ instruction.name }}.{{ object.field }}, {{ object.element_index }}) + BitElement(context->result->instruction.{{ instruction.name }}.{{ object.field }}, {{ object.element_index }}) {%- endif -%} {%- elif object.type == 'immediate' -%} {{ object.value }} @@ -52,29 +52,38 @@ typedef struct { uint32_t code32x1; } DecodeContext; +typedef uint32_t (*SetBitCountFunction)(uint32_t value); + /* * Internal function declarations */ -static uint8_t bit_element(uint32_t value, uint8_t element_index); -static uint32_t setbit_count(uint32_t value); +static uint8_t BitElement(uint32_t value, uint8_t element_index); +static uint32_t SetBitCount(uint32_t value); {% for tree in mcdecoder.decision_trees -%} {% for node in tree.root_node.all_nodes -%} - static bool decision_node_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.index }}(DecodeContext *context, uint32_t code); + static bool DecisionNode_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.index }}(DecodeContext *context, uint32_t code); {% endfor %} {% endfor %} {% for inst in instruction_decoders -%} - static bool decode_instruction_{{ inst.name }}(DecodeContext *context); + static bool DecodeInstruction_{{ inst.name }}(DecodeContext *context); {% endfor %} +/* + * Internal global variables + */ + +static const SetBitCountFunction setbit_count = SetBitCount; + + /* * External function definitions */ /* decode function */ -bool {{ ns }}decode_instruction(const {{ ns }}DecodeRequest *request, {{ ns }}DecodeResult *result) { +bool {{ ns }}DecodeInstruction(const {{ ns }}DecodeRequest *request, {{ ns }}DecodeResult *result) { const uint8_t *raw_code = request->codes; {% if machine_decoder.byteorder == 'little' -%} uint16_t word1_16bit = *((uint16_t *) &raw_code[0]); @@ -95,7 +104,7 @@ bool {{ ns }}decode_instruction(const {{ ns }}DecodeRequest *request, {{ ns }}De context.code32x1 = context.code16x2; {% endif %} {% for tree in mcdecoder.decision_trees -%} - if (decision_node_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ tree.root_node.index }}(&context, context.code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }})) { + if (DecisionNode_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ tree.root_node.index }}(&context, context.code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }})) { return true; } {% endfor %} @@ -108,11 +117,11 @@ bool {{ ns }}decode_instruction(const {{ ns }}DecodeRequest *request, {{ ns }}De */ /* functions for conditions */ -static uint8_t bit_element(uint32_t value, uint8_t element_index) { +static uint8_t BitElement(uint32_t value, uint8_t element_index) { return (value & (1u << element_index)) >> element_index; } -static uint32_t setbit_count(uint32_t value) { +static uint32_t SetBitCount(uint32_t value) { uint32_t count = 0; while (value) { count += value & 1; @@ -123,7 +132,7 @@ static uint32_t setbit_count(uint32_t value) { /* individual decode functions */ {% for inst in instruction_decoders %} - static bool decode_instruction_{{ inst.name }}(DecodeContext *context) { + static bool DecodeInstruction_{{ inst.name }}(DecodeContext *context) { if ((context->code{{ inst.encoding_element_bit_length }}x{{ inst.length_of_encoding_elements }} & (0x{{ '%08x'|format(inst.fixed_bits_mask) }}l)) != (0x{{ '%08x'|format(inst.fixed_bits) }}l)) { return false; } @@ -156,9 +165,9 @@ static uint32_t setbit_count(uint32_t value) { /* decision node functions */ {% for tree in mcdecoder.decision_trees -%} {% for node in tree.root_node.all_nodes -%} - static bool decision_node_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.index }}(DecodeContext *context, uint32_t code) { + static bool DecisionNode_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.index }}(DecodeContext *context, uint32_t code) { {% for inst in node.instructions -%} - if (decode_instruction_{{ inst.name }}(context)) { + if (DecodeInstruction_{{ inst.name }}(context)) { return true; } {% endfor %} @@ -166,7 +175,7 @@ static uint32_t setbit_count(uint32_t value) { switch (code & 0x{{ '%08x'|format(node.mask) }}) { {% for threshold_value, child_node in node.fixed_bit_nodes.items() -%} case 0x{{ '%08x'|format(threshold_value) }}: - if (decision_node_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ child_node.index }}(context, code)) { + if (DecisionNode_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ child_node.index }}(context, code)) { return true; } break; @@ -174,7 +183,7 @@ static uint32_t setbit_count(uint32_t value) { } {% endif %} {% if node.arbitrary_bit_node -%} - if (decision_node_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.arbitrary_bit_node.index }}(context, code)) { + if (DecisionNode_code{{ tree.encoding_element_bit_length }}x{{ tree.length_of_encoding_elements }}_{{ node.arbitrary_bit_node.index }}(context, code)) { return true; } {% endif %} diff --git a/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.h b/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.h index a97ee36..a62b25e 100755 --- a/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.h +++ b/src/mcdecoder/templates/mcdecoder/{{ns}}mcdecoder.h @@ -52,10 +52,11 @@ typedef struct { /** * Decode an instruction * - * @param request decoding request - * @param result decoding result + * @param request Decoding request + * @param result Decoding result + * @return True if decoding succeeded. False otherwise */ -extern bool {{ ns }}decode_instruction(const {{ ns }}DecodeRequest *request, {{ ns }}DecodeResult *result); +extern bool {{ ns }}DecodeInstruction(const {{ ns }}DecodeRequest *request, {{ ns }}DecodeResult *result); #endif /* !_{{ ns }}MC_DECODER_H_ */ diff --git a/src_docs/spec_mcdecoder_api.rst b/src_docs/spec_mcdecoder_api.rst index 4362e1c..9781a74 100644 --- a/src_docs/spec_mcdecoder_api.rst +++ b/src_docs/spec_mcdecoder_api.rst @@ -6,7 +6,7 @@ MC decoder API specification Usage ********************************* -Here's an example of :code:`decode_instruction` usage (without namespace). +Here's an example of :code:`DecodeInstruction` usage (without namespace). .. code-block:: c @@ -20,7 +20,7 @@ Here's an example of :code:`decode_instruction` usage (without namespace). bool succeeded; request.codes = &codes[0]; - succeeded = decode_instruction(&request, &result); + succeeded = DecodeInstruction(&request, &result); /* Decoding succeeded? */ if (succeeded) { @@ -96,8 +96,8 @@ Types where + * : Appropriate unsigned integer type for the field: :code:`uint8_t`, :code:`uint16_t` or :code:`uint32_t` * : Field name - * : Appropriate unsigned integer type for the field: :code:`uint8_t`, :code:`uint16_t` or :code:`uint32_t`. ********************************* Macros @@ -111,10 +111,10 @@ Macros Functions ********************************* -.. c:function:: bool decode_instruction(const DecodeRequest *request, DecodeResult *result) +.. c:function:: bool DecodeInstruction(const DecodeRequest *request, DecodeResult *result) Decode an instruction - :param request: decoding request - :param result: decoding result - :return: :code:`true` if an instruction matches codes. :code:`false` otherwise. + :param request: Decoding request + :param result: Decoding result + :return: :code:`true` if an instruction matches codes. :code:`false` otherwise