1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#!/usr/bin/env python
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# (C) Copyright IBM Corporation 2005
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# copy of this software and associated documentation files (the "Software"),
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# to deal in the Software without restriction, including without limitation
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# on the rights to use, copy, modify, merge, publish, distribute, sub
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# license, and/or sell copies of the Software, and to permit persons to whom
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# the Software is furnished to do so, subject to the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# The above copyright notice and this permission notice (including the next
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# paragraph) shall be included in all copies or substantial portions of the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# Authors:
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#    Ian Romanick <idr@us.ibm.com>
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport license
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport gl_XML, glX_XML
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgimport sys, getopt, copy
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef should_use_push(registers):
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for [reg, offset] in registers:
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if reg[1:4] == "xmm":
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return 0
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	N = len(registers)
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (N & 1) != 0
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef local_size(registers):
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	# The x86-64 ABI says "the value (%rsp - 8) is always a multiple of
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	# 16 when control is transfered to the function entry point."  This
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	# means that the local stack usage must be (16*N)+8 for some value
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	# of N.  (16*N)+8 = (8*(2N))+8 = 8*(2N+1).  As long as N is odd, we
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	# meet this requirement.
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	N = (len(registers) | 1)
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 8*N
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef save_all_regs(registers):
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	adjust_stack = 0
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if not should_use_push(registers):
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		adjust_stack = local_size(registers)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tsubq\t$%u, %%rsp' % (adjust_stack)
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for [reg, stack_offset] in registers:
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		save_reg( reg, stack_offset, adjust_stack )
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef restore_all_regs(registers):
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	adjust_stack = 0
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if not should_use_push(registers):
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		adjust_stack = local_size(registers)
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	temp = copy.deepcopy(registers)
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	while len(temp):
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		[reg, stack_offset] = temp.pop()
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_reg(reg, stack_offset, adjust_stack)
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if adjust_stack:
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\taddq\t$%u, %%rsp' % (adjust_stack)
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef save_reg(reg, offset, use_move):
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if use_move:
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if offset == 0:
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t%s, (%%rsp)' % (reg)
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else:
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t%s, %u(%%rsp)' % (reg, offset)
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else:
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tpushq\t%s' % (reg)
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef restore_reg(reg, offset, use_move):
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if use_move:
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if offset == 0:
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t(%%rsp), %s' % (reg)
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t%u(%%rsp), %s' % (offset, reg)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tpopq\t%s' % (reg)
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass PrintGenericStubs(gl_XML.gl_print_base):
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def __init__(self):
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		gl_XML.gl_print_base.__init__(self)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		self.name = "gl_x86-64_asm.py (from Mesa)"
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def get_stack_size(self, f):
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		size = 0
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for p in f.parameterIterator():
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			size += p.get_stack_size()
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return size
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def printRealHeader(self):
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print "/* If we build with gcc's -fvisibility=hidden flag, we'll need to change"
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print " * the symbol visibility mode to 'default'."
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ' */'
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#include "x86/assyntax.h"'
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#ifdef __GNUC__'
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  pragma GCC visibility push(default)'
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define HIDDEN(x) .hidden x'
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#else'
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define HIDDEN(x)'
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif'
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '# if defined(USE_MGL_NAMESPACE)'
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define GL_PREFIX(n) GLNAME(CONCAT(mgl,n))'
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define _glapi_Dispatch _mglapi_Dispatch'
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '# else'
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define GL_PREFIX(n) GLNAME(CONCAT(gl,n))'
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '# endif'
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#if defined(HAVE_PTHREAD) || defined(WIN32)'
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#  define THREADS'
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif'
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.text'
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#ifdef GLX_USE_TLS'
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.globl _x86_64_get_get_dispatch; HIDDEN(_x86_64_get_get_dispatch)'
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '_x86_64_get_get_dispatch:'
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tlea\t_x86_64_get_dispatch(%rip), %rax'
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tret'
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.p2align\t4,,15'
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '_x86_64_get_dispatch:'
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t_glapi_tls_Dispatch@GOTTPOFF(%rip), %rax'
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t%fs:(%rax), %rax'
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tret'
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.size\t_x86_64_get_dispatch, .-_x86_64_get_dispatch'
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#elif defined(HAVE_PTHREAD)'
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.extern\t_glapi_Dispatch'
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.extern\t_gl_DispatchTSD'
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.extern\tpthread_getspecific'
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.p2align\t4,,15'
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '_x86_64_get_dispatch:'
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t_gl_DispatchTSD@GOTPCREL(%rip), %rax'
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovl\t(%rax), %edi'
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tjmp\tpthread_getspecific@PLT'
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#elif defined(THREADS)'
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.extern\t_glapi_get_dispatch'
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif'
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def printRealFooter(self):
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#if defined(GLX_USE_TLS) && defined(__linux__)'
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.section ".note.ABI-tag", "a"'
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.p2align 2'
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.long	1f - 0f   /* name length */'
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.long	3f - 2f   /* data length */'
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.long	1         /* note length */'
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '0:	.asciz "GNU"      /* vendor name */'
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '1:	.p2align 2'
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '2:	.long	0         /* note data: the ABI tag */'
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.long	2,4,20    /* Minimum kernel version w/TLS */'
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '3:	.p2align 2        /* pad out section */'
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif /* GLX_USE_TLS */'
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#if defined (__ELF__) && defined (__linux__)'
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '	.section .note.GNU-stack,"",%progbits'
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif'
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def printFunction(self, f):
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# The x86-64 ABI divides function parameters into a couple
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# classes.  For the OpenGL interface, the only ones that are
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# relevent are INTEGER and SSE.  Basically, the first 8
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# GLfloat or GLdouble parameters are placed in %xmm0 - %xmm7,
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# the first 6 non-GLfloat / non-GLdouble parameters are placed
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# in registers listed in int_parameters.
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		#
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# If more parameters than that are required, they are passed
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# on the stack.  Therefore, we just have to make sure that
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# %esp hasn't changed when we jump to the actual function.
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# Since we're jumping to the function (and not calling it), we
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		# have to make sure of that anyway!
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int_parameters = ["%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"]
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int_class = 0
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sse_class = 0
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		stack_offset = 0
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		registers = []
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for p in f.parameterIterator():
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			type_name = p.get_base_type_string()
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if p.is_pointer() or (type_name != "GLfloat" and type_name != "GLdouble"):
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if int_class < 6:
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					registers.append( [int_parameters[int_class], stack_offset] )
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					int_class += 1
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					stack_offset += 8
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else:
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if sse_class < 8:
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					registers.append( ["%%xmm%u" % (sse_class), stack_offset] )
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					sse_class += 1
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					stack_offset += 8
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if ((int_class & 1) == 0) and (sse_class == 0):
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			registers.append( ["%rbp", 0] )
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		name = f.dispatch_name()
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.p2align\t4,,15'
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.globl\tGL_PREFIX(%s)' % (name)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.type\tGL_PREFIX(%s), @function' % (name)
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if not f.is_static_entry_point(f.name):
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tHIDDEN(GL_PREFIX(%s))' % (name)
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print 'GL_PREFIX(%s):' % (name)
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#if defined(GLX_USE_TLS)'
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tcall\t_x86_64_get_dispatch@PLT'
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8)
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tjmp\t*%r11'
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#elif defined(HAVE_PTHREAD)'
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		save_all_regs(registers)
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tcall\t_x86_64_get_dispatch@PLT'
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_all_regs(registers)
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if f.offset == 0:
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t(%rax), %r11'
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else:
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8)
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tjmp\t*%r11'
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#else'
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t_glapi_Dispatch(%rip), %rax'
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\ttestq\t%rax, %rax'
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tje\t1f'
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8)
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tjmp\t*%r11'
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '1:'
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		save_all_regs(registers)
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tcall\t_glapi_get_dispatch'
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_all_regs(registers)
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\tjmp\t*%r11'
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '#endif /* defined(GLX_USE_TLS) */'
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print '\t.size\tGL_PREFIX(%s), .-GL_PREFIX(%s)' % (name, name)
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print ''
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	def printBody(self, api):
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for f in api.functionIterateByOffset():
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			self.printFunction(f)
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for f in api.functionIterateByOffset():
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			dispatch = f.dispatch_name()
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for n in f.entry_points:
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if n != f.name:
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					if f.is_static_entry_point(n):
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						text = '\t.globl GL_PREFIX(%s) ; .set GL_PREFIX(%s), GL_PREFIX(%s)' % (n, n, dispatch)
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						if f.has_different_protocol(n):
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							print '#ifndef GLX_INDIRECT_RENDERING'
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							print text
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							print '#endif'
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						else:
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							print text
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef show_usage():
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sys.exit(1)
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif __name__ == '__main__':
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	file_name = "gl_API.xml"
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mode = "generic"
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	try:
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	except Exception,e:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		show_usage()
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (arg,val) in args:
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if arg == '-m':
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			mode = val
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		elif arg == "-f":
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			file_name = val
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if mode == "generic":
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printer = PrintGenericStubs()
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else:
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print "ERROR: Invalid mode \"%s\" specified." % mode
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		show_usage()
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	printer.Print(api)
336