mesa: Resurrect SPARC asm code.
This rewrites the sparc GLAPI code so that it's PIC friendly and works with all of the TLS/PTHREADS/64-bit/32-bit combinations properly. As a result we can turn SPARC asm back on. Currently it's only enabled on Linux, as that's the only place where I can test this stuff out. For the moment the cliptest SPARC asm routines are disabled as they are non-working. The problem is that they use register %g7 as a temporary which is where the threading libraries store the thread pointer on SPARC. I will fix that code up in a future change as it's a pretty important routine to optimize. Like x86 we do the runtime patch as a pthread once-invoked initializer in init_glapi_relocs(). Unlike x86, however, our GLAPI stubs on SPARC are just two instruction sequences that branch to a trampoline and put the GLAPI offset into a register. The trampoline is what we run-time patch. The stubs thus all look like: glFoo: ba __glapi_sparc_foo_stub sethi GLAPI_OFFSET(glFOO) * PTR_SIZE, %g3 This actually makes generate_entrypoint() a lot simpler on SPARC. For this case in generate_entrypoint() we generate stubs using a 'call' instead of the 'ba' above to make sure it can reach. In order to get a proper tail call going here, in the unpatched case, we do several tricks. To get the current PC, for example, we save the return address register into a temporary, do a call, save the return address register written by the call to another temporary, then restore the original return address register value. This is to avoid having to allocate a stack frame. This is necessary for PIC address formation. This new GLAPI scheme lets us get rid of the ugly SPARC GLAPI hacks in __glXInitialize() and one_time_init(). Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
Brian Paul

parent
b12dc74f86
commit
857ac1e817
13
configure.ac
13
configure.ac
@@ -307,6 +307,13 @@ if test "x$enable_asm" = xyes; then
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sparc*)
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
asm_arch=sparc
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$asm_arch" in
|
||||
@@ -327,6 +334,12 @@ if test "x$enable_asm" = xyes; then
|
||||
MESA_ASM_SOURCES='$(PPC_SOURCES)'
|
||||
AC_MSG_RESULT([yes, ppc])
|
||||
;;
|
||||
sparc)
|
||||
ASM_FLAGS="-DUSE_SPARC_ASM"
|
||||
MESA_ASM_SOURCES='$(SPARC_SOURCES)'
|
||||
GLAPI_ASM_SOURCES='$(SPARC_API)'
|
||||
AC_MSG_RESULT([yes, sparc])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no, platform not supported])
|
||||
;;
|
||||
|
@@ -56,19 +56,6 @@
|
||||
void __glXDumpDrawBuffer(__GLXcontext * ctx);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPARC_ASM
|
||||
static void _glx_mesa_init_sparc_glapi_relocs(void);
|
||||
static int _mesa_sparc_needs_init = 1;
|
||||
#define INIT_MESA_SPARC do { \
|
||||
if (_mesa_sparc_needs_init) { \
|
||||
_glx_mesa_init_sparc_glapi_relocs(); \
|
||||
_mesa_sparc_needs_init = 0; \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define INIT_MESA_SPARC do { } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** You can set this cell to 1 to force the gl drawing stuff to be
|
||||
** one command per packet
|
||||
@@ -670,7 +657,6 @@ __glXInitialize(Display * dpy)
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT_MESA_SPARC;
|
||||
/* The one and only long long lock */
|
||||
__glXLock();
|
||||
|
||||
@@ -785,7 +771,6 @@ __glXSetupForCommand(Display * dpy)
|
||||
|
||||
if (gc->currentDpy == dpy) {
|
||||
/* Use opcode from gc because its right */
|
||||
INIT_MESA_SPARC;
|
||||
return gc->majorOpcode;
|
||||
}
|
||||
else {
|
||||
@@ -979,74 +964,3 @@ __glXDumpDrawBuffer(__GLXcontext * ctx)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPARC_ASM
|
||||
/*
|
||||
* This is where our dispatch table's bounds are.
|
||||
* And the static mesa_init is taken directly from
|
||||
* Mesa's 'sparc.c' initializer.
|
||||
*
|
||||
* We need something like this here, because this version
|
||||
* of openGL/glx never initializes a Mesa context, and so
|
||||
* the address of the dispatch table pointer never gets stuffed
|
||||
* into the dispatch jump table otherwise.
|
||||
*
|
||||
* It matters only on SPARC, and only if you are using assembler
|
||||
* code instead of C-code indirect dispatch.
|
||||
*
|
||||
* -- FEM, 04.xii.03
|
||||
*/
|
||||
extern unsigned int _mesa_sparc_glapi_begin;
|
||||
extern unsigned int _mesa_sparc_glapi_end;
|
||||
extern void __glapi_sparc_icache_flush(unsigned int *);
|
||||
|
||||
static void
|
||||
_glx_mesa_init_sparc_glapi_relocs(void)
|
||||
{
|
||||
unsigned int *insn_ptr, *end_ptr;
|
||||
unsigned long disp_addr;
|
||||
|
||||
insn_ptr = &_mesa_sparc_glapi_begin;
|
||||
end_ptr = &_mesa_sparc_glapi_end;
|
||||
disp_addr = (unsigned long) &_glapi_Dispatch;
|
||||
|
||||
/*
|
||||
* Verbatim from Mesa sparc.c. It's needed because there doesn't
|
||||
* seem to be a better way to do this:
|
||||
*
|
||||
* UNCONDITIONAL_JUMP ( (*_glapi_Dispatch) + entry_offset )
|
||||
*
|
||||
* This code is patching in the ADDRESS of the pointer to the
|
||||
* dispatch table. Hence, it must be called exactly once, because
|
||||
* that address is not going to change.
|
||||
*
|
||||
* What it points to can change, but Mesa (and hence, we) assume
|
||||
* that there is only one pointer.
|
||||
*
|
||||
*/
|
||||
while (insn_ptr < end_ptr) {
|
||||
#if ( defined(__sparc_v9__) && ( !defined(__linux__) || defined(__linux_64__) ) )
|
||||
/*
|
||||
This code patches for 64-bit addresses. This had better
|
||||
not happen for Sparc/Linux, no matter what architecture we
|
||||
are building for. So, don't do this.
|
||||
|
||||
The 'defined(__linux_64__)' is used here as a placeholder for
|
||||
when we do do 64-bit usermode on sparc linux.
|
||||
*/
|
||||
insn_ptr[0] |= (disp_addr >> (32 + 10));
|
||||
insn_ptr[1] |= ((disp_addr & 0xffffffff) >> 10);
|
||||
__glapi_sparc_icache_flush(&insn_ptr[0]);
|
||||
insn_ptr[2] |= ((disp_addr >> 32) & ((1 << 10) - 1));
|
||||
insn_ptr[3] |= (disp_addr & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&insn_ptr[2]);
|
||||
insn_ptr += 11;
|
||||
#else
|
||||
insn_ptr[0] |= (disp_addr >> 10);
|
||||
insn_ptr[1] |= (disp_addr & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&insn_ptr[0]);
|
||||
insn_ptr += 5;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* sparc ASM in use */
|
||||
|
@@ -39,80 +39,202 @@ class PrintGenericStubs(gl_XML.gl_print_base):
|
||||
|
||||
|
||||
def printRealHeader(self):
|
||||
print '#include "glapioffsets.h"'
|
||||
print '#include "glapi/glapioffsets.h"'
|
||||
print ''
|
||||
print '#ifdef __arch64__'
|
||||
print '# define GL_STUB(fn,off)\t\t\t\t\\'
|
||||
print 'fn:\t\t\t\t\t\\'
|
||||
print '\tsethi\t%hi(0xDEADBEEF), %g4 ;\t\t\t\\'
|
||||
print '\tsethi\t%hi(0xDEADBEEF), %g1 ;\t\t\t\\'
|
||||
print '\tor\t%g4, %lo(0xDEADBEEF), %g4 ;\t\t\\'
|
||||
print '\tor\t%g1, %lo(0xDEADBEEF), %g1 ;\t\t\\'
|
||||
print '\tsllx\t%g4, 32, %g4 ;\t\t\t\t\\'
|
||||
print '\tldx\t[%g1 + %g4], %g1 ;\t\t\t\\'
|
||||
print '\tsethi\t%hi(8 * off), %g4 ;\t\t\t\\'
|
||||
print '\tor\t%g4, %lo(8 * off), %g4 ;\t\t\\'
|
||||
print '\tldx\t[%g1 + %g4], %g5 ;\t\t\t\\'
|
||||
print '\tjmpl\t%g5, %g0 ;\t\t\t\t\\'
|
||||
print '\tnop'
|
||||
print '#define GL_OFF(N)\t((N) * 8)'
|
||||
print '#define GL_LL\t\tldx'
|
||||
print '#define GL_TIE_LD(SYM)\t%tie_ldx(SYM)'
|
||||
print '#define GL_STACK_SIZE\t128'
|
||||
print '#else'
|
||||
print '# define GL_STUB(fn,off)\t\t\t\t\\'
|
||||
print 'fn:\t\t\t\t\t\\'
|
||||
print '\tsethi\t%hi(0xDEADBEEF), %g1 ;\t\t\t\\'
|
||||
print '\tld\t[%g1 + %lo(0xDEADBEEF)], %g1 ;\t\t\\'
|
||||
print '\tld\t[%g1 + (4 * off)], %g5 ;\t\t\\'
|
||||
print '\tjmpl\t%g5, %g0 ;\t\t\t\t\\'
|
||||
print '\tnop'
|
||||
print '#define GL_OFF(N)\t((N) * 4)'
|
||||
print '#define GL_LL\t\tld'
|
||||
print '#define GL_TIE_LD(SYM)\t%tie_ld(SYM)'
|
||||
print '#define GL_STACK_SIZE\t64'
|
||||
print '#endif'
|
||||
print ''
|
||||
print '#define GL_STUB_ALIAS(fn,alias) fn = alias'
|
||||
print '#define GLOBL_FN(x) .globl x ; .type x, @function'
|
||||
print '#define HIDDEN(x) .hidden x'
|
||||
print ''
|
||||
print '.text'
|
||||
print '.align 32'
|
||||
print '\t\t.globl __glapi_sparc_icache_flush ; .type __glapi_sparc_icache_flush,#function'
|
||||
print '\t.register %g2, #scratch'
|
||||
print '\t.register %g3, #scratch'
|
||||
print ''
|
||||
print '\t.text'
|
||||
print ''
|
||||
print '\tGLOBL_FN(__glapi_sparc_icache_flush)'
|
||||
print '\tHIDDEN(__glapi_sparc_icache_flush)'
|
||||
print '\t.type\t__glapi_sparc_icache_flush, @function'
|
||||
print '__glapi_sparc_icache_flush: /* %o0 = insn_addr */'
|
||||
print '\tflush\t%o0'
|
||||
print '\tretl'
|
||||
print '\tnop'
|
||||
print '\t nop'
|
||||
print ''
|
||||
print '.data'
|
||||
print '.align 64'
|
||||
print '\t.align\t32'
|
||||
print ''
|
||||
print '\t.type\t__glapi_sparc_get_pc, @function'
|
||||
print '__glapi_sparc_get_pc:'
|
||||
print '\tretl'
|
||||
print '\t add\t%o7, %g2, %g2'
|
||||
print '\t.size\t__glapi_sparc_get_pc, .-__glapi_sparc_get_pc'
|
||||
print ''
|
||||
print '#ifdef GLX_USE_TLS'
|
||||
print ''
|
||||
print '\tGLOBL_FN(__glapi_sparc_get_dispatch)'
|
||||
print '\tHIDDEN(__glapi_sparc_get_dispatch)'
|
||||
print '__glapi_sparc_get_dispatch:'
|
||||
print '\tmov\t%o7, %g1'
|
||||
print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
|
||||
print '\tcall\t__glapi_sparc_get_pc'
|
||||
print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
|
||||
print '\tmov\t%g1, %o7'
|
||||
print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1'
|
||||
print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1'
|
||||
print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)'
|
||||
print '\tretl'
|
||||
print '\t mov\t%g2, %o0'
|
||||
print ''
|
||||
print '\t.data'
|
||||
print '\t.align\t32'
|
||||
print ''
|
||||
print '\t/* --> sethi %hi(_glapi_tls_Dispatch), %g1 */'
|
||||
print '\t/* --> or %g1, %lo(_glapi_tls_Dispatch), %g1 */'
|
||||
print '\tGLOBL_FN(__glapi_sparc_tls_stub)'
|
||||
print '\tHIDDEN(__glapi_sparc_tls_stub)'
|
||||
print '__glapi_sparc_tls_stub: /* Call offset in %g3 */'
|
||||
print '\tmov\t%o7, %g1'
|
||||
print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
|
||||
print '\tcall\t__glapi_sparc_get_pc'
|
||||
print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
|
||||
print '\tmov\t%g1, %o7'
|
||||
print '\tsrl\t%g3, 10, %g3'
|
||||
print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1'
|
||||
print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1'
|
||||
print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)'
|
||||
print '\tGL_LL\t[%g7+%g2], %g1'
|
||||
print '\tGL_LL\t[%g1 + %g3], %g1'
|
||||
print '\tjmp\t%g1'
|
||||
print '\t nop'
|
||||
print '\t.size\t__glapi_sparc_tls_stub, .-__glapi_sparc_tls_stub'
|
||||
print ''
|
||||
print '#define GL_STUB(fn, off)\t\t\t\t\\'
|
||||
print '\tGLOBL_FN(fn);\t\t\t\t\t\\'
|
||||
print 'fn:\tba\t__glapi_sparc_tls_stub;\t\t\t\\'
|
||||
print '\t sethi\tGL_OFF(off), %g3;\t\t\t\\'
|
||||
print '\t.size\tfn,.-fn;'
|
||||
print ''
|
||||
print '#elif defined(PTHREADS)'
|
||||
print ''
|
||||
print '\t/* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */'
|
||||
print '\t/* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */'
|
||||
print '\t/* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */'
|
||||
print '\t/* 64-bit 0x0c --> sllx %g1, 32, %g1 */'
|
||||
print '\t/* 64-bit 0x10 --> add %g1, %g2, %g1 */'
|
||||
print '\t/* 64-bit 0x14 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */'
|
||||
print ''
|
||||
print '\t/* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */'
|
||||
print '\t/* 32-bit 0x04 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */'
|
||||
print ''
|
||||
print '\t.data'
|
||||
print '\t.align\t32'
|
||||
print ''
|
||||
print '\tGLOBL_FN(__glapi_sparc_pthread_stub)'
|
||||
print '\tHIDDEN(__glapi_sparc_pthread_stub)'
|
||||
print '__glapi_sparc_pthread_stub: /* Call offset in %g3 */'
|
||||
print '\tmov\t%o7, %g1'
|
||||
print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
|
||||
print '\tcall\t__glapi_sparc_get_pc'
|
||||
print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
|
||||
print '\tmov\t%g1, %o7'
|
||||
print '\tsethi\t%hi(_glapi_Dispatch), %g1'
|
||||
print '\tor\t%g1, %lo(_glapi_Dispatch), %g1'
|
||||
print '\tsrl\t%g3, 10, %g3'
|
||||
print '\tGL_LL\t[%g2+%g1], %g2'
|
||||
print '\tGL_LL\t[%g2], %g1'
|
||||
print '\tcmp\t%g1, 0'
|
||||
print '\tbe\t2f'
|
||||
print '\t nop'
|
||||
print '1:\tGL_LL\t[%g1 + %g3], %g1'
|
||||
print '\tjmp\t%g1'
|
||||
print '\t nop'
|
||||
print '2:\tsave\t%sp, GL_STACK_SIZE, %sp'
|
||||
print '\tmov\t%g3, %l0'
|
||||
print '\tcall\t_glapi_get_dispatch'
|
||||
print '\t nop'
|
||||
print '\tmov\t%o0, %g1'
|
||||
print '\tmov\t%l0, %g3'
|
||||
print '\tba\t1b'
|
||||
print '\t restore %g0, %g0, %g0'
|
||||
print '\t.size\t__glapi_sparc_pthread_stub, .-__glapi_sparc_pthread_stub'
|
||||
print ''
|
||||
print '#define GL_STUB(fn, off)\t\t\t\\'
|
||||
print '\tGLOBL_FN(fn);\t\t\t\t\\'
|
||||
print 'fn:\tba\t__glapi_sparc_pthread_stub;\t\\'
|
||||
print '\t sethi\tGL_OFF(off), %g3;\t\t\\'
|
||||
print '\t.size\tfn,.-fn;'
|
||||
print ''
|
||||
print '#else /* Non-threaded version. */'
|
||||
print ''
|
||||
print '\t.type __glapi_sparc_nothread_stub, @function'
|
||||
print '__glapi_sparc_nothread_stub: /* Call offset in %g3 */'
|
||||
print '\tmov\t%o7, %g1'
|
||||
print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2'
|
||||
print '\tcall\t__glapi_sparc_get_pc'
|
||||
print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2'
|
||||
print '\tmov\t%g1, %o7'
|
||||
print '\tsrl\t%g3, 10, %g3'
|
||||
print '\tsethi\t%hi(_glapi_Dispatch), %g1'
|
||||
print '\tor\t%g1, %lo(_glapi_Dispatch), %g1'
|
||||
print '\tGL_LL\t[%g2+%g1], %g2'
|
||||
print '\tGL_LL\t[%g2], %g1'
|
||||
print '\tGL_LL\t[%g1 + %g3], %g1'
|
||||
print '\tjmp\t%g1'
|
||||
print '\t nop'
|
||||
print '\t.size\t__glapi_sparc_nothread_stub, .-__glapi_sparc_nothread_stub'
|
||||
print ''
|
||||
print '#define GL_STUB(fn, off)\t\t\t\\'
|
||||
print '\tGLOBL_FN(fn);\t\t\t\t\\'
|
||||
print 'fn:\tba\t__glapi_sparc_nothread_stub;\t\\'
|
||||
print '\t sethi\tGL_OFF(off), %g3;\t\t\\'
|
||||
print '\t.size\tfn,.-fn;'
|
||||
print ''
|
||||
print '#endif'
|
||||
print ''
|
||||
print '#define GL_STUB_ALIAS(fn, alias) \\'
|
||||
print ' .globl fn; \\'
|
||||
print ' .set fn, alias'
|
||||
print ''
|
||||
print '\t.text'
|
||||
print '\t.align\t32'
|
||||
print ''
|
||||
print '\t.globl\tgl_dispatch_functions_start'
|
||||
print '\tHIDDEN(gl_dispatch_functions_start)'
|
||||
print 'gl_dispatch_functions_start:'
|
||||
print ''
|
||||
return
|
||||
|
||||
def printRealFooter(self):
|
||||
print ''
|
||||
print '\t.globl\tgl_dispatch_functions_end'
|
||||
print '\tHIDDEN(gl_dispatch_functions_end)'
|
||||
print 'gl_dispatch_functions_end:'
|
||||
return
|
||||
|
||||
def printBody(self, api):
|
||||
for f in api.functionIterateByOffset():
|
||||
if f.is_static_entry_point(f.name):
|
||||
name = f.name
|
||||
else:
|
||||
name = "_dispatch_stub_%u" % (f.offset)
|
||||
name = f.dispatch_name()
|
||||
|
||||
print '\t\t.globl gl%s ; .type gl%s,#function' % (name, name)
|
||||
print '\tGL_STUB(gl%s, _gloffset_%s)' % (name, f.name)
|
||||
|
||||
print '\t\t.globl _mesa_sparc_glapi_begin ; .type _mesa_sparc_glapi_begin,#function'
|
||||
print '_mesa_sparc_glapi_begin:'
|
||||
print ''
|
||||
if not f.is_static_entry_point(f.name):
|
||||
print '\tHIDDEN(gl%s)' % (name)
|
||||
|
||||
for f in api.functionIterateByOffset():
|
||||
name = f.dispatch_name()
|
||||
|
||||
if f.is_static_entry_point(f.name):
|
||||
name = f.name
|
||||
else:
|
||||
name = "_dispatch_stub_%u" % (f.offset)
|
||||
|
||||
print '\tGL_STUB(gl%s, _gloffset_%s)' % (name, name)
|
||||
|
||||
print ''
|
||||
print '\t\t.globl _mesa_sparc_glapi_end ; .type _mesa_sparc_glapi_end,#function'
|
||||
print '_mesa_sparc_glapi_end:'
|
||||
print ''
|
||||
|
||||
|
||||
for f in api.functionIterateByOffset():
|
||||
for n in f.entry_points:
|
||||
if n != f.name:
|
||||
if f.is_static_entry_point(n):
|
||||
text = '\t.globl gl%s ; .type gl%s,#function ; gl%s = gl%s' % (n, n, n, f.name)
|
||||
for n in f.entry_points:
|
||||
if n != f.name:
|
||||
text = '\tGL_STUB_ALIAS(gl%s, gl%s)' % (n, f.name)
|
||||
|
||||
if f.has_different_protocol(n):
|
||||
print '#ifndef GLX_INDIRECT_RENDERING'
|
||||
|
@@ -318,6 +318,14 @@ extern const GLubyte gl_dispatch_functions_start[];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPARC_ASM
|
||||
#ifdef GLX_USE_TLS
|
||||
extern unsigned int __glapi_sparc_tls_stub;
|
||||
#else
|
||||
extern unsigned int __glapi_sparc_pthread_stub;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer)
|
||||
# define NEED_FUNCTION_POINTER
|
||||
#endif
|
||||
@@ -344,6 +352,129 @@ init_glapi_relocs( void )
|
||||
curr_func += DISPATCH_FUNCTION_SIZE;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SPARC_ASM
|
||||
extern void __glapi_sparc_icache_flush(unsigned int *);
|
||||
static const unsigned int template[] = {
|
||||
#ifdef GLX_USE_TLS
|
||||
0x05000000, /* sethi %hi(_glapi_tls_Dispatch), %g2 */
|
||||
0x8730e00a, /* srl %g3, 10, %g3 */
|
||||
0x8410a000, /* or %g2, %lo(_glapi_tls_Dispatch), %g2 */
|
||||
#ifdef __arch64__
|
||||
0xc259c002, /* ldx [%g7 + %g2], %g1 */
|
||||
0xc2584003, /* ldx [%g1 + %g3], %g1 */
|
||||
#else
|
||||
0xc201c002, /* ld [%g7 + %g2], %g1 */
|
||||
0xc2004003, /* ld [%g1 + %g3], %g1 */
|
||||
#endif
|
||||
0x81c04000, /* jmp %g1 */
|
||||
0x01000000, /* nop */
|
||||
#else
|
||||
#ifdef __arch64__
|
||||
0x03000000, /* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */
|
||||
0x05000000, /* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */
|
||||
0x82106000, /* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */
|
||||
0x8730e00a, /* 64-bit 0x0c --> srl %g3, 10, %g3 */
|
||||
0x83287020, /* 64-bit 0x10 --> sllx %g1, 32, %g1 */
|
||||
0x82004002, /* 64-bit 0x14 --> add %g1, %g2, %g1 */
|
||||
0xc2586000, /* 64-bit 0x18 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */
|
||||
#else
|
||||
0x03000000, /* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */
|
||||
0x8730e00a, /* 32-bit 0x04 --> srl %g3, 10, %g3 */
|
||||
0xc2006000, /* 32-bit 0x08 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */
|
||||
#endif
|
||||
0x80a06000, /* --> cmp %g1, 0 */
|
||||
0x02800005, /* --> be +4*5 */
|
||||
0x01000000, /* --> nop */
|
||||
#ifdef __arch64__
|
||||
0xc2584003, /* 64-bit --> ldx [%g1 + %g3], %g1 */
|
||||
#else
|
||||
0xc2004003, /* 32-bit --> ld [%g1 + %g3], %g1 */
|
||||
#endif
|
||||
0x81c04000, /* --> jmp %g1 */
|
||||
0x01000000, /* --> nop */
|
||||
#ifdef __arch64__
|
||||
0x9de3bf80, /* 64-bit --> save %sp, -128, %sp */
|
||||
#else
|
||||
0x9de3bfc0, /* 32-bit --> save %sp, -64, %sp */
|
||||
#endif
|
||||
0xa0100003, /* --> mov %g3, %l0 */
|
||||
0x40000000, /* --> call _glapi_get_dispatch */
|
||||
0x01000000, /* --> nop */
|
||||
0x82100008, /* --> mov %o0, %g1 */
|
||||
0x86100010, /* --> mov %l0, %g3 */
|
||||
0x10bffff7, /* --> ba -4*9 */
|
||||
0x81e80000, /* --> restore */
|
||||
#endif
|
||||
};
|
||||
#ifdef GLX_USE_TLS
|
||||
extern unsigned long __glapi_sparc_get_dispatch(void);
|
||||
unsigned int *code = &__glapi_sparc_tls_stub;
|
||||
unsigned long dispatch = __glapi_sparc_get_dispatch();
|
||||
#else
|
||||
unsigned int *code = &__glapi_sparc_pthread_stub;
|
||||
unsigned long dispatch = (unsigned long) &_glapi_Dispatch;
|
||||
unsigned long call_dest = (unsigned long ) &_glapi_get_dispatch;
|
||||
int idx;
|
||||
#endif
|
||||
|
||||
#if defined(GLX_USE_TLS)
|
||||
code[0] = template[0] | (dispatch >> 10);
|
||||
code[1] = template[1];
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
code[2] = template[2] | (dispatch & 0x3ff);
|
||||
code[3] = template[3];
|
||||
__glapi_sparc_icache_flush(&code[2]);
|
||||
code[4] = template[4];
|
||||
code[5] = template[5];
|
||||
__glapi_sparc_icache_flush(&code[4]);
|
||||
code[6] = template[6];
|
||||
__glapi_sparc_icache_flush(&code[6]);
|
||||
#else
|
||||
#if defined(__arch64__)
|
||||
code[0] = template[0] | (dispatch >> (32 + 10));
|
||||
code[1] = template[1] | ((dispatch & 0xffffffff) >> 10);
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
code[2] = template[2] | ((dispatch >> 32) & 0x3ff);
|
||||
code[3] = template[3];
|
||||
__glapi_sparc_icache_flush(&code[2]);
|
||||
code[4] = template[4];
|
||||
code[5] = template[5];
|
||||
__glapi_sparc_icache_flush(&code[4]);
|
||||
code[6] = template[6] | (dispatch & 0x3ff);
|
||||
idx = 7;
|
||||
#else
|
||||
code[0] = template[0] | (dispatch >> 10);
|
||||
code[1] = template[1];
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
code[2] = template[2] | (dispatch & 0x3ff);
|
||||
idx = 3;
|
||||
#endif
|
||||
code[idx + 0] = template[idx + 0];
|
||||
__glapi_sparc_icache_flush(&code[idx - 1]);
|
||||
code[idx + 1] = template[idx + 1];
|
||||
code[idx + 2] = template[idx + 2];
|
||||
__glapi_sparc_icache_flush(&code[idx + 1]);
|
||||
code[idx + 3] = template[idx + 3];
|
||||
code[idx + 4] = template[idx + 4];
|
||||
__glapi_sparc_icache_flush(&code[idx + 3]);
|
||||
code[idx + 5] = template[idx + 5];
|
||||
code[idx + 6] = template[idx + 6];
|
||||
__glapi_sparc_icache_flush(&code[idx + 5]);
|
||||
code[idx + 7] = template[idx + 7];
|
||||
code[idx + 8] = template[idx + 8] |
|
||||
(((call_dest - ((unsigned long) &code[idx + 8]))
|
||||
>> 2) & 0x3fffffff);
|
||||
__glapi_sparc_icache_flush(&code[idx + 7]);
|
||||
code[idx + 9] = template[idx + 9];
|
||||
code[idx + 10] = template[idx + 10];
|
||||
__glapi_sparc_icache_flush(&code[idx + 9]);
|
||||
code[idx + 11] = template[idx + 11];
|
||||
code[idx + 12] = template[idx + 12];
|
||||
__glapi_sparc_icache_flush(&code[idx + 11]);
|
||||
code[idx + 13] = template[idx + 13];
|
||||
__glapi_sparc_icache_flush(&code[idx + 13]);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
|
||||
|
||||
|
@@ -259,53 +259,30 @@ generate_entrypoint(GLuint functionOffset)
|
||||
}
|
||||
|
||||
return (_glapi_proc) code;
|
||||
#elif defined(USE_SPARC_ASM)
|
||||
|
||||
#ifdef __arch64__
|
||||
static const unsigned int insn_template[] = {
|
||||
0x05000000, /* sethi %uhi(_glapi_Dispatch), %g2 */
|
||||
0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */
|
||||
0x8410a000, /* or %g2, %ulo(_glapi_Dispatch), %g2 */
|
||||
0x82106000, /* or %g1, %lo(_glapi_Dispatch), %g1 */
|
||||
0x8528b020, /* sllx %g2, 32, %g2 */
|
||||
0xc2584002, /* ldx [%g1 + %g2], %g1 */
|
||||
0x05000000, /* sethi %hi(8 * glapioffset), %g2 */
|
||||
0x8410a000, /* or %g2, %lo(8 * glapioffset), %g2 */
|
||||
0xc6584002, /* ldx [%g1 + %g2], %g3 */
|
||||
0x81c0c000, /* jmpl %g3, %g0 */
|
||||
0x01000000 /* nop */
|
||||
#elif defined(USE_SPARC_ASM) && (defined(PTHREADS) || defined(GLX_USE_TLS))
|
||||
static const unsigned int template[] = {
|
||||
0x07000000, /* sethi %hi(0), %g3 */
|
||||
0x8210000f, /* mov %o7, %g1 */
|
||||
0x40000000, /* call */
|
||||
0x9e100001, /* mov %g1, %o7 */
|
||||
};
|
||||
#ifdef GLX_USE_TLS
|
||||
extern unsigned int __glapi_sparc_tls_stub;
|
||||
unsigned long call_dest = (unsigned long ) &__glapi_sparc_tls_stub;
|
||||
#else
|
||||
static const unsigned int insn_template[] = {
|
||||
0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */
|
||||
0xc2006000, /* ld [%g1 + %lo(_glapi_Dispatch)], %g1 */
|
||||
0xc6006000, /* ld [%g1 + %lo(4*glapioffset)], %g3 */
|
||||
0x81c0c000, /* jmpl %g3, %g0 */
|
||||
0x01000000 /* nop */
|
||||
};
|
||||
#endif /* __arch64__ */
|
||||
unsigned int *code = (unsigned int *) malloc(sizeof(insn_template));
|
||||
unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch;
|
||||
extern unsigned int __glapi_sparc_pthread_stub;
|
||||
unsigned long call_dest = (unsigned long ) &__glapi_sparc_pthread_stub;
|
||||
#endif
|
||||
unsigned int *code = (unsigned int *) malloc(sizeof(template));
|
||||
if (code) {
|
||||
memcpy(code, insn_template, sizeof(insn_template));
|
||||
|
||||
#ifdef __arch64__
|
||||
code[0] |= (glapi_addr >> (32 + 10));
|
||||
code[1] |= ((glapi_addr & 0xffffffff) >> 10);
|
||||
code[0] = template[0] | (functionOffset & 0x3fffff);
|
||||
code[1] = template[1];
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1));
|
||||
code[3] |= (glapi_addr & ((1 << 10) - 1));
|
||||
code[2] = template[2] |
|
||||
(((call_dest - ((unsigned long) &code[2]))
|
||||
>> 2) & 0x3fffffff);
|
||||
code[3] = template[3];
|
||||
__glapi_sparc_icache_flush(&code[2]);
|
||||
code[6] |= ((functionOffset * 8) >> 10);
|
||||
code[7] |= ((functionOffset * 8) & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&code[6]);
|
||||
#else
|
||||
code[0] |= (glapi_addr >> 10);
|
||||
code[1] |= (glapi_addr & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
code[2] |= (functionOffset * 4);
|
||||
__glapi_sparc_icache_flush(&code[2]);
|
||||
#endif /* __arch64__ */
|
||||
}
|
||||
return (_glapi_proc) code;
|
||||
#else
|
||||
@@ -337,21 +314,10 @@ fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset)
|
||||
#endif
|
||||
|
||||
#elif defined(USE_SPARC_ASM)
|
||||
|
||||
/* XXX this hasn't been tested! */
|
||||
unsigned int *code = (unsigned int *) entrypoint;
|
||||
#ifdef __arch64__
|
||||
code[6] = 0x05000000; /* sethi %hi(8 * glapioffset), %g2 */
|
||||
code[7] = 0x8410a000; /* or %g2, %lo(8 * glapioffset), %g2 */
|
||||
code[6] |= ((offset * 8) >> 10);
|
||||
code[7] |= ((offset * 8) & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&code[6]);
|
||||
#else /* __arch64__ */
|
||||
code[2] = 0xc6006000; /* ld [%g1 + %lo(4*glapioffset)], %g3 */
|
||||
code[2] |= (offset * 4);
|
||||
__glapi_sparc_icache_flush(&code[2]);
|
||||
#endif /* __arch64__ */
|
||||
|
||||
code[0] &= ~0x3fffff;
|
||||
code[0] |= (offset * sizeof(void *)) & 0x3fffff;
|
||||
__glapi_sparc_icache_flush(&code[0]);
|
||||
#else
|
||||
|
||||
/* an unimplemented architecture */
|
||||
|
@@ -390,9 +390,6 @@ one_time_init( GLcontext *ctx )
|
||||
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
|
||||
}
|
||||
|
||||
#ifdef USE_SPARC_ASM
|
||||
_mesa_init_sparc_glapi_relocs();
|
||||
#endif
|
||||
if (_mesa_getenv("MESA_DEBUG")) {
|
||||
_glapi_noop_enable_warnings(GL_TRUE);
|
||||
_glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -109,10 +109,10 @@ void _mesa_init_all_sparc_transform_asm(void)
|
||||
ASSIGN_XFORM_GROUP(sparc, 2)
|
||||
ASSIGN_XFORM_GROUP(sparc, 3)
|
||||
ASSIGN_XFORM_GROUP(sparc, 4)
|
||||
|
||||
#if 0
|
||||
_mesa_clip_tab[4] = _mesa_sparc_cliptest_points4;
|
||||
_mesa_clip_np_tab[4] = _mesa_sparc_cliptest_points4_np;
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
/* disable these too. See bug 673938 */
|
||||
_mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] =
|
||||
@@ -140,38 +140,4 @@ void _mesa_init_all_sparc_transform_asm(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern unsigned int _mesa_sparc_glapi_begin;
|
||||
extern unsigned int _mesa_sparc_glapi_end;
|
||||
extern void __glapi_sparc_icache_flush(unsigned int *);
|
||||
|
||||
#endif /* USE_SPARC_ASM */
|
||||
|
||||
|
||||
void _mesa_init_sparc_glapi_relocs(void)
|
||||
{
|
||||
#ifdef USE_SPARC_ASM
|
||||
unsigned int *insn_ptr, *end_ptr;
|
||||
unsigned long disp_addr;
|
||||
|
||||
insn_ptr = &_mesa_sparc_glapi_begin;
|
||||
end_ptr = &_mesa_sparc_glapi_end;
|
||||
disp_addr = (unsigned long) &_glapi_Dispatch;
|
||||
|
||||
while (insn_ptr < end_ptr) {
|
||||
#ifdef __arch64__
|
||||
insn_ptr[0] |= (disp_addr >> (32 + 10));
|
||||
insn_ptr[1] |= ((disp_addr & 0xffffffff) >> 10);
|
||||
__glapi_sparc_icache_flush(&insn_ptr[0]);
|
||||
insn_ptr[2] |= ((disp_addr >> 32) & ((1 << 10) - 1));
|
||||
insn_ptr[3] |= (disp_addr & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&insn_ptr[2]);
|
||||
insn_ptr += 11;
|
||||
#else
|
||||
insn_ptr[0] |= (disp_addr >> 10);
|
||||
insn_ptr[1] |= (disp_addr & ((1 << 10) - 1));
|
||||
__glapi_sparc_icache_flush(&insn_ptr[0]);
|
||||
insn_ptr += 5;
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_SPARC_ASM */
|
||||
}
|
||||
|
@@ -32,6 +32,5 @@
|
||||
#define SPARC_H
|
||||
|
||||
extern void _mesa_init_all_sparc_transform_asm(void);
|
||||
extern void _mesa_init_sparc_glapi_relocs(void);
|
||||
|
||||
#endif /* !(SPARC_H) */
|
||||
|
Reference in New Issue
Block a user