Allow drivers to perform the perspective divide themselves. Assembly to do cliptesting without perspective divide for size-4 vectors.tags/mesa_3_5
@@ -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; | |||
} |
@@ -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) |
@@ -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); | |||
} |
@@ -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]; |
@@ -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 |
@@ -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 ); | |||
} | |||
} |
@@ -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; |
@@ -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 ); | |||
} | |||
} | |||
@@ -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); | |||
} | |||
} | |||
} | |||
} |
@@ -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; |
@@ -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 |
@@ -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" ); |
@@ -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 | |||