Source file src/cmd/compile/internal/ssa/flags_test.go

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

View as plain text