blob: 88421b1b833e752df2854e067ee1381f9498e4f6 [file] [log] [blame]
// Copyright 2020 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 s390x
import (
"testing"
)
func TestRotateParamsMask(t *testing.T) {
tests := []struct {
start, end, amount uint8
inMask, outMask uint64
}{
// start before end, no rotation
{start: 0, end: 63, amount: 0, inMask: ^uint64(0), outMask: ^uint64(0)},
{start: 1, end: 63, amount: 0, inMask: ^uint64(0) >> 1, outMask: ^uint64(0) >> 1},
{start: 0, end: 62, amount: 0, inMask: ^uint64(1), outMask: ^uint64(1)},
{start: 1, end: 62, amount: 0, inMask: ^uint64(3) >> 1, outMask: ^uint64(3) >> 1},
// end before start, no rotation
{start: 63, end: 0, amount: 0, inMask: 1<<63 | 1, outMask: 1<<63 | 1},
{start: 62, end: 0, amount: 0, inMask: 1<<63 | 3, outMask: 1<<63 | 3},
{start: 63, end: 1, amount: 0, inMask: 3<<62 | 1, outMask: 3<<62 | 1},
{start: 62, end: 1, amount: 0, inMask: 3<<62 | 3, outMask: 3<<62 | 3},
// rotation
{start: 32, end: 63, amount: 32, inMask: 0xffffffff00000000, outMask: 0x00000000ffffffff},
{start: 48, end: 15, amount: 16, inMask: 0xffffffff00000000, outMask: 0xffff00000000ffff},
{start: 0, end: 7, amount: -8 & 63, inMask: 0xff, outMask: 0xff << 56},
}
for i, test := range tests {
r := NewRotateParams(test.start, test.end, test.amount)
if m := r.OutMask(); m != test.outMask {
t.Errorf("out mask %v: want %#x, got %#x", i, test.outMask, m)
}
if m := r.InMask(); m != test.inMask {
t.Errorf("in mask %v: want %#x, got %#x", i, test.inMask, m)
}
}
}
func TestRotateParamsMerge(t *testing.T) {
tests := []struct {
// inputs
src RotateParams
mask uint64
// results
in *RotateParams
out *RotateParams
}{
{
src: RotateParams{Start: 48, End: 15, Amount: 16},
mask: 0xffffffffffffffff,
in: &RotateParams{Start: 48, End: 15, Amount: 16},
out: &RotateParams{Start: 48, End: 15, Amount: 16},
},
{
src: RotateParams{Start: 16, End: 47, Amount: 0},
mask: 0x00000000ffffffff,
in: &RotateParams{Start: 32, End: 47, Amount: 0},
out: &RotateParams{Start: 32, End: 47, Amount: 0},
},
{
src: RotateParams{Start: 16, End: 47, Amount: 0},
mask: 0xffff00000000ffff,
in: nil,
out: nil,
},
{
src: RotateParams{Start: 0, End: 63, Amount: 0},
mask: 0xf7f0000000000000,
in: nil,
out: nil,
},
{
src: RotateParams{Start: 0, End: 63, Amount: 1},
mask: 0x000000000000ff00,
in: &RotateParams{Start: 47, End: 54, Amount: 1},
out: &RotateParams{Start: 48, End: 55, Amount: 1},
},
{
src: RotateParams{Start: 32, End: 63, Amount: 32},
mask: 0xffff00000000ffff,
in: &RotateParams{Start: 32, End: 47, Amount: 32},
out: &RotateParams{Start: 48, End: 63, Amount: 32},
},
{
src: RotateParams{Start: 0, End: 31, Amount: 32},
mask: 0x8000000000000000,
in: nil,
out: &RotateParams{Start: 0, End: 0, Amount: 32},
},
{
src: RotateParams{Start: 0, End: 31, Amount: 32},
mask: 0x0000000080000000,
in: &RotateParams{Start: 0, End: 0, Amount: 32},
out: nil,
},
}
eq := func(x, y *RotateParams) bool {
if x == nil && y == nil {
return true
}
if x == nil || y == nil {
return false
}
return *x == *y
}
for _, test := range tests {
if r := test.src.InMerge(test.mask); !eq(r, test.in) {
t.Errorf("%v merged with %#x (input): want %v, got %v", test.src, test.mask, test.in, r)
}
if r := test.src.OutMerge(test.mask); !eq(r, test.out) {
t.Errorf("%v merged with %#x (output): want %v, got %v", test.src, test.mask, test.out, r)
}
}
}