summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/mkasmh.sh
blob: f37fe21495937b981ff066dcd8b3b1f4971a0459 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/sh
# Copyright 2009 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.

trap "rm -f arch_GOARCH.h defs_GOOS_GOARCH.h os_GOOS.h signals_GOOS.h" EXIT INT TERM
set -e

SYS=$1
export GOOS=$(echo $SYS | sed 's/_.*//')
export GOARCH=$(echo $SYS | sed 's/.*_//')
shift

case "$GOARCH" in
386) CC=8c;;
amd64) CC=6c;;
arm) CC=5c;;
esac
CC="$GOROOT/bin/tool/$CC"
export CC

export CFLAGS="-Dos_$GOOS -Darch_$GOARCH"

cp arch_$GOARCH.h arch_GOARCH.h
cp defs_${GOOS}_$GOARCH.h defs_GOOS_GOARCH.h
cp os_$GOOS.h os_GOOS.h
cp signals_$GOOS.h signals_GOOS.h

cat <<'EOF'
// Assembly constants.
// AUTO-GENERATED by autogen.sh; DO NOT EDIT

EOF
if [ ! -x "$CC" ]; then
	echo "// dummy file for cmd/go to correctly generate buildscript"
	exit
fi

case "$GOARCH" in
386)
	# The offsets 0 and 4 are also known to:
	#	../../cmd/8l/pass.c:/D_GS
	#	cgo/gcc_linux_386.c:/^threadentry
	#	cgo/gcc_darwin_386.c:/^threadentry
	case "$GOOS" in
	windows)
		echo '#define	get_tls(r)	MOVL 0x14(FS), r'
		echo '#define	g(r)	0(r)'
		echo '#define	m(r)	4(r)'
		;;
	plan9)
		echo '#define	get_tls(r)	MOVL _tos(SB), r '
		echo '#define	g(r)	-8(r)'
		echo '#define	m(r)	-4(r)'
		;;
	linux)
		# On Linux systems, what we call 0(GS) and 4(GS) for g and m
		# turn into %gs:-8 and %gs:-4 (using gcc syntax to denote
		# what the machine sees as opposed to 8l input).
		# 8l rewrites 0(GS) and 4(GS) into these.
		#
		# On Linux Xen, it is not allowed to use %gs:-8 and %gs:-4
		# directly.  Instead, we have to store %gs:0 into a temporary
		# register and then use -8(%reg) and -4(%reg).  This kind
		# of addressing is correct even when not running Xen.
		#
		# 8l can rewrite MOVL 0(GS), CX into the appropriate pair
		# of mov instructions, using CX as the intermediate register
		# (safe because CX is about to be written to anyway).
		# But 8l cannot handle other instructions, like storing into 0(GS),
		# which is where these macros come into play.
		# get_tls sets up the temporary and then g and r use it.
		#
		# The final wrinkle is that get_tls needs to read from %gs:0,
		# but in 8l input it's called 8(GS), because 8l is going to
		# subtract 8 from all the offsets, as described above.
		echo '#define	get_tls(r)	MOVL 8(GS), r'
		echo '#define	g(r)	-8(r)'
		echo '#define	m(r)	-4(r)'
		;;
	*)
		echo '#define	get_tls(r)'
		echo '#define	g(r)	0(GS)'
		echo '#define	m(r)	4(GS)'
		;;
	esac
	;;
amd64)
	case "$GOOS" in
	windows)
		echo '#define	get_tls(r) MOVQ 0x28(GS), r'
		echo '#define	g(r) 0(r)'
		echo '#define	m(r) 8(r)'
		;;
	*)
		# The offsets 0 and 8 are known to:
		#	../../cmd/6l/pass.c:/D_GS
		#	cgo/gcc_linux_amd64.c:/^threadentry
		#	cgo/gcc_darwin_amd64.c:/^threadentry
		#
		echo '#define	get_tls(r)'
		echo '#define	g(r) 0(GS)'
		echo '#define	m(r) 8(GS)'
		;;
	esac
	;;
arm)
	echo '#define	g	R10'
	echo '#define	m	R9'
	echo '#define	LR	R14'
	;;
*)
	echo 'unknown $GOARCH: '$GOARCH 1>&2
	exit 1
	;;
esac
echo

"$CC" $CFLAGS -a proc.c |
awk '
{ gsub(/\r/, ""); }
/^aggr G$/ { aggr="g" }
/^aggr M$/ { aggr = "m" }
/^aggr Gobuf$/ { aggr = "gobuf" }
/^aggr WinCall$/ { aggr = "wincall" }
/^}/ { aggr = "" }

#	Gobuf 24 sched;
#	'Y' 48 stack0;
#	'Y' 56 entry;
#	'A' G 64 alllink;
aggr != "" && /^	/ {
	name=$NF;
	sub(/;/, "", name);
	offset=$(NF-1);
	printf("#define %s_%s %s\n", aggr, name, offset);
}
'