glide2x, grDrawTriangle() dispatch code for cvg and h3:

It fails to build for linux with the current compiler flags:

- static builds:
gdraw.c: In function `grDrawTriangle':
gdraw.c:757: error: bp cannot be used in asm here

- shared lib (-fPIC) builds:
gdraw.c: In function `grDrawTriangle':
gdraw.c:731: error: PIC register `ebx' clobbered in `asm'

Only if I use '-DBIG_OPT -fomit-frame-pointer', _then_ it builds into:

00000a20 <grDrawTriangle>:
     a20:	a1 2c 00 00 00       	mov    0x2c,%eax
     a25:	ff a0 50 03 00 00    	jmp    *0x350(%eax)
     a2b:	c3                   	ret
     a2c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi

... which is good but only for static builds.  The PIC build still
fails with the above message with my gcc3.4 or gcc4.x.

So, I moved the x86 dispatch code to a new xdrawtri.asm, for linux,
and even for MSVC without any prologue/epilogue like the following:
  movl (_GlideRoot + curGC),%eax
  jmp  *kTriProcOffset(%eax)

Let's see how this goes.
This commit is contained in:
sezero
2018-08-19 10:41:20 +03:00
parent d13007941b
commit eb96ad7944
8 changed files with 176 additions and 110 deletions

View File

@@ -103,6 +103,8 @@ override USE_FIFO = 1
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1 CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1
override USE_FIFO = 1 override USE_FIFO = 1
CDEFS += -DHAVE_XDRAWTRI_ASM=1
override USE_DRAWTRI_ASM = 1
else else
CDEFS += -DGLIDE_USE_C_TRISETUP=1 CDEFS += -DGLIDE_USE_C_TRISETUP=1
endif endif
@@ -187,6 +189,9 @@ GLIDE_OBJECTS = \
fpu.obj \ fpu.obj \
xtexdl_def.obj xtexdl_def.obj
ifeq ($(USE_DRAWTRI_ASM),1)
GLIDE_OBJECTS += xdrawtri.obj
endif
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
GLIDE_OBJECTS += \ GLIDE_OBJECTS += \
xdraw2_def.obj xdraw2_def.obj
@@ -268,6 +273,8 @@ xdraw2_3dnow.obj: xdraw2.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xtexdl_3dnow.obj: xtexdl.asm xtexdl_3dnow.obj: xtexdl.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xdrawtri.obj: xdrawtri.asm
$(AS) -o $@ $(ASFLAGS) $<
$(GLIDE_OBJECTS): fxinline.h fxgasm.h $(GLIDE_OBJECTS): fxinline.h fxgasm.h

View File

@@ -649,7 +649,8 @@ all_done: /* come here on degenerate lines */
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
** grDrawTriangle ** grDrawTriangle
*/ */
#if (GLIDE_PLATFORM & GLIDE_OS_WIN32) && !GLIDE_USE_C_TRISETUP && !defined(GLIDE_DEBUG) #ifndef HAVE_XDRAWTRI_ASM /* grDrawTriangle() not in asm */
#if defined(_MSC_VER) && !GLIDE_USE_C_TRISETUP && !defined(GLIDE_DEBUG)
__declspec(naked) __declspec(naked)
#endif #endif
GR_ENTRY(grDrawTriangle, void, (const GrVertex *a, const GrVertex *b, const GrVertex *c)) GR_ENTRY(grDrawTriangle, void, (const GrVertex *a, const GrVertex *b, const GrVertex *c))
@@ -693,8 +694,8 @@ GR_ENTRY(grDrawTriangle, void, (const GrVertex *a, const GrVertex *b, const GrVe
all_done: all_done:
GR_END(); GR_END();
#else
#if defined(__MSC__) #elif defined(_MSC_VER)
{ {
__asm { __asm {
mov edx, [_GlideRoot + kCurGCOffset]; mov edx, [_GlideRoot + kCurGCOffset];
@@ -702,59 +703,13 @@ all_done:
jmp eax; jmp eax;
} }
} }
#endif
#if defined( __linux__ )
/* Here's the basic strategy for this dispatch code: #else
* We jump to _GlideRoot.curGC->archDispatchProcs.triSetupProc #error "Write triangle proc dispatch for this compiler"
* which contains code that looks like a function, we leave the
* paramters passed to grDrawTriangle on the stack and the dispatched
* function picks them up. However we have to compensate for
* the compiler pushing anything on the stack. The following describes
* why and when we have to pop.
*
* BIG_OPT: gcc pushes a frame pointer to maintain things, BIG_OPT
* turns on -fomit-frame-pointer so we don't have to pop it.
*
* PIC: When using position independant code gcc stores eip in ebx
* so it saves ebx from the previous call automatically.
* Therefore, once we have the jump address we have to pop ebx
* to restore the stack.
*
* The syntax is further complicated by the fact that gcc can (and will)
* emit code between the asm statements, so they all need to be in a single
* asm statement, wrapped with #ifdef's. This means we have fun with
* deciding if we need to list trashed registers and when we need commas
* between them.
*/
asm (
#if defined(PIC)
"popl %%ebx\n\t"
#endif
#if !defined(BIG_OPT)
"popl %%ebp\n\t"
#endif
"jmp *%0"
: /* no outputs */
: "m" (_GlideRoot.curGC->curArchProcs.triSetupProc)
#if defined (PIC) || !defined (BIG_OPT)
:
#endif
#if defined (PIC)
"ebx"
#endif
#if defined (PIC) && !defined (BIG_OPT)
,
#endif
#if !defined(BIG_OPT)
"ebp"
#endif
);
#endif
#endif #endif
#undef FN_NAME #undef FN_NAME
} /* grDrawTriangle */ } /* grDrawTriangle */
#endif /* HAVE_XDRAWTRI_ASM */
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
** grDrawPlanarPolygon ** grDrawPlanarPolygon

View File

@@ -105,6 +105,8 @@ override USE_FIFO = 1
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1 CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1
override USE_FIFO = 1 override USE_FIFO = 1
CDEFS += -DHAVE_XDRAWTRI_ASM=1
override USE_DRAWTRI_ASM = 1
else else
CDEFS += -DGLIDE_USE_C_TRISETUP=1 CDEFS += -DGLIDE_USE_C_TRISETUP=1
endif endif
@@ -187,6 +189,9 @@ GLIDE_OBJECTS = \
fpu.o \ fpu.o \
xtexdl_def.o xtexdl_def.o
ifeq ($(USE_DRAWTRI_ASM),1)
GLIDE_OBJECTS += xdrawtri.o
endif
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
GLIDE_OBJECTS += \ GLIDE_OBJECTS += \
xdraw2_def.o xdraw2_def.o
@@ -277,6 +282,8 @@ xdraw2_3dnow.o: xdraw2.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xtexdl_3dnow.o: xtexdl.asm xtexdl_3dnow.o: xtexdl.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xdrawtri.o: xdrawtri.asm
$(AS) -o $@ $(ASFLAGS) $<
#cpuid.lo: cpuid.o #cpuid.lo: cpuid.o
# $(CP) $< $@ # $(CP) $< $@
@@ -290,6 +297,8 @@ xdraw2_3dnow.lo: xdraw2_3dnow.o
$(CP) $< $@ $(CP) $< $@
xtexdl_3dnow.lo: xtexdl_3dnow.o xtexdl_3dnow.lo: xtexdl_3dnow.o
$(CP) $< $@ $(CP) $< $@
xdrawtri.lo: xdrawtri.o
$(CP) $< $@
$(GLIDE_OBJECTS): fxinline.h fxgasm.h $(GLIDE_OBJECTS): fxinline.h fxgasm.h

View File

@@ -0,0 +1,46 @@
;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
;; FULL TEXT OF THE NON-WARRANTY PROVISIONS.
;;
;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
;; THE UNITED STATES.
;;
;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
;; Adapted from gdraw.c:grDrawTriangle() for nasm
%include "xos.inc"
%include "fxgasm.h"
extrn _GlideRoot
segment SEG_TEXT
align 16
proc grDrawTriangle, 12
;;mov edx, dword [_GlideRoot+curGC]
;;mov eax, dword [edx+kTriProcOffset]
mov eax, dword [_GlideRoot+curGC]
jmp [eax + kTriProcOffset]
endp
align 16
%if XOS == XOS_WIN32
%ifdef __MINGW32__
; GNU LD fails with '_' prefix
export grDrawTriangle@12
%else
export _grDrawTriangle@12
%endif
%endif ; _WIN32

View File

@@ -653,7 +653,10 @@ all_done: /* come here on degenerate lines */
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
** grDrawTriangle ** grDrawTriangle
*/ */
#ifndef HAVE_XDRAWTRI_ASM /* grDrawTriangle() not in asm */
#if defined(_MSC_VER) && !GLIDE_USE_C_TRISETUP && !defined(GLIDE_DEBUG)
__declspec(naked)
#endif
#ifdef GLIDE3 #ifdef GLIDE3
GR_ENTRY(grDrawTriangle, void, (void *a, void *b, void *c)) GR_ENTRY(grDrawTriangle, void, (void *a, void *b, void *c))
#else #else
@@ -716,70 +719,23 @@ GR_ENTRY(grDrawTriangle, void, (const GrVertex *a, const GrVertex *b, const GrVe
all_done: all_done:
GR_END(); GR_END();
#else
#if defined(__MSC__) #elif defined(_MSC_VER)
{ {
extern struct _GlideRoot_s _GlideRoot; extern struct _GlideRoot_s _GlideRoot;
__asm {
_asm { mov edx, [_GlideRoot + kCurGCOffset];
mov eax, [_GlideRoot + kCurGCOffset]; mov eax, [edx + kTriProcOffset];
mov eax, [eax + kTriProcOffset];
jmp eax; jmp eax;
} }
} }
#endif
#if defined( __linux__ )
/* Here's the basic strategy for this dispatch code: #else
* We jump to _GlideRoot.curGC->archDispatchProcs.triSetupProc #error "Write triangle proc dispatch for this compiler"
* which contains code that looks like a function, we leave the
* paramters passed to grDrawTriangle on the stack and the dispatched
* function picks them up. However we have to compensate for
* the compiler pushing anything on the stack. The following describes
* why and when we have to pop.
*
* BIG_OPT: gcc pushes a frame pointer to maintain things, BIG_OPT
* turns on -fomit-frame-pointer so we don't have to pop it.
*
* PIC: When using position independant code gcc stores eip in ebx
* so it saves ebx from the previous call automatically.
* Therefore, once we have the jump address we have to pop ebx
* to restore the stack.
*
* The syntax is further complicated by the fact that gcc can (and will)
* emit code between the asm statements, so they all need to be in a single
* asm statement, wrapped with #ifdef's. This means we have fun with
* deciding if we need to list trashed registers and when we need commas
* between them.
*/
asm (
#if defined(PIC)
"popl %%ebx\n\t"
#endif
#if !defined(BIG_OPT)
"popl %%ebp\n\t"
#endif
"jmp *%0"
: /* no outputs */
:"m" (_GlideRoot.curGC->archDispatchProcs.triSetupProc)
#if defined (PIC) || !defined (BIG_OPT)
:
#endif
#if defined (PIC)
"ebx"
#endif
#if defined (PIC) && !defined (BIG_OPT)
,
#endif
#if !defined(BIG_OPT)
"ebp"
#endif
);
#endif
#endif #endif
#undef FN_NAME #undef FN_NAME
} /* grDrawTriangle */ } /* grDrawTriangle */
#endif /* HAVE_XDRAWTRI_ASM */
#ifndef GLIDE3_ALPHA #ifndef GLIDE3_ALPHA
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------

View File

@@ -102,6 +102,8 @@ override USE_FIFO = 1
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1 CDEFS += -DGLIDE_DISPATCH_SETUP=1 -DGLIDE_DISPATCH_DOWNLOAD=1
override USE_FIFO = 1 override USE_FIFO = 1
CDEFS += -DHAVE_XDRAWTRI_ASM=1
override USE_DRAWTRI_ASM = 1
else else
CDEFS += -DGLIDE_USE_C_TRISETUP=1 CDEFS += -DGLIDE_USE_C_TRISETUP=1
endif endif
@@ -180,6 +182,9 @@ GLIDE_OBJECTS = \
cpuid.o \ cpuid.o \
xtexdl_def.o xtexdl_def.o
ifeq ($(USE_DRAWTRI_ASM),1)
GLIDE_OBJECTS += xdrawtri.o
endif
ifeq ($(USE_X86),1) ifeq ($(USE_X86),1)
GLIDE_OBJECTS += \ GLIDE_OBJECTS += \
xdraw2_def.o xdraw2_def.o
@@ -241,8 +246,6 @@ $(GLIDE_LIBDIR)/$(GLIDE_SHARED): $(GLIDE_OBJECTS:.o=.lo)
# rules(2) # rules(2)
############################################################################### ###############################################################################
#using nasm now
#
#cpuid.o: cpudtect.S #cpuid.o: cpudtect.S
# $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) $< # $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) $<
#xdraw2_def.o: xdraw2.S #xdraw2_def.o: xdraw2.S
@@ -251,6 +254,8 @@ $(GLIDE_LIBDIR)/$(GLIDE_SHARED): $(GLIDE_OBJECTS:.o=.lo)
# $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) -DGL_AMD3D=1 $< # $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) -DGL_AMD3D=1 $<
#xtexdl_3dnow.o: xtexdl.S #xtexdl_3dnow.o: xtexdl.S
# $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) -DGL_AMD3D=1 $< # $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) -DGL_AMD3D=1 $<
#xdrawtri.o: xdrawtri.S
# $(CC) -o $@ -xassembler-with-cpp -c $(CDEFS) $<
cpuid.o: cpudtect.asm cpuid.o: cpudtect.asm
$(AS) -o $@ $(ASFLAGS) $< $(AS) -o $@ $(ASFLAGS) $<
xdraw2_def.o: xdraw2.asm xdraw2_def.o: xdraw2.asm
@@ -259,6 +264,8 @@ xdraw2_3dnow.o: xdraw2.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xtexdl_3dnow.o: xtexdl.asm xtexdl_3dnow.o: xtexdl.asm
$(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $< $(AS) -o $@ $(ASFLAGS) -DGL_AMD3D=1 $<
xdrawtri.o: xdrawtri.asm
$(AS) -o $@ $(ASFLAGS) $<
cpuid.lo: cpuid.o cpuid.lo: cpuid.o
$(CP) $< $@ $(CP) $< $@
@@ -268,6 +275,8 @@ xdraw2_3dnow.lo: xdraw2_3dnow.o
$(CP) $< $@ $(CP) $< $@
xtexdl_3dnow.lo: xtexdl_3dnow.o xtexdl_3dnow.lo: xtexdl_3dnow.o
$(CP) $< $@ $(CP) $< $@
xdrawtri.lo: xdrawtri.o
$(CP) $< $@
$(GLIDE_OBJECTS): fxinline.h fxgasm.h $(GLIDE_OBJECTS): fxinline.h fxgasm.h

View File

@@ -0,0 +1,38 @@
/*
* THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
* PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
* TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
* INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
* DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
* THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
* FULL TEXT OF THE NON-WARRANTY PROVISIONS.
*
* USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
* RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
* TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
* AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
* SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
* THE UNITED STATES.
*
* COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
/* Adapted from gdraw.c:grDrawTriangle() for gas */
#include "fxgasm.h"
.extern _GlideRoot
.text
.p2align 4,,15
.globl grDrawTriangle
.type grDrawTriangle,@function
grDrawTriangle:
/*movl (_GlideRoot+curGC),%edx
movl kTriProcOffset(%edx),%eax*/
movl (_GlideRoot + curGC),%eax
jmp *kTriProcOffset(%eax)
.p2align 4,,15

View File

@@ -0,0 +1,46 @@
;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
;; FULL TEXT OF THE NON-WARRANTY PROVISIONS.
;;
;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
;; THE UNITED STATES.
;;
;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
;; Adapted from gdraw.c:grDrawTriangle() for nasm
%include "xos.inc"
%include "fxgasm.h"
extrn _GlideRoot
segment SEG_TEXT
align 16
proc grDrawTriangle, 12
;;mov edx, dword [_GlideRoot+curGC]
;;mov eax, dword [edx+kTriProcOffset]
mov eax, dword [_GlideRoot+curGC]
jmp [eax + kTriProcOffset]
endp
align 16
%if XOS == XOS_WIN32
%ifdef __MINGW32__
; GNU LD fails with '_' prefix
export grDrawTriangle@12
%else
export _grDrawTriangle@12
%endif
%endif ; _WIN32