Source file test/codegen/stack.go

     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  
     7  package codegen
     8  
     9  import "runtime"
    10  
    11  // This file contains code generation tests related to the use of the
    12  // stack.
    13  
    14  // Check that stack stores are optimized away.
    15  
    16  // 386:"TEXT\t.*, [$]0-"
    17  // amd64:"TEXT\t.*, [$]0-"
    18  // arm:"TEXT\t.*, [$]-4-"
    19  // arm64:"TEXT\t.*, [$]0-"
    20  // mips:"TEXT\t.*, [$]-4-"
    21  // ppc64:"TEXT\t.*, [$]0-"
    22  // ppc64le:"TEXT\t.*, [$]0-"
    23  // s390x:"TEXT\t.*, [$]0-"
    24  func StackStore() int {
    25  	var x int
    26  	return *(&x)
    27  }
    28  
    29  type T struct {
    30  	A, B, C, D int // keep exported fields
    31  	x, y, z    int // reset unexported fields
    32  }
    33  
    34  // Check that large structs are cleared directly (issue #24416).
    35  
    36  // 386:"TEXT\t.*, [$]0-"
    37  // amd64:"TEXT\t.*, [$]0-"
    38  // arm:"TEXT\t.*, [$]0-" (spills return address)
    39  // arm64:"TEXT\t.*, [$]0-"
    40  // mips:"TEXT\t.*, [$]-4-"
    41  // ppc64:"TEXT\t.*, [$]0-"
    42  // ppc64le:"TEXT\t.*, [$]0-"
    43  // s390x:"TEXT\t.*, [$]0-"
    44  func ZeroLargeStruct(x *T) {
    45  	t := T{}
    46  	*x = t
    47  }
    48  
    49  // Check that structs are partially initialised directly (issue #24386).
    50  
    51  // Notes:
    52  // - 386 fails due to spilling a register
    53  // amd64:"TEXT\t.*, [$]0-"
    54  // arm:"TEXT\t.*, [$]0-" (spills return address)
    55  // arm64:"TEXT\t.*, [$]0-"
    56  // ppc64:"TEXT\t.*, [$]0-"
    57  // ppc64le:"TEXT\t.*, [$]0-"
    58  // s390x:"TEXT\t.*, [$]0-"
    59  // Note: that 386 currently has to spill a register.
    60  func KeepWanted(t *T) {
    61  	*t = T{A: t.A, B: t.B, C: t.C, D: t.D}
    62  }
    63  
    64  // Check that small array operations avoid using the stack (issue #15925).
    65  
    66  // Notes:
    67  // - 386 fails due to spilling a register
    68  // - arm & mips fail due to softfloat calls
    69  // amd64:"TEXT\t.*, [$]0-"
    70  // arm64:"TEXT\t.*, [$]0-"
    71  // ppc64:"TEXT\t.*, [$]0-"
    72  // ppc64le:"TEXT\t.*, [$]0-"
    73  // s390x:"TEXT\t.*, [$]0-"
    74  func ArrayAdd64(a, b [4]float64) [4]float64 {
    75  	return [4]float64{a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]}
    76  }
    77  
    78  // Check that small array initialization avoids using the stack.
    79  
    80  // 386:"TEXT\t.*, [$]0-"
    81  // amd64:"TEXT\t.*, [$]0-"
    82  // arm:"TEXT\t.*, [$]0-" (spills return address)
    83  // arm64:"TEXT\t.*, [$]0-"
    84  // mips:"TEXT\t.*, [$]-4-"
    85  // ppc64:"TEXT\t.*, [$]0-"
    86  // ppc64le:"TEXT\t.*, [$]0-"
    87  // s390x:"TEXT\t.*, [$]0-"
    88  func ArrayInit(i, j int) [4]int {
    89  	return [4]int{i, 0, j, 0}
    90  }
    91  
    92  // Check that assembly output has matching offset and base register
    93  // (issue #21064).
    94  
    95  func check_asmout(b [2]int) int {
    96  	runtime.GC() // use some frame
    97  	// amd64:`.*b\+24\(SP\)`
    98  	// arm:`.*b\+4\(FP\)`
    99  	return b[1]
   100  }
   101  
   102  // Check that simple functions get promoted to nosplit, even when
   103  // they might panic in various ways. See issue 31219.
   104  // amd64:"TEXT\t.*NOSPLIT.*"
   105  func MightPanic(a []int, i, j, k, s int) {
   106  	_ = a[i]     // panicIndex
   107  	_ = a[i:j]   // panicSlice
   108  	_ = a[i:j:k] // also panicSlice
   109  	_ = i << s   // panicShift
   110  	_ = i / j    // panicDivide
   111  }
   112  
   113  // Put a defer in a loop, so second defer is not open-coded
   114  func Defer() {
   115  	for i := 0; i < 2; i++ {
   116  		defer func() {}()
   117  	}
   118  	// amd64:`CALL\truntime\.deferprocStack`
   119  	defer func() {}()
   120  }
   121  

View as plain text