mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-20 14:41:09 +00:00
spaces -> tabs
This commit is contained in:
@@ -9,99 +9,99 @@ import "../../isa"
|
||||
|
||||
@(private="file")
|
||||
check :: proc(name: string, instructions: []v.Instruction, label_defs: []isa.Label_Definition, want: []u8) {
|
||||
code := make([]u8, 64, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
code := make([]u8, 64, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
|
||||
byte_count, success := v.encode(instructions, label_defs, code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] %s: encode failed\n", name)
|
||||
for e in errors { fmt.printf(" code=%v inst_idx=%d\n", e.code, e.inst_idx) }
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
if int(byte_count) != len(want) {
|
||||
fmt.printf(" [FAIL] %s: byte_count %d (want %d)\n", name, byte_count, len(want))
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
for i in 0..<len(want) {
|
||||
if code[i] != want[i] {
|
||||
fmt.printf(" [FAIL] %s: byte %d (got %02x, want %02x)\n", name, i, code[i], want[i])
|
||||
fmt.printf(" got ")
|
||||
for j in 0..<len(want) { fmt.printf("%02x ", code[j]) }
|
||||
fmt.printf("\n want ")
|
||||
for j in 0..<len(want) { fmt.printf("%02x ", want[j]) }
|
||||
fmt.println()
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.printf(" [ok] %-35s bytes=", name)
|
||||
for i in 0..<len(want) { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
byte_count, success := v.encode(instructions, label_defs, code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] %s: encode failed\n", name)
|
||||
for e in errors { fmt.printf(" code=%v inst_idx=%d\n", e.code, e.inst_idx) }
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
if int(byte_count) != len(want) {
|
||||
fmt.printf(" [FAIL] %s: byte_count %d (want %d)\n", name, byte_count, len(want))
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
for i in 0..<len(want) {
|
||||
if code[i] != want[i] {
|
||||
fmt.printf(" [FAIL] %s: byte %d (got %02x, want %02x)\n", name, i, code[i], want[i])
|
||||
fmt.printf(" got ")
|
||||
for j in 0..<len(want) { fmt.printf("%02x ", code[j]) }
|
||||
fmt.printf("\n want ")
|
||||
for j in 0..<len(want) { fmt.printf("%02x ", want[j]) }
|
||||
fmt.println()
|
||||
fail_count += 1
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.printf(" [ok] %-35s bytes=", name)
|
||||
for i in 0..<len(want) { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
}
|
||||
|
||||
run_branch_test :: proc() {
|
||||
fmt.println("==== ppc_vle branches + labels ====")
|
||||
fmt.println("==== ppc_vle branches + labels ====")
|
||||
|
||||
// se_b L0; se_blr; L0: se_blr
|
||||
// -> first inst: se_b with displacement 4 (encoded as 4/2=2 in 8-bit field)
|
||||
// se_b form bits 0xE800, mask 0xFF00, B8 at bits 0..7, signed << 1
|
||||
// Target = pc + 4 = 4 bytes ahead, so B8 value = 2 (= 4/2)
|
||||
// bits: 0xE8 | 0x04 wait no. Looking at binutils BD8(58, 0, 0) = (58 << 10) = 0xE800
|
||||
// Actually se_b is BD8(58,0,0). Let me just verify encoder produces something reasonable.
|
||||
{
|
||||
label_defs := [?]isa.Label_Definition{isa.Label_Definition(2)} // points to inst 2
|
||||
instructions := [?]v.Instruction{
|
||||
v.inst_branch(.SE_B, 0),
|
||||
v.inst_none(.SE_BLR),
|
||||
v.inst_none(.SE_BLR),
|
||||
}
|
||||
// Just check encode succeeds and roundtrips
|
||||
code := make([]u8, 16, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
byte_count, success := v.encode(instructions[:], label_defs[:], code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] se_b+label: encode failed\n")
|
||||
for e in errors { fmt.printf(" code=%v\n", e.code) }
|
||||
fail_count += 1
|
||||
} else {
|
||||
fmt.printf(" [ok] se_b+label: %d bytes, bytes=", byte_count)
|
||||
for i in 0..<byte_count { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
}
|
||||
}
|
||||
// se_b L0; se_blr; L0: se_blr
|
||||
// -> first inst: se_b with displacement 4 (encoded as 4/2=2 in 8-bit field)
|
||||
// se_b form bits 0xE800, mask 0xFF00, B8 at bits 0..7, signed << 1
|
||||
// Target = pc + 4 = 4 bytes ahead, so B8 value = 2 (= 4/2)
|
||||
// bits: 0xE8 | 0x04 wait no. Looking at binutils BD8(58, 0, 0) = (58 << 10) = 0xE800
|
||||
// Actually se_b is BD8(58,0,0). Let me just verify encoder produces something reasonable.
|
||||
{
|
||||
label_defs := [?]isa.Label_Definition{isa.Label_Definition(2)} // points to inst 2
|
||||
instructions := [?]v.Instruction{
|
||||
v.inst_branch(.SE_B, 0),
|
||||
v.inst_none(.SE_BLR),
|
||||
v.inst_none(.SE_BLR),
|
||||
}
|
||||
// Just check encode succeeds and roundtrips
|
||||
code := make([]u8, 16, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
byte_count, success := v.encode(instructions[:], label_defs[:], code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] se_b+label: encode failed\n")
|
||||
for e in errors { fmt.printf(" code=%v\n", e.code) }
|
||||
fail_count += 1
|
||||
} else {
|
||||
fmt.printf(" [ok] se_b+label: %d bytes, bytes=", byte_count)
|
||||
for i in 0..<byte_count { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
}
|
||||
}
|
||||
|
||||
// e_b L0; nop instruction (could be e_or); L0: e_blr equivalent
|
||||
{
|
||||
label_defs := [?]isa.Label_Definition{isa.Label_Definition(2)}
|
||||
instructions := [?]v.Instruction{
|
||||
v.inst_branch(.E_B, 0),
|
||||
v.inst_none(.SE_BLR),
|
||||
v.inst_none(.SE_BLR),
|
||||
}
|
||||
code := make([]u8, 16, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
byte_count, success := v.encode(instructions[:], label_defs[:], code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] e_b+label: encode failed\n")
|
||||
fail_count += 1
|
||||
} else {
|
||||
fmt.printf(" [ok] e_b+label: %d bytes, bytes=", byte_count)
|
||||
for i in 0..<byte_count { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
}
|
||||
}
|
||||
// e_b L0; nop instruction (could be e_or); L0: e_blr equivalent
|
||||
{
|
||||
label_defs := [?]isa.Label_Definition{isa.Label_Definition(2)}
|
||||
instructions := [?]v.Instruction{
|
||||
v.inst_branch(.E_B, 0),
|
||||
v.inst_none(.SE_BLR),
|
||||
v.inst_none(.SE_BLR),
|
||||
}
|
||||
code := make([]u8, 16, context.temp_allocator)
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
byte_count, success := v.encode(instructions[:], label_defs[:], code, &relocs, &errors)
|
||||
if !success {
|
||||
fmt.printf(" [FAIL] e_b+label: encode failed\n")
|
||||
fail_count += 1
|
||||
} else {
|
||||
fmt.printf(" [ok] e_b+label: %d bytes, bytes=", byte_count)
|
||||
for i in 0..<byte_count { fmt.printf("%02x", code[i]) }
|
||||
fmt.println()
|
||||
ok_count += 1
|
||||
}
|
||||
}
|
||||
|
||||
fmt.printf("\n==> branch_test: %d passed, %d failed\n", ok_count, fail_count)
|
||||
if fail_count > 0 { os.exit(1) }
|
||||
fmt.printf("\n==> branch_test: %d passed, %d failed\n", ok_count, fail_count)
|
||||
if fail_count > 0 { os.exit(1) }
|
||||
}
|
||||
|
||||
@@ -10,85 +10,85 @@ import "../../isa"
|
||||
stats: struct { ok, mn_alias, byte_mismatch, encode_fail, decode_fail: int }
|
||||
|
||||
run_full_sweep :: proc() {
|
||||
fmt.println("==== ppc_vle full sweep ====")
|
||||
fmt.println("==== ppc_vle full sweep ====")
|
||||
|
||||
for mn in v.Mnemonic {
|
||||
_run := v.ENCODE_RUNS[u16(mn)]
|
||||
forms := v.ENCODE_FORMS[_run.start:][:_run.count]
|
||||
for &f, fi in forms {
|
||||
test_one(mn, fi, &f)
|
||||
}
|
||||
}
|
||||
for mn in v.Mnemonic {
|
||||
_run := v.ENCODE_RUNS[u16(mn)]
|
||||
forms := v.ENCODE_FORMS[_run.start:][:_run.count]
|
||||
for &f, fi in forms {
|
||||
test_one(mn, fi, &f)
|
||||
}
|
||||
}
|
||||
|
||||
total := stats.ok + stats.mn_alias + stats.byte_mismatch + stats.encode_fail + stats.decode_fail
|
||||
fmt.printf("\n[TOTAL] %d entries\n", total)
|
||||
fmt.printf(" OK: %d (%.1f%%)\n", stats.ok, 100.0 * f32(stats.ok) / f32(total))
|
||||
fmt.printf(" MN_ALIAS: %d (%.1f%%)\n", stats.mn_alias, 100.0 * f32(stats.mn_alias) / f32(total))
|
||||
fmt.printf(" BYTE_MISMATCH: %d (%.1f%%)\n", stats.byte_mismatch, 100.0 * f32(stats.byte_mismatch) / f32(total))
|
||||
fmt.printf(" ENCODE_FAIL: %d (%.1f%%)\n", stats.encode_fail, 100.0 * f32(stats.encode_fail) / f32(total))
|
||||
fmt.printf(" DECODE_FAIL: %d (%.1f%%)\n", stats.decode_fail, 100.0 * f32(stats.decode_fail) / f32(total))
|
||||
total := stats.ok + stats.mn_alias + stats.byte_mismatch + stats.encode_fail + stats.decode_fail
|
||||
fmt.printf("\n[TOTAL] %d entries\n", total)
|
||||
fmt.printf(" OK: %d (%.1f%%)\n", stats.ok, 100.0 * f32(stats.ok) / f32(total))
|
||||
fmt.printf(" MN_ALIAS: %d (%.1f%%)\n", stats.mn_alias, 100.0 * f32(stats.mn_alias) / f32(total))
|
||||
fmt.printf(" BYTE_MISMATCH: %d (%.1f%%)\n", stats.byte_mismatch, 100.0 * f32(stats.byte_mismatch) / f32(total))
|
||||
fmt.printf(" ENCODE_FAIL: %d (%.1f%%)\n", stats.encode_fail, 100.0 * f32(stats.encode_fail) / f32(total))
|
||||
fmt.printf(" DECODE_FAIL: %d (%.1f%%)\n", stats.decode_fail, 100.0 * f32(stats.decode_fail) / f32(total))
|
||||
}
|
||||
|
||||
test_one :: proc(mn: v.Mnemonic, fi: int, f: ^v.Encoding) {
|
||||
inst := v.Instruction{
|
||||
mnemonic = mn,
|
||||
mode = .PPC32_VLE,
|
||||
form_id = u16(fi + 1),
|
||||
length = f.flags.short ? 2 : 4,
|
||||
}
|
||||
code := make([]u8, 8, context.temp_allocator)
|
||||
label_defs: []isa.Label_Definition
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
inst := v.Instruction{
|
||||
mnemonic = mn,
|
||||
mode = .PPC32_VLE,
|
||||
form_id = u16(fi + 1),
|
||||
length = f.flags.short ? 2 : 4,
|
||||
}
|
||||
code := make([]u8, 8, context.temp_allocator)
|
||||
label_defs: []isa.Label_Definition
|
||||
relocs: [dynamic]v.Relocation
|
||||
errors: [dynamic]v.Error
|
||||
defer delete(relocs); defer delete(errors)
|
||||
|
||||
instructions := []v.Instruction{inst}
|
||||
byte_count, success := v.encode(instructions, label_defs, code, &relocs, &errors)
|
||||
if !success {
|
||||
stats.encode_fail += 1
|
||||
return
|
||||
}
|
||||
instructions := []v.Instruction{inst}
|
||||
byte_count, success := v.encode(instructions, label_defs, code, &relocs, &errors)
|
||||
if !success {
|
||||
stats.encode_fail += 1
|
||||
return
|
||||
}
|
||||
|
||||
decoded: [dynamic]v.Instruction
|
||||
info: [dynamic]v.Instruction_Info
|
||||
dec_labels: [dynamic]v.Label_Definition
|
||||
dec_errors: [dynamic]v.Error
|
||||
defer delete(decoded); defer delete(info); defer delete(dec_labels); defer delete(dec_errors)
|
||||
decoded: [dynamic]v.Instruction
|
||||
info: [dynamic]v.Instruction_Info
|
||||
dec_labels: [dynamic]v.Label_Definition
|
||||
dec_errors: [dynamic]v.Error
|
||||
defer delete(decoded); defer delete(info); defer delete(dec_labels); defer delete(dec_errors)
|
||||
|
||||
dbyte_count, dsuccess := v.decode(code[:byte_count], nil, &decoded, &info, &dec_labels, &dec_errors)
|
||||
if !dsuccess || len(decoded) == 0 || decoded[0].mnemonic == .INVALID {
|
||||
stats.decode_fail += 1
|
||||
return
|
||||
}
|
||||
dbyte_count, dsuccess := v.decode(code[:byte_count], nil, &decoded, &info, &dec_labels, &dec_errors)
|
||||
if !dsuccess || len(decoded) == 0 || decoded[0].mnemonic == .INVALID {
|
||||
stats.decode_fail += 1
|
||||
return
|
||||
}
|
||||
|
||||
// Re-encode and check bytes
|
||||
code2 := make([]u8, 8, context.temp_allocator)
|
||||
re_relocs: [dynamic]v.Relocation
|
||||
re_errors: [dynamic]v.Error
|
||||
defer delete(re_relocs); defer delete(re_errors)
|
||||
// Re-encode and check bytes
|
||||
code2 := make([]u8, 8, context.temp_allocator)
|
||||
re_relocs: [dynamic]v.Relocation
|
||||
re_errors: [dynamic]v.Error
|
||||
defer delete(re_relocs); defer delete(re_errors)
|
||||
|
||||
rrbyte_count, rrsuccess := v.encode(decoded[:], dec_labels[:], code2, &re_relocs, &re_errors)
|
||||
if !rrsuccess || rrbyte_count != byte_count {
|
||||
stats.byte_mismatch += 1
|
||||
return
|
||||
}
|
||||
for i in 0..<byte_count {
|
||||
if code[i] != code2[i] {
|
||||
stats.byte_mismatch += 1
|
||||
if stats.byte_mismatch <= 10 {
|
||||
fmt.printf(" [BYTE_MISMATCH] %v: orig=", mn)
|
||||
for j in 0..<byte_count { fmt.printf("%02x", code[j]) }
|
||||
fmt.printf(" re=")
|
||||
for j in 0..<byte_count { fmt.printf("%02x", code2[j]) }
|
||||
fmt.printf(" decoded=%v\n", decoded[0].mnemonic)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
rrbyte_count, rrsuccess := v.encode(decoded[:], dec_labels[:], code2, &re_relocs, &re_errors)
|
||||
if !rrsuccess || rrbyte_count != byte_count {
|
||||
stats.byte_mismatch += 1
|
||||
return
|
||||
}
|
||||
for i in 0..<byte_count {
|
||||
if code[i] != code2[i] {
|
||||
stats.byte_mismatch += 1
|
||||
if stats.byte_mismatch <= 10 {
|
||||
fmt.printf(" [BYTE_MISMATCH] %v: orig=", mn)
|
||||
for j in 0..<byte_count { fmt.printf("%02x", code[j]) }
|
||||
fmt.printf(" re=")
|
||||
for j in 0..<byte_count { fmt.printf("%02x", code2[j]) }
|
||||
fmt.printf(" decoded=%v\n", decoded[0].mnemonic)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if decoded[0].mnemonic == mn {
|
||||
stats.ok += 1
|
||||
} else {
|
||||
stats.mn_alias += 1
|
||||
}
|
||||
if decoded[0].mnemonic == mn {
|
||||
stats.ok += 1
|
||||
} else {
|
||||
stats.mn_alias += 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user