]> Cypherpunks.ru repositories - gostls13.git/blob - test/codegen/noextend.go
61c98a796a3185e28dfdd71c8707a9d3ad6925fc
[gostls13.git] / test / codegen / noextend.go
1 // asmcheck
2
3 // Copyright 2018 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 package codegen
8
9 import "math/bits"
10
11 var sval64 [8]int64
12 var sval32 [8]int32
13 var sval16 [8]int16
14 var sval8 [8]int8
15 var val64 [8]uint64
16 var val32 [8]uint32
17 var val16 [8]uint16
18 var val8 [8]uint8
19
20 // Avoid zero/sign extensions following a load
21 // which has extended the value correctly.
22 // Note: No tests are done for int8 since
23 // an extra extension is usually needed due to
24 // no signed byte load.
25
26 func set16(x8 int8, u8 *uint8, y8 int8, z8 uint8) {
27         // Truncate not needed, load does sign/zero extend
28
29         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
30         val16[0] = uint16(*u8)
31
32         // AND not needed due to size
33         // ppc64x:-"ANDCC"
34         sval16[1] = 255 & int16(x8+y8)
35
36         // ppc64x:-"ANDCC"
37         val16[1] = 255 & uint16(*u8+z8)
38
39 }
40 func shiftidx(u8 *uint8, x16 *int16, u16 *uint16) {
41
42         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
43         val16[0] = uint16(sval16[*u8>>2])
44
45         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
46         sval16[1] = int16(val16[*x16>>1])
47
48         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
49         val16[1] = uint16(sval16[*u16>>2])
50
51 }
52
53 func setnox(x8 int8, u8 *uint8, y8 *int8, z8 *uint8, x16 *int16, u16 *uint16, x32 *int32, u32 *uint32) {
54
55         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
56         val16[0] = uint16(*u8)
57
58         // AND not needed due to size
59         // ppc64x:-"ANDCC"
60         sval16[1] = 255 & int16(x8+*y8)
61
62         // ppc64x:-"ANDCC"
63         val16[1] = 255 & uint16(*u8+*z8)
64
65         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
66         sval32[1] = int32(*x16)
67
68         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
69         val32[0] = uint32(*u8)
70
71         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
72         val32[1] = uint32(*u16)
73
74         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
75         sval64[1] = int64(*x16)
76
77         // ppc64x:-"MOVW\tR\\d+,\\sR\\d+"
78         sval64[2] = int64(*x32)
79
80         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
81         val64[0] = uint64(*u8)
82
83         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
84         val64[1] = uint64(*u16)
85
86         // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+"
87         val64[2] = uint64(*u32)
88 }
89
90 func cmp16(u8 *uint8, x32 *int32, u32 *uint32, x64 *int64, u64 *uint64) bool {
91
92         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
93         if uint16(*u8) == val16[0] {
94                 return true
95         }
96
97         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
98         if uint16(*u32>>16) == val16[0] {
99                 return true
100         }
101
102         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
103         if uint16(*u64>>48) == val16[0] {
104                 return true
105         }
106
107         // Verify the truncates are using the correct sign.
108         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
109         if int16(*x32) == sval16[0] {
110                 return true
111         }
112
113         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
114         if uint16(*u32) == val16[0] {
115                 return true
116         }
117
118         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
119         if int16(*x64) == sval16[0] {
120                 return true
121         }
122
123         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
124         if uint16(*u64) == val16[0] {
125                 return true
126         }
127
128         return false
129 }
130
131 func cmp32(u8 *uint8, x16 *int16, u16 *uint16, x64 *int64, u64 *uint64) bool {
132
133         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
134         if uint32(*u8) == val32[0] {
135                 return true
136         }
137
138         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
139         if int32(*x16) == sval32[0] {
140                 return true
141         }
142
143         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
144         if uint32(*u16) == val32[0] {
145                 return true
146         }
147
148         // Verify the truncates are using the correct sign.
149         // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+"
150         if int32(*x64) == sval32[0] {
151                 return true
152         }
153
154         // ppc64x:-"MOVW\tR\\d+,\\sR\\d+"
155         if uint32(*u64) == val32[0] {
156                 return true
157         }
158
159         return false
160 }
161
162 func cmp64(u8 *uint8, x16 *int16, u16 *uint16, x32 *int32, u32 *uint32) bool {
163
164         // ppc64x:-"MOVBZ\tR\\d+,\\sR\\d+"
165         if uint64(*u8) == val64[0] {
166                 return true
167         }
168
169         // ppc64x:-"MOVH\tR\\d+,\\sR\\d+"
170         if int64(*x16) == sval64[0] {
171                 return true
172         }
173
174         // ppc64x:-"MOVHZ\tR\\d+,\\sR\\d+"
175         if uint64(*u16) == val64[0] {
176                 return true
177         }
178
179         // ppc64x:-"MOVW\tR\\d+,\\sR\\d+"
180         if int64(*x32) == sval64[0] {
181                 return true
182         }
183
184         // ppc64x:-"MOVWZ\tR\\d+,\\sR\\d+"
185         if uint64(*u32) == val64[0] {
186                 return true
187         }
188         return false
189 }
190
191 // no unsign extension following 32 bits ops
192
193 func noUnsignEXT(t1, t2, t3, t4 uint32, k int64) uint64 {
194         var ret uint64
195
196         // arm64:"RORW",-"MOVWU"
197         ret += uint64(bits.RotateLeft32(t1, 7))
198
199         // arm64:"MULW",-"MOVWU"
200         ret *= uint64(t1 * t2)
201
202         // arm64:"MNEGW",-"MOVWU"
203         ret += uint64(-t1 * t3)
204
205         // arm64:"UDIVW",-"MOVWU"
206         ret += uint64(t1 / t4)
207
208         // arm64:-"MOVWU"
209         ret += uint64(t2 % t3)
210
211         // arm64:"MSUBW",-"MOVWU"
212         ret += uint64(t1 - t2*t3)
213
214         // arm64:"MADDW",-"MOVWU"
215         ret += uint64(t3*t4 + t2)
216
217         // arm64:"REVW",-"MOVWU"
218         ret += uint64(bits.ReverseBytes32(t1))
219
220         // arm64:"RBITW",-"MOVWU"
221         ret += uint64(bits.Reverse32(t1))
222
223         // arm64:"CLZW",-"MOVWU"
224         ret += uint64(bits.LeadingZeros32(t1))
225
226         // arm64:"REV16W",-"MOVWU"
227         ret += uint64(((t1 & 0xff00ff00) >> 8) | ((t1 & 0x00ff00ff) << 8))
228
229         // arm64:"EXTRW",-"MOVWU"
230         ret += uint64((t1 << 25) | (t2 >> 7))
231
232         return ret
233 }
234
235 // no sign extension when the upper bits of the result are zero
236
237 func noSignEXT(x int) int64 {
238         t1 := int32(x)
239
240         var ret int64
241
242         // arm64:-"MOVW"
243         ret += int64(t1 & 1)
244
245         // arm64:-"MOVW"
246         ret += int64(int32(x & 0x7fffffff))
247
248         // arm64:-"MOVH"
249         ret += int64(int16(x & 0x7fff))
250
251         // arm64:-"MOVB"
252         ret += int64(int8(x & 0x7f))
253
254         return ret
255 }
256
257 // corner cases that sign extension must not be omitted
258
259 func shouldSignEXT(x int) int64 {
260         t1 := int32(x)
261
262         var ret int64
263
264         // arm64:"MOVW"
265         ret += int64(t1 & (-1))
266
267         // arm64:"MOVW"
268         ret += int64(int32(x & 0x80000000))
269
270         // arm64:"MOVW"
271         ret += int64(int32(x & 0x1100000011111111))
272
273         // arm64:"MOVH"
274         ret += int64(int16(x & 0x1100000000001111))
275
276         // arm64:"MOVB"
277         ret += int64(int8(x & 0x1100000000000011))
278
279         return ret
280
281 }