diff --git a/code/8086/decoder.c b/code/8086/decoder.c index 541c6af..c48f402 100644 --- a/code/8086/decoder.c +++ b/code/8086/decoder.c @@ -24,9 +24,9 @@ RO_ global U1 x8616_decode_payload_bytes[] = { }; typedef Struct_(X8616_DecodePlex) { - U1 const* source; - U4 source_size; - U4 source_offset; + U1* source; + U4 source_size; + U4 source_offset; U1 body[X8616_DECODE_BODY_CAP + X8616_DECODE_BODY_PAD]; U1 body_available; diff --git a/code/8086/decoder.h b/code/8086/decoder.h index ed238c7..4ab635d 100644 --- a/code/8086/decoder.h +++ b/code/8086/decoder.h @@ -142,8 +142,8 @@ enum { }; typedef Struct_(X8616_DecodeRequest) { - U1 const* source; - U4 source_size; + U1* source; + U4 source_size; X8616_DecodedInstruction* instructions; U4 instruction_capacity; diff --git a/code/8086/decoder.test.c b/code/8086/decoder.test.c deleted file mode 100644 index f787ebc..0000000 --- a/code/8086/decoder.test.c +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef INTELLISENSE_DIRECTIVES -# include "duffle/dsl.h" -# include "encoder.h" -# include "decoder.h" -# include "info.h" -#endif - -internal void -x8616_decoder_smoke_test(void) -{ - U1 bytes[] = { - x8616_mov_r16_i (x8616_ax, 0x1234), - x8616_add_r16_i8s(x8616_ax, -2), - x8616_nop(), - }; - - X8616_DecodedInstruction instructions[3] = {0}; - U1 info_memory[1024] = {0}; - FArena info_scratch = farena_make(slice_ut_arr(info_memory)); - - X8616_DecodeInfo info = x8616_decode((X8616_DecodeRequest){ - .source = bytes, - .source_size = S_(bytes), - .instructions = instructions, - .instruction_capacity = Array_len(instructions), - .info_arena = & info_scratch, - }); - - assert(info.source_consumed == S_(bytes)); - assert(info.instruction_count == 3); - assert(info.msgs.error_count == 0); - - assert(instructions[0].op == x8616_op_mov); - assert(instructions[1].op == x8616_op_add); - assert(instructions[2].op == x8616_op_xchg); /* 0x90 in the Part 1 table */ -} diff --git a/code/8086/decoder_table_generator.meta.c b/code/8086/decoder_table_generator.meta.c index fd05991..c66163f 100644 --- a/code/8086/decoder_table_generator.meta.c +++ b/code/8086/decoder_table_generator.meta.c @@ -370,7 +370,9 @@ x8616_decode_gen_emit(Str8Gen_R out, X8616_DecodeGen_R gen) str8gen_append_str8(out, slit8( "// Generated from encoder_table.h. Do not hand-edit.\n" "// Plan 0 is a nil/invalid entry.\n" - "\n" + "#ifdef INTELLISENSE_DIRECTIVES\n" + "#\tinclude \"dsl.h\"\n" + "#endif\n\n" )); gen_fmt(out, code_str8(RO_ global X8616_DecodePlan x8616_decode_plans[] =\n{\n) , entry("plan_count", dec(X8616_ENCODING_COUNT + 1)) @@ -466,8 +468,7 @@ x8616_decode_gen_emit(Str8Gen_R out, X8616_DecodeGen_R gen) #undef hex_u1 #undef dec -int -main(void) { +int main(void) { FArena info_scratch = farena_make(slice_ut_arr(smem.info)); X8616_DecodeGenInfo gen_info = x8616_decode_table_generate(& smem.gen, & info_scratch); if (gen_info.msgs.error_count) { ms_exit_process(1); return 1; } diff --git a/code/8086/gen/decoder_table.h b/code/8086/gen/decoder_table.h index d5c1a5a..4331387 100644 --- a/code/8086/gen/decoder_table.h +++ b/code/8086/gen/decoder_table.h @@ -1,103 +1,106 @@ // Generated from encoder_table.h. Do not hand-edit. // Plan 0 is a nil/invalid entry. +#ifdef INTELLISENSE_DIRECTIVES +# include "dsl.h" +#endif RO_ global X8616_DecodePlan x8616_decode_plans[132] = { { 0x0000, 0x00, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x02, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x02, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0088, 0x02, 0x00, 0x00, {0x03, 0x07}, 2, 1, 0, 0, 3, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x000c, 0x02, 0x00, 0x00, {0x06, 0x0a}, 2, 4, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0205, 0x02, 0x00, 0x02, {0x01, 0x04}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x20}, {0x00, 0x00}, }, - { 0x0201, 0x0b, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, - { 0x0080, 0x0b, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0100, 0x0b, 0x00, 0x02, {0x05, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x0c, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0080, 0x0c, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0100, 0x0c, 0x00, 0x02, {0x05, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x0d, 0x00, 0x00, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0080, 0x0d, 0x00, 0x02, {0x06, 0x03}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x0e, 0x00, 0x00, {0x06, 0x08}, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x0e, 0x00, 0x00, {0x06, 0x0e}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x0f, 0x00, 0x00, {0x08, 0x06}, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x0f, 0x00, 0x00, {0x0e, 0x06}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x02, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x02, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0110, 0x02, 0x00, 0x00, {0x03, 0x07}, 2, 1, 0, 0, 3, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0018, 0x02, 0x00, 0x00, {0x06, 0x0a}, 2, 4, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x040a, 0x02, 0x00, 0x02, {0x01, 0x04}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x20}, {0x00, 0x00}, }, + { 0x0402, 0x0b, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, + { 0x0100, 0x0b, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0200, 0x0b, 0x00, 0x02, {0x05, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0402, 0x0c, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0100, 0x0c, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0200, 0x0c, 0x00, 0x02, {0x05, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x0d, 0x00, 0x00, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0100, 0x0d, 0x00, 0x02, {0x06, 0x03}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x0e, 0x00, 0x00, {0x06, 0x08}, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x0e, 0x00, 0x00, {0x06, 0x0e}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x0f, 0x00, 0x00, {0x08, 0x06}, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x0f, 0x00, 0x00, {0x0e, 0x06}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x10, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x11, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x12, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x13, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0402, 0x11, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0402, 0x12, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0402, 0x13, 0x00, 0x02, {0x02, 0x01}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x14, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x15, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x16, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x17, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x03, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0219, 0x03, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x03, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x04, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x04, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x04, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x05, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0219, 0x05, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x05, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x06, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0219, 0x06, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x06, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x07, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x07, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x07, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x08, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0219, 0x08, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x08, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x09, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x09, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x09, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x020d, 0x0a, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0219, 0x0a, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x0a, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x18, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0080, 0x18, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x03, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0432, 0x03, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x03, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x04, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x04, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x04, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x05, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0432, 0x05, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x05, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x06, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0432, 0x06, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x06, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x07, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x07, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x07, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x08, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0432, 0x08, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x08, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x09, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x09, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x09, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x041a, 0x0a, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0432, 0x0a, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x0a, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x18, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0100, 0x18, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x19, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x1a, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x1b, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, - { 0x0080, 0x1b, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x1c, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x1f, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x20, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x22, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x23, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x27, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x1b, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, + { 0x0100, 0x1b, 0x00, 0x02, {0x03, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x1c, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x1f, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x20, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x22, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x30, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x23, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x27, 0x00, 0x00, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, { 0x0000, 0x1d, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x1e, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0002, 0x21, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x0a, 0xff}, }, - { 0x0002, 0x24, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x0a, 0xff}, }, + { 0x0004, 0x21, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x0a, 0xff}, }, + { 0x0004, 0x24, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x0a, 0xff}, }, { 0x0000, 0x25, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x26, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0229, 0x2b, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x2c, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x2d, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x2e, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x28, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x29, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, - { 0x0229, 0x2a, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, - { 0x0209, 0x2f, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0209, 0x2f, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, - { 0x0008, 0x2f, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0440, 0x30, 0x02, 0x00, {0x00, 0x00}, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x31, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x32, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x33, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x34, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0008, 0x35, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0400, 0x5b, 0x02, 0x00, {0x00, 0x00}, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0500, 0x5c, 0x02, 0x00, {0x00, 0x00}, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0452, 0x2b, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x2c, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x08, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x2d, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x2e, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x28, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x29, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, + { 0x0452, 0x2a, 0x00, 0x00, {0x01, 0x0f}, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, {0x38, 0x38}, {0x00, 0x00}, }, + { 0x0412, 0x2f, 0x00, 0x00, {0x01, 0x02}, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0412, 0x2f, 0x00, 0x00, {0x01, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x38}, {0x00, 0x00}, }, + { 0x0010, 0x2f, 0x00, 0x00, {0x06, 0x07}, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0880, 0x30, 0x02, 0x00, {0x00, 0x00}, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x31, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x32, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x33, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x34, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0010, 0x35, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0800, 0x5b, 0x02, 0x00, {0x00, 0x00}, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, + { 0x0a00, 0x5c, 0x02, 0x00, {0x00, 0x00}, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x36, 0x00, 0x00, {0x0c, 0x00}, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x36, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, + { 0x0402, 0x36, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x10, 0x38}, {0x00, 0x00}, }, { 0x0000, 0x36, 0x01, 0x00, {0x0d, 0x00}, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x36, 0x01, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, + { 0x0402, 0x36, 0x01, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x18, 0x38}, {0x00, 0x00}, }, { 0x0000, 0x37, 0x00, 0x00, {0x0c, 0x00}, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x37, 0x00, 0x00, {0x0b, 0x00}, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x37, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, + { 0x0402, 0x37, 0x00, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x20, 0x38}, {0x00, 0x00}, }, { 0x0000, 0x37, 0x01, 0x00, {0x0d, 0x00}, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, - { 0x0201, 0x37, 0x01, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, + { 0x0402, 0x37, 0x01, 0x02, {0x01, 0x00}, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x28, 0x38}, {0x00, 0x00}, }, { 0x0000, 0x38, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x38, 0x00, 0x00, {0x09, 0x00}, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, { 0x0000, 0x39, 0x00, 0x00, {0x00, 0x00}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0x00, 0x00}, {0x00, 0x00}, }, diff --git a/code/8086/serializer.c b/code/8086/serializer.c new file mode 100644 index 0000000..7964486 --- /dev/null +++ b/code/8086/serializer.c @@ -0,0 +1,522 @@ +#ifdef INTELLISENSE_DIRECTIVES +# include "serializer.h" +#endif + +enum { + X8616_SERIALIZE_HEADER_LEN = 9, +}; + +RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n"); + +RO_ global Str8 x8616_serialize_mnemonic[] = { + [x8616_op_invalid] = slit8(""), + [x8616_op_nop] = slit8("nop"), + [x8616_op_mov] = slit8("mov"), + [x8616_op_add] = slit8("add"), + [x8616_op_or] = slit8("or"), + [x8616_op_adc] = slit8("adc"), + [x8616_op_sbb] = slit8("sbb"), + [x8616_op_and] = slit8("and"), + [x8616_op_sub] = slit8("sub"), + [x8616_op_xor] = slit8("xor"), + [x8616_op_cmp] = slit8("cmp"), + [x8616_op_push] = slit8("push"), + [x8616_op_pop] = slit8("pop"), + [x8616_op_xchg] = slit8("xchg"), + [x8616_op_in] = slit8("in"), + [x8616_op_out] = slit8("out"), + [x8616_op_xlat] = slit8("xlat"), + [x8616_op_lea] = slit8("lea"), + [x8616_op_lds] = slit8("lds"), + [x8616_op_les] = slit8("les"), + [x8616_op_lahf] = slit8("lahf"), + [x8616_op_sahf] = slit8("sahf"), + [x8616_op_pushf] = slit8("pushf"), + [x8616_op_popf] = slit8("popf"), + [x8616_op_inc] = slit8("inc"), + [x8616_op_aaa] = slit8("aaa"), + [x8616_op_daa] = slit8("daa"), + [x8616_op_dec] = slit8("dec"), + [x8616_op_neg] = slit8("neg"), + [x8616_op_aas] = slit8("aas"), + [x8616_op_das] = slit8("das"), + [x8616_op_mul] = slit8("mul"), + [x8616_op_imul] = slit8("imul"), + [x8616_op_aam] = slit8("aam"), + [x8616_op_div] = slit8("div"), + [x8616_op_idiv] = slit8("idiv"), + [x8616_op_aad] = slit8("aad"), + [x8616_op_cbw] = slit8("cbw"), + [x8616_op_cwd] = slit8("cwd"), + [x8616_op_not] = slit8("not"), + [x8616_op_shl] = slit8("shl"), + [x8616_op_shr] = slit8("shr"), + [x8616_op_sar] = slit8("sar"), + [x8616_op_rol] = slit8("rol"), + [x8616_op_ror] = slit8("ror"), + [x8616_op_rcl] = slit8("rcl"), + [x8616_op_rcr] = slit8("rcr"), + [x8616_op_test] = slit8("test"), + [x8616_op_rep] = slit8(""), + [x8616_op_movs] = slit8("movs"), + [x8616_op_cmps] = slit8("cmps"), + [x8616_op_scas] = slit8("scas"), + [x8616_op_lods] = slit8("lods"), + [x8616_op_stos] = slit8("stos"), + [x8616_op_call] = slit8("call"), + [x8616_op_jmp] = slit8("jmp"), + [x8616_op_ret] = slit8("ret"), + [x8616_op_retf] = slit8("retf"), + [x8616_op_je] = slit8("je"), + [x8616_op_jl] = slit8("jl"), + [x8616_op_jle] = slit8("jle"), + [x8616_op_jb] = slit8("jb"), + [x8616_op_jbe] = slit8("jbe"), + [x8616_op_jp] = slit8("jp"), + [x8616_op_jo] = slit8("jo"), + [x8616_op_js] = slit8("js"), + [x8616_op_jne] = slit8("jne"), + [x8616_op_jnl] = slit8("jnl"), + [x8616_op_jg] = slit8("jg"), + [x8616_op_jnb] = slit8("jnb"), + [x8616_op_ja] = slit8("ja"), + [x8616_op_jnp] = slit8("jnp"), + [x8616_op_jno] = slit8("jno"), + [x8616_op_jns] = slit8("jns"), + [x8616_op_loop] = slit8("loop"), + [x8616_op_loopz] = slit8("loopz"), + [x8616_op_loopnz] = slit8("loopnz"), + [x8616_op_jcxz] = slit8("jcxz"), + [x8616_op_int] = slit8("int"), + [x8616_op_int3] = slit8("int3"), + [x8616_op_into] = slit8("into"), + [x8616_op_iret] = slit8("iret"), + [x8616_op_clc] = slit8("clc"), + [x8616_op_cmc] = slit8("cmc"), + [x8616_op_stc] = slit8("stc"), + [x8616_op_cld] = slit8("cld"), + [x8616_op_std] = slit8("std"), + [x8616_op_cli] = slit8("cli"), + [x8616_op_sti] = slit8("sti"), + [x8616_op_hlt] = slit8("hlt"), + [x8616_op_wait] = slit8("wait"), + [x8616_op_lock] = slit8(""), + [x8616_op_segment] = slit8(""), +}; + +RO_ global Str8 x8616_serialize_reg8[] = { + [x8616_al] = slit8("al"), + [x8616_cl] = slit8("cl"), + [x8616_dl] = slit8("dl"), + [x8616_bl] = slit8("bl"), + [x8616_ah] = slit8("ah"), + [x8616_ch] = slit8("ch"), + [x8616_dh] = slit8("dh"), + [x8616_bh] = slit8("bh"), +}; + +RO_ global Str8 x8616_serialize_reg16[] = { + [x8616_ax] = slit8("ax"), + [x8616_cx] = slit8("cx"), + [x8616_dx] = slit8("dx"), + [x8616_bx] = slit8("bx"), + [x8616_sp] = slit8("sp"), + [x8616_bp] = slit8("bp"), + [x8616_si] = slit8("si"), + [x8616_di] = slit8("di"), +}; + +RO_ global Str8 x8616_serialize_seg[] = { + [x8616_es] = slit8("es"), + [x8616_cs] = slit8("cs"), + [x8616_ss] = slit8("ss"), + [x8616_ds] = slit8("ds"), +}; + +RO_ global Str8 x8616_serialize_ea[] = { + [x8616_ea_bx_si] = slit8("bx + si"), + [x8616_ea_bx_di] = slit8("bx + di"), + [x8616_ea_bp_si] = slit8("bp + si"), + [x8616_ea_bp_di] = slit8("bp + di"), + [x8616_ea_si] = slit8("si"), + [x8616_ea_di] = slit8("di"), + [x8616_ea_bp] = slit8("bp"), + [x8616_ea_bx] = slit8("bx"), +}; + +typedef Enum_(U1, X8616_SerializeSizeWhere) { + x8616_serialize_size_none = 0x00, + x8616_serialize_size_before_mem = 0x01, + x8616_serialize_size_before_imm = 0x02, +}; + +FI_ B4 x8616_serialize_put(Str8Gen_R gen, Str8 piece) { + if (piece.len > gen->cap - gen->len) return false; + str8gen_append_str8(gen, piece); return true; +} + +FI_ X8616_SerializeStatus x8616_serialize_put_or_full(Str8Gen_R gen, Str8 piece) { + X8616_SerializeStatus status = x8616_serialize_ok; + if (x8616_serialize_put(gen, piece) == 0) status = x8616_serialize_output_full; + return status; +} + +internal B4 x8616_serialize_put_u4(Str8Gen_R gen, U4 value) { + Info_str8_from_u4 info = str8_from_u4_info(value, 10, 0, 0); + UTF8 digits[16]; + B4 ok = info.size_required != 0 && info.size_required <= Array_len(digits) && info.size_required <= gen->cap - gen->len; + if (ok) { + Str8 text = str8_from_u4_buf(slice_ut(digits, info.size_required), value, 10, 0, 0, info); + ok = x8616_serialize_put(gen, text); + } + return ok; +} + +internal B4 x8616_serialize_put_s4(Str8Gen_R gen, S4 value) { + B4 ok = true; + if (value < 0) { + ok = x8616_serialize_put(gen, slit8("-")); + if (ok) ok = x8616_serialize_put_u4(gen, C_(U4, -value)); + } + else { + ok = x8616_serialize_put_u4(gen, C_(U4, value)); + } + return ok; +} + +internal S4 x8616_serialize_s4_from_bits(U2 bits, U1 byte_count) { + if (byte_count <= 1) { + U4 value = bits & 0xFF; + if (value & 0x80) return C_(S4, value) - 256; + return C_(S4, value); + } + U4 value = bits; + if (value & 0x8000) return C_(S4, value) - 65536; + return C_(S4, value); +} + +FI_ B4 x8616_serialize_imm_is_signed(X8616_Op op) { switch (op) { + case x8616_op_mov: + case x8616_op_add: + case x8616_op_adc: + case x8616_op_sub: + case x8616_op_sbb: + case x8616_op_cmp: + case x8616_op_ret: + case x8616_op_retf: + return 1; + default: + return 0; +}} + +FI_ U1 x8616_serialize_imm_bytes(X8616_DecodedOperandFlags flags, U1 immediate_bytes, X8616_WidthMode width) { + if (immediate_bytes) return immediate_bytes; + if (flags & x8616_decoded_operand_sign_extended) return 1; + if (width == x8616_width_word) return 2; + return 1; +} + +internal B4 +x8616_serialize_put_imm(Str8Gen_R gen, X8616_DecodedInstruction_R inst, X8616_DecodedOperand_R operand) { + U1 bytes = x8616_serialize_imm_bytes(operand->flags, operand->immediate_bytes, operand->width); + if (x8616_serialize_imm_is_signed(inst->op)) { + return x8616_serialize_put_s4(gen, x8616_serialize_s4_from_bits(operand->immediate, bytes)); + } + U4 value = operand->immediate; + if (bytes <= 1) value &= 0xFF; + return x8616_serialize_put_u4(gen, value); +} + +internal X8616_WidthMode +x8616_serialize_mem_width(X8616_DecodedInstruction_R inst) { + for (U1 id = 0; id < inst->operand_count; ++id) { + if (inst->operands[id].flags & x8616_decoded_operand_memory) return inst->operands[id].width; + } + return inst->width; +} + +internal X8616_SerializeSizeWhere +x8616_serialize_size_where(X8616_Op op, U1 operand_count, X8616_DecodedOperand operands[static 2]) +{ + B4 has_mem = 0; + B4 has_imm = 0; + for (U1 id = 0; id < operand_count; ++id) { + X8616_DecodedOperandFlags flags = operands[id].flags; + if (flags & x8616_decoded_operand_memory) has_mem = 1; + if ((flags & x8616_decoded_operand_immediate) && ((flags & x8616_decoded_operand_register) == 0)) has_imm = 1; + } + switch (op) { + case x8616_op_mov: + if (has_mem && has_imm) return x8616_serialize_size_before_imm; + return x8616_serialize_size_none; + case x8616_op_add: + case x8616_op_adc: + case x8616_op_sub: + case x8616_op_sbb: + case x8616_op_cmp: + case x8616_op_and: + case x8616_op_or: + case x8616_op_xor: + case x8616_op_test: + if (has_mem && has_imm) return x8616_serialize_size_before_mem; + return x8616_serialize_size_none; + case x8616_op_not: + case x8616_op_neg: + case x8616_op_inc: + case x8616_op_dec: + case x8616_op_mul: + case x8616_op_imul: + case x8616_op_div: + case x8616_op_idiv: + case x8616_op_push: + case x8616_op_pop: + case x8616_op_shl: + case x8616_op_shr: + case x8616_op_sar: + case x8616_op_rol: + case x8616_op_ror: + case x8616_op_rcl: + case x8616_op_rcr: + if (has_mem) return x8616_serialize_size_before_mem; + return x8616_serialize_size_none; + default: + return x8616_serialize_size_none; + } +} + +internal B4 x8616_serialize_put_size(Str8Gen_R gen, X8616_WidthMode width) { + Str8 name = slit8(""); + if (width == x8616_width_byte) name = slit8("byte"); + if (width == x8616_width_word) name = slit8("word"); + B4 ok = name.len != 0; + if (ok) ok = x8616_serialize_put(gen, name); + if (ok) ok = x8616_serialize_put(gen, slit8(" ")); + return ok; +} + +internal B4 +x8616_serialize_put_memory(Str8Gen_R gen, X8616_DecodedInstruction_R inst, X8616_DecodedOperand_R operand) +{ + B4 ok = true; + if (inst->prefixes.has_segment) { + ok = x8616_serialize_put(gen, x8616_serialize_seg[inst->prefixes.segment]); + if (ok) ok = x8616_serialize_put(gen, slit8(":")); + } + if (ok) ok = x8616_serialize_put(gen, slit8("[")); + if (ok && (operand->flags & x8616_decoded_operand_direct)) { + ok = x8616_serialize_put_u4(gen, operand->address); + } + else if (ok) { + ok = x8616_serialize_put(gen, x8616_serialize_ea[operand->ea]); + S4 disp = operand->displacement; + if (ok && disp > 0) { + ok = x8616_serialize_put(gen, slit8(" + ")); + if (ok) ok = x8616_serialize_put_u4(gen, C_(U4, disp)); + } + else if (ok && disp < 0) { + ok = x8616_serialize_put(gen, slit8(" - ")); + if (ok) ok = x8616_serialize_put_u4(gen, C_(U4, -disp)); + } + } + if (ok) ok = x8616_serialize_put(gen, slit8("]")); + return ok; +} + +FI_ B4 x8616_serialize_is_string(X8616_Op op) { switch (op) { + case x8616_op_movs: + case x8616_op_cmps: + case x8616_op_scas: + case x8616_op_lods: + case x8616_op_stos: + return 1; + default: + return 0; +}} + +FI_ B4 x8616_serialize_has_memory(X8616_DecodedInstruction* inst) { + for (U1 id = 0; id < inst->operand_count; ++id) { if (inst->operands[id].flags & x8616_decoded_operand_memory) return 1; } + return 0; +} + +internal X8616_SerializeStatus +x8616_serialize_put_operand(Str8Gen_R gen, X8616_DecodedInstruction* inst, X8616_DecodedOperand* operand) +{ + X8616_SerializeStatus status = x8616_serialize_ok; + X8616_SerializeSizeWhere where = x8616_serialize_size_where(inst->op, inst->operand_count, inst->operands); + X8616_WidthMode width = x8616_serialize_mem_width(inst); + B4 is_mem = (operand->flags & x8616_decoded_operand_memory) != 0; + B4 is_imm = ((operand->flags & x8616_decoded_operand_immediate) != 0) && ((operand->flags & x8616_decoded_operand_register) == 0); + B4 is_reg = (operand->flags & x8616_decoded_operand_register) != 0; + B4 is_seg = (operand->flags & x8616_decoded_operand_segment) != 0; + B4 is_rel = (operand->flags & x8616_decoded_operand_relative) != 0; + B4 is_far = (operand->flags & x8616_decoded_operand_far_ptr) != 0; + + if (status == x8616_serialize_ok && where == x8616_serialize_size_before_mem && is_mem) { + if (x8616_serialize_put_size(gen, width) == 0) status = x8616_serialize_output_full; + } + if (status == x8616_serialize_ok && where == x8616_serialize_size_before_imm && is_imm) { + if (x8616_serialize_put_size(gen, width) == 0) status = x8616_serialize_output_full; + } + if (status == x8616_serialize_ok && (inst->flags & x8616_encoding_far) && is_mem) { + status = x8616_serialize_put_or_full(gen, slit8("far ")); + } + + if (status == x8616_serialize_ok) { + if (is_reg) { + U1 index = C_(U1, operand->reg.r16); + if (operand->width == x8616_width_byte) status = x8616_serialize_put_or_full(gen, x8616_serialize_reg8 [index]); + else if (operand->width == x8616_width_word) status = x8616_serialize_put_or_full(gen, x8616_serialize_reg16[index]); + else status = x8616_serialize_unsupported_form; + } + else if (is_seg) { + status = x8616_serialize_put_or_full(gen, x8616_serialize_seg[operand->segment]); + } + else if (is_mem) { + if (x8616_serialize_put_memory(gen, inst, operand) == 0) status = x8616_serialize_output_full; + } + else if (is_imm) { + if (x8616_serialize_put_imm(gen, inst, operand) == 0) status = x8616_serialize_output_full; + } + else if (is_rel) { + S4 rel = C_(S4, inst->size) + operand->displacement; + status = x8616_serialize_put_or_full(gen, slit8("$")); + if (status == x8616_serialize_ok && rel >= 0) status = x8616_serialize_put_or_full(gen, slit8("+")); + if (status == x8616_serialize_ok && x8616_serialize_put_s4(gen, rel) == 0) status = x8616_serialize_output_full; + } + else if (is_far) { + if (x8616_serialize_put_u4(gen, operand->far_segment) == 0) status = x8616_serialize_output_full; + if (status == x8616_serialize_ok) status = x8616_serialize_put_or_full(gen, slit8(":")); + if (status == x8616_serialize_ok && x8616_serialize_put_u4(gen, operand->far_offset) == 0) status = x8616_serialize_output_full; + } + else { + status = x8616_serialize_unsupported_form; + } + } + return status; +} + +FI_ X8616_DecodedOperandFlags x8616_serialize_base_flags(X8616_DecodedOperandFlags flags) { + return flags & ( + x8616_decoded_operand_register + | x8616_decoded_operand_segment + | x8616_decoded_operand_memory + | x8616_decoded_operand_immediate + | x8616_decoded_operand_relative + | x8616_decoded_operand_far_ptr + ); +} + +FI_ B4 x8616_serialize_one_flag(X8616_DecodedOperandFlags flags) { U2 bits = C_(U2, flags); return (bits != 0) && ((bits & (bits - 1)) == 0); } + +internal X8616_SerializeStatus +x8616_serialize_validate(X8616_DecodedInstruction_R inst) +{ + X8616_SerializeStatus status = x8616_serialize_ok; + + B4 bad_decode = inst->decode_flags & (x8616_decode_invalid | x8616_decode_truncated); + B4 invalid_sig = inst->size == 0 || inst->operand_count > 2; + B4 invalid_mnemonic = u4_(inst->op) >= Array_len(x8616_serialize_mnemonic) || inst->op == x8616_op_invalid; + B4 invalid_prefix_with_seg = inst->prefixes.has_segment && u1_(inst->prefixes.segment) >= Array_len(x8616_serialize_seg); + + if (bad_decode || invalid_sig || invalid_mnemonic || invalid_prefix_with_seg) { + status = x8616_serialize_invalid_record; goto status_failed; + } + B4 bad_prefix_segement = inst->prefixes.has_segment && (x8616_serialize_has_memory(inst) == 0); + B4 bad_prefix_repeat = inst->prefixes.has_repeat && (x8616_serialize_is_string(inst->op) == 0); + if (bad_prefix_segement || bad_prefix_repeat) { + status = x8616_serialize_unsupported_form; goto status_failed; + } + + for (U1 id = 0; id < inst->operand_count; ++id) + { + X8616_DecodedOperand_R operand = & inst->operands[id]; + X8616_DecodedOperandFlags base = x8616_serialize_base_flags(operand->flags); + B4 invalid_flag = x8616_serialize_one_flag(base) == 0; + B4 has_operand_register = base & x8616_decoded_operand_register; + B4 has_operand_segment = base & x8616_decoded_operand_segment; + B4 has_operand_memory = base & x8616_decoded_operand_memory; + B4 invalid_reg_r16 = u1_(operand->reg.r16) >= Array_len(x8616_serialize_reg16); + B4 invalid_width = operand->width != x8616_width_byte && operand->width != x8616_width_word; + B4 invalid_operand_seg = u1_(operand->segment) >= Array_len(x8616_serialize_seg); + B4 invalid_operand_ea = u1_(operand->ea) >= Array_len(x8616_serialize_ea); + B4 invalid_direct_ea = has_operand_memory && ((operand->flags & x8616_decoded_operand_direct) == 0) && invalid_operand_ea; + B4 invalid_operand = invalid_flag + || (has_operand_register && (invalid_reg_r16 || invalid_width)) + || (has_operand_segment && invalid_operand_seg) + || invalid_direct_ea; + if (invalid_operand) { + status = x8616_serialize_invalid_record; goto status_failed; + } + } +status_failed: + return status; +} + +internal X8616_SerializeStatus +x8616_serialize_instruction_line(Str8Gen_R line, X8616_DecodedInstruction* inst) +{ + X8616_SerializeStatus st = x8616_serialize_ok; + Str8 mnemonic = x8616_serialize_mnemonic[inst->op]; + if (mnemonic.len == 0) st = x8616_serialize_unsupported_form; + + if (st == x8616_serialize_ok && inst->prefixes.lock) { + st = x8616_serialize_put_or_full(line, slit8("lock ")); + } + if (st == x8616_serialize_ok && inst->prefixes.has_repeat) { + if (inst->prefixes.repeat == x8616_rep) st = x8616_serialize_put_or_full(line, slit8("rep ")); + else st = x8616_serialize_put_or_full(line, slit8("repne ")); + } + if (st == x8616_serialize_ok) st = x8616_serialize_put_or_full(line, mnemonic); + + if (st == x8616_serialize_ok && x8616_serialize_is_string(inst->op)) { + if (inst->width == x8616_width_byte) st = x8616_serialize_put_or_full(line, slit8("b")); + else if (inst->width == x8616_width_word) st = x8616_serialize_put_or_full(line, slit8("w")); + else st = x8616_serialize_unsupported_form; + } + + if (st == x8616_serialize_ok && inst->operand_count) { + st = x8616_serialize_put_or_full(line, slit8(" ")); + for (U1 id = 0; st == x8616_serialize_ok && id < inst->operand_count; ++id) { + if (id) st = x8616_serialize_put_or_full(line, slit8(", ")); + if (st == x8616_serialize_ok) st = x8616_serialize_put_operand(line, inst, & inst->operands[id]); + } + } + if (st == x8616_serialize_ok) st = x8616_serialize_put_or_full(line, slit8("\n")); + return st; +} + +X8616_SerializeInfo +x8616_serialize_instructions(X8616_SerializeRequest request) +{ + X8616_SerializeInfo result = {0}; result.text.ptr = C_(UTF8*, request.output.ptr); + B4 invalid_record = + (request.instruction_count && request.instructions == 0) + || (request.output.len && request.output.ptr == 0) + || (request.scratch.len && request.scratch.ptr == 0); + if (invalid_record) { result.status = x8616_serialize_invalid_record; goto exit; } + if (request.output.len < X8616_SERIALIZE_HEADER_LEN) { result.status = x8616_serialize_output_full; goto exit; } + + Str8Gen gen = str8gen_make(request.output); + if (x8616_serialize_header.len > gen.cap - gen.len) { result.status = x8616_serialize_output_full; goto exit; } + str8gen_append_str8(& gen, x8616_serialize_header); + result.text.len = gen.len; + + for (U4 id = 0; id < request.instruction_count; ++id) { + X8616_SerializeStatus line_status = x8616_serialize_validate(& request.instructions[id]); + if (line_status != x8616_serialize_ok) { result.status = line_status; goto exit; } + + Str8Gen line = str8gen_make(request.scratch); + line_status = x8616_serialize_instruction_line(& line, & request.instructions[id]); + if (line_status != x8616_serialize_ok) { result.status = line_status; goto exit; } + + Str8 text = str8(line.ptr, line.len); + if (text.len > gen.cap - gen.len) { result.status = x8616_serialize_output_full; goto exit; } + str8gen_append_str8(& gen, text); + result.text.len = gen.len; + result.instructions_written += 1; + } + + result.status = x8616_serialize_ok; +exit: + return result; +} diff --git a/code/8086/serializer.h b/code/8086/serializer.h new file mode 100644 index 0000000..dc1350e --- /dev/null +++ b/code/8086/serializer.h @@ -0,0 +1,26 @@ +#ifdef INTELLISENSE_DIRECTIVES +# pragma once +# include "decoder.h" +#endif + +typedef Enum_(U1, X8616_SerializeStatus) { + x8616_serialize_ok = 0x00, + x8616_serialize_output_full = 0x01, + x8616_serialize_invalid_record = 0x02, + x8616_serialize_unsupported_form = 0x03, +}; + +typedef Struct_(X8616_SerializeRequest) { + X8616_DecodedInstruction* instructions; + U4 instruction_count; + Slice output; + Slice scratch; +}; + +typedef Struct_(X8616_SerializeInfo) { + Str8 text; + U4 instructions_written; + X8616_SerializeStatus status; +}; + +X8616_SerializeInfo x8616_serialize_instructions(X8616_SerializeRequest request); diff --git a/code/duffle/dsl.h b/code/duffle/dsl.h index f73f7ff..6ff9264 100644 --- a/code/duffle/dsl.h +++ b/code/duffle/dsl.h @@ -222,6 +222,10 @@ def_signed_ops(le, <=) #define dbg_args(...) __VA_ARGS__ #pragma region Control Flow & Iteration +#define jump_ne(a,b,label) if (a != b) goto label +#define jump_gt(a,b,label) if (a > b) goto label +#define jump_lt(a,b,label) if (a < b) goto label + #define unreachable() __builtin_unreachable() #define each_iter(type, iter, end) (type iter = 0; iter < end; ++ iter) diff --git a/code/part_1/sim_8086.c b/code/part_1/sim_8086.c index c1ba231..9bd350e 100644 --- a/code/part_1/sim_8086.c +++ b/code/part_1/sim_8086.c @@ -16,9 +16,11 @@ #include "8086/info.h" #include "8086/info_render.h" #include "8086/decoder.h" +#include "8086/serializer.h" #include "8086/gen/decoder_table.h" #include "8086/decoder.c" +#include "8086/serializer.c" // #include "8086/decoder.h" @@ -57,7 +59,6 @@ FI_ void a8utf8_from_u1_be(UTF8 out[8], U1 value) { I_ U4 binary_as_str8_eval_len(Slice_U1 data) { return data.len * 8; } -#define jump_lt(a,b,label) if (a < b) goto label I_ Str8 binary_as_str8(Slice_U1 data, FArena* str8_mem) { Str8 result = {0}; U4 req_len = data.len * 8; jump_lt(str8_mem->capacity,req_len, jret); @@ -74,7 +75,8 @@ typedef Struct_(SMemory) { U1 Scratchpad [Scratchpad_Len]; U1 FileRam [FileRam_Len]; - U1 decode_mem[kilo(64)]; + U1 decode_mem[kilo(64)]; + UTF8 text_mem [kilo(16)]; }; global SMemory smem; @@ -103,8 +105,22 @@ int main() .instruction_capacity = decoded.len, .info_arena = & decode_arena, ); - assert(info.instruction_count > 0); - // Str8 infO_report = x8616_info_render(slice_ut_arr(smem.Scratchpad), info.msgs.first,); + if (info.source_consumed != data.len || info.instruction_count == 0 || info.msgs.error_count || info.msgs.dropped_count) { + ms_exit_process(10); + return 10; + } + X8616_SerializeInfo text = x8616_serialize_instructions((X8616_SerializeRequest){ + .instructions = decoded.ptr, + .instruction_count = info.instruction_count, + .output = slice_ut_arr(smem.text_mem), + .scratch = slice_ut_arr(smem.Scratchpad), + }); + if (text.status != x8616_serialize_ok || text.instructions_written != info.instruction_count) { + ms_exit_process(13); + return 13; + } + Str8 listing_text = text.text; + (void)listing_text; ms_exit_process(0); return 0;