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//go:build ignore 6 7// Generate Windows callback assembly file. 8 9package main 10 11import ( 12 "bytes" 13 "fmt" 14 "os" 15) 16 17const maxCallback = 2000 18 19func genasm386Amd64() { 20 var buf bytes.Buffer 21 22 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 23 24//go:build 386 || amd64 25 26#include "textflag.h" 27 28// runtime·callbackasm is called by external code to 29// execute Go implemented callback function. It is not 30// called from the start, instead runtime·compilecallback 31// always returns address into runtime·callbackasm offset 32// appropriately so different callbacks start with different 33// CALL instruction in runtime·callbackasm. This determines 34// which Go callback function is executed later on. 35 36TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0 37`) 38 for i := 0; i < maxCallback; i++ { 39 buf.WriteString("\tCALL\truntime·callbackasm1(SB)\n") 40 } 41 42 filename := fmt.Sprintf("zcallback_windows.s") 43 err := os.WriteFile(filename, buf.Bytes(), 0666) 44 if err != nil { 45 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 46 os.Exit(2) 47 } 48} 49 50func genasmArm() { 51 var buf bytes.Buffer 52 53 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 54 55// External code calls into callbackasm at an offset corresponding 56// to the callback index. Callbackasm is a table of MOV and B instructions. 57// The MOV instruction loads R12 with the callback index, and the 58// B instruction branches to callbackasm1. 59// callbackasm1 takes the callback index from R12 and 60// indexes into an array that stores information about each callback. 61// It then calls the Go implementation for that callback. 62#include "textflag.h" 63 64TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0 65`) 66 for i := 0; i < maxCallback; i++ { 67 fmt.Fprintf(&buf, "\tMOVW\t$%d, R12\n", i) 68 buf.WriteString("\tB\truntime·callbackasm1(SB)\n") 69 } 70 71 err := os.WriteFile("zcallback_windows_arm.s", buf.Bytes(), 0666) 72 if err != nil { 73 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 74 os.Exit(2) 75 } 76} 77 78func genasmArm64() { 79 var buf bytes.Buffer 80 81 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 82 83// External code calls into callbackasm at an offset corresponding 84// to the callback index. Callbackasm is a table of MOV and B instructions. 85// The MOV instruction loads R12 with the callback index, and the 86// B instruction branches to callbackasm1. 87// callbackasm1 takes the callback index from R12 and 88// indexes into an array that stores information about each callback. 89// It then calls the Go implementation for that callback. 90#include "textflag.h" 91 92TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0 93`) 94 for i := 0; i < maxCallback; i++ { 95 fmt.Fprintf(&buf, "\tMOVD\t$%d, R12\n", i) 96 buf.WriteString("\tB\truntime·callbackasm1(SB)\n") 97 } 98 99 err := os.WriteFile("zcallback_windows_arm64.s", buf.Bytes(), 0666) 100 if err != nil { 101 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 102 os.Exit(2) 103 } 104} 105 106func gengo() { 107 var buf bytes.Buffer 108 109 fmt.Fprintf(&buf, `// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 110 111package runtime 112 113const cb_max = %d // maximum number of windows callbacks allowed 114`, maxCallback) 115 err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666) 116 if err != nil { 117 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 118 os.Exit(2) 119 } 120} 121 122func main() { 123 genasm386Amd64() 124 genasmArm() 125 genasmArm64() 126 gengo() 127} 128