From 8d50b25246e1f895c7f8d25a835ed295ab9243a1 Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Fri, 14 Feb 2025 20:06:01 -0600 Subject: [PATCH] Minor changes --- bootstrap/bloat-buster/bb.c | 8 +- bootstrap/bloat-buster/data/instructions.dat | 12 +- build.c | 164 +++++++++++++------ 3 files changed, 121 insertions(+), 63 deletions(-) diff --git a/bootstrap/bloat-buster/bb.c b/bootstrap/bloat-buster/bb.c index b1f6977..f8fc78b 100644 --- a/bootstrap/bloat-buster/bb.c +++ b/bootstrap/bloat-buster/bb.c @@ -1524,7 +1524,7 @@ u32 encode_wide(u8* restrict buffer, const EncodingBatch* const restrict batch) __mmask64 has_base_register = _kor_mask64(_kor_mask64(is_rm_register, is_reg_register), is_implicit_register); __m512i rex_b = _mm512_maskz_set1_epi8(_mm512_test_epi8_mask(rm_register, _mm512_set1_epi8(0b1000)), 1 << 0); - __m512i rex_x = _mm512_set1_epi8(0); // TODO + __m512i rex_x = _mm512_setzero(); // TODO __m512i rex_r = _mm512_maskz_set1_epi8(_mm512_test_epi8_mask(reg_register, _mm512_set1_epi8(0b1000)), 1 << 2); __m512i rex_w = _mm512_maskz_set1_epi8(_cvtu64_mask64(batch->rex_w), 1 << 3); __m512i rex_byte = _mm512_or_epi32(_mm512_set1_epi32(0x40), _mm512_or_epi32(_mm512_or_epi32(rex_b, rex_x), _mm512_or_epi32(rex_r, rex_w))); @@ -1588,7 +1588,7 @@ u32 encode_wide(u8* restrict buffer, const EncodingBatch* const restrict batch) _mm512_storeu_epi8(mod_rm_positions, mod_rm_position); __mmask64 sib_mask = _kand_mask64(_mm512_cmpneq_epi8_mask(mod, _mm512_set1_epi8(0b11)), _mm512_cmpeq_epi8_mask(rm, _mm512_set1_epi8(0b100))); - __m512i sib_scale = _mm512_set1_epi8(0); + __m512i sib_scale = _mm512_setzero(); __m512i sib_index = _mm512_maskz_set1_epi8(sib_mask, 0b100 << 3); __m512i sib_base = _mm512_or_epi32(_mm512_and_si512(rm_register, _mm512_maskz_set1_epi8(is_rm_register, 0b111)), _mm512_maskz_set1_epi8(_knot_mask64(is_rm_register), 0b101)); __m512i sib = _mm512_or_epi32(_mm512_or_epi32(sib_index, sib_base), sib_scale); @@ -4865,7 +4865,7 @@ String assemble(String text) __mmask64 has_base_register = _kor_mask64(_kor_mask64(is_rm_register, is_reg_register), is_implicit_register); __m512i rex_b = _mm512_maskz_set1_epi8(_mm512_test_epi8_mask(rm_register, _mm512_set1_epi8(0b1000)), 1 << 0); - __m512i rex_x = _mm512_set1_epi8(0); // TODO + __m512i rex_x = _mm512_setzero(); // TODO __m512i rex_r = _mm512_maskz_set1_epi8(_mm512_test_epi8_mask(reg_register, _mm512_set1_epi8(0b1000)), 1 << 2); __m512i rex_w = _mm512_maskz_set1_epi8(is_rex_w, 1 << 3); __m512i rex_byte = _mm512_or_epi32(_mm512_set1_epi32(0x40), _mm512_or_epi32(_mm512_or_epi32(rex_b, rex_x), _mm512_or_epi32(rex_r, rex_w))); @@ -4939,7 +4939,7 @@ String assemble(String text) _mm512_storeu_epi8(mod_rm_positions, mod_rm_position); __mmask64 sib_mask = _kand_mask64(_mm512_cmpneq_epi8_mask(mod, _mm512_set1_epi8(0b11)), _mm512_cmpeq_epi8_mask(rm, _mm512_set1_epi8(0b100))); - __m512i sib_scale = _mm512_set1_epi8(0); + __m512i sib_scale = _mm512_setzero(); __m512i sib_index = _mm512_maskz_set1_epi8(sib_mask, 0b100 << 3); __m512i sib_base = _mm512_or_epi32(_mm512_and_si512(rm_register, _mm512_maskz_set1_epi8(is_rm_register, 0b111)), _mm512_maskz_set1_epi8(_knot_mask64(is_rm_register), 0b101)); __m512i sib = _mm512_or_epi32(_mm512_or_epi32(sib_index, sib_base), sib_scale); diff --git a/bootstrap/bloat-buster/data/instructions.dat b/bootstrap/bloat-buster/data/instructions.dat index cee89a1..56f8254 100644 --- a/bootstrap/bloat-buster/data/instructions.dat +++ b/bootstrap/bloat-buster/data/instructions.dat @@ -4,13 +4,13 @@ add: class base_arithmetic(/0, 05, 01, 03) adox: class unsigned_add_flag(f3) and: class base_arithmetic(/4, 25, 21, 23) bsf: - r16, rm16 [rm: rex.r 0f bc /r] - r32, rm32 [rm: 0f bc /r] - r64, rm64 [rm: rex.w 0f bc /r] + r16, rm16 [rm: \66 rex.r \0f bc /r] + r32, rm32 [rm: \0f bc /r] + r64, rm64 [rm: rex.w \0f bc /r] bsr: - r16, rm16 [rm: rex.r 0f bd /r] - r32, rm32 [rm: 0f bd /r] - r64, rm64 [rm: rex.w 0f bd /r] + r16, rm16 [rm: \66 rex.r \0f bd /r] + r32, rm32 [rm: \0f bd /r] + r64, rm64 [rm: rex.w \0f bd /r] bswap: r32 [o: 0f c8+r] r64 [o: rex.w 0f c8+r] diff --git a/build.c b/build.c index 94bbd62..4ce90d8 100644 --- a/build.c +++ b/build.c @@ -1787,6 +1787,44 @@ fn x86_64_Register define_register(RegisterSpec spec) return reg; } +STRUCT(BitsetComponent) +{ + String name; + u64 bit_count; +}; + +STRUCT(ByteComponent) +{ + String type_name; + String field_name; + u8 array_length; + u8 type_size; + u8 type_alignment; + u8 bit_count; +}; + +global_variable BitsetComponent bitset_components[] = { + { strlit("is_rm_register"), 1 }, + { strlit("is_reg_register"), 1 }, + { strlit("implicit_register"), 1 }, + { strlit("is_immediate"), 1 }, + { strlit("immediate_size"), 2 }, + { strlit("is_displacement"), 1 }, + { strlit("is_relative"), 1 }, + { strlit("displacement_size"), 1 }, + { strlit("rex_w"), 1 }, + { strlit("opcode_plus_register"), 1 }, + { strlit("opcode_extension"), 3 }, + { strlit("prefix_0f"), 1 }, +}; + +global_variable ByteComponent byte_components[] = { + // TODO: opcode, length -> 1 byte + { .type_name = strlit("u8"), .type_size = sizeof(u8), .type_alignment = alignof(u8), .field_name = strlit("opcode"), .array_length = 2, }, +}; + +global_variable u8 bit_offsets[array_length(bitset_components)]; + fn void metaprogram(Arena* arena) { let(file, file_read(arena, strlit("bootstrap/bloat-buster/data/x86_mnemonic.dat"))); @@ -1803,45 +1841,6 @@ fn void metaprogram(Arena* arena) vb_copy_string(&generated_h, strlit("#endif\n\n")); { - - STRUCT(BitsetComponent) - { - String name; - u64 bit_count; - }; - - STRUCT(ByteComponent) - { - String type_name; - String field_name; - u8 array_length; - u8 type_size; - u8 type_alignment; - u8 bit_count; - }; - - BitsetComponent bitset_components[] = { - { strlit("is_rm_register"), 1 }, - { strlit("is_reg_register"), 1 }, - { strlit("implicit_register"), 1 }, - { strlit("is_immediate"), 1 }, - { strlit("immediate_size"), 2 }, - { strlit("is_displacement"), 1 }, - { strlit("is_relative"), 1 }, - { strlit("displacement_size"), 1 }, - { strlit("rex_w"), 1 }, - { strlit("opcode_plus_register"), 1 }, - { strlit("opcode_extension"), 3 }, - { strlit("prefix_0f"), 1 }, - }; - - ByteComponent byte_components[] = { - // TODO: opcode, length -> 1 byte - { .type_name = strlit("u8"), .type_size = sizeof(u8), .type_alignment = alignof(u8), .field_name = strlit("opcode"), .array_length = 2, }, - }; - - u8 bit_offsets[array_length(bitset_components)]; - u64 total_bit_count = 0; for (u64 i = 0; i < array_length(bitset_components); i += 1) { @@ -2258,6 +2257,14 @@ fn u8 expect_decimal_digit(Parser* parser) } } +fn u8 ascii_couple_to_hex(u8 high_ch, u8 low_ch) +{ + u8 high_int = hex_ch_to_int(high_ch); + u8 low_int = hex_ch_to_int(low_ch); + u8 byte = (high_int << 4) | low_int; + return byte; +} + fn u8 consume_hex_byte(Parser* parser, u8* hex_byte) { u32 i = parser->i; @@ -2272,10 +2279,7 @@ fn u8 consume_hex_byte(Parser* parser, u8* hex_byte) u8 result = is_hex_byte; if (likely(result)) { - u8 high_int = hex_ch_to_int(high_ch); - u8 low_int = hex_ch_to_int(low_ch); - u8 byte = (high_int << 4) | low_int; - *hex_byte = byte; + *hex_byte = ascii_couple_to_hex(high_ch, low_ch); } return result; @@ -2351,25 +2355,40 @@ fn String parse_encoding_type(Parser* parser) return result; } -fn void parse_encoding_details(Parser* parser) +fn void parse_encoding_details(Parser* parser, VirtualBuffer(u8)* buffer) { expect_character(parser, '['); String encoding_type = parse_encoding_type(parser); expect_character(parser, ':'); expect_character(parser, ' '); + u8 plus_register = 0; + u8 opcode_byte = 0; + u8 opcode_byte_is_set = 0; + + u32 atom_count = 0; + while (!consume_character(parser, ']')) { // Parser encoding atom u8 byte; if (consume_hex_byte(parser, &byte)) { + assert(!opcode_byte_is_set); + opcode_byte = byte; + opcode_byte_is_set = 1; + u8 ch = get_ch(parser); - u8 is_plus = ch == '+'; - parser->i += is_plus; - if (unlikely(is_plus)) + switch (ch) { - expect_character(parser, 'r'); + case '+': + { + parser->i += 1; + expect_character(parser, 'r'); + plus_register = 1; + } break; + default: + break; } } else @@ -2388,6 +2407,25 @@ fn void parse_encoding_details(Parser* parser) os_exit(1); } } + else if (string_starts_with(identifier, strlit("lp"))) + { + assert(identifier.length == 6); + assert(identifier.pointer[2] == '('); + assert(identifier.pointer[5] == ')'); + u8 high_ch = identifier.pointer[3]; + u8 low_ch = identifier.pointer[4]; + u8 legacy_prefix = ascii_couple_to_hex(high_ch, low_ch); + + switch (legacy_prefix) + { + } + + todo(); + } + else if (identifier.pointer[0] == 'p') + { + todo(); + } else if (s_equal(identifier, strlit("rex"))) { expect_character(parser, '.'); @@ -2432,10 +2470,14 @@ fn void parse_encoding_details(Parser* parser) } consume_character(parser, ' '); + + atom_count += 1; } + + // TODO: serialize } -fn void parse_encoding(Parser* parser) +fn void parse_encoding(Parser* parser, VirtualBuffer(u8)* buffer) { u8 first_ch = get_ch(parser); u32 start = parser->i; @@ -2459,7 +2501,7 @@ fn void parse_encoding(Parser* parser) expect_character(parser, ' '); } - parse_encoding_details(parser); + parse_encoding_details(parser, buffer); } fn void parse_instruction_table(Arena* arena) @@ -2474,18 +2516,31 @@ fn void parse_instruction_table(Arena* arena) VirtualBuffer(u8) file_memory = {}; VirtualBuffer(u8)* f = &file_memory; + VirtualBuffer(u8) isel_table = {}; + VirtualBuffer(u8) encoding_table = {}; + + u16 mnemonic_count = 0; + u32 total_encoding_count = 0; let_cast(u32, file_length, file.length); + while (parser->i < file_length) { String mnemonic = parse_mnemonic(parser); + u16 mnemonic_index = mnemonic_count; + + u32 encoding_offset = total_encoding_count; + u16 encoding_count = 0; + + mnemonic_count += 1; expect_character(parser, ':'); if (consume_character(parser, '\n')) { while (consume_tab(parser)) { - parse_encoding(parser); + parse_encoding(parser, &encoding_table); expect_character(parser, '\n'); + encoding_count += 1; } } else if (consume_character(parser, ' ')) @@ -2495,7 +2550,8 @@ fn void parse_instruction_table(Arena* arena) { case '[': { - parse_encoding_details(parser); + parse_encoding_details(parser, &encoding_table); + encoding_count += 1; } break; default: { @@ -2616,7 +2672,7 @@ fn void parse_instruction_table(Arena* arena) else { parser->i -= identifier.length; - parse_encoding(parser); + parse_encoding(parser, &encoding_table); } } break; } @@ -2627,6 +2683,8 @@ fn void parse_instruction_table(Arena* arena) { todo(); } + + total_encoding_count += encoding_count; } }