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

View as plain text