blob: 83a3acd37e560e5da58b7ac47379a9327f2dbc56 [file] [log] [blame]
// 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)
}
}
}