Commit 857ac1e8 authored by David S. Miller's avatar David S. Miller Committed by Brian Paul

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: 's avatarDavid S. Miller <davem@davemloft.net>
parent b12dc74f
......@@ -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 '\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 '.data'
print '.align 64'
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():
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)
name = f.dispatch_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)
if f.is_static_entry_point(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 );
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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) */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment