1
2
3
4
5 package test
6
7 import (
8 "encoding/binary"
9 "testing"
10 )
11
12 var gv = [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8}
13
14
15 func readGlobalUnaligned() uint64 {
16 return binary.LittleEndian.Uint64(gv[1:])
17 }
18
19 func TestUnalignedGlobal(t *testing.T) {
20
21
22
23 if got, want := readGlobalUnaligned(), uint64(0x0807060504030201); got != want {
24 t.Errorf("read global %x, want %x", got, want)
25 }
26 }
27
28 func TestSpillOfExtendedEndianLoads(t *testing.T) {
29 b := []byte{0xaa, 0xbb, 0xcc, 0xdd}
30
31 var testCases = []struct {
32 fn func([]byte) uint64
33 want uint64
34 }{
35 {readUint16le, 0xbbaa},
36 {readUint16be, 0xaabb},
37 {readUint32le, 0xddccbbaa},
38 {readUint32be, 0xaabbccdd},
39 }
40 for _, test := range testCases {
41 if got := test.fn(b); got != test.want {
42 t.Errorf("got %x, want %x", got, test.want)
43 }
44 }
45 }
46
47 func readUint16le(b []byte) uint64 {
48 y := uint64(binary.LittleEndian.Uint16(b))
49 nop()
50 return y
51 }
52
53 func readUint16be(b []byte) uint64 {
54 y := uint64(binary.BigEndian.Uint16(b))
55 nop()
56 return y
57 }
58
59 func readUint32le(b []byte) uint64 {
60 y := uint64(binary.LittleEndian.Uint32(b))
61 nop()
62 return y
63 }
64
65 func readUint32be(b []byte) uint64 {
66 y := uint64(binary.BigEndian.Uint32(b))
67 nop()
68 return y
69 }
70
71
72 func nop() {
73 }
74
75 type T32 struct {
76 a, b uint32
77 }
78
79
80 func (t *T32) bigEndianLoad() uint64 {
81 return uint64(t.a)<<32 | uint64(t.b)
82 }
83
84
85 func (t *T32) littleEndianLoad() uint64 {
86 return uint64(t.a) | (uint64(t.b) << 32)
87 }
88
89
90 func (t *T32) bigEndianStore(x uint64) {
91 t.a = uint32(x >> 32)
92 t.b = uint32(x)
93 }
94
95
96 func (t *T32) littleEndianStore(x uint64) {
97 t.a = uint32(x)
98 t.b = uint32(x >> 32)
99 }
100
101 type T16 struct {
102 a, b uint16
103 }
104
105
106 func (t *T16) bigEndianLoad() uint32 {
107 return uint32(t.a)<<16 | uint32(t.b)
108 }
109
110
111 func (t *T16) littleEndianLoad() uint32 {
112 return uint32(t.a) | (uint32(t.b) << 16)
113 }
114
115
116 func (t *T16) bigEndianStore(x uint32) {
117 t.a = uint16(x >> 16)
118 t.b = uint16(x)
119 }
120
121
122 func (t *T16) littleEndianStore(x uint32) {
123 t.a = uint16(x)
124 t.b = uint16(x >> 16)
125 }
126
127 type T8 struct {
128 a, b uint8
129 }
130
131
132 func (t *T8) bigEndianLoad() uint16 {
133 return uint16(t.a)<<8 | uint16(t.b)
134 }
135
136
137 func (t *T8) littleEndianLoad() uint16 {
138 return uint16(t.a) | (uint16(t.b) << 8)
139 }
140
141
142 func (t *T8) bigEndianStore(x uint16) {
143 t.a = uint8(x >> 8)
144 t.b = uint8(x)
145 }
146
147
148 func (t *T8) littleEndianStore(x uint16) {
149 t.a = uint8(x)
150 t.b = uint8(x >> 8)
151 }
152
153 func TestIssue64468(t *testing.T) {
154 t32 := T32{1, 2}
155 if got, want := t32.bigEndianLoad(), uint64(1<<32+2); got != want {
156 t.Errorf("T32.bigEndianLoad got %x want %x\n", got, want)
157 }
158 if got, want := t32.littleEndianLoad(), uint64(1+2<<32); got != want {
159 t.Errorf("T32.littleEndianLoad got %x want %x\n", got, want)
160 }
161 t16 := T16{1, 2}
162 if got, want := t16.bigEndianLoad(), uint32(1<<16+2); got != want {
163 t.Errorf("T16.bigEndianLoad got %x want %x\n", got, want)
164 }
165 if got, want := t16.littleEndianLoad(), uint32(1+2<<16); got != want {
166 t.Errorf("T16.littleEndianLoad got %x want %x\n", got, want)
167 }
168 t8 := T8{1, 2}
169 if got, want := t8.bigEndianLoad(), uint16(1<<8+2); got != want {
170 t.Errorf("T8.bigEndianLoad got %x want %x\n", got, want)
171 }
172 if got, want := t8.littleEndianLoad(), uint16(1+2<<8); got != want {
173 t.Errorf("T8.littleEndianLoad got %x want %x\n", got, want)
174 }
175 t32.bigEndianStore(1<<32 + 2)
176 if got, want := t32, (T32{1, 2}); got != want {
177 t.Errorf("T32.bigEndianStore got %x want %x\n", got, want)
178 }
179 t32.littleEndianStore(1<<32 + 2)
180 if got, want := t32, (T32{2, 1}); got != want {
181 t.Errorf("T32.littleEndianStore got %x want %x\n", got, want)
182 }
183 t16.bigEndianStore(1<<16 + 2)
184 if got, want := t16, (T16{1, 2}); got != want {
185 t.Errorf("T16.bigEndianStore got %x want %x\n", got, want)
186 }
187 t16.littleEndianStore(1<<16 + 2)
188 if got, want := t16, (T16{2, 1}); got != want {
189 t.Errorf("T16.littleEndianStore got %x want %x\n", got, want)
190 }
191 t8.bigEndianStore(1<<8 + 2)
192 if got, want := t8, (T8{1, 2}); got != want {
193 t.Errorf("T8.bigEndianStore got %x want %x\n", got, want)
194 }
195 t8.littleEndianStore(1<<8 + 2)
196 if got, want := t8, (T8{2, 1}); got != want {
197 t.Errorf("T8.littleEndianStore got %x want %x\n", got, want)
198 }
199 }
200
View as plain text