- align sse control word storage space to 16 byte boundary for snapvector

- replace some whitespace with tabs in snapvector.c
- Give gcc a bit more freedom in choice of registers
This commit is contained in:
Thilo Schulz 2011-06-22 14:36:11 +00:00
parent d9ea902c31
commit 664f8e578d
5 changed files with 52 additions and 39 deletions

View file

@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
long qftolsse(float f) long qftolsse(float f)
{ {
register long retval; long retval;
__asm__ volatile __asm__ volatile
( (
@ -40,21 +40,25 @@ long qftolsse(float f)
return retval; return retval;
} }
void qvmftolsse(void) int qvmftolsse(void)
{ {
int retval;
__asm__ volatile __asm__ volatile
( (
"movss (" EDI ", " EBX ", 4), %%xmm0\n" "movss (" EDI ", " EBX ", 4), %%xmm0\n"
"cvttss2si %%xmm0, " EAX "\n" "cvttss2si %%xmm0, %0\n"
: : "=r" (retval)
: :
: "%xmm0" : "%xmm0"
); );
return retval;
} }
long qftolx87(float f) long qftolx87(float f)
{ {
register long retval; long retval;
__asm__ volatile __asm__ volatile
( (
@ -68,13 +72,17 @@ long qftolx87(float f)
return retval; return retval;
} }
void qvmftolx87(void) int qvmftolx87(void)
{ {
int retval;
__asm__ volatile __asm__ volatile
( (
"flds (" EDI ", " EBX ", 4)\n" "flds (" EDI ", " EBX ", 4)\n"
"fistpl (" EDI ", " EBX ", 4)\n" "fistpl (" EDI ", " EBX ", 4)\n"
"mov (" EDI ", " EBX ", 4), " EAX "\n" "mov (" EDI ", " EBX ", 4), %0\n"
: : "=r" (retval)
); );
return retval;
} }

View file

@ -44,7 +44,7 @@ IFDEF idx64
; qsnapvector using SSE ; qsnapvector using SSE
qsnapvectorsse PROC qsnapvectorsse PROC
sub rsp, 4 sub rsp, 8
stmxcsr [rsp] ; save SSE control word stmxcsr [rsp] ; save SSE control word
ldmxcsr ssecw ; set to round nearest ldmxcsr ssecw ; set to round nearest
@ -58,19 +58,19 @@ IFDEF idx64
pop rdi pop rdi
ldmxcsr [rsp] ; restore sse control word to old value ldmxcsr [rsp] ; restore sse control word to old value
add rsp, 4 add rsp, 8
ret ret
qsnapvectorsse ENDP qsnapvectorsse ENDP
ELSE ELSE
qsnapvectorsse PROC qsnapvectorsse PROC
sub esp, 4 sub esp, 8
stmxcsr [esp] ; save SSE control word stmxcsr [esp] ; save SSE control word
ldmxcsr ssecw ; set to round nearest ldmxcsr ssecw ; set to round nearest
push edi push edi
mov edi, dword ptr 12[esp] ; maskmovdqu uses edi as implicit memory operand mov edi, dword ptr 16[esp] ; maskmovdqu uses edi as implicit memory operand
movaps xmm1, ssemask ; initialize the mask register for maskmovdqu movaps xmm1, ssemask ; initialize the mask register for maskmovdqu
movups xmm0, [edi] ; here is stored our vector. Read 4 values in one go movups xmm0, [edi] ; here is stored our vector. Read 4 values in one go
cvtps2dq xmm0, xmm0 ; convert 4 single fp to int cvtps2dq xmm0, xmm0 ; convert 4 single fp to int
@ -79,7 +79,7 @@ ELSE
pop edi pop edi
ldmxcsr [esp] ; restore sse control word to old value ldmxcsr [esp] ; restore sse control word to old value
add esp, 4 add esp, 8
ret ret
qsnapvectorsse ENDP qsnapvectorsse ENDP

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/* /*
* GNU inline asm version of qsnapvector * GNU inline asm version of qsnapvector
* See MASM snapvector.asm for commentary
*/ */
static unsigned char ssemask[16] __attribute__((aligned(16))) = static unsigned char ssemask[16] __attribute__((aligned(16))) =
@ -32,29 +33,33 @@ static unsigned char ssemask[16] __attribute__((aligned(16))) =
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
}; };
static unsigned int ssecw __attribute__((aligned(16))) = 0x00001F80; static const unsigned int ssecw __attribute__((aligned(16))) = 0x00001F80;
static unsigned short fpucw = 0x037F; static const unsigned short fpucw = 0x037F;
void qsnapvectorsse(vec3_t vec) void qsnapvectorsse(vec3_t vec)
{ {
uint32_t oldcw __attribute__((aligned(16)));
__asm__ volatile __asm__ volatile
( (
"sub $4, " ESP "\n" "stmxcsr %3\n"
"stmxcsr (" ESP ")\n"
"ldmxcsr %1\n" "ldmxcsr %1\n"
"movaps (%0), %%xmm1\n" "movaps (%0), %%xmm1\n"
"movups (" EDI "), %%xmm0\n" "movups (%2), %%xmm0\n"
"cvtps2dq %%xmm0, %%xmm0\n" "cvtps2dq %%xmm0, %%xmm0\n"
"cvtdq2ps %%xmm0, %%xmm0\n" "cvtdq2ps %%xmm0, %%xmm0\n"
// vec MUST reside in register rdi as maskmovdqu uses
// it as an implicit operand. The "D" constraint makes
// sure of that.
"maskmovdqu %%xmm1, %%xmm0\n" "maskmovdqu %%xmm1, %%xmm0\n"
"ldmxcsr (" ESP ")\n" "ldmxcsr %3\n"
"add $4, " ESP "\n"
: :
: "r" (ssemask), "m" (ssecw), "D" (vec) : "r" (ssemask), "m" (ssecw), "D" (vec), "m" (oldcw)
: "memory", "%xmm0", "%xmm1" : "memory", "%xmm0", "%xmm1"
); );
} }
#define QROUNDX87(src) \ #define QROUNDX87(src) \

View file

@ -91,10 +91,10 @@ cvar_t *com_homepath;
cvar_t *com_busyWait; cvar_t *com_busyWait;
#if idx64 #if idx64
void (*Q_VMftol)(void); int (*Q_VMftol)(void);
#elif id386 #elif id386
long (QDECL *Q_ftol)(float f); long (QDECL *Q_ftol)(float f);
void (QDECL *Q_VMftol)(void); int (QDECL *Q_VMftol)(void);
void (QDECL *Q_SnapVector)(vec3_t vec); void (QDECL *Q_SnapVector)(vec3_t vec);
#endif #endif

View file

@ -423,23 +423,23 @@ int Q_isnan(float x);
#if idx64 #if idx64
extern long qftolsse(float f); extern long qftolsse(float f);
extern void qvmftolsse(void); extern int qvmftolsse(void);
extern void qsnapvectorsse(vec3_t vec); extern void qsnapvectorsse(vec3_t vec);
#define Q_ftol qftolsse #define Q_ftol qftolsse
#define Q_SnapVector qsnapvectorsse #define Q_SnapVector qsnapvectorsse
extern void (*Q_VMftol)(void); extern int (*Q_VMftol)(void);
#elif id386 #elif id386
extern long QDECL qftolx87(float f); extern long QDECL qftolx87(float f);
extern long QDECL qftolsse(float f); extern long QDECL qftolsse(float f);
extern void QDECL qvmftolx87(void); extern int QDECL qvmftolx87(void);
extern void QDECL qvmftolsse(void); extern int QDECL qvmftolsse(void);
extern void QDECL qsnapvectorx87(vec3_t vec); extern void QDECL qsnapvectorx87(vec3_t vec);
extern void QDECL qsnapvectorsse(vec3_t vec); extern void QDECL qsnapvectorsse(vec3_t vec);
extern long (QDECL *Q_ftol)(float f); extern long (QDECL *Q_ftol)(float f);
extern void (QDECL *Q_VMftol)(void); extern int (QDECL *Q_VMftol)(void);
extern void (QDECL *Q_SnapVector)(vec3_t vec); extern void (QDECL *Q_SnapVector)(vec3_t vec);
#else #else
#define Q_ftol(f) lrintf((f)) #define Q_ftol(f) lrintf((f))