Source file src/cmd/internal/obj/riscv/obj_test.go

     1  // Copyright 2025 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 riscv
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  )
    11  
    12  func TestSplitShiftConst(t *testing.T) {
    13  	tests := []struct {
    14  		v       int64
    15  		wantImm int64
    16  		wantLsh int
    17  		wantRsh int
    18  		wantOk  bool
    19  	}{
    20  		{0xfffff001, -4095, 32, 32, true},
    21  		{0xfffff801, -2047, 32, 32, true},
    22  		{0xfffffff1, -15, 32, 32, true},
    23  		{0xffffffff, -1, 0, 32, true},
    24  		{0xfffffffe, 0x7fffffff, 1, 0, true},
    25  		{0x80a9b553, -2136361645, 32, 32, true},
    26  		{0x100000000, 1, 32, 0, true},
    27  		{0xfffffffffffda, -19, 13, 12, true},
    28  		{0xfffffffffffde, -17, 13, 12, true},
    29  		{0x000003ffffffffff, -1, 0, 22, true},
    30  		{0x0007ffffffffffff, -1, 0, 13, true},
    31  		{0x7fffffff00000000, 0x7fffffff, 32, 0, true},
    32  		{0x7fffffffffffffff, -1, 0, 1, true},
    33  		{0x7f7f7f7f7f7f7f7f, 0, 0, 0, false},
    34  		{0x0080000010000000, 0x8000001, 28, 0, true},
    35  		{0x0abcdabcd0000000, -1412584499, 32, 4, true},
    36  		{-4503599610593281, 0, 0, 0, false}, // 0x8abcdabcd0000000
    37  		{-7543254330000000, 0, 0, 0, false}, // 0xfff0000000ffffff
    38  	}
    39  	for _, test := range tests {
    40  		t.Run(fmt.Sprintf("0x%x", test.v), func(t *testing.T) {
    41  			c, l, r, ok := splitShiftConst(test.v)
    42  
    43  			if got, want := c, test.wantImm; got != want {
    44  				t.Errorf("Got immediate %d, want %d", got, want)
    45  			}
    46  			if got, want := l, test.wantLsh; got != want {
    47  				t.Errorf("Got left shift %d, want %d", got, want)
    48  			}
    49  			if got, want := r, test.wantRsh; got != want {
    50  				t.Errorf("Got right shift %d, want %d", got, want)
    51  			}
    52  			switch {
    53  			case !ok && test.wantOk:
    54  				t.Error("Failed to split shift constant, want success")
    55  			case ok && !test.wantOk:
    56  				t.Error("Successfully split shift constant, want failure")
    57  			}
    58  			if !ok || ok != test.wantOk {
    59  				return
    60  			}
    61  
    62  			// Reconstruct as either a 12 bit or 32 bit signed constant.
    63  			s := 64 - 12
    64  			v := int64((uint64(((c << s) >> s)) << l) >> r)
    65  			if test.wantImm != ((test.wantImm << s) >> s) {
    66  				v = int64((uint64(int32(test.wantImm)) << l) >> r)
    67  			}
    68  			if v != test.v {
    69  				t.Errorf("Got v = %d (%x), want v = %d (%x)", v, v, test.v, test.v)
    70  			}
    71  		})
    72  	}
    73  }
    74  

View as plain text