1#!/usr/bin/env python
2
3# (C) Copyright IBM Corporation 2004
4# All Rights Reserved.
5#
6# Permission is hereby granted, free of charge, to any person obtaining a
7# copy of this software and associated documentation files (the "Software"),
8# to deal in the Software without restriction, including without limitation
9# on the rights to use, copy, modify, merge, publish, distribute, sub
10# license, and/or sell copies of the Software, and to permit persons to whom
11# the Software is furnished to do so, subject to the following conditions:
12#
13# The above copyright notice and this permission notice (including the next
14# paragraph) shall be included in all copies or substantial portions of the
15# Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23# IN THE SOFTWARE.
24#
25# Authors:
26#    Ian Romanick <idr@us.ibm.com>
27
28import license
29import gl_XML, glX_XML
30import sys, getopt
31
32class PrintGenericStubs(gl_XML.gl_print_base):
33	def __init__(self):
34		gl_XML.gl_print_base.__init__(self)
35		self.name = "gl_SPARC_asm.py (from Mesa)"
36		self.license = license.bsd_license_template % ( \
37"""Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
38(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM")
39
40
41	def printRealHeader(self):
42		print '#ifdef __arch64__'
43		print '#define GL_OFF(N)\t((N) * 8)'
44		print '#define GL_LL\t\tldx'
45		print '#define GL_TIE_LD(SYM)\t%tie_ldx(SYM)'
46		print '#define GL_STACK_SIZE\t128'
47		print '#else'
48		print '#define GL_OFF(N)\t((N) * 4)'
49		print '#define GL_LL\t\tld'
50		print '#define GL_TIE_LD(SYM)\t%tie_ld(SYM)'
51		print '#define GL_STACK_SIZE\t64'
52		print '#endif'
53		print ''
54		print '#define GLOBL_FN(x) .globl x ; .type x, @function'
55		print '#define HIDDEN(x) .hidden x'
56		print ''
57		print '\t.register %g2, #scratch'
58		print '\t.register %g3, #scratch'
59		print ''
60		print '\t.text'
61		print ''
62		print '\tGLOBL_FN(__glapi_sparc_icache_flush)'
63		print '\tHIDDEN(__glapi_sparc_icache_flush)'
64		print '\t.type\t__glapi_sparc_icache_flush, @function'
65		print '__glapi_sparc_icache_flush: /* %o0 = insn_addr */'
66		print '\tflush\t%o0'
67		print '\tretl'
68		print '\t nop'
69		print ''
70		print '\t.align\t32'
71		print ''
72		print '\t.type\t__glapi_sparc_get_pc, @function'
73		print '__glapi_sparc_get_pc:'
74		print '\tretl'
75		print '\t add\t%o7, %g2, %g2'
76		print '\t.size\t__glapi_sparc_get_pc, .-__glapi_sparc_get_pc'
77		print ''
78		print '#ifdef GLX_USE_TLS'
79		print ''
80		print '\tGLOBL_FN(__glapi_sparc_get_dispatch)'
81		print '\tHIDDEN(__glapi_sparc_get_dispatch)'
82		print '__glapi_sparc_get_dispatch:'
83		print '\tmov\t%o7, %g1'
84		print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
85		print '\tcall\t__glapi_sparc_get_pc'
86		print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
87		print '\tmov\t%g1, %o7'
88		print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1'
89		print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1'
90		print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)'
91		print '\tretl'
92		print '\t mov\t%g2, %o0'
93		print ''
94		print '\t.data'
95		print '\t.align\t32'
96		print ''
97		print '\t/* --> sethi %hi(_glapi_tls_Dispatch), %g1 */'
98		print '\t/* --> or %g1, %lo(_glapi_tls_Dispatch), %g1 */'
99		print '\tGLOBL_FN(__glapi_sparc_tls_stub)'
100		print '\tHIDDEN(__glapi_sparc_tls_stub)'
101		print '__glapi_sparc_tls_stub: /* Call offset in %g3 */'
102		print '\tmov\t%o7, %g1'
103		print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
104		print '\tcall\t__glapi_sparc_get_pc'
105		print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
106		print '\tmov\t%g1, %o7'
107		print '\tsrl\t%g3, 10, %g3'
108		print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1'
109		print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1'
110		print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)'
111		print '\tGL_LL\t[%g7+%g2], %g1'
112		print '\tGL_LL\t[%g1 + %g3], %g1'
113		print '\tjmp\t%g1'
114		print '\t nop'
115		print '\t.size\t__glapi_sparc_tls_stub, .-__glapi_sparc_tls_stub'
116		print ''
117		print '#define GL_STUB(fn, off)\t\t\t\t\\'
118		print '\tGLOBL_FN(fn);\t\t\t\t\t\\'
119		print 'fn:\tba\t__glapi_sparc_tls_stub;\t\t\t\\'
120		print '\t sethi\tGL_OFF(off), %g3;\t\t\t\\'
121		print '\t.size\tfn,.-fn;'
122		print ''
123		print '#elif defined(HAVE_PTHREAD)'
124		print ''
125		print '\t/* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */'
126		print '\t/* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */'
127		print '\t/* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */'
128		print '\t/* 64-bit 0x0c --> sllx %g1, 32, %g1 */'
129		print '\t/* 64-bit 0x10 --> add %g1, %g2, %g1 */'
130		print '\t/* 64-bit 0x14 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */'
131		print ''
132		print '\t/* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */'
133		print '\t/* 32-bit 0x04 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */'
134		print ''
135		print '\t.data'
136		print '\t.align\t32'
137		print ''
138		print '\tGLOBL_FN(__glapi_sparc_pthread_stub)'
139		print '\tHIDDEN(__glapi_sparc_pthread_stub)'
140		print '__glapi_sparc_pthread_stub: /* Call offset in %g3 */'
141		print '\tmov\t%o7, %g1'
142		print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
143		print '\tcall\t__glapi_sparc_get_pc'
144		print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
145		print '\tmov\t%g1, %o7'
146		print '\tsethi\t%hi(_glapi_Dispatch), %g1'
147		print '\tor\t%g1, %lo(_glapi_Dispatch), %g1'
148		print '\tsrl\t%g3, 10, %g3'
149		print '\tGL_LL\t[%g2+%g1], %g2'
150		print '\tGL_LL\t[%g2], %g1'
151		print '\tcmp\t%g1, 0'
152		print '\tbe\t2f'
153		print '\t nop'
154		print '1:\tGL_LL\t[%g1 + %g3], %g1'
155		print '\tjmp\t%g1'
156		print '\t nop'
157		print '2:\tsave\t%sp, GL_STACK_SIZE, %sp'
158		print '\tmov\t%g3, %l0'
159		print '\tcall\t_glapi_get_dispatch'
160		print '\t nop'
161		print '\tmov\t%o0, %g1'
162		print '\tmov\t%l0, %g3'
163		print '\tba\t1b'
164		print '\t restore %g0, %g0, %g0'
165		print '\t.size\t__glapi_sparc_pthread_stub, .-__glapi_sparc_pthread_stub'
166		print ''
167		print '#define GL_STUB(fn, off)\t\t\t\\'
168		print '\tGLOBL_FN(fn);\t\t\t\t\\'
169		print 'fn:\tba\t__glapi_sparc_pthread_stub;\t\\'
170		print '\t sethi\tGL_OFF(off), %g3;\t\t\\'
171		print '\t.size\tfn,.-fn;'
172		print ''
173		print '#else /* Non-threaded version. */'
174		print ''
175		print '\t.type	__glapi_sparc_nothread_stub, @function'
176		print '__glapi_sparc_nothread_stub: /* Call offset in %g3 */'
177		print '\tmov\t%o7, %g1'
178		print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
179		print '\tcall\t__glapi_sparc_get_pc'
180		print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
181		print '\tmov\t%g1, %o7'
182		print '\tsrl\t%g3, 10, %g3'
183		print '\tsethi\t%hi(_glapi_Dispatch), %g1'
184		print '\tor\t%g1, %lo(_glapi_Dispatch), %g1'
185		print '\tGL_LL\t[%g2+%g1], %g2'
186		print '\tGL_LL\t[%g2], %g1'
187		print '\tGL_LL\t[%g1 + %g3], %g1'
188		print '\tjmp\t%g1'
189		print '\t nop'
190		print '\t.size\t__glapi_sparc_nothread_stub, .-__glapi_sparc_nothread_stub'
191		print ''
192		print '#define GL_STUB(fn, off)\t\t\t\\'
193		print '\tGLOBL_FN(fn);\t\t\t\t\\'
194		print 'fn:\tba\t__glapi_sparc_nothread_stub;\t\\'
195		print '\t sethi\tGL_OFF(off), %g3;\t\t\\'
196		print '\t.size\tfn,.-fn;'
197		print ''
198		print '#endif'
199		print ''
200		print '#define GL_STUB_ALIAS(fn, alias)		\\'
201		print '	.globl	fn;				\\'
202		print '	.set	fn, alias'
203		print ''
204		print '\t.text'
205		print '\t.align\t32'
206		print ''
207		print '\t.globl\tgl_dispatch_functions_start'
208		print '\tHIDDEN(gl_dispatch_functions_start)'
209		print 'gl_dispatch_functions_start:'
210		print ''
211		return
212
213	def printRealFooter(self):
214		print ''
215		print '\t.globl\tgl_dispatch_functions_end'
216		print '\tHIDDEN(gl_dispatch_functions_end)'
217		print 'gl_dispatch_functions_end:'
218		return
219
220	def printBody(self, api):
221		for f in api.functionIterateByOffset():
222			name = f.dispatch_name()
223
224			print '\tGL_STUB(gl%s, %d)' % (name, f.offset)
225
226			if not f.is_static_entry_point(f.name):
227				print '\tHIDDEN(gl%s)' % (name)
228
229		for f in api.functionIterateByOffset():
230			name = f.dispatch_name()
231
232			if f.is_static_entry_point(f.name):
233				for n in f.entry_points:
234					if n != f.name:
235						text = '\tGL_STUB_ALIAS(gl%s, gl%s)' % (n, f.name)
236
237						if f.has_different_protocol(n):
238							print '#ifndef GLX_INDIRECT_RENDERING'
239							print text
240							print '#endif'
241						else:
242							print text
243
244		return
245
246
247def show_usage():
248	print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
249	sys.exit(1)
250
251if __name__ == '__main__':
252	file_name = "gl_API.xml"
253	mode = "generic"
254
255	try:
256		(args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
257	except Exception,e:
258		show_usage()
259
260	for (arg,val) in args:
261		if arg == '-m':
262			mode = val
263		elif arg == "-f":
264			file_name = val
265
266	if mode == "generic":
267		printer = PrintGenericStubs()
268	else:
269		print "ERROR: Invalid mode \"%s\" specified." % mode
270		show_usage()
271
272	api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
273	printer.Print(api)
274