1
2
3
4
5 package arm64
6
7 import (
8 "math/bits"
9 "testing"
10
11 "cmd/internal/obj"
12 )
13
14
15
16 func decodeLogicalImmArrEncoding(imm13 uint32, arr uint32) (uint64, bool) {
17 n := (imm13 >> 12) & 1
18 immr := (imm13 >> 6) & 0x3F
19 imms := imm13 & 0x3F
20
21 notImms := (^imms) & 0x3F
22 combined := (n << 6) | notImms
23
24
25 if combined <= 1 {
26 return 0, false
27 }
28
29 lenVal := bits.Len32(uint32(combined)) - 1
30 esize := uint64(1 << lenVal)
31
32 levels := uint32((1 << lenVal) - 1)
33
34 if (imms & levels) == levels {
35 return 0, false
36 }
37
38 s := uint64(imms & levels)
39 r := uint64(immr & levels)
40
41
42 welem := (uint64(1) << (s + 1)) - 1
43
44
45 rotated := welem
46 mask := (uint64(1) << esize) - 1
47 if r > 0 {
48 r %= esize
49 rotated = ((welem >> r) | (welem << (esize - r))) & mask
50 }
51
52
53 wmask := uint64(0)
54 for i := uint64(0); i < 64; i += esize {
55 wmask |= rotated << i
56 }
57
58
59 var M uint64
60 switch arr {
61 case ARNG_B:
62 M = 8
63 case ARNG_H:
64 M = 16
65 case ARNG_S:
66 M = 32
67 case ARNG_D:
68 M = 64
69 default:
70 return 0, false
71 }
72
73 mask = (uint64(1) << M) - 1
74 return wmask & mask, true
75 }
76
77 func FuzzLogicalImmArrEncoding(f *testing.F) {
78 f.Add(uint64(0x55), uint32(ARNG_B))
79 f.Add(uint64(0xAA), uint32(ARNG_B))
80 f.Add(uint64(0x0F), uint32(ARNG_B))
81 f.Add(uint64(0x0101), uint32(ARNG_H))
82 f.Add(uint64(0x00FF), uint32(ARNG_H))
83 f.Add(uint64(0x0000FFFF), uint32(ARNG_S))
84 f.Add(uint64(0x55555555), uint32(ARNG_S))
85 f.Add(uint64(0x0000FFFF), uint32(ARNG_D))
86 f.Add(uint64(0x0101010101010101), uint32(ARNG_D))
87
88 f.Fuzz(func(t *testing.T, v uint64, arr uint32) {
89 if arr != ARNG_B && arr != ARNG_H && arr != ARNG_S && arr != ARNG_D {
90 return
91 }
92 adjacentAddr := &obj.Addr{
93 Type: obj.TYPE_REG,
94 Reg: int16(REG_ZARNG) + 0 + (int16(arr) << 5),
95 }
96
97 encoded, ok := encodeLogicalImmArrEncoding(v, adjacentAddr)
98 if !ok {
99 return
100 }
101
102 imm13 := encoded >> 5
103 decoded, ok := decodeLogicalImmArrEncoding(imm13, arr)
104 if !ok {
105 t.Errorf("Failed to decode imm13=0x%x arr=%d", imm13, arr)
106 return
107 }
108
109 var mask uint64
110 switch arr {
111 case ARNG_B:
112 mask = 0xFF
113 case ARNG_H:
114 mask = 0xFFFF
115 case ARNG_S:
116 mask = 0xFFFFFFFF
117 case ARNG_D:
118 mask = 0xFFFFFFFFFFFFFFFF
119 }
120 expected := v & mask
121
122 if decoded != expected {
123 t.Errorf("Fuzz roundtrip failed for v=0x%x arr=%d. Expected 0x%x, got 0x%x (imm13=0x%x)", v, arr, expected, decoded, imm13)
124 }
125 })
126 }
127
View as plain text