• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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//go:build amd64 || arm64
6
7package ssa
8
9// This file tests the functions addFlags64 and subFlags64 by comparing their
10// results to what the chip calculates.
11
12import (
13	"runtime"
14	"testing"
15)
16
17func TestAddFlagsNative(t *testing.T) {
18	var numbers = []int64{
19		1, 0, -1,
20		2, -2,
21		1<<63 - 1, -1 << 63,
22	}
23	coverage := map[flagConstant]bool{}
24	for _, x := range numbers {
25		for _, y := range numbers {
26			a := addFlags64(x, y)
27			b := flagRegister2flagConstant(asmAddFlags(x, y), false)
28			if a != b {
29				t.Errorf("asmAdd diff: x=%x y=%x got=%s want=%s\n", x, y, a, b)
30			}
31			coverage[a] = true
32		}
33	}
34	if len(coverage) != 9 { // TODO: can we cover all outputs?
35		t.Errorf("coverage too small, got %d want 9", len(coverage))
36	}
37}
38
39func TestSubFlagsNative(t *testing.T) {
40	var numbers = []int64{
41		1, 0, -1,
42		2, -2,
43		1<<63 - 1, -1 << 63,
44	}
45	coverage := map[flagConstant]bool{}
46	for _, x := range numbers {
47		for _, y := range numbers {
48			a := subFlags64(x, y)
49			b := flagRegister2flagConstant(asmSubFlags(x, y), true)
50			if a != b {
51				t.Errorf("asmSub diff: x=%x y=%x got=%s want=%s\n", x, y, a, b)
52			}
53			coverage[a] = true
54		}
55	}
56	if len(coverage) != 7 { // TODO: can we cover all outputs?
57		t.Errorf("coverage too small, got %d want 7", len(coverage))
58	}
59}
60
61func TestAndFlagsNative(t *testing.T) {
62	var numbers = []int64{
63		1, 0, -1,
64		2, -2,
65		1<<63 - 1, -1 << 63,
66	}
67	coverage := map[flagConstant]bool{}
68	for _, x := range numbers {
69		for _, y := range numbers {
70			a := logicFlags64(x & y)
71			b := flagRegister2flagConstant(asmAndFlags(x, y), false)
72			if a != b {
73				t.Errorf("asmAnd diff: x=%x y=%x got=%s want=%s\n", x, y, a, b)
74			}
75			coverage[a] = true
76		}
77	}
78	if len(coverage) != 3 {
79		t.Errorf("coverage too small, got %d want 3", len(coverage))
80	}
81}
82
83func asmAddFlags(x, y int64) int
84func asmSubFlags(x, y int64) int
85func asmAndFlags(x, y int64) int
86
87func flagRegister2flagConstant(x int, sub bool) flagConstant {
88	var fcb flagConstantBuilder
89	switch runtime.GOARCH {
90	case "amd64":
91		fcb.Z = x>>6&1 != 0
92		fcb.N = x>>7&1 != 0
93		fcb.C = x>>0&1 != 0
94		if sub {
95			// Convert from amd64-sense to arm-sense
96			fcb.C = !fcb.C
97		}
98		fcb.V = x>>11&1 != 0
99	case "arm64":
100		fcb.Z = x>>30&1 != 0
101		fcb.N = x>>31&1 != 0
102		fcb.C = x>>29&1 != 0
103		fcb.V = x>>28&1 != 0
104	default:
105		panic("unsupported architecture: " + runtime.GOARCH)
106	}
107	return fcb.encode()
108}
109