1// run
2
3// Copyright 2023 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
7package main
8
9func main() {
10	var b [8]byte
11	one := uint8(1)
12	f16(&one, b[:2])
13	if b[1] != 1 {
14		println("2-byte value lost")
15	}
16	f32(&one, b[:4])
17	if b[3] != 1 {
18		println("4-byte value lost")
19	}
20	f64(&one, b[:8])
21	if b[7] != 1 {
22		println("8-byte value lost")
23	}
24}
25
26//go:noinline
27func f16(p *uint8, b []byte) {
28	_ = b[1]            // bounds check
29	x := *p             // load a byte
30	y := uint16(x)      // zero extend to 16 bits
31	b[0] = byte(y >> 8) // compute ROLW
32	b[1] = byte(y)
33	nop()               // spill/restore ROLW
34	b[0] = byte(y >> 8) // use ROLW
35	b[1] = byte(y)
36}
37
38//go:noinline
39func f32(p *uint8, b []byte) {
40	_ = b[3]             // bounds check
41	x := *p              // load a byte
42	y := uint32(x)       // zero extend to 32 bits
43	b[0] = byte(y >> 24) // compute ROLL
44	b[1] = byte(y >> 16)
45	b[2] = byte(y >> 8)
46	b[3] = byte(y)
47	nop()                // spill/restore ROLL
48	b[0] = byte(y >> 24) // use ROLL
49	b[1] = byte(y >> 16)
50	b[2] = byte(y >> 8)
51	b[3] = byte(y)
52}
53
54//go:noinline
55func f64(p *uint8, b []byte) {
56	_ = b[7]             // bounds check
57	x := *p              // load a byte
58	y := uint64(x)       // zero extend to 64 bits
59	b[0] = byte(y >> 56) // compute ROLQ
60	b[1] = byte(y >> 48)
61	b[2] = byte(y >> 40)
62	b[3] = byte(y >> 32)
63	b[4] = byte(y >> 24)
64	b[5] = byte(y >> 16)
65	b[6] = byte(y >> 8)
66	b[7] = byte(y)
67	nop()                // spill/restore ROLQ
68	b[0] = byte(y >> 56) // use ROLQ
69	b[1] = byte(y >> 48)
70	b[2] = byte(y >> 40)
71	b[3] = byte(y >> 32)
72	b[4] = byte(y >> 24)
73	b[5] = byte(y >> 16)
74	b[6] = byte(y >> 8)
75	b[7] = byte(y)
76}
77
78//go:noinline
79func nop() {
80}
81