...

Source file src/golang.org/x/arch/ppc64/ppc64asm/decode_test.go

Documentation: golang.org/x/arch/ppc64/ppc64asm

     1  // Copyright 2014 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 ppc64asm
     6  
     7  import (
     8  	"encoding/binary"
     9  	"encoding/hex"
    10  	"io/ioutil"
    11  	"path"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestDecode(t *testing.T) {
    17  	files, err := ioutil.ReadDir("testdata")
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	for _, f := range files {
    22  		if !strings.HasPrefix(f.Name(), "decode") {
    23  			continue
    24  		}
    25  		filename := path.Join("testdata", f.Name())
    26  		data, err := ioutil.ReadFile(filename)
    27  		if err != nil {
    28  			t.Fatal(err)
    29  		}
    30  		decode(data, t, filename)
    31  	}
    32  }
    33  
    34  // Provide a fake symbol to verify PCrel argument decoding.
    35  func symlookup(pc uint64) (string, uint64) {
    36  	foopc := uint64(0x100000)
    37  	if pc >= foopc && pc < foopc+0x10 {
    38  		return "foo", foopc
    39  	}
    40  	return "", 0
    41  }
    42  
    43  func decode(data []byte, t *testing.T, filename string) {
    44  	all := string(data)
    45  	// Simulate PC based on number of instructions found in the test file.
    46  	pc := uint64(0)
    47  	for strings.Contains(all, "\t\t") {
    48  		all = strings.Replace(all, "\t\t", "\t", -1)
    49  	}
    50  	for _, line := range strings.Split(all, "\n") {
    51  		line = strings.TrimSpace(line)
    52  		if line == "" || strings.HasPrefix(line, "#") {
    53  			continue
    54  		}
    55  		f := strings.SplitN(line, "\t", 3)
    56  		i := strings.Index(f[0], "|")
    57  		if i < 0 {
    58  			t.Errorf("%s: parsing %q: missing | separator", filename, f[0])
    59  			continue
    60  		}
    61  		if i%2 != 0 {
    62  			t.Errorf("%s: parsing %q: misaligned | separator", filename, f[0])
    63  		}
    64  		size := i / 2
    65  		code, err := hex.DecodeString(f[0][:i] + f[0][i+1:])
    66  		if err != nil {
    67  			t.Errorf("%s: parsing %q: %v", filename, f[0], err)
    68  			continue
    69  		}
    70  		syntax, asm := f[1], f[2]
    71  		inst, err := Decode(code, binary.BigEndian)
    72  		var out string
    73  		if err != nil {
    74  			out = "error: " + err.Error()
    75  		} else {
    76  			switch syntax {
    77  			case "gnu":
    78  				out = GNUSyntax(inst, pc)
    79  			case "plan9":
    80  				pc := pc
    81  				// Hack: Setting PC to 0 effectively transforms the PC relative address
    82  				// of CALL (bl) into an absolute address when decoding in GoSyntax. This
    83  				// simplifies the testing of symbol lookups via symlookup above.
    84  				if inst.Op == BL {
    85  					pc = 0
    86  				}
    87  				out = GoSyntax(inst, pc, symlookup)
    88  			default:
    89  				t.Errorf("unknown syntax %q", syntax)
    90  				continue
    91  			}
    92  		}
    93  		pc += uint64(size)
    94  		if out != asm || inst.Len != size {
    95  			t.Errorf("%s: Decode(%s) [%s] = %s want %s", filename, f[0], syntax, out, asm)
    96  		}
    97  	}
    98  }
    99  

View as plain text