mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 08:40:55 +00:00 
			
		
		
		
	 e0948d825d
			
		
	
	
		e0948d825d
		
	
	
	
	
		
			
			It is one less dependent load away, and right next to another field in the itab we also load as part of the type switch or type assert. Change-Id: If7aaa7814c47bd79a6c7ed4232ece0bc1d63550e Reviewed-on: https://go-review.googlesource.com/c/go/+/533117 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // asmcheck
 | |
| 
 | |
| // Copyright 2019 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| // These tests check code generation of switch statements.
 | |
| 
 | |
| package codegen
 | |
| 
 | |
| // see issue 33934
 | |
| func f(x string) int {
 | |
| 	// amd64:-`cmpstring`
 | |
| 	switch x {
 | |
| 	case "":
 | |
| 		return -1
 | |
| 	case "1", "2", "3":
 | |
| 		return -2
 | |
| 	default:
 | |
| 		return -3
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // use jump tables for 8+ int cases
 | |
| func square(x int) int {
 | |
| 	// amd64:`JMP\s\(.*\)\(.*\)$`
 | |
| 	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
 | |
| 	switch x {
 | |
| 	case 1:
 | |
| 		return 1
 | |
| 	case 2:
 | |
| 		return 4
 | |
| 	case 3:
 | |
| 		return 9
 | |
| 	case 4:
 | |
| 		return 16
 | |
| 	case 5:
 | |
| 		return 25
 | |
| 	case 6:
 | |
| 		return 36
 | |
| 	case 7:
 | |
| 		return 49
 | |
| 	case 8:
 | |
| 		return 64
 | |
| 	default:
 | |
| 		return x * x
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // use jump tables for 8+ string lengths
 | |
| func length(x string) int {
 | |
| 	// amd64:`JMP\s\(.*\)\(.*\)$`
 | |
| 	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
 | |
| 	switch x {
 | |
| 	case "a":
 | |
| 		return 1
 | |
| 	case "bb":
 | |
| 		return 2
 | |
| 	case "ccc":
 | |
| 		return 3
 | |
| 	case "dddd":
 | |
| 		return 4
 | |
| 	case "eeeee":
 | |
| 		return 5
 | |
| 	case "ffffff":
 | |
| 		return 6
 | |
| 	case "ggggggg":
 | |
| 		return 7
 | |
| 	case "hhhhhhhh":
 | |
| 		return 8
 | |
| 	default:
 | |
| 		return len(x)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Use single-byte ordered comparisons for binary searching strings.
 | |
| // See issue 53333.
 | |
| func mimetype(ext string) string {
 | |
| 	// amd64: `CMPB\s1\(.*\), \$104$`,-`cmpstring`
 | |
| 	// arm64: `MOVB\s1\(R.*\), R.*$`, `CMPW\s\$104, R.*$`, -`cmpstring`
 | |
| 	switch ext {
 | |
| 	// amd64: `CMPL\s\(.*\), \$1836345390$`
 | |
| 	// arm64: `MOVD\s\$1836345390`, `CMPW\sR.*, R.*$`
 | |
| 	case ".htm":
 | |
| 		return "A"
 | |
| 	// amd64: `CMPL\s\(.*\), \$1953457454$`
 | |
| 	// arm64: `MOVD\s\$1953457454`, `CMPW\sR.*, R.*$`
 | |
| 	case ".eot":
 | |
| 		return "B"
 | |
| 	// amd64: `CMPL\s\(.*\), \$1735815982$`
 | |
| 	// arm64: `MOVD\s\$1735815982`, `CMPW\sR.*, R.*$`
 | |
| 	case ".svg":
 | |
| 		return "C"
 | |
| 	// amd64: `CMPL\s\(.*\), \$1718907950$`
 | |
| 	// arm64: `MOVD\s\$1718907950`, `CMPW\sR.*, R.*$`
 | |
| 	case ".ttf":
 | |
| 		return "D"
 | |
| 	default:
 | |
| 		return ""
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // use jump tables for type switches to concrete types.
 | |
| func typeSwitch(x any) int {
 | |
| 	// amd64:`JMP\s\(.*\)\(.*\)$`
 | |
| 	// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
 | |
| 	switch x.(type) {
 | |
| 	case int:
 | |
| 		return 0
 | |
| 	case int8:
 | |
| 		return 1
 | |
| 	case int16:
 | |
| 		return 2
 | |
| 	case int32:
 | |
| 		return 3
 | |
| 	case int64:
 | |
| 		return 4
 | |
| 	}
 | |
| 	return 7
 | |
| }
 | |
| 
 | |
| type I interface {
 | |
| 	foo()
 | |
| }
 | |
| type J interface {
 | |
| 	bar()
 | |
| }
 | |
| type IJ interface {
 | |
| 	I
 | |
| 	J
 | |
| }
 | |
| type K interface {
 | |
| 	baz()
 | |
| }
 | |
| 
 | |
| // use a runtime call for type switches to interface types.
 | |
| func interfaceSwitch(x any) int {
 | |
| 	// amd64:`CALL\truntime.interfaceSwitch`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*8)`
 | |
| 	// arm64:`CALL\truntime.interfaceSwitch`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
 | |
| 	switch x.(type) {
 | |
| 	case I:
 | |
| 		return 1
 | |
| 	case J:
 | |
| 		return 2
 | |
| 	default:
 | |
| 		return 3
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func interfaceSwitch2(x K) int {
 | |
| 	// amd64:`CALL\truntime.interfaceSwitch`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*8)`
 | |
| 	// arm64:`CALL\truntime.interfaceSwitch`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
 | |
| 	switch x.(type) {
 | |
| 	case I:
 | |
| 		return 1
 | |
| 	case J:
 | |
| 		return 2
 | |
| 	default:
 | |
| 		return 3
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func interfaceCast(x any) int {
 | |
| 	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
 | |
| 	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
 | |
| 	if _, ok := x.(I); ok {
 | |
| 		return 3
 | |
| 	}
 | |
| 	return 5
 | |
| }
 | |
| 
 | |
| func interfaceCast2(x K) int {
 | |
| 	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
 | |
| 	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
 | |
| 	if _, ok := x.(I); ok {
 | |
| 		return 3
 | |
| 	}
 | |
| 	return 5
 | |
| }
 | |
| 
 | |
| func interfaceConv(x IJ) I {
 | |
| 	// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(AX\)`,`MOVQ\t8\(.*\)(.*\*1)`
 | |
| 	// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU\t16\(R0\)`,`MOVD\t\(R.*\)\(R.*\)`
 | |
| 	return x
 | |
| }
 |