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 28f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanickimport license 29f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanickimport gl_XML, glX_XML 30f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickimport sys, getopt, copy 31f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 32f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef should_use_push(registers): 33f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for [reg, offset] in registers: 34f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if reg[1:4] == "xmm": 35f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 0 36f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 37f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick N = len(registers) 38f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return (N & 1) != 0 39f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 40f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 41f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef local_size(registers): 42f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # The x86-64 ABI says "the value (%rsp - 8) is always a multiple of 43f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # 16 when control is transfered to the function entry point." This 44f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # means that the local stack usage must be (16*N)+8 for some value 45f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # of N. (16*N)+8 = (8*(2N))+8 = 8*(2N+1). As long as N is odd, we 46f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # meet this requirement. 47f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 48f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick N = (len(registers) | 1) 49f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 8*N 50f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 51f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 52f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef save_all_regs(registers): 53f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick adjust_stack = 0 54f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if not should_use_push(registers): 55f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick adjust_stack = local_size(registers) 56f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tsubq\t$%u, %%rsp' % (adjust_stack) 57f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 58f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for [reg, stack_offset] in registers: 59f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick save_reg( reg, stack_offset, adjust_stack ) 60f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 61f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 62f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 63f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef restore_all_regs(registers): 64f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick adjust_stack = 0 65f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if not should_use_push(registers): 66f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick adjust_stack = local_size(registers) 67f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 68f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick temp = copy.deepcopy(registers) 69f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick while len(temp): 70f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick [reg, stack_offset] = temp.pop() 71f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick restore_reg(reg, stack_offset, adjust_stack) 72f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 73f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if adjust_stack: 74f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\taddq\t$%u, %%rsp' % (adjust_stack) 75f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 76f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 77f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 78f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef save_reg(reg, offset, use_move): 79f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if use_move: 80f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if offset == 0: 81f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%s, (%%rsp)' % (reg) 82f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 83f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%s, %u(%%rsp)' % (reg, offset) 84f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 85f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tpushq\t%s' % (reg) 86f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 87f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 88f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 89f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 90f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef restore_reg(reg, offset, use_move): 91f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if use_move: 92f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if offset == 0: 93f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t(%%rsp), %s' % (reg) 94f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 95f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%u(%%rsp), %s' % (offset, reg) 96f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 97f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tpopq\t%s' % (reg) 98f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 99f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 100f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 101f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 102f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickclass PrintGenericStubs(gl_XML.gl_print_base): 103f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 104f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def __init__(self): 105f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick gl_XML.gl_print_base.__init__(self) 106f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 107f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick self.name = "gl_x86-64_asm.py (from Mesa)" 108f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") 109f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 110f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 111f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 112f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def get_stack_size(self, f): 113f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick size = 0 114f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for p in f.parameterIterator(): 115f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick size += p.get_stack_size() 116f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 117f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return size 118f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 119f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 120f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def printRealHeader(self): 121f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print "/* If we build with gcc's -fvisibility=hidden flag, we'll need to change" 122f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print " * the symbol visibility mode to 'default'." 123f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' */' 12460031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '' 1255b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu print '#include "x86/assyntax.h"' 12660031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '' 1276e8e4b918d1dac8a0c20e7a5d6f4665a1eaf174fIan Romanick print '#ifdef __GNUC__' 128f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '# pragma GCC visibility push(default)' 129f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '# define HIDDEN(x) .hidden x' 130f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#else' 131f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '# define HIDDEN(x)' 132f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#endif' 133f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 13460031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '# if defined(USE_MGL_NAMESPACE)' 13560031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '# define GL_PREFIX(n) GLNAME(CONCAT(mgl,n))' 13664d952c92cf9393ec7e02902f2c6960d5028fe64Brian Paul print '# define _glapi_Dispatch _mglapi_Dispatch' 13760031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '# else' 13860031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '# define GL_PREFIX(n) GLNAME(CONCAT(gl,n))' 13960031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '# endif' 14060031ace7504a78af75284d66a2d0b4ed9a92b73Brian Paul print '' 141a2f28ceea22254f09ee37039eec873ccdf689e6cMatt Turner print '#if defined(HAVE_PTHREAD) || defined(WIN32)' 142f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '# define THREADS' 143f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#endif' 144f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 145f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.text' 146f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 147f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#ifdef GLX_USE_TLS' 148f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 149f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.globl _x86_64_get_get_dispatch; HIDDEN(_x86_64_get_get_dispatch)' 150f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '_x86_64_get_get_dispatch:' 151f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tlea\t_x86_64_get_dispatch(%rip), %rax' 152f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tret' 153f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 154f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.p2align\t4,,15' 155f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '_x86_64_get_dispatch:' 1567bf08c23fdfe3e8a1dbfc44cad9e7e427f6e2630Brian Paul print '\tmovq\t_glapi_tls_Dispatch@GOTTPOFF(%rip), %rax' 157f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%fs:(%rax), %rax' 158f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tret' 159f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.size\t_x86_64_get_dispatch, .-_x86_64_get_dispatch' 160f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 161a2f28ceea22254f09ee37039eec873ccdf689e6cMatt Turner print '#elif defined(HAVE_PTHREAD)' 162f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 163f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.extern\t_glapi_Dispatch' 164f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.extern\t_gl_DispatchTSD' 165f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.extern\tpthread_getspecific' 166f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 167f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.p2align\t4,,15' 168f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '_x86_64_get_dispatch:' 169cfb9aae3ec4e42bd9be8445039dc52b8d6c71f9cDimitry Andric print '\tmovq\t_gl_DispatchTSD@GOTPCREL(%rip), %rax' 170cfb9aae3ec4e42bd9be8445039dc52b8d6c71f9cDimitry Andric print '\tmovl\t(%rax), %edi' 171f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tjmp\tpthread_getspecific@PLT' 172f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 173f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#elif defined(THREADS)' 174f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 175f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.extern\t_glapi_get_dispatch' 176f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 177f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#endif' 178f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 179f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 180f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 181f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 182f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def printRealFooter(self): 183f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 184f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#if defined(GLX_USE_TLS) && defined(__linux__)' 185f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .section ".note.ABI-tag", "a"' 186f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .p2align 2' 187f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .long 1f - 0f /* name length */' 188f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .long 3f - 2f /* data length */' 189f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .long 1 /* note length */' 190f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '0: .asciz "GNU" /* vendor name */' 191f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '1: .p2align 2' 192f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '2: .long 0 /* note data: the ABI tag */' 193f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print ' .long 2,4,20 /* Minimum kernel version w/TLS */' 194f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '3: .p2align 2 /* pad out section */' 195f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#endif /* GLX_USE_TLS */' 196fcdc6a7d2488defd66bc7e8398c6d8c9a6190a1aKristian Høgsberg print '' 197fcdc6a7d2488defd66bc7e8398c6d8c9a6190a1aKristian Høgsberg print '#if defined (__ELF__) && defined (__linux__)' 198fcdc6a7d2488defd66bc7e8398c6d8c9a6190a1aKristian Høgsberg print ' .section .note.GNU-stack,"",%progbits' 199fcdc6a7d2488defd66bc7e8398c6d8c9a6190a1aKristian Høgsberg print '#endif' 200f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 201f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 202f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 203f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def printFunction(self, f): 204f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 205f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # The x86-64 ABI divides function parameters into a couple 206f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # classes. For the OpenGL interface, the only ones that are 207f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # relevent are INTEGER and SSE. Basically, the first 8 208f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # GLfloat or GLdouble parameters are placed in %xmm0 - %xmm7, 209f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # the first 6 non-GLfloat / non-GLdouble parameters are placed 210f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # in registers listed in int_parameters. 211f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # 212f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # If more parameters than that are required, they are passed 213f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # on the stack. Therefore, we just have to make sure that 214f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # %esp hasn't changed when we jump to the actual function. 215f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # Since we're jumping to the function (and not calling it), we 216f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick # have to make sure of that anyway! 217f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 218f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick int_parameters = ["%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"] 219f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 220f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick int_class = 0 221f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick sse_class = 0 222f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick stack_offset = 0 223f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick registers = [] 224f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for p in f.parameterIterator(): 225f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick type_name = p.get_base_type_string() 226f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 227f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if p.is_pointer() or (type_name != "GLfloat" and type_name != "GLdouble"): 228f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if int_class < 6: 229f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick registers.append( [int_parameters[int_class], stack_offset] ) 230f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick int_class += 1 231f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick stack_offset += 8 232f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 233f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if sse_class < 8: 234f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick registers.append( ["%%xmm%u" % (sse_class), stack_offset] ) 235f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick sse_class += 1 236f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick stack_offset += 8 237f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 238f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if ((int_class & 1) == 0) and (sse_class == 0): 239f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick registers.append( ["%rbp", 0] ) 240f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 241f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 242258751f4a0ac505e66346d8e6ccaec7c5a585534Ian Romanick name = f.dispatch_name() 2434e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick 244f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\t.p2align\t4,,15' 2454e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick print '\t.globl\tGL_PREFIX(%s)' % (name) 2464e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick print '\t.type\tGL_PREFIX(%s), @function' % (name) 2477e9737b3704b92865242d7564825cdc57db5c4c9Ian Romanick if not f.is_static_entry_point(f.name): 2484e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick print '\tHIDDEN(GL_PREFIX(%s))' % (name) 2494e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick print 'GL_PREFIX(%s):' % (name) 250f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#if defined(GLX_USE_TLS)' 251f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tcall\t_x86_64_get_dispatch@PLT' 252f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) 253f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tjmp\t*%r11' 254a2f28ceea22254f09ee37039eec873ccdf689e6cMatt Turner print '#elif defined(HAVE_PTHREAD)' 255f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 256f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick save_all_regs(registers) 257f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tcall\t_x86_64_get_dispatch@PLT' 258f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick restore_all_regs(registers) 259f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 260f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if f.offset == 0: 261f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t(%rax), %r11' 262f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 263f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) 264f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 265f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tjmp\t*%r11' 266f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 267f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#else' 268967b006f518849e57fef68ab71359485b1535b3aIan Romanick print '\tmovq\t_glapi_Dispatch(%rip), %rax' 269f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\ttestq\t%rax, %rax' 270f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tje\t1f' 271f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) 272f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tjmp\t*%r11' 273f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '1:' 274f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 275f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick save_all_regs(registers) 276f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tcall\t_glapi_get_dispatch' 277f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick restore_all_regs(registers) 278f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 279f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) 280f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '\tjmp\t*%r11' 281f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '#endif /* defined(GLX_USE_TLS) */' 282f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 2834e4b5f40081cb3e4cefe4dce30712d8d330c0774Ian Romanick print '\t.size\tGL_PREFIX(%s), .-GL_PREFIX(%s)' % (name, name) 284f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print '' 285f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 286f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 287f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 288f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick def printBody(self, api): 289f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for f in api.functionIterateByOffset(): 290f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick self.printFunction(f) 291f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 292f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 293f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for f in api.functionIterateByOffset(): 294258751f4a0ac505e66346d8e6ccaec7c5a585534Ian Romanick dispatch = f.dispatch_name() 2957e9737b3704b92865242d7564825cdc57db5c4c9Ian Romanick for n in f.entry_points: 2967e9737b3704b92865242d7564825cdc57db5c4c9Ian Romanick if n != f.name: 2977e9737b3704b92865242d7564825cdc57db5c4c9Ian Romanick if f.is_static_entry_point(n): 298f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick text = '\t.globl GL_PREFIX(%s) ; .set GL_PREFIX(%s), GL_PREFIX(%s)' % (n, n, dispatch) 299f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick 300f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick if f.has_different_protocol(n): 301f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick print '#ifndef GLX_INDIRECT_RENDERING' 302f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick print text 303f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick print '#endif' 304f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick else: 305f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick print text 306f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 307f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick return 308f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 309f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickdef show_usage(): 310f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] 311f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick sys.exit(1) 312f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 313f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanickif __name__ == '__main__': 314f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick file_name = "gl_API.xml" 315f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick mode = "generic" 316f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 317f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick try: 318f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick (args, trail) = getopt.getopt(sys.argv[1:], "m:f:") 319f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick except Exception,e: 320f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick show_usage() 321f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 322f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick for (arg,val) in args: 323f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if arg == '-m': 324f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick mode = val 325f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick elif arg == "-f": 326f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick file_name = val 327f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 328f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick if mode == "generic": 329f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick printer = PrintGenericStubs() 330f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick else: 331f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick print "ERROR: Invalid mode \"%s\" specified." % mode 332f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick show_usage() 333f0ff50d4edbeab5aa0df349772ed2eda64878282Ian Romanick 334f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) 335f3f51bc844c8749250724d164722402cb9a07dc7Ian Romanick printer.Print(api) 336