Home | History | Annotate | Download | only in gen
      1 #!/usr/bin/env python
      2 
      3 # (C) Copyright IBM Corporation 2004, 2005
      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 (at] us.ibm.com>
     27 
     28 import license
     29 import gl_XML, glX_XML
     30 import sys, getopt
     31 
     32 class PrintGenericStubs(gl_XML.gl_print_base):
     33 
     34 	def __init__(self):
     35 		gl_XML.gl_print_base.__init__(self)
     36 
     37 		self.name = "gl_x86_asm.py (from Mesa)"
     38 		self.license = license.bsd_license_template % ( \
     39 """Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
     40 (C) Copyright IBM Corporation 2004, 2005""", "BRIAN PAUL, IBM")
     41 		return
     42 
     43 
     44 	def get_stack_size(self, f):
     45 		size = 0
     46 		for p in f.parameterIterator():
     47 			if p.is_padding:
     48 				continue
     49 
     50 			size += p.get_stack_size()
     51 
     52 		return size
     53 
     54 
     55 	def printRealHeader(self):
     56 		print '#include "x86/assyntax.h"'
     57 		print ''
     58 		print '#if defined(STDCALL_API)'
     59 		print '# if defined(USE_MGL_NAMESPACE)'
     60 		print '#  define GL_PREFIX(n,n2) GLNAME(CONCAT(mgl,n2))'
     61 		print '# else'
     62 		print '#  define GL_PREFIX(n,n2) GLNAME(CONCAT(gl,n2))'
     63 		print '# endif'
     64 		print '#else'
     65 		print '# if defined(USE_MGL_NAMESPACE)'
     66 		print '#  define GL_PREFIX(n,n2) GLNAME(CONCAT(mgl,n))'
     67 		print '#  define _glapi_Dispatch _mglapi_Dispatch'
     68 		print '# else'
     69 		print '#  define GL_PREFIX(n,n2) GLNAME(CONCAT(gl,n))'
     70 		print '# endif'
     71 		print '#endif'
     72 		print ''
     73 		print '#define GL_OFFSET(x) CODEPTR(REGOFF(4 * x, EAX))'
     74 		print ''
     75 		print '#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__)'
     76 		print '#define GLOBL_FN(x) GLOBL x ; .type x, @function'
     77 		print '#else'
     78 		print '#define GLOBL_FN(x) GLOBL x'
     79 		print '#endif'
     80 		print ''
     81 		print '#if defined(HAVE_PTHREAD) || defined(WIN32)'
     82 		print '#  define THREADS'
     83 		print '#endif'
     84 		print ''
     85 		print '#ifdef GLX_USE_TLS'
     86 		print ''
     87 		print '#ifdef GLX_X86_READONLY_TEXT'
     88 		print '# define CTX_INSNS MOV_L(GS:(EAX), EAX)'
     89 		print '#else'
     90 		print '# define CTX_INSNS NOP /* Pad for init_glapi_relocs() */'
     91 		print '#endif'
     92 		print ''
     93 		print '#  define GL_STUB(fn,off,fn_alt)\t\t\t\\'
     94 		print 'ALIGNTEXT16;\t\t\t\t\t\t\\'
     95 		print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\'
     96 		print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\'
     97 		print '\tCALL(_x86_get_dispatch) ;\t\t\t\\'
     98 		print '\tCTX_INSNS ;					\\'
     99 		print '\tJMP(GL_OFFSET(off))'
    100 		print ''
    101 		print '#elif defined(HAVE_PTHREAD)'
    102 		print '#  define GL_STUB(fn,off,fn_alt)\t\t\t\\'
    103 		print 'ALIGNTEXT16;\t\t\t\t\t\t\\'
    104 		print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\'
    105 		print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\'
    106 		print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\'
    107 		print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\'
    108 		print '\tJE(1f) ;\t\t\t\t\t\\'
    109 		print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\'
    110 		print '1:\tCALL(_x86_get_dispatch) ;\t\t\t\\'
    111 		print '\tJMP(GL_OFFSET(off))'
    112 		print '#elif defined(THREADS)'
    113 		print '#  define GL_STUB(fn,off,fn_alt)\t\t\t\\'
    114 		print 'ALIGNTEXT16;\t\t\t\t\t\t\\'
    115 		print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\'
    116 		print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\'
    117 		print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\'
    118 		print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\'
    119 		print '\tJE(1f) ;\t\t\t\t\t\\'
    120 		print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\'
    121 		print '1:\tCALL(_glapi_get_dispatch) ;\t\t\t\\'
    122 		print '\tJMP(GL_OFFSET(off))'
    123 		print '#else /* Non-threaded version. */'
    124 		print '#  define GL_STUB(fn,off,fn_alt)\t\t\t\\'
    125 		print 'ALIGNTEXT16;\t\t\t\t\t\t\\'
    126 		print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\'
    127 		print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\'
    128 		print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\'
    129 		print '\tJMP(GL_OFFSET(off))'
    130 		print '#endif'
    131 		print ''
    132 		print '#ifdef HAVE_ALIAS'
    133 		print '#  define GL_STUB_ALIAS(fn,off,fn_alt,alias,alias_alt)\t\\'
    134 		print '\t.globl\tGL_PREFIX(fn, fn_alt) ;\t\t\t\\'
    135 		print '\t.set\tGL_PREFIX(fn, fn_alt), GL_PREFIX(alias, alias_alt)'
    136 		print '#else'
    137 		print '#  define GL_STUB_ALIAS(fn,off,fn_alt,alias,alias_alt)\t\\'
    138 		print '    GL_STUB(fn, off, fn_alt)'
    139 		print '#endif'
    140 		print ''
    141 		print 'SEG_TEXT'
    142 		print ''
    143 		print '#ifdef GLX_USE_TLS'
    144 		print ''
    145 		print '\tGLOBL\tGLNAME(_x86_get_dispatch)'
    146 		print '\tHIDDEN(GLNAME(_x86_get_dispatch))'
    147 		print 'ALIGNTEXT16'
    148 		print 'GLNAME(_x86_get_dispatch):'
    149 		print '\tcall	1f'
    150 		print '1:\tpopl	%eax'
    151 		print '\taddl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %eax'
    152 		print '\tmovl	_glapi_tls_Dispatch@GOTNTPOFF(%eax), %eax'
    153 		print '\tret'
    154 		print ''
    155 		print '#elif defined(HAVE_PTHREAD)'
    156 		print 'EXTERN GLNAME(_glapi_Dispatch)'
    157 		print 'EXTERN GLNAME(_gl_DispatchTSD)'
    158 		print 'EXTERN GLNAME(pthread_getspecific)'
    159 		print ''
    160 		print 'ALIGNTEXT16'
    161 		print 'GLNAME(_x86_get_dispatch):'
    162 		print '\tSUB_L(CONST(24), ESP)'
    163 		print '\tPUSH_L(GLNAME(_gl_DispatchTSD))'
    164 		print '\tCALL(GLNAME(pthread_getspecific))'
    165 		print '\tADD_L(CONST(28), ESP)'
    166 		print '\tRET'
    167 		print '#elif defined(THREADS)'
    168 		print 'EXTERN GLNAME(_glapi_get_dispatch)'
    169 		print '#endif'
    170 		print ''
    171 
    172 		print '#if defined( GLX_USE_TLS ) && !defined( GLX_X86_READONLY_TEXT )'
    173 		print '\t\t.section\twtext, "awx", @progbits'
    174 		print '#endif /* defined( GLX_USE_TLS ) */'
    175 
    176 		print ''
    177 		print '\t\tALIGNTEXT16'
    178 		print '\t\tGLOBL GLNAME(gl_dispatch_functions_start)'
    179 		print '\t\tHIDDEN(GLNAME(gl_dispatch_functions_start))'
    180 		print 'GLNAME(gl_dispatch_functions_start):'
    181 		print ''
    182 		return
    183 
    184 
    185 	def printRealFooter(self):
    186 		print ''
    187 		print '\t\tGLOBL\tGLNAME(gl_dispatch_functions_end)'
    188 		print '\t\tHIDDEN(GLNAME(gl_dispatch_functions_end))'
    189 		print '\t\tALIGNTEXT16'
    190 		print 'GLNAME(gl_dispatch_functions_end):'
    191 		print ''
    192 		print '#if defined(GLX_USE_TLS) && defined(__linux__)'
    193 		print '	.section ".note.ABI-tag", "a"'
    194 		print '	.p2align 2'
    195 		print '	.long	1f - 0f   /* name length */'
    196 		print '	.long	3f - 2f   /* data length */'
    197 		print '	.long	1         /* note length */'
    198 		print '0:	.asciz "GNU"      /* vendor name */'
    199 		print '1:	.p2align 2'
    200 		print '2:	.long	0         /* note data: the ABI tag */'
    201 		print '	.long	2,4,20    /* Minimum kernel version w/TLS */'
    202 		print '3:	.p2align 2        /* pad out section */'
    203 		print '#endif /* GLX_USE_TLS */'
    204 		print ''
    205 		print '#if defined (__ELF__) && defined (__linux__)'
    206 		print '	.section .note.GNU-stack,"",%progbits'
    207 		print '#endif'
    208 		return
    209 
    210 
    211 	def printBody(self, api):
    212 		for f in api.functionIterateByOffset():
    213 			name = f.dispatch_name()
    214 			stack = self.get_stack_size(f)
    215 			alt = "%s@%u" % (name, stack)
    216 
    217 			print '\tGL_STUB(%s, %d, %s)' % (name, f.offset, alt)
    218 
    219 			if not f.is_static_entry_point(f.name):
    220 				print '\tHIDDEN(GL_PREFIX(%s, %s))' % (name, alt)
    221 
    222 
    223 		for f in api.functionIterateByOffset():
    224 			name = f.dispatch_name()
    225 			stack = self.get_stack_size(f)
    226 			alt = "%s@%u" % (name, stack)
    227 
    228 			for n in f.entry_points:
    229 				if f.is_static_entry_point(n):
    230 					if n != f.name:
    231 						alt2 = "%s@%u" % (n, stack)
    232 						text = '\tGL_STUB_ALIAS(%s, %d, %s, %s, %s)' % (n, f.offset, alt2, name, alt)
    233 
    234 						if f.has_different_protocol(n):
    235 							print '#ifndef GLX_INDIRECT_RENDERING'
    236 							print text
    237 							print '#endif'
    238 						else:
    239 							print text
    240 
    241 		return
    242 
    243 def show_usage():
    244 	print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
    245 	sys.exit(1)
    246 
    247 if __name__ == '__main__':
    248 	file_name = "gl_API.xml"
    249 	mode = "generic"
    250 
    251 	try:
    252 		(args, trail) = getopt.getopt(sys.argv[1:], "m:f:")
    253 	except Exception,e:
    254 		show_usage()
    255 
    256 	for (arg,val) in args:
    257 		if arg == '-m':
    258 			mode = val
    259 		elif arg == "-f":
    260 			file_name = val
    261 
    262 	if mode == "generic":
    263 		printer = PrintGenericStubs()
    264 	else:
    265 		print "ERROR: Invalid mode \"%s\" specified." % mode
    266 		show_usage()
    267 
    268 	api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
    269 	printer.Print(api)
    270