1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package arm64asm 6 7 import ( 8 "encoding/hex" 9 "io/ioutil" 10 "strings" 11 "testing" 12 ) 13 14 func TestDecode(t *testing.T) { 15 data, err := ioutil.ReadFile("testdata/cases.txt") 16 if err != nil { 17 t.Fatal(err) 18 } 19 all := string(data) 20 for strings.Contains(all, "\t\t") { 21 all = strings.Replace(all, "\t\t", "\t", -1) 22 } 23 for _, line := range strings.Split(all, "\n") { 24 line = strings.TrimSpace(line) 25 if line == "" || strings.HasPrefix(line, "#") { 26 continue 27 } 28 f := strings.SplitN(line, "\t", 3) 29 i := strings.Index(f[0], "|") 30 if i < 0 { 31 t.Errorf("parsing %q: missing | separator", f[0]) 32 continue 33 } 34 if i%2 != 0 { 35 t.Errorf("parsing %q: misaligned | separator", f[0]) 36 } 37 code, err := hex.DecodeString(f[0][:i] + f[0][i+1:]) 38 if err != nil { 39 t.Errorf("parsing %q: %v", f[0], err) 40 continue 41 } 42 syntax, asm := f[1], f[2] 43 inst, decodeErr := Decode(code) 44 if decodeErr != nil && decodeErr != errUnknown { 45 // Some rarely used system instructions are not supported 46 // Following logicals will filter such unknown instructions 47 48 t.Errorf("parsing %x: %s", code, decodeErr) 49 continue 50 } 51 var out string 52 switch syntax { 53 case "gnu": 54 out = GNUSyntax(inst) 55 case "plan9": 56 out = GoSyntax(inst, 0, nil, nil) 57 default: 58 t.Errorf("unknown syntax %q", syntax) 59 continue 60 } 61 // TODO: system instruction. 62 var Todo = strings.Fields(` 63 sys 64 dc 65 at 66 tlbi 67 ic 68 hvc 69 smc 70 `) 71 if strings.Replace(out, " ", "", -1) != strings.Replace(asm, " ", "", -1) && !hasPrefix(asm, Todo...) { 72 // Exclude MSR since GNU objdump result is incorrect. eg. 0xd504431f msr s0_4_c4_c3_0, xzr 73 if !strings.HasSuffix(asm, " nv") && !strings.HasPrefix(asm, "msr") { 74 t.Errorf("Decode(%s) [%s] = %s, want %s", f[0], syntax, out, asm) 75 } 76 } 77 } 78 } 79