From 321f67c4729adeebd7aa9ef9e22c95e709952851 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 13 Jan 2001 05:48:25 +0000 Subject: [PATCH] Fix crash in book/stencil. Allow drivers to perform the perspective divide themselves. Assembly to do cliptesting without perspective divide for size-4 vectors. --- src/mesa/main/light.c | 18 +++-- src/mesa/main/lines.c | 8 ++- src/mesa/math/m_clip_tmp.h | 60 +++++++++++++++- src/mesa/math/m_xform.c | 3 +- src/mesa/math/m_xform.h | 3 +- src/mesa/tnl/t_context.c | 14 +++- src/mesa/tnl/t_context.h | 6 +- src/mesa/tnl/t_imm_exec.c | 21 +++--- src/mesa/tnl/t_vb_cliptmp.h | 45 ++++++------ src/mesa/tnl/t_vb_vertex.c | 56 ++++++++------- src/mesa/tnl/tnl.h | 12 +--- src/mesa/x86/x86.c | 10 ++- src/mesa/x86/x86_cliptest.S | 162 +++++++++++++++++++++++++++++++++++++++++++- 13 files changed, 335 insertions(+), 83 deletions(-) diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 1eed79b..bee9f0d 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,4 +1,4 @@ -/* $Id: light.c,v 1.33 2001/01/04 16:22:18 brianp Exp $ */ +/* $Id: light.c,v 1.34 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -1050,14 +1050,12 @@ static void validate_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess ) struct gl_shine_tab *list = ctx->_ShineTabList; struct gl_shine_tab *s; -/* fprintf(stderr, "validate_shine_table %d, shininess %f\n", i, shininess); */ - foreach(s, list) if ( s->shininess == shininess ) break; if (s == list) { - GLint i; + GLint j; GLfloat *m; foreach(s, list) @@ -1067,19 +1065,19 @@ static void validate_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess ) m = s->tab; m[0] = 0.0; if (shininess == 0.0) { - for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) - m[i] = 1.0; + for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) + m[j] = 1.0; } else { - for (i = 1 ; i < SHINE_TABLE_SIZE ; i++) { - GLdouble t, x = i / (GLfloat) (SHINE_TABLE_SIZE - 1); + for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { + GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); if (x < 0.005) /* underflow check */ x = 0.005; t = pow(x, shininess); if (t > 1e-20) - m[i] = t; + m[j] = t; else - m[i] = 0.0; + m[j] = 0.0; } m[SHINE_TABLE_SIZE] = 1.0; } diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index 730e3f5..8a9256c 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -1,4 +1,4 @@ -/* $Id: lines.c,v 1.25 2001/01/08 04:09:41 keithw Exp $ */ +/* $Id: lines.c,v 1.26 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -79,12 +79,14 @@ _mesa_LineStipple( GLint factor, GLushort pattern ) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Line.StippleFactor == CLAMP( factor, 1, 256 ) && + factor = CLAMP( factor, 1, 256 ); + + if (ctx->Line.StippleFactor == factor && ctx->Line.StipplePattern == pattern) return; FLUSH_VERTICES(ctx, _NEW_LINE); - ctx->Line.StippleFactor = CLAMP( factor, 1, 256 ); + ctx->Line.StippleFactor = factor; ctx->Line.StipplePattern = pattern; if (ctx->Driver.LineStipple) diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h index d977698..8757154 100644 --- a/src/mesa/math/m_clip_tmp.h +++ b/src/mesa/math/m_clip_tmp.h @@ -1,4 +1,4 @@ -/* $Id: m_clip_tmp.h,v 1.2 2000/12/26 05:09:31 keithw Exp $ */ +/* $Id: m_clip_tmp.h,v 1.3 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -100,6 +100,59 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, return proj_vec; } + + +static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLfloat *from = (GLfloat *)clip_vec->start; + const GLuint count = clip_vec->count; + GLuint c = 0; + GLubyte tmpAndMask = *andMask; + GLubyte tmpOrMask = *orMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0]; + const GLfloat cy = from[1]; + const GLfloat cz = from[2]; + const GLfloat cw = from[3]; +#if defined(macintosh) + /* on powerpc cliptest is 17% faster in this way. */ + GLuint mask; + mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); + mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); + mask |= (((cw < cy) << CLIP_TOP_SHIFT)); + mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); + mask |= (((cw < cz) << CLIP_FAR_SHIFT)); + mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); +#else /* !defined(macintosh)) */ + GLubyte mask = 0; + if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; + if (-cy + cw < 0) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; + if (-cz + cw < 0) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; +#endif /* defined(macintosh) */ + + clipMask[i] = mask; + if (mask) { + c++; + tmpAndMask &= mask; + tmpOrMask |= mask; + } + } + + *orMask = tmpOrMask; + *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); + return clip_vec; +} + + static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, GLvector4f *proj_vec, GLubyte clipMask[], @@ -132,6 +185,7 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, return clip_vec; } + static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, GLvector4f *proj_vec, GLubyte clipMask[], @@ -168,4 +222,8 @@ static void TAG(init_c_cliptest)( void ) gl_clip_tab[4] = TAG(cliptest_points4); gl_clip_tab[3] = TAG(cliptest_points3); gl_clip_tab[2] = TAG(cliptest_points2); + + gl_clip_np_tab[4] = TAG(cliptest_np_points4); + gl_clip_np_tab[3] = TAG(cliptest_points3); + gl_clip_np_tab[2] = TAG(cliptest_points2); } diff --git a/src/mesa/math/m_xform.c b/src/mesa/math/m_xform.c index 77acce9..a510377 100644 --- a/src/mesa/math/m_xform.c +++ b/src/mesa/math/m_xform.c @@ -1,4 +1,4 @@ -/* $Id: m_xform.c,v 1.6 2001/01/08 04:09:41 keithw Exp $ */ +/* $Id: m_xform.c,v 1.7 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -57,6 +57,7 @@ #endif clip_func gl_clip_tab[5]; +clip_func gl_clip_np_tab[5]; dotprod_func gl_dotprod_tab[2][5]; vec_copy_func gl_copy_tab[2][0x10]; normal_func gl_normal_tab[0xf][0x4]; diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h index 4024949..f6b10d6 100644 --- a/src/mesa/math/m_xform.h +++ b/src/mesa/math/m_xform.h @@ -1,4 +1,4 @@ -/* $Id: m_xform.h,v 1.4 2001/01/05 05:31:42 keithw Exp $ */ +/* $Id: m_xform.h,v 1.5 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -201,6 +201,7 @@ extern dotprod_func gl_dotprod_tab[2][5]; extern vec_copy_func gl_copy_tab[2][0x10]; extern vec_copy_func gl_copy_clean_tab[2][5]; extern clip_func gl_clip_tab[5]; +extern clip_func gl_clip_np_tab[5]; extern normal_func gl_normal_tab[0xf][0x4]; /* Use of 3 layers of linked 1-dimensional arrays to reduce diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 93886b7..e0d254e 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -1,4 +1,4 @@ -/* $Id: t_context.c,v 1.9 2001/01/08 21:56:00 keithw Exp $ */ +/* $Id: t_context.c,v 1.10 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -104,6 +104,8 @@ _tnl_CreateContext( GLcontext *ctx ) _tnl_eval_init( ctx ); _tnl_install_pipeline( ctx, _tnl_default_pipeline ); + + tnl->NeedProjCoords = GL_TRUE; /* Hook our functions into exec and compile dispatch tables. */ @@ -195,3 +197,13 @@ _tnl_wakeup_save_exec( GLcontext *ctx ) ctx->Save->Begin = _tnl_save_Begin; } + +void +_tnl_need_projected_coords( GLcontext *ctx, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + if (tnl->NeedProjCoords != mode) { + tnl->NeedProjCoords = mode; + _tnl_InvalidateState( ctx, _NEW_PROJECTION ); + } +} diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index 8e3952a..d49c854 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -1,4 +1,4 @@ -/* $Id: t_context.h,v 1.9 2001/01/05 02:26:49 keithw Exp $ */ +/* $Id: t_context.h,v 1.10 2001/01/13 05:48:26 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -412,6 +412,10 @@ typedef struct { GLuint DlistPrimitiveLength; GLuint DlistLastPrimitive; + /* Probably need a better configuration mechanism: + */ + GLboolean NeedProjCoords; + /* Derived state and storage for _tnl_eval_vb: */ struct tnl_eval_store eval; diff --git a/src/mesa/tnl/t_imm_exec.c b/src/mesa/tnl/t_imm_exec.c index e8904df..6feff84 100644 --- a/src/mesa/tnl/t_imm_exec.c +++ b/src/mesa/tnl/t_imm_exec.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_exec.c,v 1.6 2001/01/08 21:56:00 keithw Exp $ */ +/* $Id: t_imm_exec.c,v 1.7 2001/01/13 05:48:26 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -357,16 +357,21 @@ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM ) */ void _tnl_run_empty_cassette( GLcontext *ctx, struct immediate *IM ) { - GLuint start = IM->CopyStart; - copy_to_current( ctx, IM, IM->OrFlag ); - if (IM->OrFlag & VERT_MATERIAL) - gl_update_material( ctx, IM->Material[start], IM->MaterialMask[start] ); + if (IM->OrFlag & (VERT_RGBA|VERT_MATERIAL)) { + GLuint start = IM->CopyStart; - if (IM->OrFlag & VERT_RGBA) - if (ctx->Light.ColorMaterialEnabled) - gl_update_color_material( ctx, ctx->Current.Color ); + if (IM->OrFlag & VERT_MATERIAL) + gl_update_material( ctx, IM->Material[start], + IM->MaterialMask[start] ); + + if (IM->OrFlag & VERT_RGBA) + if (ctx->Light.ColorMaterialEnabled) + gl_update_color_material( ctx, ctx->Current.Color ); + + gl_validate_all_lighting_tables( ctx ); + } } diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index 5957f49..56f2031 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -1,4 +1,4 @@ -/* $Id: t_vb_cliptmp.h,v 1.5 2001/01/05 02:26:49 keithw Exp $ */ +/* $Id: t_vb_cliptmp.h,v 1.6 2001/01/13 05:48:26 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -115,29 +115,32 @@ do { \ } while (0) -/* Project if necessary. - */ static void TAG(build_proj_verts)( GLcontext *ctx ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; - GLuint last = VB->LastClipped; - GLuint i; - - for (i = VB->FirstClipped; i < last; i++) { - if (VB->ClipMask[i] == 0) { - if (SIZE == 4 && W(i) != 0.0F) { - GLfloat wInv = 1.0F / W(i); - proj[i][0] = X(i) * wInv; - proj[i][1] = Y(i) * wInv; - proj[i][2] = Z(i) * wInv; - proj[i][3] = wInv; - } else { - proj[i][0] = X(i); - proj[i][1] = Y(i); - proj[i][2] = Z(i); - proj[i][3] = W(i); + + /* Project if necessary. + */ + if (VB->ProjectedClipPtr) { + GLfloat (*coord)[4] = VB->ClipPtr->data; + GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; + GLuint last = VB->LastClipped; + GLuint i; + + for (i = VB->FirstClipped; i < last; i++) { + if (VB->ClipMask[i] == 0) { + if (SIZE == 4 && W(i) != 0.0F) { + GLfloat wInv = 1.0F / W(i); + proj[i][0] = X(i) * wInv; + proj[i][1] = Y(i) * wInv; + proj[i][2] = Z(i) * wInv; + proj[i][3] = wInv; + } else { + proj[i][0] = X(i); + proj[i][1] = Y(i); + proj[i][2] = Z(i); + proj[i][3] = W(i); + } } } } diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c index 7667d42..0c163ee 100644 --- a/src/mesa/tnl/t_vb_vertex.c +++ b/src/mesa/tnl/t_vb_vertex.c @@ -1,4 +1,4 @@ -/* $Id: t_vb_vertex.c,v 1.1 2000/12/26 05:09:33 keithw Exp $ */ +/* $Id: t_vb_vertex.c,v 1.2 2001/01/13 05:48:26 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -134,7 +134,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx, struct gl_pipeline_stage *stage ) { struct vertex_stage_data *store = (struct vertex_stage_data *)stage->private; - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; if (stage->changed_inputs) { @@ -172,12 +173,36 @@ static GLboolean run_vertex_stage( GLcontext *ctx, store->ormask = 0; store->andmask = CLIP_ALL_BITS; - VB->ProjectedClipPtr = - gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, - &store->proj, - store->clipmask, - &store->ormask, - &store->andmask ); + if (tnl->NeedProjCoords) { + VB->ProjectedClipPtr = + gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &store->proj, + store->clipmask, + &store->ormask, + &store->andmask ); + + /* Drivers expect this to be size 4... + */ + if (VB->ProjectedClipPtr->size < 4) { + ASSERT(VB->ProjectedClipPtr == VB->ClipPtr); + if (VB->ProjectedClipPtr->flags & VEC_NOT_WRITEABLE) { + ASSERT(VB->ProjectedClipPtr == VB->ObjPtr); + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + VB->ProjectedClipPtr = VB->ClipPtr = VB->ObjPtr; + } + if (VB->ClipPtr->size == 2) + gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + VB->ClipPtr->size = 4; + } + } else { + VB->ProjectedClipPtr = 0; + gl_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr, + 0, + store->clipmask, + &store->ormask, + &store->andmask ); + } if (store->andmask) return GL_FALSE; @@ -203,21 +228,6 @@ static GLboolean run_vertex_stage( GLcontext *ctx, if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ)) VB->importable_data |= VERT_CLIP; - /* Drivers expect this to be size 4... - */ - if (VB->ProjectedClipPtr->size < 4) { - ASSERT(VB->ProjectedClipPtr == VB->ClipPtr); - if (VB->ProjectedClipPtr->flags & VEC_NOT_WRITEABLE) { - ASSERT(VB->ProjectedClipPtr == VB->ObjPtr); - VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); - VB->ProjectedClipPtr = VB->ClipPtr = VB->ObjPtr; - } - if (VB->ClipPtr->size == 2) - gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); - gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); - VB->ClipPtr->size = 4; - } - store->save_eyeptr = VB->EyePtr; store->save_clipptr = VB->ClipPtr; store->save_projptr = VB->ProjectedClipPtr; diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index f95ce0e..eb8e905 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -59,17 +59,7 @@ _tnl_wakeup_exec( GLcontext *ctx ); extern void _tnl_wakeup_save_exec( GLcontext *ctx ); - -/* Functions to assist driver t&l modules which have to fallback to - * this module in the middle of a begin/end pair. Use this instead of - * glBegin() to identify the primitive as wrapped: - * - * Even with this it's difficult to see how the drivers are going to - * replay any glMaterial commands received in the few vertices before - * the fallback. - */ extern void -_tnl_fallback_begin( GLcontext *ctx, GLenum mode ); - +_tnl_need_projected_coords( GLcontext *ctx, GLboolean flag ); #endif diff --git a/src/mesa/x86/x86.c b/src/mesa/x86/x86.c index fd8a224..b49965f 100644 --- a/src/mesa/x86/x86.c +++ b/src/mesa/x86/x86.c @@ -1,4 +1,4 @@ -/* $Id: x86.c,v 1.14 2000/12/27 19:57:37 keithw Exp $ */ +/* $Id: x86.c,v 1.15 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -93,6 +93,13 @@ extern GLvector4f * _ASMAPI gl_x86_cliptest_points4( GLvector4f *clip_vec, GLubyte *andMask ); +extern GLvector4f * _ASMAPI gl_x86_cliptest_points4_np( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ); + + extern void _ASMAPI gl_v16_x86_cliptest_points4( GLfloat *first_vert, GLfloat *last_vert, GLubyte *or_mask, @@ -121,6 +128,7 @@ void gl_init_x86_transform_asm( void ) /* XXX this function has been found to cause FP overflow exceptions */ gl_clip_tab[4] = gl_x86_cliptest_points4; + gl_clip_np_tab[4] = gl_x86_cliptest_points4_np; #ifdef DEBUG gl_test_all_transform_functions( "x86" ); diff --git a/src/mesa/x86/x86_cliptest.S b/src/mesa/x86/x86_cliptest.S index 0258a9b..8679bcb 100644 --- a/src/mesa/x86/x86_cliptest.S +++ b/src/mesa/x86/x86_cliptest.S @@ -1,4 +1,4 @@ -/* $Id: x86_cliptest.S,v 1.3 2000/12/26 05:09:31 keithw Exp $ */ +/* $Id: x86_cliptest.S,v 1.4 2001/01/13 05:48:25 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -246,3 +246,163 @@ LLBL( ctp4_finish ): POP_L( ESI ) RET + + + + + + + +ALIGNTEXT16 +GLOBL GLNAME( gl_x86_cliptest_points4_np ) +GLNAME( gl_x86_cliptest_points4_np ): + +#ifdef ELFPIC +#define FRAME_OFFSET 20 +#else +#define FRAME_OFFSET 16 +#endif + PUSH_L( ESI ) + PUSH_L( EDI ) + PUSH_L( EBP ) + PUSH_L( EBX ) + +#ifdef ELFPIC + /* store pointer to clip_table on stack */ + CALL( LLBL( ctp4_np_get_eip ) ) + ADD_L( CONST(_GLOBAL_OFFSET_TABLE_), EBX ) + MOV_L( REGOFF(clip_table@GOT, EBX), EBX ) + PUSH_L( EBX ) + JMP( LLBL( ctp4_np_clip_table_ready ) ) + +LLBL( ctp4_np_get_eip ): + /* store eip in ebx */ + MOV_L( REGIND(ESP), EBX ) + RET + +LLBL( ctp4_np_clip_table_ready ): +#endif + + MOV_L( ARG_SOURCE, ESI ) + /* slot */ + + MOV_L( ARG_CLIP, EDX ) + MOV_L( ARG_OR, EBX ) + + MOV_L( ARG_AND, EBP ) + MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) + + MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) + MOV_L( REGOFF(V4F_START, ESI), ESI ) + + MOV_L( EAX, ARG_DEST ) /* put stride in ARG_DEST */ + ADD_L( EDX, ECX ) + + MOV_L( ECX, EDI ) /* put clipmask + count in EDI */ + CMP_L( ECX, EDX ) + + MOV_B( REGIND(EBX), AL ) + MOV_B( REGIND(EBP), AH ) + + JZ( LLBL( ctp4_np_finish ) ) + +ALIGNTEXT16 +LLBL( ctp4_np_top ): + + MOV_L( SRC(3), EBP ) + MOV_L( SRC(2), EBX ) + + XOR_L( ECX, ECX ) + ADD_L( EBP, EBP ) /* ebp = abs(S(3))*2 ; carry = sign of S(3) */ + + ADC_L( ECX, ECX ) + ADD_L( EBX, EBX ) /* ebx = abs(S(2))*2 ; carry = sign of S(2) */ + + ADC_L( ECX, ECX ) + CMP_L( EBX, EBP ) /* carry = abs(S(2))*2 > abs(S(3))*2 */ + + ADC_L( ECX, ECX ) + MOV_L( SRC(1), EBX ) + + ADD_L( EBX, EBX ) /* ebx = abs(S(1))*2 ; carry = sign of S(1) */ + + ADC_L( ECX, ECX ) + CMP_L( EBX, EBP ) /* carry = abs(S(1))*2 > abs(S(3))*2 */ + + ADC_L( ECX, ECX ) + MOV_L( SRC(0), EBX ) + + ADD_L( EBX, EBX ) /* ebx = abs(S(0))*2 ; carry = sign of S(0) */ + + ADC_L( ECX, ECX ) + CMP_L( EBX, EBP ) /* carry = abs(S(0))*2 > abs(S(3))*2 */ + + ADC_L( ECX, ECX ) + +#ifdef ELFPIC + MOV_L( REGIND(ESP), EBP ) /* clip_table */ + + MOV_B( REGBI(EBP, ECX), CL ) +#else + MOV_B( REGOFF(clip_table,ECX), CL ) +#endif + + OR_B( CL, AL ) + AND_B( CL, AH ) + + TEST_B( CL, CL ) + MOV_B( CL, REGIND(EDX) ) + + INC_L( EDX ) + /* slot */ + + ADD_L( ARG_DEST, ESI ) + CMP_L( EDX, EDI ) + + JNZ( LLBL( ctp4_np_top ) ) + + MOV_L( ARG_OR, ECX ) + MOV_L( ARG_AND, EDX ) + + MOV_B( AL, REGIND(ECX) ) + MOV_B( AH, REGIND(EDX) ) + +LLBL( ctp4_np_finish ): + + MOV_L( ARG_SOURCE, EAX ) +#ifdef ELFPIC + POP_L( ESI ) /* discard ptr to clip_table */ +#endif + POP_L( EBX ) + POP_L( EBP ) + POP_L( EDI ) + POP_L( ESI ) + + RET + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- 2.7.4