Improve formatting for x86 tables and minimize outputting "zero" entries

This commit is contained in:
gingerBill
2026-06-14 19:16:53 +01:00
parent 2cf2a1341b
commit 1adbd0dcb4
3 changed files with 1072 additions and 10338 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -298,20 +298,19 @@ sbprint :: proc(
}
}
for instruction_index in 0..<len(instructions) {
inst := &instructions[instruction_index]
for &inst, instruction_index in instructions {
info := &inst_info[instruction_index]
// Check if there's a label at this offset
for label_id in 0..<u32(len(label_defs)) {
if label_defs[label_id] != LABEL_UNDEFINED && u32(label_defs[label_id]) == info.offset {
for label_def, label_id in label_defs {
if label_def != LABEL_UNDEFINED && u32(label_def) == info.offset {
// Print label definition
start := strings.builder_len(sb^)
if name, ok := label_names^[label_id]; ok {
if name, ok := label_names^[u32(label_id)]; ok {
strings.write_string(sb, name)
} else {
strings.write_string(sb, options.label_prefix)
print_decimal(sb, label_id)
print_decimal(sb, u32(label_id))
}
strings.write_byte(sb, ':')
emit_token(tokens, sb, .LABEL_DEF, 0xFFFF, start)
@@ -342,7 +341,7 @@ sbprint :: proc(
// Print mnemonic
{
start := strings.builder_len(sb^)
write_mnemonic(sb, inst, &options)
write_mnemonic(sb, &inst, &options)
emit_token(tokens, sb, .MNEMONIC, u16(instruction_index), start)
}
@@ -364,7 +363,9 @@ sbprint :: proc(
}
op := &inst.ops[i]
#partial switch op.kind {
switch op.kind {
case .NONE:
//
case .REGISTER:
start := strings.builder_len(sb^)
write_register(sb, op.reg, &options)

View File

@@ -51,14 +51,14 @@ generate_header :: proc(sb: ^strings.Builder) {
// =============================================================================
// ModR/M Lookup Table
// =============================================================================
// Precomputed extraction of mod, reg, rm fields from ModR/M byte
// Precomputed extraction of mod, reg, rm fields from ModR/M byte
ModRM_Info :: struct #packed {
mod: u8, // bits [7:6] - addressing mode
reg: u8, // bits [5:3] - register or opcode extension
rm: u8, // bits [2:0] - register or memory
has_sib: bool, // rm==4 && mod!=3 (SIB byte follows)
disp_size: u8, // displacement size: 0, 1, or 4 bytes
mod: u8, // bits [7:6] - addressing mode
reg: u8, // bits [5:3] - register or opcode extension
rm: u8, // bits [2:0] - register or memory
has_sib: bool, // rm==4 && mod!=3 (SIB byte follows)
disp_size: u8, // displacement size: 0, 1, or 4 bytes
}
`)
@@ -99,12 +99,12 @@ generate_sib_table :: proc(sb: ^strings.Builder) {
strings.write_string(sb, `// =============================================================================
// SIB Lookup Table
// =============================================================================
// Precomputed extraction of scale, index, base fields from SIB byte
// Precomputed extraction of scale, index, base fields from SIB byte
SIB_Info :: struct #packed {
scale: u8, // 1, 2, 4, or 8
index: u8, // index register (0-7, or 0xFF if none when index==4)
base: u8, // base register (0-7, or 0xFF for special cases)
scale: u8, // 1, 2, 4, or 8
index: u8, // index register (0-7, or 0xFF if none when index==4)
base: u8, // base register (0-7, or 0xFF for special cases)
}
`)
@@ -200,17 +200,17 @@ generate_opcode_tables :: proc(sb: ^strings.Builder) {
strings.write_string(sb, `// =============================================================================
// Decode Entry
// =============================================================================
// Information needed to decode an instruction given its opcode bytes
// Information needed to decode an instruction given its opcode bytes
Decode_Entry :: struct {
esc: Escape, // escape sequence used to find this entry
prefix: u8, // mandatory prefix (0=none, 1=66, 2=F3, 3=F2)
opcode: u8, // primary opcode byte
ext: u8, // ModR/M reg extension (0-7) or 0xFF if not used
esc: Escape, // escape sequence used to find this entry
prefix: u8, // mandatory prefix (0=none, 1=66, 2=F3, 3=F2)
opcode: u8, // primary opcode byte
ext: u8, // ModR/M reg extension (0-7) or 0xFF if not used
mnemonic: Mnemonic,
ops: [4]Operand_Type, // operand types
enc: [4]Operand_Encoding, // operand encodings
flags: Encoding_Flags,
ops: [4]Operand_Type, // operand types
enc: [4]Operand_Encoding, // operand encodings
flags: Encoding_Flags,
}
`)
@@ -230,16 +230,16 @@ Decode_Entry :: struct {
// =============================================================================
VEX_Decode_Entry :: struct {
esc: Escape,
prefix: u8,
opcode: u8,
ext: u8,
vex_w: VEX_W,
vex_l: VEX_L,
esc: Escape,
prefix: u8,
opcode: u8,
ext: u8,
vex_w: VEX_W,
vex_l: VEX_L,
mnemonic: Mnemonic,
ops: [4]Operand_Type,
enc: [4]Operand_Encoding,
flags: Encoding_Flags,
ops: [4]Operand_Type,
enc: [4]Operand_Encoding,
flags: Encoding_Flags,
}
`)
@@ -389,8 +389,8 @@ generate_vex_index_tables :: proc(sb: ^strings.Builder, entries: []Collected_Ent
strings.write_string(sb, fmt.tprintf(`// =============================================================================
// %s Index Tables for O(1) Opcode Lookup
// =============================================================================
// Indexed by [esc_idx][prefix][opcode] where esc_idx: 0=0F, 1=0F38, 2=0F3A
// Indexed by [esc_idx][prefix][opcode] where esc_idx: 0=0F, 1=0F38, 2=0F3A
`, name))
for esc_idx in 0..<3 {
@@ -432,13 +432,11 @@ generate_vex_index_tables :: proc(sb: ^strings.Builder, entries: []Collected_Ent
}
if count > 0 {
strings.write_string(sb, fmt.tprintf("\t\t{{%d, %d}}, // 0x%02X\n", start, count, opcode))
} else {
strings.write_string(sb, fmt.tprintf("\t\t{{0, 0}}, // 0x%02X\n", opcode))
fmt.sbprintfln(sb, "\t\t0x%02X = {{%d, %d}},", opcode, start, count)
}
}
strings.write_string(sb, " },\n")
strings.write_string(sb, "\t},\n")
}
strings.write_string(sb, "}\n\n")
@@ -452,9 +450,9 @@ generate_index_tables :: proc(sb: ^strings.Builder, entries: []Collected_Entry)
strings.write_string(sb, `// =============================================================================
// Index Tables for O(1) Opcode Lookup
// =============================================================================
// Each entry contains (start_index, count) into LEGACY_DECODE_ENTRIES
// Indexed by [esc][prefix][opcode]
Decode_Index :: struct {
start: u16, // start index in LEGACY_DECODE_ENTRIES
count: u8, // number of entries
@@ -504,9 +502,7 @@ Decode_Index :: struct {
}
if count > 0 {
strings.write_string(sb, fmt.tprintf("\t\t{{%d, %d}}, // 0x%02X\n", start, count, opcode))
} else {
strings.write_string(sb, fmt.tprintf("\t\t{{0, 0}}, // 0x%02X\n", opcode))
fmt.sbprintfln(sb, "\t\t0x%02X = {{%d, %d}},", opcode, start, count)
}
}