// Copyright 2014 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 ppc64asm import ( "encoding/binary" "encoding/hex" "io/ioutil" "path" "strings" "testing" ) func TestDecode(t *testing.T) { files, err := ioutil.ReadDir("testdata") if err != nil { t.Fatal(err) } for _, f := range files { if !strings.HasPrefix(f.Name(), "decode") { continue } filename := path.Join("testdata", f.Name()) data, err := ioutil.ReadFile(filename) if err != nil { t.Fatal(err) } decode(data, t, filename) } } // Provide a fake symbol to verify PCrel argument decoding. func symlookup(pc uint64) (string, uint64) { foopc := uint64(0x100000) if pc >= foopc && pc < foopc+0x10 { return "foo", foopc } return "", 0 } func decode(data []byte, t *testing.T, filename string) { all := string(data) // Simulate PC based on number of instructions found in the test file. pc := uint64(0) 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", 3) i := strings.Index(f[0], "|") if i < 0 { t.Errorf("%s: parsing %q: missing | separator", filename, f[0]) continue } if i%2 != 0 { t.Errorf("%s: parsing %q: misaligned | separator", filename, f[0]) } size := i / 2 code, err := hex.DecodeString(f[0][:i] + f[0][i+1:]) if err != nil { t.Errorf("%s: parsing %q: %v", filename, f[0], err) continue } syntax, asm := f[1], f[2] inst, err := Decode(code, binary.BigEndian) var out string if err != nil { out = "error: " + err.Error() } else { switch syntax { case "gnu": out = GNUSyntax(inst, pc) case "plan9": pc := pc // Hack: Setting PC to 0 effectively transforms the PC relative address // of CALL (bl) into an absolute address when decoding in GoSyntax. This // simplifies the testing of symbol lookups via symlookup above. if inst.Op == BL { pc = 0 } out = GoSyntax(inst, pc, symlookup) default: t.Errorf("unknown syntax %q", syntax) continue } } pc += uint64(size) if out != asm || inst.Len != size { t.Errorf("%s: Decode(%s) [%s] = %s want %s", filename, f[0], syntax, out, asm) } } }