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
7package codegen
8
9import "runtime"
10
11// Check small copies are replaced with moves.
12
13func movesmall4() {
14	x := [...]byte{1, 2, 3, 4}
15	// 386:-".*memmove"
16	// amd64:-".*memmove"
17	// arm:-".*memmove"
18	// arm64:-".*memmove"
19	// ppc64x:-".*memmove"
20	copy(x[1:], x[:])
21}
22
23func movesmall7() {
24	x := [...]byte{1, 2, 3, 4, 5, 6, 7}
25	// 386:-".*memmove"
26	// amd64:-".*memmove"
27	// arm64:-".*memmove"
28	// ppc64x:-".*memmove"
29	copy(x[1:], x[:])
30}
31
32func movesmall16() {
33	x := [...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
34	// amd64:-".*memmove"
35	// ppc64x:".*memmove"
36	copy(x[1:], x[:])
37}
38
39var x [256]byte
40
41// Check that large disjoint copies are replaced with moves.
42
43func moveDisjointStack32() {
44	var s [32]byte
45	// ppc64x:-".*memmove"
46	// ppc64x/power8:"LXVD2X",-"ADD",-"BC"
47	// ppc64x/power9:"LXV",-"LXVD2X",-"ADD",-"BC"
48	copy(s[:], x[:32])
49	runtime.KeepAlive(&s)
50}
51
52func moveDisjointStack64() {
53	var s [96]byte
54	// ppc64x:-".*memmove"
55	// ppc64x/power8:"LXVD2X","ADD","BC"
56	// ppc64x/power9:"LXV",-"LXVD2X",-"ADD",-"BC"
57	copy(s[:], x[:96])
58	runtime.KeepAlive(&s)
59}
60
61func moveDisjointStack() {
62	var s [256]byte
63	// s390x:-".*memmove"
64	// amd64:-".*memmove"
65	// ppc64x:-".*memmove"
66	// ppc64x/power8:"LXVD2X"
67	// ppc64x/power9:"LXV",-"LXVD2X"
68	copy(s[:], x[:])
69	runtime.KeepAlive(&s)
70}
71
72func moveDisjointArg(b *[256]byte) {
73	var s [256]byte
74	// s390x:-".*memmove"
75	// amd64:-".*memmove"
76	// ppc64x:-".*memmove"
77	// ppc64x/power8:"LXVD2X"
78	// ppc64x/power9:"LXV",-"LXVD2X"
79	copy(s[:], b[:])
80	runtime.KeepAlive(&s)
81}
82
83func moveDisjointNoOverlap(a *[256]byte) {
84	// s390x:-".*memmove"
85	// amd64:-".*memmove"
86	// ppc64x:-".*memmove"
87	// ppc64x/power8:"LXVD2X"
88	// ppc64x/power9:"LXV",-"LXVD2X"
89	copy(a[:], a[128:])
90}
91
92// Check arch-specific memmove lowering. See issue 41662 fot details
93
94func moveArchLowering1(b []byte, x *[1]byte) {
95	_ = b[1]
96	// amd64:-".*memmove"
97	// arm64:-".*memmove"
98	// ppc64x:-".*memmove"
99	copy(b, x[:])
100}
101
102func moveArchLowering2(b []byte, x *[2]byte) {
103	_ = b[2]
104	// amd64:-".*memmove"
105	// arm64:-".*memmove"
106	// ppc64x:-".*memmove"
107	copy(b, x[:])
108}
109
110func moveArchLowering4(b []byte, x *[4]byte) {
111	_ = b[4]
112	// amd64:-".*memmove"
113	// arm64:-".*memmove"
114	// ppc64x:-".*memmove"
115	copy(b, x[:])
116}
117
118func moveArchLowering8(b []byte, x *[8]byte) {
119	_ = b[8]
120	// amd64:-".*memmove"
121	// arm64:-".*memmove"
122	// ppc64x:-".*memmove"
123	copy(b, x[:])
124}
125
126func moveArchLowering16(b []byte, x *[16]byte) {
127	_ = b[16]
128	// amd64:-".*memmove"
129	copy(b, x[:])
130}
131
132// Check that no branches are generated when the pointers are [not] equal.
133
134func ptrEqual() {
135	// amd64:-"JEQ",-"JNE"
136	// ppc64x:-"BEQ",-"BNE"
137	// s390x:-"BEQ",-"BNE"
138	copy(x[:], x[:])
139}
140
141func ptrOneOffset() {
142	// amd64:-"JEQ",-"JNE"
143	// ppc64x:-"BEQ",-"BNE"
144	// s390x:-"BEQ",-"BNE"
145	copy(x[1:], x[:])
146}
147
148func ptrBothOffset() {
149	// amd64:-"JEQ",-"JNE"
150	// ppc64x:-"BEQ",-"BNE"
151	// s390x:-"BEQ",-"BNE"
152	copy(x[1:], x[2:])
153}
154
155// Verify #62698 on PPC64.
156func noMaskOnCopy(a []int, s string, x int) int {
157	// ppc64x:-"MOVD\t$-1", -"AND"
158	return a[x&^copy([]byte{}, s)]
159}
160