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

View as plain text