github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/cmd/link/testdata/genpcln.go (about)

     1  // Copyright 2014 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This program generates a .s file using a pseudorandom
     6  // value stream for the runtime function data.
     7  // The pclntab test checks that the linked copy
     8  // still has the same pseudorandom value stream.
     9  
    10  package main
    11  
    12  import (
    13  	"fmt"
    14  	"math/rand"
    15  )
    16  
    17  func main() {
    18  	fmt.Printf("// generated by genpcln.go; do not edit\n\n")
    19  	for f := 0; f < 3; f++ {
    20  		r := rand.New(rand.NewSource(int64(f)))
    21  		file := "input"
    22  		line := 1
    23  		args := r.Intn(100) * 8
    24  		frame := 32 + r.Intn(32)/8*8
    25  		fmt.Printf("#line %d %q\n", line, file)
    26  		fmt.Printf("TEXT func%d(SB),7,$%d-%d\n", f, frame, args)
    27  		fmt.Printf("\tFUNCDATA $1, funcdata%d(SB)\n", f)
    28  		fmt.Printf("#line %d %q\n", line, file)
    29  		size := 200 + r.Intn(100)*8
    30  		spadj := 0
    31  		flushed := 0
    32  		firstpc := 4
    33  		flush := func(i int) {
    34  			for i-flushed >= 10 {
    35  				fmt.Printf("#line %d %q\n", line, file)
    36  				fmt.Printf("/*%#04x*/\tMOVQ $0x123456789, AX\n", firstpc+flushed)
    37  				flushed += 10
    38  			}
    39  			for i-flushed >= 5 {
    40  				fmt.Printf("#line %d %q\n", line, file)
    41  				fmt.Printf("/*%#04x*/\tMOVL $0x1234567, AX\n", firstpc+flushed)
    42  				flushed += 5
    43  			}
    44  			for i-flushed > 0 {
    45  				fmt.Printf("#line %d %q\n", line, file)
    46  				fmt.Printf("/*%#04x*/\tBYTE $0\n", firstpc+flushed)
    47  				flushed++
    48  			}
    49  		}
    50  		for i := 0; i < size; i++ {
    51  			// Possible SP adjustment.
    52  			if r.Intn(100) == 0 {
    53  				flush(i)
    54  				fmt.Printf("#line %d %q\n", line, file)
    55  				if spadj <= -32 || spadj < 32 && r.Intn(2) == 0 {
    56  					spadj += 8
    57  					fmt.Printf("/*%#04x*/\tPUSHQ AX\n", firstpc+i)
    58  				} else {
    59  					spadj -= 8
    60  					fmt.Printf("/*%#04x*/\tPOPQ AX\n", firstpc+i)
    61  				}
    62  				i += 1
    63  				flushed = i
    64  			}
    65  
    66  			// Possible PCFile change.
    67  			if r.Intn(100) == 0 {
    68  				flush(i)
    69  				file = fmt.Sprintf("file%d.s", r.Intn(10))
    70  				line = r.Intn(100) + 1
    71  			}
    72  
    73  			// Possible PCLine change.
    74  			if r.Intn(10) == 0 {
    75  				flush(i)
    76  				line = r.Intn(1000) + 1
    77  			}
    78  
    79  			// Possible PCData $1 change.
    80  			if r.Intn(100) == 0 {
    81  				flush(i)
    82  				fmt.Printf("/*%6s*/\tPCDATA $1, $%d\n", "", r.Intn(1000))
    83  			}
    84  
    85  			// Possible PCData $2 change.
    86  			if r.Intn(100) == 0 {
    87  				flush(i)
    88  				fmt.Printf("/*%6s*/\tPCDATA $2, $%d\n", "", r.Intn(1000))
    89  			}
    90  		}
    91  		flush(size)
    92  		for spadj < 0 {
    93  			fmt.Printf("\tPUSHQ AX\n")
    94  			spadj += 8
    95  		}
    96  		for spadj > 0 {
    97  			fmt.Printf("\tPOPQ AX\n")
    98  			spadj -= 8
    99  		}
   100  		fmt.Printf("\tRET\n")
   101  
   102  		fmt.Printf("\n")
   103  		fmt.Printf("GLOBL funcdata%d(SB), $16\n", f)
   104  	}
   105  
   106  	fmt.Printf("\nTEXT start(SB),7,$0\n")
   107  	for f := 0; f < 3; f++ {
   108  		fmt.Printf("\tCALL func%d(SB)\n", f)
   109  	}
   110  	fmt.Printf("\tMOVQ $runtime·pclntab(SB), AX\n")
   111  	fmt.Printf("\n\tRET\n")
   112  }