1// run
2
3// Copyright 2017 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// This file tests the splitting of constants into
8// multiple immediates on arm.
9
10package main
11
12import "fmt"
13
14const c32a = 0x00aa00dd
15const c32s = 0x00ffff00
16const c64a = 0x00aa00dd55000066
17const c64s = 0x00ffff00004fff00
18
19//go:noinline
20func add32a(x uint32) uint32 {
21	return x + c32a
22}
23
24//go:noinline
25func add32s(x uint32) uint32 {
26	return x + c32s
27}
28
29//go:noinline
30func sub32a(x uint32) uint32 {
31	return x - c32a
32}
33
34//go:noinline
35func sub32s(x uint32) uint32 {
36	return x - c32s
37}
38
39//go:noinline
40func or32(x uint32) uint32 {
41	return x | c32a
42}
43
44//go:noinline
45func xor32(x uint32) uint32 {
46	return x ^ c32a
47}
48
49//go:noinline
50func subr32a(x uint32) uint32 {
51	return c32a - x
52}
53
54//go:noinline
55func subr32s(x uint32) uint32 {
56	return c32s - x
57}
58
59//go:noinline
60func bic32(x uint32) uint32 {
61	return x &^ c32a
62}
63
64//go:noinline
65func add64a(x uint64) uint64 {
66	return x + c64a
67}
68
69//go:noinline
70func add64s(x uint64) uint64 {
71	return x + c64s
72}
73
74//go:noinline
75func sub64a(x uint64) uint64 {
76	return x - c64a
77}
78
79//go:noinline
80func sub64s(x uint64) uint64 {
81	return x - c64s
82}
83
84//go:noinline
85func or64(x uint64) uint64 {
86	return x | c64a
87}
88
89//go:noinline
90func xor64(x uint64) uint64 {
91	return x ^ c64a
92}
93
94//go:noinline
95func subr64a(x uint64) uint64 {
96	return c64a - x
97}
98
99//go:noinline
100func subr64s(x uint64) uint64 {
101	return c64s - x
102}
103
104//go:noinline
105func bic64(x uint64) uint64 {
106	return x &^ c64a
107}
108
109// Note: x-c gets rewritten to x+(-c), so SUB and SBC are not directly testable.
110// I disabled that rewrite rule before running this test.
111
112func main() {
113	test32()
114	test64()
115}
116
117func test32() {
118	var a uint32 = 0x11111111
119	var want, got uint32
120	if want, got = a+c32a, add32a(a); got != want {
121		panic(fmt.Sprintf("add32a(%x) = %x, want %x", a, got, want))
122	}
123	if want, got = a+c32s, add32s(a); got != want {
124		panic(fmt.Sprintf("add32s(%x) = %x, want %x", a, got, want))
125	}
126	if want, got = a-c32a, sub32a(a); got != want {
127		panic(fmt.Sprintf("sub32a(%x) = %x, want %x", a, got, want))
128	}
129	if want, got = a-c32s, sub32s(a); got != want {
130		panic(fmt.Sprintf("sub32s(%x) = %x, want %x", a, got, want))
131	}
132	if want, got = a|c32a, or32(a); got != want {
133		panic(fmt.Sprintf("or32(%x) = %x, want %x", a, got, want))
134	}
135	if want, got = a^c32a, xor32(a); got != want {
136		panic(fmt.Sprintf("xor32(%x) = %x, want %x", a, got, want))
137	}
138	if want, got = c32a-a, subr32a(a); got != want {
139		panic(fmt.Sprintf("subr32a(%x) = %x, want %x", a, got, want))
140	}
141	if want, got = c32s-a, subr32s(a); got != want {
142		panic(fmt.Sprintf("subr32s(%x) = %x, want %x", a, got, want))
143	}
144	if want, got = a&^c32a, bic32(a); got != want {
145		panic(fmt.Sprintf("bic32(%x) = %x, want %x", a, got, want))
146	}
147}
148
149func test64() {
150	var a uint64 = 0x1111111111111111
151	var want, got uint64
152	if want, got = a+c64a, add64a(a); got != want {
153		panic(fmt.Sprintf("add64a(%x) = %x, want %x", a, got, want))
154	}
155	if want, got = a+c64s, add64s(a); got != want {
156		panic(fmt.Sprintf("add64s(%x) = %x, want %x", a, got, want))
157	}
158	if want, got = a-c64a, sub64a(a); got != want {
159		panic(fmt.Sprintf("sub64a(%x) = %x, want %x", a, got, want))
160	}
161	if want, got = a-c64s, sub64s(a); got != want {
162		panic(fmt.Sprintf("sub64s(%x) = %x, want %x", a, got, want))
163	}
164	if want, got = a|c64a, or64(a); got != want {
165		panic(fmt.Sprintf("or64(%x) = %x, want %x", a, got, want))
166	}
167	if want, got = a^c64a, xor64(a); got != want {
168		panic(fmt.Sprintf("xor64(%x) = %x, want %x", a, got, want))
169	}
170	if want, got = c64a-a, subr64a(a); got != want {
171		panic(fmt.Sprintf("subr64a(%x) = %x, want %x", a, got, want))
172	}
173	if want, got = c64s-a, subr64s(a); got != want {
174		panic(fmt.Sprintf("subr64s(%x) = %x, want %x", a, got, want))
175	}
176	if want, got = a&^c64a, bic64(a); got != want {
177		panic(fmt.Sprintf("bic64(%x) = %x, want %x", a, got, want))
178	}
179}
180