Source file test/codegen/switch.go

     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  
     9  package codegen
    10  
    11  // see issue 33934
    12  func 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
    25  func 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
    51  func 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.
    78  func 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.
   104  func 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  
   122  type I interface {
   123  	foo()
   124  }
   125  type J interface {
   126  	bar()
   127  }
   128  type IJ interface {
   129  	I
   130  	J
   131  }
   132  type K interface {
   133  	baz()
   134  }
   135  
   136  // use a runtime call for type switches to interface types.
   137  func 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  
   150  func 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  
   163  func 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  
   172  func 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  
   181  func 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  

View as plain text