1// asmcheck
2
3// Copyright 2019 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// These tests check code generation of switch statements.
8
9package codegen
10
11// see issue 33934
12func f(x string) int {
13	// amd64:-`cmpstring`
14	switch x {
15	case "":
16		return -1
17	case "1", "2", "3":
18		return -2
19	default:
20		return -3
21	}
22}
23
24// use jump tables for 8+ int cases
25func square(x int) int {
26	// amd64:`JMP\s\(.*\)\(.*\)$`
27	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
28	switch x {
29	case 1:
30		return 1
31	case 2:
32		return 4
33	case 3:
34		return 9
35	case 4:
36		return 16
37	case 5:
38		return 25
39	case 6:
40		return 36
41	case 7:
42		return 49
43	case 8:
44		return 64
45	default:
46		return x * x
47	}
48}
49
50// use jump tables for 8+ string lengths
51func length(x string) int {
52	// amd64:`JMP\s\(.*\)\(.*\)$`
53	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
54	switch x {
55	case "a":
56		return 1
57	case "bb":
58		return 2
59	case "ccc":
60		return 3
61	case "dddd":
62		return 4
63	case "eeeee":
64		return 5
65	case "ffffff":
66		return 6
67	case "ggggggg":
68		return 7
69	case "hhhhhhhh":
70		return 8
71	default:
72		return len(x)
73	}
74}
75
76// Use single-byte ordered comparisons for binary searching strings.
77// See issue 53333.
78func mimetype(ext string) string {
79	// amd64: `CMPB\s1\(.*\), \$104$`,-`cmpstring`
80	// arm64: `MOVB\s1\(R.*\), R.*$`, `CMPW\s\$104, R.*$`, -`cmpstring`
81	switch ext {
82	// amd64: `CMPL\s\(.*\), \$1836345390$`
83	// arm64: `MOVD\s\$1836345390`, `CMPW\sR.*, R.*$`
84	case ".htm":
85		return "A"
86	// amd64: `CMPL\s\(.*\), \$1953457454$`
87	// arm64: `MOVD\s\$1953457454`, `CMPW\sR.*, R.*$`
88	case ".eot":
89		return "B"
90	// amd64: `CMPL\s\(.*\), \$1735815982$`
91	// arm64: `MOVD\s\$1735815982`, `CMPW\sR.*, R.*$`
92	case ".svg":
93		return "C"
94	// amd64: `CMPL\s\(.*\), \$1718907950$`
95	// arm64: `MOVD\s\$1718907950`, `CMPW\sR.*, R.*$`
96	case ".ttf":
97		return "D"
98	default:
99		return ""
100	}
101}
102
103// use jump tables for type switches to concrete types.
104func typeSwitch(x any) int {
105	// amd64:`JMP\s\(.*\)\(.*\)$`
106	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
107	switch x.(type) {
108	case int:
109		return 0
110	case int8:
111		return 1
112	case int16:
113		return 2
114	case int32:
115		return 3
116	case int64:
117		return 4
118	}
119	return 7
120}
121
122type I interface {
123	foo()
124}
125type J interface {
126	bar()
127}
128type IJ interface {
129	I
130	J
131}
132type K interface {
133	baz()
134}
135
136// use a runtime call for type switches to interface types.
137func interfaceSwitch(x any) int {
138	// amd64:`CALL\truntime.interfaceSwitch`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*8)`
139	// arm64:`CALL\truntime.interfaceSwitch`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
140	switch x.(type) {
141	case I:
142		return 1
143	case J:
144		return 2
145	default:
146		return 3
147	}
148}
149
150func interfaceSwitch2(x K) int {
151	// amd64:`CALL\truntime.interfaceSwitch`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*8)`
152	// arm64:`CALL\truntime.interfaceSwitch`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
153	switch x.(type) {
154	case I:
155		return 1
156	case J:
157		return 2
158	default:
159		return 3
160	}
161}
162
163func interfaceCast(x any) int {
164	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
165	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
166	if _, ok := x.(I); ok {
167		return 3
168	}
169	return 5
170}
171
172func interfaceCast2(x K) int {
173	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
174	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
175	if _, ok := x.(I); ok {
176		return 3
177	}
178	return 5
179}
180
181func interfaceConv(x IJ) I {
182	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
183	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
184	return x
185}
186