// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package arm64asm import ( "encoding/hex" "io/ioutil" "path/filepath" "strings" "testing" ) func testDecode(t *testing.T, syntax string) { input := filepath.Join("testdata", syntax+"cases.txt") data, err := ioutil.ReadFile(input) if err != nil { t.Fatal(err) } all := string(data) for strings.Contains(all, "\t\t") { all = strings.Replace(all, "\t\t", "\t", -1) } for _, line := range strings.Split(all, "\n") { line = strings.TrimSpace(line) if line == "" || strings.HasPrefix(line, "#") { continue } f := strings.SplitN(line, "\t", 2) i := strings.Index(f[0], "|") if i < 0 { t.Errorf("parsing %q: missing | separator", f[0]) continue } if i%2 != 0 { t.Errorf("parsing %q: misaligned | separator", f[0]) } code, err := hex.DecodeString(f[0][:i] + f[0][i+1:]) if err != nil { t.Errorf("parsing %q: %v", f[0], err) continue } asm := f[1] inst, decodeErr := Decode(code) if decodeErr != nil && decodeErr != errUnknown { // Some rarely used system instructions are not supported // Following logicals will filter such unknown instructions t.Errorf("parsing %x: %s", code, decodeErr) continue } var out string switch syntax { case "gnu": out = GNUSyntax(inst) case "plan9": out = GoSyntax(inst, 0, nil, nil) default: t.Errorf("unknown syntax %q", syntax) continue } // TODO: system instruction. var Todo = strings.Fields(` sys at ic hvc smc `) if strings.Replace(out, " ", "", -1) != strings.Replace(asm, " ", "", -1) && !hasPrefix(asm, Todo...) { // Exclude MSR since GNU objdump result is incorrect. eg. 0xd504431f msr s0_4_c4_c3_0, xzr if !strings.HasSuffix(asm, " nv") && !strings.HasPrefix(asm, "msr") { t.Errorf("Decode(%s) [%s] = %s, want %s", strings.Trim(f[0], "|"), syntax, out, asm) } } } } func TestDecodeGNUSyntax(t *testing.T) { testDecode(t, "gnu") } func TestDecodeGoSyntax(t *testing.T) { testDecode(t, "plan9") }