forked from amazingfate/loongoffice
sal: require sun4u or newer hardware / SPARCv8plus / SPARCv9 CPU
Drop implementation of osl_incrementInterlockedCount / osl_decrementInterlockedCount for antique 32-bit SPARC without cas instruction (sun4, sun4c, sun4d, sun4m). Apparently only NetBSD and OpenBSD even support such ancient hardware at all, the Debian SPARC port already requires sun4u hardware. Change-Id: Ic254622ae80ad65c9f545013b68d82665474402c
This commit is contained in:
@ -18,22 +18,10 @@
|
||||
|
||||
|
||||
/*
|
||||
* Implements osl_[increment|decrement]InterlockedCount in two ways:
|
||||
* sparcv8 architecture: use the "swap" instruction
|
||||
* Implements osl_[increment|decrement]InterlockedCount:
|
||||
* sparcv9/sparcv8plus architecture: use the "cas" instruction
|
||||
*
|
||||
* 32 bit mode with v8 and v8plus support:
|
||||
* Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to
|
||||
* use the "cas" instruction, which is faster (no spinlock needed)
|
||||
* Default is to use the "swap" instruction, which works on all supported
|
||||
* SPARC cpu's
|
||||
*
|
||||
* osl_InterlockedCountSetV9(int bv9)
|
||||
* bv9 = 0 use sparcv8 "swap" (spinlock)
|
||||
* bv9 = 1 use sparcv9/sparcv8plus "cas" (no spinlock)
|
||||
*
|
||||
* 32 bit mode without v8 support (implies v8plus) or 64 bit mode:
|
||||
* No need (nor the possibilty) to call osl_InterlockedCountSetV9(),
|
||||
* 32 bit mode with v8plus support or 64 bit mode:
|
||||
* sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or
|
||||
* -xarch=v9 (64 bit).
|
||||
*
|
||||
@ -41,181 +29,18 @@
|
||||
|
||||
#if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
|
||||
|
||||
.section ".data"
|
||||
.align 4
|
||||
osl_incrementInterLockCountFuncPtr:
|
||||
.word osl_incrementInterlockedCountV8
|
||||
.type osl_incrementInterLockCountFuncPtr,#object
|
||||
.size osl_incrementInterLockCountFuncPtr,4
|
||||
#error LibreOffice requires SPARCv8plus or SPARCv9 CPU with "cas" instruction
|
||||
|
||||
.align 4
|
||||
osl_decrementInterLockCountFuncPtr:
|
||||
.word osl_decrementInterlockedCountV8
|
||||
.type osl_decrementInterLockCountFuncPtr,#object
|
||||
.size osl_decrementInterLockCountFuncPtr,4
|
||||
#endif
|
||||
|
||||
.section ".text"
|
||||
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
/* add the address of the calling "call" instruction (stored in %o7) to
|
||||
* %o5 which contains _GLOBAL_OFFSET_TABLE_
|
||||
*/
|
||||
.Laddoseven:
|
||||
retl
|
||||
add %o7, %o5, %o5
|
||||
#endif
|
||||
|
||||
.global osl_incrementInterlockedCount
|
||||
.align 4
|
||||
|
||||
osl_incrementInterlockedCount:
|
||||
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
mov %o7, %g1
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
|
||||
call .Laddoseven
|
||||
add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
|
||||
mov %g1, %o7
|
||||
#endif
|
||||
set osl_incrementInterLockCountFuncPtr, %o1
|
||||
#if defined(NETBSD)
|
||||
ld [%o1 + %o5], %o1
|
||||
#endif
|
||||
ld [%o1], %o1
|
||||
jmp %o1
|
||||
nop ! delay slot
|
||||
.type osl_incrementInterlockedCount,#function
|
||||
.size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
|
||||
|
||||
.section ".text"
|
||||
.global osl_decrementInterlockedCount
|
||||
.align 4
|
||||
|
||||
osl_decrementInterlockedCount:
|
||||
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
mov %o7, %g1
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
|
||||
call .Laddoseven
|
||||
add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
|
||||
mov %g1, %o7
|
||||
#endif
|
||||
set osl_decrementInterLockCountFuncPtr, %o1
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
ld [%o1 + %o5], %o1
|
||||
#endif
|
||||
ld [%o1], %o1
|
||||
jmp %o1
|
||||
nop ! delay slot
|
||||
.type osl_decrementInterlockedCount,#function
|
||||
.size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
|
||||
|
||||
.section ".text"
|
||||
.global osl_InterlockedCountSetV9
|
||||
.align 4
|
||||
|
||||
osl_InterlockedCountSetV9:
|
||||
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
mov %o7, %g1
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
|
||||
call .Laddoseven
|
||||
add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
|
||||
mov %g1, %o7
|
||||
#endif
|
||||
set osl_incrementInterLockCountFuncPtr, %o1
|
||||
set osl_decrementInterLockCountFuncPtr, %o2
|
||||
cmp %o0, %g0
|
||||
bnz 1f
|
||||
nop ! delay slot
|
||||
set osl_incrementInterlockedCountV8, %o0
|
||||
set osl_decrementInterlockedCountV8, %o3
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
ld [%o0 + %o5], %o0
|
||||
ld [%o1 + %o5], %o1
|
||||
ld [%o2 + %o5], %o2
|
||||
ld [%o3 + %o5], %o3
|
||||
#endif
|
||||
st %o3,[%o2]
|
||||
retl
|
||||
st %o0,[%o1]
|
||||
1: set osl_incrementInterlockedCountV9, %o0
|
||||
set osl_decrementInterlockedCountV9, %o3
|
||||
#if defined(NETBSD) || defined(LINUX)
|
||||
ld [%o0 + %o5], %o0
|
||||
ld [%o1 + %o5], %o1
|
||||
ld [%o2 + %o5], %o2
|
||||
ld [%o3 + %o5], %o3
|
||||
#endif
|
||||
st %o3,[%o2]
|
||||
retl
|
||||
st %o0,[%o1]
|
||||
|
||||
.type osl_InterlockedCountSetV9,#function
|
||||
.size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
|
||||
|
||||
|
||||
.section ".text"
|
||||
.local osl_incrementInterlockedCountV8
|
||||
.align 4
|
||||
|
||||
! Implements osl_[increment|decrement]InterlockedCount with sparcv8 "swap" instruction.
|
||||
! Uses -4096 as lock value for spinlock to allow for small negative counts.
|
||||
|
||||
osl_incrementInterlockedCountV8:
|
||||
|
||||
1: ld [%o0], %o1
|
||||
cmp %o1, -4096 ! test spinlock
|
||||
be 1b
|
||||
mov -4096, %o1 ! delay slot
|
||||
swap [%o0], %o1
|
||||
cmp %o1, -4096
|
||||
be 1b
|
||||
inc %o1 ! delay slot, if we got spinlock, increment count
|
||||
st %o1, [%o0]
|
||||
retl
|
||||
mov %o1, %o0 ! delay slot
|
||||
|
||||
.type osl_incrementInterlockedCountV8,#function
|
||||
.size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
|
||||
|
||||
|
||||
.section ".text"
|
||||
.local osl_decrementInterlockedCountV8
|
||||
.align 4
|
||||
|
||||
osl_decrementInterlockedCountV8:
|
||||
|
||||
1: ld [%o0], %o1
|
||||
cmp %o1, -4096 ! test spinlock
|
||||
be 1b
|
||||
mov -4096, %o1 ! delay slot
|
||||
swap [%o0], %o1
|
||||
cmp %o1, -4096
|
||||
be 1b
|
||||
dec %o1 ! delay slot, if we got spinlock, decrement count
|
||||
st %o1, [%o0] ! delay slot
|
||||
retl
|
||||
mov %o1, %o0 ! delay slot
|
||||
|
||||
.type osl_decrementInterlockedCountV8,#function
|
||||
.size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
|
||||
|
||||
#endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
|
||||
|
||||
.section ".text"
|
||||
#if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
|
||||
#define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
|
||||
.global osl_incrementInterlockedCountV9
|
||||
#else
|
||||
.local osl_incrementInterlockedCountV9
|
||||
#endif
|
||||
.global osl_incrementInterlockedCount
|
||||
.align 8
|
||||
|
||||
! Implements osl_[increment|decrement]InterlockedCount with sparcv9(sparcv8plus) "cas"
|
||||
! instruction.
|
||||
|
||||
osl_incrementInterlockedCountV9:
|
||||
osl_incrementInterlockedCount:
|
||||
|
||||
1: ld [%o0], %o1
|
||||
add %o1, 1, %o2
|
||||
@ -228,20 +53,15 @@ osl_incrementInterlockedCountV9:
|
||||
retl
|
||||
add %o2, 1, %o0 ! delay slot
|
||||
|
||||
.type osl_incrementInterlockedCountV9,#function
|
||||
.size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
|
||||
.type osl_incrementInterlockedCount,#function
|
||||
.size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
|
||||
|
||||
|
||||
.section ".text"
|
||||
#if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
|
||||
#define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
|
||||
.global osl_decrementInterlockedCountV9
|
||||
#else
|
||||
.local osl_decrementInterlockedCountV9
|
||||
#endif
|
||||
.global osl_decrementInterlockedCount
|
||||
.align 8
|
||||
|
||||
osl_decrementInterlockedCountV9:
|
||||
osl_decrementInterlockedCount:
|
||||
|
||||
1: ld [%o0], %o1
|
||||
sub %o1, 1, %o2
|
||||
@ -254,5 +74,6 @@ osl_decrementInterlockedCountV9:
|
||||
retl
|
||||
sub %o2, 1, %o0 ! delay slot
|
||||
|
||||
.type osl_decrementInterlockedCountV9,#function
|
||||
.size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9
|
||||
.type osl_decrementInterlockedCount,#function
|
||||
.size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
|
||||
|
||||
|
||||
@ -288,99 +288,6 @@ char *fcvt(double value, int ndigit, int *decpt, int *sign)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (SPARC)
|
||||
|
||||
#if defined (SOLARIS) && !defined(__sparcv8plus) && !defined(__sparcv9)
|
||||
#include <sys/types.h>
|
||||
#include <sys/processor.h>
|
||||
|
||||
void osl_InterlockedCountSetV9(sal_Bool bV9);
|
||||
|
||||
/*
|
||||
* osl_InitSparcV9() should be executed as early as possible. We place it in the
|
||||
* .init section of sal
|
||||
*/
|
||||
#if defined ( __SUNPRO_C ) || defined ( __SUNPRO_CC )
|
||||
void osl_InitSparcV9(void);
|
||||
#pragma init (osl_InitSparcV9)
|
||||
#elif defined ( __GNUC__ )
|
||||
void osl_InitSparcV9(void) __attribute__((constructor));
|
||||
#endif
|
||||
|
||||
void osl_InitSparcV9(void)
|
||||
{
|
||||
/* processor_info() identifies SPARCV8 (ie sun4c machines) simply as "sparc"
|
||||
* and SPARCV9 (ie ultra sparcs, sun4u) as "sparcv9". Since we know that we
|
||||
* run at least on a SPARCV8 architecture or better, any processor type != "sparc"
|
||||
* and != "i386" is considered to be SPARCV9 or better
|
||||
*
|
||||
* This way we are certain that this will still work if someone names SPARCV10
|
||||
* "foobar"
|
||||
*/
|
||||
processor_info_t aInfo;
|
||||
int rc;
|
||||
|
||||
rc = processor_info(0, &aInfo);
|
||||
|
||||
if ( rc != -1 ) {
|
||||
if ( !strcmp( "sparc", aInfo.pi_processor_type ) /* SPARCV8 */
|
||||
|| !strcmp( "i386", aInfo.pi_processor_type ) ) /* can't happen, but ... */
|
||||
return;
|
||||
/* we are reasonably certain to be on sparcv9/sparcv8plus or better */
|
||||
osl_InterlockedCountSetV9(sal_True);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SOLARIS */
|
||||
|
||||
#if defined(NETBSD) && defined(__GNUC__) && !defined(__sparcv9) && !defined(__sparc_v9__)
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
void osl_InitSparcV9(void) __attribute__((constructor));
|
||||
void osl_InterlockedCountSetV9(sal_Bool bV9);
|
||||
|
||||
/* Determine which processor we are running on (sparc v8 or v9)
|
||||
* The approach is very similar to Solaris.
|
||||
*/
|
||||
|
||||
void osl_InitSparcV9(void)
|
||||
{
|
||||
int mib[2]={CTL_HW,HW_MACHINE};
|
||||
char processorname[256];
|
||||
size_t len=256;
|
||||
|
||||
/* get the machine name */
|
||||
sysctl(mib, 2, processorname, &len, NULL, 0);
|
||||
if (!strncmp("sparc64",processorname, len)) {
|
||||
osl_InterlockedCountSetV9(sal_True);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NETBSD */
|
||||
|
||||
#endif /* SPARC */
|
||||
|
||||
#if defined ( LINUX ) && defined ( SPARC )
|
||||
#include <sys/utsname.h>
|
||||
void osl_InitSparcV9(void) __attribute__((constructor));
|
||||
void osl_InterlockedCountSetV9(sal_Bool bV9);
|
||||
/* Determine which processor we are running on (sparc v8 or v9)
|
||||
* The approach is very similar to Solaris.
|
||||
*/
|
||||
void osl_InitSparcV9(void)
|
||||
{
|
||||
struct utsname name;
|
||||
int rc;
|
||||
rc = uname(&name);
|
||||
if ( rc != -1 ) {
|
||||
if ( !strcmp( "sparc", name.machine ))
|
||||
return;
|
||||
osl_InterlockedCountSetV9(sal_True);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( defined(__GNUC__) && (defined(X86) || defined(X86_64)) )\
|
||||
|| ( defined(SOLARIS) && defined(__i386) )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user