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