Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 554 → Rev 553

/programs/develop/open watcom/trunk/clib/char/isprint.c
File deleted
/programs/develop/open watcom/trunk/clib/char/istable.h
File deleted
/programs/develop/open watcom/trunk/clib/char/tolower.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isdigit.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isgraph.c
File deleted
/programs/develop/open watcom/trunk/clib/char/toupper.c
File deleted
/programs/develop/open watcom/trunk/clib/char/iscsym.c
File deleted
/programs/develop/open watcom/trunk/clib/char/iswctype.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isalnum.c
File deleted
/programs/develop/open watcom/trunk/clib/char/intwctrn.h
File deleted
/programs/develop/open watcom/trunk/clib/char/chartest.c
File deleted
/programs/develop/open watcom/trunk/clib/char/iscsymf.c
File deleted
/programs/develop/open watcom/trunk/clib/char/iscntrl.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isalpha.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isblank.c
File deleted
/programs/develop/open watcom/trunk/clib/char/towctrns.c
File deleted
/programs/develop/open watcom/trunk/clib/char/istable.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isxdigit.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isascii.c
File deleted
/programs/develop/open watcom/trunk/clib/char/islower.c
File deleted
/programs/develop/open watcom/trunk/clib/char/ispunct.c
File deleted
/programs/develop/open watcom/trunk/clib/char/intwctyp.h
File deleted
/programs/develop/open watcom/trunk/clib/char/isupper.c
File deleted
/programs/develop/open watcom/trunk/clib/char/isspace.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/strtoll.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/strtol.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/fsms386.asm
File deleted
/programs/develop/open watcom/trunk/clib/convert/msfs386.asm
File deleted
/programs/develop/open watcom/trunk/clib/convert/fdmd386.asm
File deleted
/programs/develop/open watcom/trunk/clib/convert/mdfd386.asm
File deleted
/programs/develop/open watcom/trunk/clib/convert/atoll.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/lltoa.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/itoa.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/atoi.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/ltoa.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/atol.c
File deleted
/programs/develop/open watcom/trunk/clib/convert/alphabet.c
File deleted
/programs/develop/open watcom/trunk/clib/math/min.c
File deleted
/programs/develop/open watcom/trunk/clib/math/imaxabs.c
File deleted
/programs/develop/open watcom/trunk/clib/math/rand.c
File deleted
/programs/develop/open watcom/trunk/clib/math/max.c
File deleted
/programs/develop/open watcom/trunk/clib/math/abs.c
File deleted
/programs/develop/open watcom/trunk/clib/math/randnext.h
File deleted
/programs/develop/open watcom/trunk/clib/math/hugeval.c
File deleted
/programs/develop/open watcom/trunk/clib/math/llabs.c
File deleted
/programs/develop/open watcom/trunk/clib/math/hvalptr.c
File deleted
/programs/develop/open watcom/trunk/clib/math/imaxdiv.c
File deleted
/programs/develop/open watcom/trunk/clib/math/labs.c
File deleted
/programs/develop/open watcom/trunk/clib/fpu/chipd32.asm
File deleted
/programs/develop/open watcom/trunk/clib/fpu/chipt32.asm
File deleted
/programs/develop/open watcom/trunk/clib/fpu/ini87386.asm
File deleted
/programs/develop/open watcom/trunk/clib/fpu/cntrl87.c
File deleted
/programs/develop/open watcom/trunk/clib/fpu/fclex387.c
File deleted
/programs/develop/open watcom/trunk/clib/fpu/clearfpe.h
File deleted
/programs/develop/open watcom/trunk/clib/fpu/chipa32.asm
File deleted
/programs/develop/open watcom/trunk/clib/fpu/chipr32.asm
File deleted
/programs/develop/open watcom/trunk/clib/fpu/cntrlfp.c
File deleted
/programs/develop/open watcom/trunk/clib/intel/grabfp87.c
File deleted
/programs/develop/open watcom/trunk/clib/intel/chipbug.c
File deleted
/programs/develop/open watcom/trunk/clib/intel/save8087.c
File deleted
/programs/develop/open watcom/trunk/clib/intel/i64ts386.asm
File deleted
/programs/develop/open watcom/trunk/clib/intel/segread.c
File deleted
/programs/develop/open watcom/trunk/clib/intel/chipvar.asm
File deleted
/programs/develop/open watcom/trunk/clib/src/87state.h
File deleted
/programs/develop/open watcom/trunk/clib/src/abs.c
0,0 → 1,44
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of abs().
*
****************************************************************************/
 
 
#undef __INLINE_FUNCTIONS__
#include "variety.h"
#include <stdlib.h>
 
 
 
_WCRTLINK int abs( int i )
/************************/
{
if( i < 0 )
i = - i;
return( i );
}
/programs/develop/open watcom/trunk/clib/src/alphabet.c
0,0 → 1,33
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Shared alphabet array for conversion of integers to ASCII.
*
****************************************************************************/
 
 
const char __based(__segname("_CONST")) __Alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 
/programs/develop/open watcom/trunk/clib/src/atoi.c
0,0 → 1,59
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include <stdio.h>
#ifdef __WIDECHAR__
#include <wctype.h>
#else
#include <ctype.h>
#endif
 
_WCRTLINK int __F_NAME(atoi,_wtoi)( const CHAR_TYPE *p ) /* convert ASCII string to integer */
{
register int value;
CHAR_TYPE sign;
 
__ptr_check( p, 0 );
 
while( __F_NAME(isspace,iswspace)( *p ) ) ++p;
sign = *p;
if( sign == '+' || sign == '-' ) ++p;
value = 0;
while( __F_NAME(isdigit,iswdigit)(*p) ) {
value = value * 10 + *p - '0';
++p;
}
if( sign == '-' ) value = - value;
return( value );
}
/programs/develop/open watcom/trunk/clib/src/chipa32.asm
0,0 → 1,397
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
 
 
; static char sccs_id[] = "@(#)fpatan32.asm 1.7 12/21/94 08:33:45";
;
; This code is being published by Intel to users of the Pentium(tm)
; processor. Recipients are authorized to copy, modify, compile, use and
; distribute the code.
;
; Intel makes no warranty of any kind with regard to this code, including
; but not limited to, implied warranties or merchantability and fitness for
; a particular purpose. Intel assumes no responsibility for any errors that
; may appear in this code.
;
; No patent licenses are granted, express or implied.
;
;
include mdef.inc
 
.386
.387
 
 
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
_TEXT ENDS
 
CONST SEGMENT DWORD PUBLIC USE32 'DATA'
CONST ENDS
 
CONST2 SEGMENT DWORD PUBLIC USE32 'DATA'
CONST2 ENDS
 
DATA32 SEGMENT DWORD PUBLIC USE32 'DATA'
 
 
Y EQU 0
X EQU 12
PREV_CW EQU 24
PATCH_CW EQU 28
SPILL EQU 32
STACK_SIZE EQU 36
 
 
pos_1 DD 00000000H
DD 3ff00000H
 
neg_1 DD 00000000H
DD 0bff00000H
 
 
dispatch_table DD offset label0
DD offset label1
DD offset label2
DD offset label3
DD offset label4
DD offset label5
DD offset label6
DD offset label7
;end dispatch table
 
pi DB 35H
DB 0c2H
DD 0daa22168H
DD 4000c90fH
 
pi_by_2 DB 35H
DB 0c2H
DD 0daa22168H
DD 3fffc90fH
 
flt_sixteen DD 41800000H
 
one_by_sixteen DD 3d800000H
 
 
B1 DW 0AAA8H
DD 0AAAAAAAAH
DD 0BFFDAAAAH
 
B2 DW 2D6EH
DD 0CCCCCCCCH
DD 3FFCCCCCH
 
B3 DW 4892H
DD 249241F9H
DD 0BFFC9249H
 
B4 DW 0C592H
DD 3897CDECH
DD 3FFBE38EH
 
B5 DW 5DDDH
DD 0C17BC162H
DD 0BFFBBA2DH
 
B6 DW 4854H
DD 77C7C78EH
DD 3FFB9C80H
 
 
atan_k_by_16 dd 000000000H, 000000000H, 000000000H, 000000000H
dd 067EF4E37H, 0FFAADDB9H, 000003FFAH, 000000000H
dd 0617B6E33H, 0FEADD4D5H, 000003FFBH, 000000000H
dd 072D81135H, 0BDCBDA5EH, 000003FFCH, 000000000H
dd 06406EB15H, 0FADBAFC9H, 000003FFCH, 000000000H
dd 03F5E5E6AH, 09B13B9B8H, 000003FFDH, 000000000H
dd 026F78474H, 0B7B0CA0FH, 000003FFDH, 000000000H
dd 0611FE5B6H, 0D327761EH, 000003FFDH, 000000000H
dd 00DDA7B45H, 0ED63382BH, 000003FFDH, 000000000H
dd 0D9867E2AH, 0832BF4A6H, 000003FFEH, 000000000H
dd 0F7F59F9BH, 08F005D5EH, 000003FFEH, 000000000H
dd 071BDDA20H, 09A2F80E6H, 000003FFEH, 000000000H
dd 034F70924H, 0A4BC7D19H, 000003FFEH, 000000000H
dd 0B4D8C080H, 0AEAC4C38H, 000003FFEH, 000000000H
dd 0C2319E74H, 0B8053E2BH, 000003FFEH, 000000000H
dd 0AC526641H, 0C0CE85B8H, 000003FFEH, 000000000H
dd 02168C235H, 0C90FDAA2H, 000003FFEH, 000000000H
 
DATA32 ENDS
 
BSS32 SEGMENT DWORD PUBLIC USE32 'BSS'
BSS32 ENDS
 
 
EXTRN __fdiv_fpr:NEAR
 
DGROUP GROUP CONST,CONST2,DATA32,BSS32
 
 
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME CS:_TEXT,DS:DGROUP,ES:DGROUP, SS:nothing
public __fpatan_chk
 
defpe __fpatan_chk
push eax
push ecx
push edx
sub esp, STACK_SIZE
fstp tbyte ptr [esp+X] ; save X
fstp tbyte ptr [esp+Y] ; save Y
 
mov ecx, [esp+Y+4]
add ecx, ecx
jnc hw_fpatan ; unnormals (explicit 1 missing)
mov eax, [esp+X+4]
add eax, eax
jnc hw_fpatan ; unnormals (explicit 1 missing)
mov ecx, [esp+Y+8] ; save high part of Y
mov eax, [esp+X+8] ; save high part of Y
and ecx, 7fffh ; Ey = exponent Y
jz hw_fpatan ; Ey = 0
and eax, 7fffh ; Ex = exponent X
jz hw_fpatan ; Ex = 0
cmp ecx, 7fffh ; check if Ey = 0x7fffh
je hw_fpatan
cmp eax, 7fffh ; check if Ex = 0x7fffh
je hw_fpatan
 
fld tbyte ptr [esp+X] ; reload X
fabs ; |X| = u
fld tbyte ptr [esp+Y] ; reload Y
fabs ; |Y| = v
 
; The following five lines turn off exceptions and set the
; precision control to 80 bits. The former is necessary to
; force any traps to be taken at the divide instead of the scaling
; code. The latter is necessary in order to get full precision for
; codes with incoming 32 and 64 bit precision settings. If
; it can be guaranteed that before reaching this point, the underflow
; exception is masked and the precision control is at 80 bits, these
; five lines can be omitted.
;
fnstcw [PREV_CW+esp] ; save caller's control word
mov edx, [PREV_CW+esp]
or edx, 033fh ; mask exceptions, pc=80
and edx, 0f3ffh
mov [PATCH_CW+esp], edx
fldcw [PATCH_CW+esp] ; mask exceptions & pc=80
 
 
xor edx, edx ; initialize sflag = 0
fcom ; |Y| > |x|
push eax
fstsw ax
sahf
pop eax
jb order_X_Y_ok
fxch
inc edx ; sflag = 1
order_X_Y_ok:
push eax
mov eax, 0fh
call __fdiv_fpr ; v/u = z
pop eax
fld dword ptr flt_sixteen ; 16.0
fmul st, st(1) ; z*16.0
; Top of stack looks like k, z
fistp dword ptr [SPILL+esp] ; store k as int
mov ecx, [SPILL+esp]
shl ecx, 4
fild dword ptr[SPILL+esp]
fmul dword ptr one_by_sixteen; 1.0/16.0
; Top of stack looks like g, z
fld st(1) ; duplicate g
fsub st, st(1) ; z-g = r
fxch
; Top of stack looks like g, r, z
fmulp st(2), st ; g*z
; Top of stack looks like r, g*z
fld qword ptr pos_1 ; load 1.0
faddp st(2), st ; 1+g*z
; Top of stack looks like r, 1+g*z
push eax
mov eax, 0fh
call __fdiv_fpr ; v/u = z
pop eax
fld st(0) ; duplicate s
fmul st,st(1) ; t = s*s
; Top of stack looks like t, s
 
fld st(0)
fmul st, st(1)
; Top of stack looks like t2, t, s
fld st(0)
fmul st, st(1)
fld tbyte ptr B6
fld tbyte ptr B5
; Top of stack looks like B5, B6, t4, t2, t, s
fxch
fmul st, st(2)
fld tbyte ptr B4
fxch st(2)
fmul st, st(3)
; Top of stack looks like B5t4, B6t4, B4, t4, t2, t, s
fld tbyte ptr B3
fxch st(2)
fmul st, st(5)
; Top of stack looks like B6t6, B5t4, B3, B4, t4, t2, t, s
fxch st(3)
fmulp st(4), st
fld tbyte ptr B2
; Top of stack looks like B2, B5t4, B3, B6t6, B4t4, t2, t, s
fxch st(3)
faddp st(4), st
mov eax, [esp+X+8]
fld tbyte ptr B1
fxch
shl eax, 16
; Top of stack looks like B5t4, B1, B3, B2, even, t2, t, s
fmul st, st(6)
fxch st(2)
add eax, eax
fmul st, st(5)
; Top of stack looks like B3t2, B1, B5t5, B2, even, t2, t, s
fxch st(3)
adc edx, edx ; |sflag|Sx|
fmulp st(5), st
fxch st(2)
mov eax, [Y+8+esp] ; save high part of Y
fmul st, st(5)
; Top of stack looks like B3t3, B5t5, B1, even, B2t2, t, s
fxch st(2)
shl eax, 16
fmulp st(5), st
; Top of stack looks like B5t5, B3t3, even, B2t2, B1t, s
fxch st(2)
faddp st(3), st
add eax, eax
faddp st(1), st
adc edx, edx ; |sflag|Sx|Sy|
; Top of stack looks like odd, even, B1t, s
faddp st(2), st
faddp st(1), st
fmul st,st(1) ; s*(odd+even)
faddp st(1), st ; poly
 
fld tbyte ptr atan_k_by_16[ecx] ; arctan[k;16]
faddp st(1), st ; w = poly + arctan(g)
 
jmp dword ptr dispatch_table[edx*4]
 
label0:
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label1:
fchs
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label2:
fld tbyte ptr pi
fsubrp st(1), st ; pi - w
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label3:
fld tbyte ptr pi
fsubrp st(1), st ; pi - w
fchs ; - (pi - w)
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label4:
fld tbyte ptr pi_by_2
fsubrp st(1), st ; pi/2 - w
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label5:
fld tbyte ptr pi_by_2
fsubrp st(1), st ; pi/2 - w
fchs ; - (pi/2 - w)
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label6:
fld tbyte ptr pi_by_2
faddp st(1), st ; pi/2 + w
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
label7:
fld tbyte ptr pi_by_2
faddp st(1), st ; pi/2 + w
fchs ; -(pi/2+w)
fldcw [esp+PREV_CW]
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
 
 
hw_fpatan:
fld tbyte ptr [esp+Y] ; reload Y
fld tbyte ptr [esp+X] ; reload X
fpatan
add esp, STACK_SIZE
pop edx
pop ecx
pop eax
ret
__fpatan_chk ENDP
 
_TEXT ENDS
END
/programs/develop/open watcom/trunk/clib/src/chipbug.c
0,0 → 1,58
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: verify Pentium processor divide bug
*
****************************************************************************/
 
 
#include "variety.h"
#include "rtinit.h"
#include "rtdata.h"
 
extern unsigned _WCNEAR __chipbug;
 
enum {
PROB_P5_DIV = 0x0001
};
 
_WCRTLINK void __verify_pentium_fdiv_bug()
{
/*
Verify we have got the Pentium FDIV problem.
The volatiles are to scare the optimizer away.
*/
volatile double num = 4195835;
volatile double denom = 3145727;
 
if( _RWD_real87 >= 3 ) {
if( (num - (num/denom)*denom) > 1.0e-8 ) {
__chipbug |= PROB_P5_DIV;
}
}
}
 
AXI( __verify_pentium_fdiv_bug, INIT_PRIORITY_FPU + 4 );
/programs/develop/open watcom/trunk/clib/src/chipd32.asm
0,0 → 1,991
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
 
 
; static char sccs_id[] = "@(#)patch32.asm 1.12 12/21/94 14:53:51";
;
; This code is being published by Intel to users of the Pentium(tm)
; processor. Recipients are authorized to copy, modify, compile, use and
; distribute the code.
;
; Intel makes no warranty of any kind with regard to this code, including
; but not limited to, implied warranties or merchantability and fitness for
; a particular purpose. Intel assumes no responsibility for any errors that
; may appear in this code.
;
; No patent licenses are granted, express or implied.
;
;
include mdef.inc
 
.386
.387
 
DENOM EQU 0
NUMER EQU 12
PREV_CW EQU 28 ; 24 + 4 (return size)
PATCH_CW EQU 32 ; 28 + 4 (return size)
 
DENOM_SAVE EQU 32
 
MAIN_DENOM EQU 4
MAIN_NUMER EQU 16
 
SPILL_SIZE EQU 12
MEM_OPERAND EQU 8
STACK_SIZE EQU 44
SPILL_MEM_OPERAND EQU 20
 
ONESMASK EQU 0e000000h
 
SINGLE_NAN EQU 07f800000h
DOUBLE_NAN EQU 07ff00000h
 
ILLEGAL_OPC EQU 6
 
f_stsw macro where
fstsw where
endm
 
fdivr_st MACRO reg_index, reg_index_minus1
fstp tbyte ptr [esp+DENOM]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fstp tbyte ptr [esp+NUMER]
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld tbyte ptr [esp+NUMER]
fxch st(reg_index)
add esp, STACK_SIZE
ENDM
 
fdivr_sti MACRO reg_index, reg_index_minus1
fstp tbyte ptr [esp+NUMER]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fstp tbyte ptr [esp+DENOM]
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld tbyte ptr [esp+NUMER]
add esp, STACK_SIZE
ENDM
 
fdivrp_sti MACRO reg_index, reg_index_minus1
fstp tbyte ptr [esp+NUMER]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fstp tbyte ptr [esp+DENOM]
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
add esp, STACK_SIZE
ENDM
 
fdiv_st MACRO reg_index, reg_index_minus1
fstp tbyte ptr [esp+NUMER]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld st
fstp tbyte ptr [esp+DENOM]
fstp tbyte ptr [esp+DENOM_SAVE] ; save original denom,
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld tbyte ptr [esp+DENOM_SAVE]
fxch st(reg_index)
add esp, STACK_SIZE
ENDM
 
fdiv_sti MACRO reg_index, reg_index_minus1
fxch st(reg_index)
fstp tbyte ptr [esp+NUMER]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld st
fstp tbyte ptr [esp+DENOM]
fstp tbyte ptr [esp+DENOM_SAVE] ; save original denom,
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fld tbyte ptr [esp+DENOM_SAVE]
add esp, STACK_SIZE
ENDM
 
fdivp_sti MACRO reg_index, reg_index_minus1
fstp tbyte ptr [esp+DENOM]
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
fstp tbyte ptr [esp+NUMER]
call fdiv_main_routine
IF reg_index_minus1 GE 1
fxch st(reg_index_minus1)
ENDIF
add esp, STACK_SIZE
ENDM
 
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
_TEXT ENDS
 
DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
DATA32 ENDS
 
CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST32 ENDS
 
BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS'
BSS32 ENDS
 
DGROUP GROUP CONST32, BSS32, DATA32
 
 
DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
 
fdiv_risc_table DB 0, 1, 0, 0, 4, 0, 0, 7, 0, 0, 10, 0, 0, 13, 0, 0
fdiv_scale_1 DD 03f700000h ;0.9375
fdiv_scale_2 DD 03f880000h ;1.0625
one_shl_63 DD 05f000000h
 
 
dispatch_table DD offset label0
DD offset label1
DD offset label2
DD offset label3
DD offset label4
DD offset label5
DD offset label6
DD offset label7
DD offset label8
DD offset label9
DD offset label10
DD offset label11
DD offset label12
DD offset label13
DD offset label14
DD offset label15
DD offset label16
DD offset label17
DD offset label18
DD offset label19
DD offset label20
DD offset label21
DD offset label22
DD offset label23
DD offset label24
DD offset label25
DD offset label26
DD offset label27
DD offset label28
DD offset label29
DD offset label30
DD offset label31
DD offset label32
DD offset label33
DD offset label34
DD offset label35
DD offset label36
DD offset label37
DD offset label38
DD offset label39
DD offset label40
DD offset label41
DD offset label42
DD offset label43
DD offset label44
DD offset label45
DD offset label46
DD offset label47
DD offset label48
DD offset label49
DD offset label50
DD offset label51
DD offset label52
DD offset label53
DD offset label54
DD offset label55
DD offset label56
DD offset label57
DD offset label58
DD offset label59
DD offset label60
DD offset label61
DD offset label62
DD offset label63
 
DATA32 ENDS
 
 
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
 
 
assume cs:_TEXT, ds:DGROUP, es:DGROUP, ss:nothing
 
;
; PRELIMINARY VERSION for register-register divides.
;
 
 
; In this implementation the
; fdiv_main_routine is called,
; therefore all the stack frame
; locations are adjusted for the
; return pointer.
 
fdiv_main_routine PROC NEAR
 
fld tbyte ptr [esp+MAIN_NUMER] ; load the numerator
fld tbyte ptr [esp+MAIN_DENOM] ; load the denominator
retry:
 
; The following three lines test for denormals and zeros.
; A denormal or zero has a 0 in the explicit digit to the left of the
; binary point. Since that bit is the high bit of the word, adding
; it to itself will produce a carry if and only if the number is not
; denormal or zero.
;
mov eax, [esp+MAIN_DENOM+4] ; get mantissa bits 32-64
add eax,eax ; shift the one's bit onto carry
jnc denormal ; if no carry, we're denormal
 
; The following three lines test the three bits after the four bit
; pattern (1,4,7,a,d). If these three bits are not all one, then
; the denominator cannot expose the flaw. This condition is tested by
; inverting the bits and testing that all are equal to zero afterward.
 
xor eax, ONESMASK ; invert the bits that must be ones
test eax, ONESMASK ; and make sure they are all ones
jz scale_if_needed ; if all are one scale numbers
fdivp st(1), st ; use of hardware is OK.
ret
 
;
; Now we test the four bits for one of the five patterns.
;
scale_if_needed:
shr eax, 28 ; keep first 4 bits after point
cmp byte ptr fdiv_risc_table[eax], 0 ; check for (1,4,7,a,d)
jnz divide_scaled ; are in potential problem area
fdivp st(1), st ; use of hardware is OK.
ret
 
divide_scaled:
mov eax, [esp + MAIN_DENOM+8] ; test denominator exponent
and eax, 07fffh ; if pseudodenormal ensure that only
jz invalid_denom ; invalid exception flag is set
cmp eax, 07fffh ; if NaN or infinity ensure that only
je invalid_denom ; invalid exception flag is set
;
; The following six lines turn off exceptions and set the
; precision control to 80 bits. The former is necessary to
; force any traps to be taken at the divide instead of the scaling
; code. The latter is necessary in order to get full precision for
; codes with incoming 32 and 64 bit precision settings. If
; it can be guaranteed that before reaching this point, the underflow
; exception is masked and the precision control is at 80 bits, these
; six lines can be omitted.
;
fnstcw [esp+PREV_CW] ; save caller's control word
mov eax, [esp+PREV_CW]
or eax, 033fh ; mask exceptions, pc=80
and eax, 0f3ffh ; set rounding mode to nearest
mov [esp+PATCH_CW], eax
fldcw [esp+PATCH_CW] ; mask exceptions & pc=80
 
; The following lines check the numerator exponent before scaling.
; This in order to prevent undeflow when scaling the numerator,
; which will cause a denormal exception flag to be set when the
; actual divide is preformed. This flag would not have been set
; normally. If there is a risk of underflow, the scale factor is
; 17/16 instead of 15/16.
;
mov eax, [esp+MAIN_NUMER+8] ; test numerator exponent
and eax, 07fffh
cmp eax, 00001h
je small_numer
 
fmul fdiv_scale_1 ; scale denominator by 15/16
fxch
fmul fdiv_scale_1 ; scale numerator by 15/16
fxch
 
;
; The next line restores the users control word. If the incoming
; control word had the underflow exception masked and precision
; control set to 80 bits, this line can be omitted.
;
 
fldcw [esp+PREV_CW] ; restore caller's control word
fdivp st(1), st ; use of hardware is OK.
ret
 
small_numer:
fmul fdiv_scale_2 ; scale denominator by 17/16
fxch
fmul fdiv_scale_2 ; scale numerator by 17/16
fxch
 
;
; The next line restores the users control word. If the incoming
; control word had the underflow exception masked and precision
; control set to 80 bits, this line can be omitted.
;
 
fldcw [esp+PREV_CW] ; restore caller's control word
fdivp st(1), st ; use of hardware is OK.
ret
 
denormal:
mov eax, [esp+MAIN_DENOM] ; test for whole mantissa == 0
or eax, [esp+MAIN_DENOM+4] ; test for whole mantissa == 0
jnz denormal_divide_scaled ; denominator is not zero
invalid_denom: ; zero or invalid denominator
fdivp st(1), st ; use of hardware is OK.
ret
 
denormal_divide_scaled:
mov eax, [esp + MAIN_DENOM + 8] ; get exponent
and eax, 07fffh ; check for zero exponent
jnz invalid_denom ;
;
; The following six lines turn off exceptions and set the
; precision control to 80 bits. The former is necessary to
; force any traps to be taken at the divide instead of the scaling
; code. The latter is necessary in order to get full precision for
; codes with incoming 32 and 64 bit precision settings. If
; it can be guaranteed that before reaching this point, the underflow
; exception is masked and the precision control is at 80 bits, these
; five lines can be omitted.
;
 
fnstcw [esp+PREV_CW] ; save caller's control word
mov eax, [esp+PREV_CW]
or eax, 033fh ; mask exceptions, pc=80
and eax, 0f3ffh ; set rounding mode to nearest
mov [esp+PATCH_CW], eax
fldcw [esp+PATCH_CW] ; mask exceptions & pc=80
 
mov eax, [esp + MAIN_NUMER +8] ; test numerator exponent
and eax, 07fffh ; check for denormal numerator
je denormal_numer
cmp eax, 07fffh ; NaN or infinity
je invalid_numer
mov eax, [esp + MAIN_NUMER + 4] ; get bits 32..63 of mantissa
add eax, eax ; shift the first bit into carry
jnc invalid_numer ; if there is no carry, we have an
; invalid numer
jmp numer_ok
 
denormal_numer:
mov eax, [esp + MAIN_NUMER + 4] ; get bits 32..63 of mantissa
add eax, eax ; shift the first bit into carry
jc invalid_numer ; if there is a carry, we have an
; invalid numer
 
numer_ok:
fxch
fstp st ; pop numerator
fld st ; make copy of denominator
fmul dword ptr[one_shl_63] ; make denominator not denormal
fstp tbyte ptr [esp+MAIN_DENOM] ; save modified denominator
fld tbyte ptr [esp+MAIN_NUMER] ; load numerator
fxch ; restore proper order
fwait
 
; The next line restores the users control word. If the incoming
; control word had the underflow exception masked and precision
; control set to 80 bits, this line can be omitted.
;
 
fldcw [esp+PREV_CW] ; restore caller's control word
jmp retry ; start the whole thing over
 
invalid_numer:
;
; The next line restores the users control word. If the incoming
; control word had the underflow exception masked and precision
; control set to 80 bits, this line can be omitted.
;
fldcw [esp + PREV_CW]
fdivp st(1), st ; use of hardware is OK.
ret
 
fdiv_main_routine ENDP
 
public __fdiv_fpr
defpe __fdiv_fpr
 
sub esp, STACK_SIZE
jmp dword ptr dispatch_table[eax*4]
 
 
label0:
fdiv st,st(0) ; D8 F0 FDIV ST,ST(0)
add esp, STACK_SIZE
ret
label1:
add esp, STACK_SIZE
int ILLEGAL_OPC
label2:
fdivr st,st(0) ; D8 F8 FDIVR ST,ST(0)
add esp, STACK_SIZE
ret
label3:
add esp, STACK_SIZE
int ILLEGAL_OPC
label4:
fdiv st(0),st ; DC F8/D8 F0 FDIV ST(0),ST
add esp, STACK_SIZE
ret
label5:
fdivp st(0),st ; DE F8 FDIVP ST(0),ST
add esp, STACK_SIZE
ret
label6:
fdivr st(0),st ; DC F0/DE F0 FDIVR ST(0),ST
add esp, STACK_SIZE
ret
label7:
fdivrp st(0),st ; DE F0 FDIVRP ST(0),ST
add esp, STACK_SIZE
ret
label8:
fdiv_st 1, 0
ret
label9:
add esp, STACK_SIZE
int ILLEGAL_OPC
label10:
fdivr_st 1, 0
ret
label11:
add esp, STACK_SIZE
int ILLEGAL_OPC
label12:
fdiv_sti 1, 0
ret
label13:
fdivp_sti 1, 0
ret
label14:
fdivr_sti 1, 0
ret
label15:
fdivrp_sti 1, 0
ret
label16:
fdiv_st 2, 1
ret
label17:
add esp, STACK_SIZE
int ILLEGAL_OPC
label18:
fdivr_st 2, 1
ret
label19:
add esp, STACK_SIZE
int ILLEGAL_OPC
label20:
fdiv_sti 2, 1
ret
label21:
fdivp_sti 2, 1
ret
label22:
fdivr_sti 2, 1
ret
label23:
fdivrp_sti 2, 1
ret
label24:
fdiv_st 3, 2
ret
label25:
add esp, STACK_SIZE
int ILLEGAL_OPC
label26:
fdivr_st 3, 2
ret
label27:
add esp, STACK_SIZE
int ILLEGAL_OPC
label28:
fdiv_sti 3, 2
ret
label29:
fdivp_sti 3, 2
ret
label30:
fdivr_sti 3, 2
ret
label31:
fdivrp_sti 3, 2
ret
label32:
fdiv_st 4, 3
ret
label33:
add esp, STACK_SIZE
int ILLEGAL_OPC
label34:
fdivr_st 4, 3
ret
label35:
add esp, STACK_SIZE
int ILLEGAL_OPC
label36:
fdiv_sti 4, 3
ret
label37:
fdivp_sti 4, 3
ret
label38:
fdivr_sti 4, 3
ret
label39:
fdivrp_sti 4, 3
ret
label40:
fdiv_st 5, 4
ret
label41:
add esp, STACK_SIZE
int ILLEGAL_OPC
label42:
fdivr_st 5, 4
ret
label43:
add esp, STACK_SIZE
int ILLEGAL_OPC
label44:
fdiv_sti 5, 4
ret
label45:
fdivp_sti 5, 4
ret
label46:
fdivr_sti 5, 4
ret
label47:
fdivrp_sti 5, 4
ret
label48:
fdiv_st 6, 5
ret
label49:
add esp, STACK_SIZE
int ILLEGAL_OPC
label50:
fdivr_st 6, 5
ret
label51:
add esp, STACK_SIZE
int ILLEGAL_OPC
label52:
fdiv_sti 6, 5
ret
label53:
fdivp_sti 6, 5
ret
label54:
fdivr_sti 6, 5
ret
label55:
fdivrp_sti 6, 5
ret
label56:
fdiv_st 7, 6
ret
label57:
add esp, STACK_SIZE
int ILLEGAL_OPC
label58:
fdivr_st 7, 6
ret
label59:
add esp, STACK_SIZE
int ILLEGAL_OPC
label60:
fdiv_sti 7, 6
ret
label61:
fdivp_sti 7, 6
ret
label62:
fdivr_sti 7, 6
ret
label63:
fdivrp_sti 7, 6
ret
__fdiv_fpr ENDP
 
 
__fdivp_sti_st PROC NEAR
; for calling from mem routines
sub esp, STACK_SIZE
fdivp_sti 1, 0
ret
__fdivp_sti_st ENDP
 
__fdivrp_sti_st PROC NEAR
; for calling from mem routines
sub esp, STACK_SIZE
fdivrp_sti 1, 0
ret
__fdivrp_sti_st ENDP
 
public __fdiv_chk
defpe __fdiv_chk
; for calling from mem routines
sub esp, STACK_SIZE
fdivrp_sti 1, 0
ret
__fdiv_chk ENDP
 
;
; PRELIMINARY VERSIONS of the routines for register-memory
; divide instructions
;
 
;;; FDIV_M32 - FDIV m32real FIX
;;
;; Input : Value of the m32real in the top of STACK
;;
;; Output: Result of FDIV in ST
 
PUBLIC __fdiv_m32
defpe __fdiv_m32
 
push eax ; save eax
mov eax, [esp + MEM_OPERAND] ; check for
and eax, SINGLE_NAN ; NaN
cmp eax, SINGLE_NAN ;
je memory_divide_m32 ;
 
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack ; is FP stack full?
fld dword ptr[esp + MEM_OPERAND] ; load m32real in ST
call __fdivp_sti_st ; do actual divide
pop eax
ret 4
spill_fpstack:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fld dword ptr[esp + SPILL_MEM_OPERAND] ; load m32 real
call __fdivp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivrp fn
fxch
add esp, SPILL_SIZE
pop eax
ret 4
memory_divide_m32:
fdiv dword ptr[esp + MEM_OPERAND] ; do actual divide
pop eax
ret 4
 
__fdiv_m32 ENDP
 
 
;;; FDIV_M64 - FDIV m64real FIX
;;
;; Input : Value of the m64real in the top of STACK
;;
;; Output: Result of FDIV in ST
 
PUBLIC __fdiv_m64
defpe __fdiv_m64
 
push eax ; save eax
mov eax, [esp + MEM_OPERAND + 4] ; check for
and eax, DOUBLE_NAN ; NaN
cmp eax, DOUBLE_NAN ;
je memory_divide_m64 ;
 
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m64 ; is FP stack full?
fld qword ptr[esp + MEM_OPERAND] ; load m64real in ST
call __fdivp_sti_st ; do actual divide
pop eax
ret 8
spill_fpstack_m64:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp] ; save user's ST(1)
fld qword ptr[esp + SPILL_MEM_OPERAND] ; load m64real
call __fdivp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivrp fn
fxch
add esp, SPILL_SIZE
pop eax
ret 8
 
memory_divide_m64:
fdiv qword ptr[esp + MEM_OPERAND] ; do actual divide
pop eax
ret 8
 
__fdiv_m64 ENDP
 
 
 
;;; FDIVR_M32 - FDIVR m32real FIX
;;
;; Input : Value of the m32real in the top of STACK
;;
;; Output: Result of FDIVR in ST
 
PUBLIC __fdiv_m32r
defpe __fdiv_m32r
push eax ; save eax
mov eax, [esp + MEM_OPERAND] ; check for
and eax, SINGLE_NAN ; NaN
cmp eax, SINGLE_NAN ;
je memory_divide_m32r ;
 
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m32r ; is FP stack full?
fld dword ptr[esp + MEM_OPERAND] ; load m32real in ST
call __fdivrp_sti_st ; do actual divide
pop eax
ret 4
spill_fpstack_m32r:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fld dword ptr[esp + SPILL_MEM_OPERAND] ; load m32 real
call __fdivrp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivp fn
fxch
add esp, SPILL_SIZE
pop eax
ret 4
memory_divide_m32r:
fdivr dword ptr[esp + MEM_OPERAND] ; do actual divide
pop eax
ret 4
 
__fdiv_m32r ENDP
 
 
;;; FDIVR_M64 - FDIVR m64real FIX
;;
;; Input : Value of the m64real in the top of STACK
;;
;; Output: Result of FDIVR in ST
 
PUBLIC __fdiv_m64r
defpe __fdiv_m64r
push eax ; save eax
mov eax, [esp + MEM_OPERAND + 4] ; check for
and eax, DOUBLE_NAN ; NaN
cmp eax, DOUBLE_NAN ;
je memory_divide_m64r ;
 
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m64r ; is FP stack full?
fld qword ptr[esp + MEM_OPERAND] ; load m64real in ST
call __fdivrp_sti_st ; do actual divide
pop eax
ret 8
spill_fpstack_m64r:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fld qword ptr[esp + SPILL_MEM_OPERAND] ; load m64real
call __fdivrp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivp fn
fxch
add esp, SPILL_SIZE
pop eax
ret 8
memory_divide_m64r:
fdivr qword ptr[esp + MEM_OPERAND] ; do actual divide
pop eax
ret 8
 
 
__fdiv_m64r ENDP
 
comment ~******************************************************************
;;; FDIV_M16I - FDIV m16int FIX
;;
;; Input : Value of the m16int in the top of STACK
;;
;; Output: Result of FDIV in ST
 
PUBLIC FDIV_M16I
FDIV_M16I PROC NEAR
push eax ; save eax
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m16i ; is FP stack full?
fild word ptr[esp + MEM_OPERAND] ; load m16int in ST
call __fdivp_sti_st ; do actual divide
pop eax
ret
spill_fpstack_m16i:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fild word ptr[esp + SPILL_MEM_OPERAND] ; load m16int
call __fdivp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivrp fn
fxch
add esp, SPILL_SIZE
pop eax
ret
 
FDIV_M16I ENDP
 
;;; FDIV_M32I - FDIV m16int FIX
;;
;; Input : Value of the m16int in the top of STACK
;;
;; Output: Result of FDIV in ST
 
PUBLIC FDIV_M32I
FDIV_M32I PROC NEAR
push eax ; save eax
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m32i ; is FP stack full?
fild dword ptr[esp + MEM_OPERAND] ; load m32int in ST
call __fdivp_sti_st ; do actual divide
pop eax
ret
spill_fpstack_m32i:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fild dword ptr[esp + SPILL_MEM_OPERAND] ; load m32int
call __fdivp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivrp fn
fxch
add esp, SPILL_SIZE
pop eax
ret
 
 
FDIV_M32I ENDP
 
 
;;; FDIVR_M16I - FDIVR m16int FIX
;;
;; Input : Value of the m16int in the top of STACK
;;
;; Output: Result of FDIVR in ST
 
PUBLIC FDIVR_M16I
FDIVR_M16I PROC NEAR
push eax ; save eax
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m16ir ; is FP stack full?
fild word ptr[esp + MEM_OPERAND] ; load m16int in ST
call __fdivrp_sti_st ; do actual divide
pop eax
ret
spill_fpstack_m16ir:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fild word ptr[esp + SPILL_MEM_OPERAND] ; load m16int
call __fdivrp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivp fn
fxch
add esp, SPILL_SIZE
pop eax
ret
 
 
FDIVR_M16I ENDP
 
 
;;; FDIVR_M32I - FDIVR m32int FIX
;;
;; Input : Value of the m32int in the top of STACK
;;
;; Output: Result of FDIVR in ST
 
PUBLIC FDIVR_M32I
FDIVR_M32I PROC NEAR
push eax ; save eax
f_stsw ax ; get status word
and eax, 3800h ; get top of stack
je spill_fpstack_m32ir ; is FP stack full?
fild dword ptr[esp + MEM_OPERAND] ; load m32int in ST
call __fdivrp_sti_st ; do actual divide
pop eax
ret
spill_fpstack_m32ir:
fxch
sub esp, SPILL_SIZE ; make temp space
fstp tbyte ptr[esp ] ; save user's ST(1)
fild dword ptr[esp + SPILL_MEM_OPERAND] ; load m32int
call __fdivrp_sti_st ; do actual divide
fld tbyte ptr[esp] ; restore user's ST(1)
;esp is adjusted by fdivp fn
fxch
add esp, SPILL_SIZE
pop eax
ret
 
FDIVR_M32I ENDP
**********************************************************************~
 
 
 
_TEXT ENDS
 
end
/programs/develop/open watcom/trunk/clib/src/chipr32.asm
0,0 → 1,851
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
 
 
; static char sccs_id[] = "@(#)fprem32.asm 1.5 12/22/94 12:48:07";
;
; This code is being published by Intel to users of the Pentium(tm)
; processor. Recipients are authorized to copy, modify, compile, use and
; distribute the code.
;
; Intel makes no warranty of any kind with regard to this code, including
; but not limited to, implied warranties or merchantability and fitness for
; a particular purpose. Intel assumes no responsibility for any errors that
; may appear in this code.
;
; No patent licenses are granted, express or implied.
;
;
include mdef.inc
 
.386
.387
 
;
; PRELIMINARY VERSION of the software patch for the floating
; point remainder.
;
 
 
CHECKSW MACRO
ifdef DEBUG
fnstsw [fpsw]
fnstcw [fpcw]
endif
ENDM
 
 
DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
 
;
; Stack variables for remainder routines.
;
 
FLT_SIZE EQU 12
DENOM EQU 0
DENOM_SAVE EQU DENOM + FLT_SIZE
NUMER EQU DENOM_SAVE + FLT_SIZE
PREV_CW EQU NUMER + FLT_SIZE
PATCH_CW EQU PREV_CW + 4
FPREM_SW EQU PATCH_CW + 4
STACK_SIZE EQU FPREM_SW + 4
RET_SIZE EQU 4
PUSH_SIZE EQU 4
 
MAIN_FUDGE EQU RET_SIZE + PUSH_SIZE + PUSH_SIZE + PUSH_SIZE
 
MAIN_DENOM EQU DENOM + MAIN_FUDGE
MAIN_DENOM_SAVE EQU DENOM_SAVE + MAIN_FUDGE
MAIN_NUMER EQU NUMER + MAIN_FUDGE
MAIN_PREV_CW EQU PREV_CW + MAIN_FUDGE
MAIN_PATCH_CW EQU PATCH_CW + MAIN_FUDGE
MAIN_FPREM_SW EQU FPREM_SW + MAIN_FUDGE
 
ONESMASK EQU 700h
 
fprem_risc_table DB 0, 1, 0, 0, 4, 0, 0, 7, 0, 0, 10, 0, 0, 13, 0, 0
fprem_scale DB 0, 0, 0, 0, 0, 0, 0eeh, 03fh
one_shl_64 DB 0, 0, 0, 0, 0, 0, 0f0h, 043h
one_shr_64 DB 0, 0, 0, 0, 0, 0, 0f0h, 03bh
one DB 0, 0, 0, 0, 0, 0, 0f0h, 03fh
half DB 0, 0, 0, 0, 0, 0, 0e0h, 03fh
big_number DB 0, 0, 0, 0, 0, 0, 0ffh, 0ffh, 0feh, 07fh
 
ifdef DEBUG
public fpcw
public fpsw
fpcw dw 0
fpsw dw 0
endif
 
FPU_STATE STRUC
CONTROL_WORD DW ?
reserved_1 DW ?
STATUS_WORD DD ?
TAG_WORD DW ?
reserved_3 DW ?
IP_OFFSET DD ?
CS_SLCT DW ?
OPCODE DW ?
DATA_OFFSET DD ?
OPERAND_SLCT DW ?
reserved_4 DW ?
FPU_STATE ENDS
 
ENV_SIZE EQU 28
 
 
DATA32 ENDS
 
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
_TEXT ENDS
 
DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
DATA32 ENDS
 
CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST32 ENDS
 
BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS'
BSS32 ENDS
 
DGROUP GROUP CONST32, BSS32, DATA32
 
 
 
CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE'
 
assume cs:_TEXT, ds:DGROUP, es:DGROUP, ss:nothing
 
 
fprem_common PROC NEAR
 
push eax
push ebx
push ecx
mov eax, [MAIN_DENOM+6+esp] ; exponent and high 16 bits of mantissa
xor eax, ONESMASK ; invert bits that have to be one
test eax, ONESMASK ; check bits that have to be one
jnz remainder_hardware_ok
shr eax, 11
and eax, 0fh
cmp byte ptr fprem_risc_table[eax], 0 ; check for (1,4,7,a,d)
jz remainder_hardware_ok
 
; The denominator has the bit pattern. Weed out the funny cases like NaNs
; before applying the software version. Our caller guarantees that the
; denominator is not a denormal. Here we check for:
; denominator inf, NaN, unnormal
; numerator inf, NaN, unnormal, denormal
 
mov eax, [MAIN_DENOM+6+esp] ; exponent and high 16 bits of mantissa
and eax, 07fff0000h ; mask the exponent only
cmp eax, 07fff0000h ; check for INF or NaN
je remainder_hardware_ok
mov eax, [MAIN_NUMER+6+esp] ; exponent and high 16 bits of mantissa
and eax, 07fff0000h ; mask the exponent only
jz remainder_hardware_ok ; jif numerator denormal
cmp eax, 07fff0000h ; check for INF or NaN
je remainder_hardware_ok
mov eax, [esp + MAIN_NUMER + 4] ; high mantissa bits - numerator
add eax, eax ; set carry if explicit bit set
jnz remainder_hardware_ok ; jmp if numerator is unnormal
mov eax, [esp + MAIN_DENOM + 4] ; high mantissa bits - denominator
add eax, eax ; set carry if explicit bit set
jnz remainder_hardware_ok ; jmp if denominator is unnormal
 
rem_patch:
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
add eax, 63 ; evaluate ey + 63
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference (ex - ey)
ja rem_large ; if ex > ey + 63, case of large arguments
rem_patch_loop:
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
add eax, 10 ; evaluate ey + 10
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference (ex - ey)
js remainder_hardware_ok ; safe if ey + 10 > ex
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
mov ecx, ebx
sub ebx, eax
and ebx, 07h
or ebx, 04h
sub ecx, ebx
mov ebx, eax
and ebx, 08000h ; keep sy
or ecx, ebx ; merge the sign of y
mov dword ptr [MAIN_DENOM+8+esp], ecx
fld tbyte ptr [MAIN_DENOM+esp] ; load the shifted denominator
mov dword ptr [MAIN_DENOM+8+esp], eax ; restore the initial denominator
fxch
fprem ; this rem is safe
fstp tbyte ptr [MAIN_NUMER+esp] ; update the numerator
fstp st(0) ; pop the stack
jmp rem_patch_loop
rem_large:
test edx, 02h ; is denominator already saved
jnz already_saved
fld tbyte ptr[esp + MAIN_DENOM]
fstp tbyte ptr[esp + MAIN_DENOM_SAVE] ; save denominator
already_saved:
; Save user's precision control and institute 80. The fp ops in
; rem_large_loop must not round to user's precision (if it is less
; than 80) because the hardware would not have done so. We are
; aping the hardware here, which is all extended.
 
fnstcw [esp+MAIN_PREV_CW] ; save caller's control word
mov eax, dword ptr[esp + MAIN_PREV_CW]
or eax, 033fh ; mask exceptions, pc=80
mov [esp + MAIN_PATCH_CW], eax
fldcw [esp + MAIN_PATCH_CW]
 
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference
and ebx, 03fh
or ebx, 020h
add ebx, 1
mov ecx, ebx
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
and eax, 08000h ; keep sy
or ebx, eax ; merge the sign of y
mov dword ptr[MAIN_DENOM+8+esp], ebx ; make ey equal to ex (scaled denominator)
fld tbyte ptr [MAIN_DENOM+esp] ; load the scaled denominator
fabs
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
fabs
rem_large_loop:
fcom
fstsw ax
and eax, 00100h
jnz rem_no_sub
fsub st, st(1)
rem_no_sub:
fxch
fmul qword ptr half
fxch
sub ecx, 1 ; decrement the loop counter
jnz rem_large_loop
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
fstp tbyte ptr[esp + MAIN_NUMER] ; save result
fstp st ; toss modified denom
fld tbyte ptr[esp + MAIN_DENOM_SAVE]
fld tbyte ptr[big_number] ; force C2 to be set
fprem
fstp st
fld tbyte ptr[esp + MAIN_NUMER] ; restore saved result
 
fldcw [esp + MAIN_PREV_CW] ; restore caller's control word
and ebx, 08000h ; keep sx
jz rem_done
fchs
jmp rem_done
remainder_hardware_ok:
fld tbyte ptr [MAIN_DENOM+esp] ; load the denominator
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
fprem ; and finally do a remainder
; prem_main_routine end
rem_done:
test edx, 03h
jz rem_exit
fnstsw [esp + MAIN_FPREM_SW] ; save Q0 Q1 and Q2
test edx, 01h
jz do_not_de_scale
; De-scale the result. Go to pc=80 to prevent from fmul
; from user precision (fprem does not round the result).
fnstcw [esp + MAIN_PREV_CW] ; save callers control word
mov eax, [esp + MAIN_PREV_CW]
or eax, 0300h ; pc = 80
mov [esp + MAIN_PATCH_CW], eax
fldcw [esp + MAIN_PATCH_CW]
fmul qword ptr one_shr_64
fldcw [esp + MAIN_PREV_CW] ; restore callers CW
do_not_de_scale:
mov eax, [esp + MAIN_FPREM_SW]
fxch
fstp st
fld tbyte ptr[esp + MAIN_DENOM_SAVE]
fxch
and eax, 04300h ; restore saved Q0, Q1, Q2
sub esp, ENV_SIZE
fnstenv [esp]
and [esp].STATUS_WORD, 0bcffh
or [esp].STATUS_WORD, eax
fldenv [esp]
add esp, ENV_SIZE
rem_exit:
pop ecx
pop ebx
pop eax
CHECKSW ; debug only: save status
ret
fprem_common ENDP
 
comment ~****************************************************************
 
;
; float frem_chk (float numer, float denom)
;
public frem_chk
frem_chk PROC NEAR
push edx
sub esp, STACK_SIZE
fld dword ptr [STACK_SIZE+8+esp]
fstp tbyte ptr [NUMER+esp]
fld dword ptr [STACK_SIZE+12+esp]
fstp tbyte ptr [DENOM+esp]
mov edx, 0 ; dx = 1 if denormal extended divisor
call fprem_common
fxch
fstp st
add esp, STACK_SIZE
pop edx
ret
frem_chk ENDP
; end frem_chk
 
;
; double drem_chk (double numer, double denom)
;
public drem_chk
drem_chk PROC NEAR
push edx
sub esp, STACK_SIZE
fld qword ptr [STACK_SIZE+8+esp]
fstp tbyte ptr [NUMER+esp]
fld qword ptr [STACK_SIZE+16+esp]
fstp tbyte ptr [DENOM+esp]
mov edx, 0 ; dx = 1 if denormal extended divisor
call fprem_common
fxch
fstp st
add esp, STACK_SIZE
pop edx
ret
 
drem_chk ENDP
; end drem_chk
 
;
; long double lrem_chk(long double number,long double denom)
;
public lrem_chk
lrem_chk PROC NEAR
fld tbyte ptr [20+esp]
fld tbyte ptr [4+esp]
call fprem_chk
fxch
fstp st
ret
lrem_chk ENDP
 
**********************************************************************~
 
;
; FPREM: ST = remainder(ST, ST(1))
;
; Compiler version of the FPREM must preserve the arguments in the floating
; point stack.
 
public __fprem_chk
defpe __fprem_chk
push edx
sub esp, STACK_SIZE
fstp tbyte ptr [NUMER+esp]
fstp tbyte ptr [DENOM+esp]
xor edx, edx
; prem_main_routine begin
mov eax,[DENOM+6+esp] ; exponent and high 16 bits of mantissa
test eax,07fff0000h ; check for denormal
jz denormal
call fprem_common
add esp, STACK_SIZE
pop edx
ret
 
denormal:
fld tbyte ptr [DENOM+esp] ; load the denominator
fld tbyte ptr [NUMER+esp] ; load the numerator
mov eax, [DENOM+esp] ; test for whole mantissa == 0
or eax, [DENOM+4+esp] ; test for whole mantissa == 0
jz remainder_hardware_ok_l ; denominator is zero
fxch
fstp tbyte ptr[esp + DENOM_SAVE] ; save org denominator
fld tbyte ptr[esp + DENOM]
fxch
or edx, 02h
;
; For this we need pc=80. Also, mask exceptions so we don't take any
; denormal operand exceptions. It is guaranteed that the descaling
; later on will take underflow, which is what the hardware would have done
; on a normal fprem.
;
fnstcw [PREV_CW+esp] ; save caller's control word
mov eax, [PREV_CW+esp]
or eax, 0033fh ; mask exceptions, pc=80
mov [PATCH_CW+esp], eax
fldcw [PATCH_CW+esp] ; mask exceptions & pc=80
 
; The denominator is a denormal. For most numerators, scale both numerator
; and denominator to get rid of denormals. Then execute the common code
; with the flag set to indicate that the result must be de-scaled.
; For large numerators this won't work because the scaling would cause
; overflow. In this case we know the numerator is large, the denominator
; is small (denormal), so the exponent difference is also large. This means
; the rem_large code will be used and this code depends on the difference
; in exponents modulo 64. Adding 64 to the denominators exponent
; doesn't change the modulo 64 difference. So we can scale the denominator
; by 64, making it not denormal, and this won't effect the result.
;
; To start with, figure out if numerator is large
 
mov eax, [esp + NUMER + 8] ; load numerator exponent
and eax, 7fffh ; isolate numerator exponent
cmp eax, 7fbeh ; compare Nexp to Maxexp-64
ja big_numer_rem_de ; jif big numerator
 
; So the numerator is not large scale both numerator and denominator
 
or edx, 1 ; edx = 1, if denormal extended divisor
fmul qword ptr one_shl_64 ; make numerator not denormal
fstp tbyte ptr[esp + NUMER]
fmul qword ptr one_shl_64 ; make denominator not denormal
fstp tbyte ptr[esp + DENOM]
jmp scaling_done
 
; The numerator is large. Scale only the denominator, which will not
; change the result which we know will be partial. Set the scale flag
; to false.
big_numer_rem_de:
; We must do this with pc=80 to avoid rounding to single/double.
; In this case we do not mask exceptions so that we will take
; denormal operand, as would the hardware.
fnstcw [PREV_CW+esp] ; save caller's control word
mov eax, [PREV_CW+esp]
or eax, 00300h ; pc=80
mov [PATCH_CW+esp], eax
fldcw [PATCH_CW+esp] ; pc=80
 
fstp st ; Toss numerator
fmul qword ptr one_shl_64 ; make denominator not denormal
fstp tbyte ptr[esp + DENOM]
 
; Restore the control word which was fiddled to scale at 80-bit precision.
; Then call the common code.
scaling_done:
fldcw [esp + PREV_CW] ; restore callers control word
call fprem_common
add esp, STACK_SIZE
pop edx
ret
 
remainder_hardware_ok_l:
fprem ; and finally do a remainder
 
CHECKSW
 
add esp, STACK_SIZE
pop edx
ret
__fprem_chk ENDP
; end fprem_chk
 
 
;
; FPREM1 code begins here
;
 
 
fprem1_common PROC NEAR
 
push eax
push ebx
push ecx
mov eax, [MAIN_DENOM+6+esp] ; exponent and high 16 bits of mantissa
xor eax, ONESMASK ; invert bits that have to be one
test eax, ONESMASK ; check bits that have to be one
jnz remainder1_hardware_ok
shr eax, 11
and eax, 0fh
cmp byte ptr fprem_risc_table[eax], 0 ; check for (1,4,7,a,d)
jz remainder1_hardware_ok
 
; The denominator has the bit pattern. Weed out the funny cases like NaNs
; before applying the software version. Our caller guarantees that the
; denominator is not a denormal. Here we check for:
; denominator inf, NaN, unnormal
; numerator inf, NaN, unnormal, denormal
 
mov eax, [MAIN_DENOM+6+esp] ; exponent and high 16 bits of mantissa
and eax, 07fff0000h ; mask the exponent only
cmp eax, 07fff0000h ; check for INF or NaN
je remainder1_hardware_ok
mov eax, [MAIN_NUMER+6+esp] ; exponent and high 16 bits of mantissa
and eax, 07fff0000h ; mask the exponent only
jz remainder1_hardware_ok ; jif numerator denormal
cmp eax, 07fff0000h ; check for INF or NaN
je remainder1_hardware_ok
mov eax, [esp + MAIN_NUMER + 4] ; high mantissa bits - numerator
add eax, eax ; set carry if explicit bit set
jnz remainder1_hardware_ok ; jmp if numerator is unnormal
mov eax, [esp + MAIN_DENOM + 4] ; high mantissa bits - denominator
add eax, eax ; set carry if explicit bit set
jnz remainder1_hardware_ok ; jmp if denominator is unnormal
 
rem1_patch:
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
add eax, 63 ; evaluate ey + 63
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference (ex - ey)
ja rem1_large ; if ex > ey + 63, case of large arguments
rem1_patch_loop:
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
add eax, 10 ; evaluate ey + 10
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference (ex - ey)
js remainder1_hardware_ok ; safe if ey + 10 > ex
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
mov ecx, ebx
sub ebx, eax
and ebx, 07h
or ebx, 04h
sub ecx, ebx
mov ebx, eax
and ebx, 08000h ; keep sy
or ecx, ebx ; merge the sign of y
mov dword ptr [MAIN_DENOM+8+esp], ecx
fld tbyte ptr [MAIN_DENOM+esp] ; load the shifted denominator
mov dword ptr [MAIN_DENOM+8+esp], eax ; restore the initial denominator
fxch
fprem ; this rem is safe
fstp tbyte ptr [MAIN_NUMER+esp] ; update the numerator
fstp st(0) ; pop the stack
jmp rem1_patch_loop
rem1_large:
test ebx, 02h ; is denominator already saved
jnz already_saved1
fld tbyte ptr[esp + MAIN_DENOM]
fstp tbyte ptr[esp + MAIN_DENOM_SAVE] ; save denominator
already_saved1:
; Save user's precision control and institute 80. The fp ops in
; rem1_large_loop must not round to user's precision (if it is less
; than 80) because the hardware would not have done so. We are
; aping the hardware here, which is all extended.
 
fnstcw [esp+MAIN_PREV_CW] ; save caller's control word
mov eax, dword ptr[esp + MAIN_PREV_CW]
or eax, 033fh ; mask exceptions, pc=80
mov [esp + MAIN_PATCH_CW], eax
fldcw [esp + MAIN_PATCH_CW]
 
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
and eax, 07fffh ; clear sy
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
sub ebx, eax ; evaluate the exponent difference
and ebx, 03fh
or ebx, 020h
add ebx, 1
mov ecx, ebx
mov eax, [MAIN_DENOM+8+esp] ; sign and exponent of y (denominator)
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
and ebx, 07fffh ; clear sx
and eax, 08000h ; keep sy
or ebx, eax ; merge the sign of y
mov dword ptr[MAIN_DENOM+8+esp], ebx ; make ey equal to ex (scaled denominator)
fld tbyte ptr [MAIN_DENOM+esp] ; load the scaled denominator
fabs
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
fabs
rem1_large_loop:
fcom
fstsw ax
and eax, 00100h
jnz rem1_no_sub
fsub st, st(1)
rem1_no_sub:
fxch
fmul qword ptr half
fxch
sub ecx, 1 ; decrement the loop counter
jnz rem1_large_loop
mov ebx, [MAIN_NUMER+8+esp] ; sign and exponent of x (numerator)
fstp tbyte ptr[esp + MAIN_NUMER] ; save result
fstp st ; toss modified denom
fld tbyte ptr[esp + MAIN_DENOM_SAVE]
fld tbyte ptr[big_number] ; force C2 to be set
fprem1
fstp st
fld tbyte ptr[esp + MAIN_NUMER] ; restore saved result
 
fldcw [esp + MAIN_PREV_CW] ; restore caller's control word
and ebx, 08000h ; keep sx
jz rem1_done
fchs
jmp rem1_done
remainder1_hardware_ok:
fld tbyte ptr [MAIN_DENOM+esp] ; load the denominator
fld tbyte ptr [MAIN_NUMER+esp] ; load the numerator
fprem1 ; and finally do a remainder
; prem1_main_routine end
rem1_done:
test edx, 03h
jz rem1_exit
fnstsw [esp + MAIN_FPREM_SW] ; save Q0 Q1 and Q2
test edx, 01h
jz do_not_de_scale1
; De-scale the result. Go to pc=80 to prevent from fmul
; from user precision (fprem does not round the result).
fnstcw [esp + MAIN_PREV_CW] ; save callers control word
mov eax, [esp + MAIN_PREV_CW]
or eax, 0300h ; pc = 80
mov [esp + MAIN_PATCH_CW], eax
fldcw [esp + MAIN_PATCH_CW]
fmul qword ptr one_shr_64
fldcw [esp + MAIN_PREV_CW] ; restore callers CW
do_not_de_scale1:
mov eax, [esp + MAIN_FPREM_SW]
fxch
fstp st
fld tbyte ptr[esp + MAIN_DENOM_SAVE]
fxch
and eax, 04300h ; restore saved Q0, Q1, Q2
sub esp, ENV_SIZE
fnstenv [esp]
and [esp].STATUS_WORD, 0bcffh
or [esp].STATUS_WORD, eax
fldenv [esp]
add esp, ENV_SIZE
rem1_exit:
pop ecx
pop ebx
pop eax
CHECKSW ; debug only: save status
ret
fprem1_common ENDP
 
 
comment ~***************************************************************
;
; float frem1_chk (float numer, float denom)
;
public frem1_chk
frem1_chk PROC NEAR
push edx
sub esp, STACK_SIZE
fld dword ptr [STACK_SIZE+8+esp]
fstp tbyte ptr [NUMER+esp]
fld dword ptr [STACK_SIZE+12+esp]
fstp tbyte ptr [DENOM+esp]
mov edx, 0 ; dx = 1 if denormal extended divisor
call fprem1_common
fxch
fstp st
add esp, STACK_SIZE
pop edx
ret
frem1_chk ENDP
; end frem1_chk
 
;
; double drem1_chk (double numer, double denom)
;
public drem1_chk
drem1_chk PROC NEAR
push edx
sub esp, STACK_SIZE
fld qword ptr [STACK_SIZE+8+esp]
fstp tbyte ptr [NUMER+esp]
fld qword ptr [STACK_SIZE+16+esp]
fstp tbyte ptr [DENOM+esp]
mov edx, 0 ; dx = 1 if denormal extended divisor
call fprem1_common
fxch
fstp st
add esp, STACK_SIZE
pop edx
ret
 
drem1_chk ENDP
; end drem1_chk
 
;
; long double lrem1_chk(long double number,long double denom)
;
public lrem1_chk
lrem1_chk PROC NEAR
fld tbyte ptr [20+esp]
fld tbyte ptr [4+esp]
call fprem1_chk
fxch
fstp st
ret
lrem1_chk ENDP
********************************************************************~
 
;
; FPREM1: ST = remainder(ST, ST(1)) - IEEE version of rounding
;
; Compiler version of the FPREM must preserve the arguments in the floating
; point stack.
 
public __fprem1_chk
defpe __fprem1_chk
push edx
sub esp, STACK_SIZE
fstp tbyte ptr [NUMER+esp]
fstp tbyte ptr [DENOM+esp]
mov edx, 0
; prem1_main_routine begin
mov eax,[DENOM+6+esp] ; exponent and high 16 bits of mantissa
test eax,07fff0000h ; check for denormal
jz denormal1
call fprem1_common
add esp, STACK_SIZE
pop edx
ret
 
denormal1:
fld tbyte ptr [DENOM+esp] ; load the denominator
fld tbyte ptr [NUMER+esp] ; load the numerator
mov eax, [DENOM+esp] ; test for whole mantissa == 0
or eax, [DENOM+4+esp] ; test for whole mantissa == 0
jz remainder1_hardware_ok_l ; denominator is zero
fxch
fstp tbyte ptr[esp + DENOM_SAVE] ; save org denominator
fld tbyte ptr[esp + DENOM]
fxch
or edx, 02h
;
; For this we need pc=80. Also, mask exceptions so we don't take any
; denormal operand exceptions. It is guaranteed that the descaling
; later on will take underflow, which is what the hardware would have done
; on a normal fprem.
;
fnstcw [PREV_CW+esp] ; save caller's control word
mov eax, [PREV_CW+esp]
or eax, 0033fh ; mask exceptions, pc=80
mov [PATCH_CW+esp], eax
fldcw [PATCH_CW+esp] ; mask exceptions & pc=80
 
; The denominator is a denormal. For most numerators, scale both numerator
; and denominator to get rid of denormals. Then execute the common code
; with the flag set to indicate that the result must be de-scaled.
; For large numerators this won't work because the scaling would cause
; overflow. In this case we know the numerator is large, the denominator
; is small (denormal), so the exponent difference is also large. This means
; the rem1_large code will be used and this code depends on the difference
; in exponents modulo 64. Adding 64 to the denominators exponent
; doesn't change the modulo 64 difference. So we can scale the denominator
; by 64, making it not denormal, and this won't effect the result.
;
; To start with, figure out if numerator is large
 
mov eax, [esp + NUMER + 8] ; load numerator exponent
and eax, 7fffh ; isolate numerator exponent
cmp eax, 7fbeh ; compare Nexp to Maxexp-64
ja big_numer_rem1_de ; jif big numerator
 
; So the numerator is not large scale both numerator and denominator
 
or edx, 1 ; edx = 1, if denormal extended divisor
fmul qword ptr one_shl_64 ; make numerator not denormal
fstp tbyte ptr[esp + NUMER]
fmul qword ptr one_shl_64 ; make denominator not denormal
fstp tbyte ptr[esp + DENOM]
jmp scaling_done1
 
; The numerator is large. Scale only the denominator, which will not
; change the result which we know will be partial. Set the scale flag
; to false.
big_numer_rem1_de:
; We must do this with pc=80 to avoid rounding to single/double.
; In this case we do not mask exceptions so that we will take
; denormal operand, as would the hardware.
fnstcw [PREV_CW+esp] ; save caller's control word
mov eax, [PREV_CW+esp]
or eax, 00300h ; pc=80
mov [PATCH_CW+esp], eax
fldcw [PATCH_CW+esp] ; pc=80
 
fstp st ; Toss numerator
fmul qword ptr one_shl_64 ; make denominator not denormal
fstp tbyte ptr[esp + DENOM]
 
; Restore the control word which was fiddled to scale at 80-bit precision.
; Then call the common code.
scaling_done1:
fldcw [esp + PREV_CW] ; restore callers control word
call fprem1_common
add esp, STACK_SIZE
pop edx
ret
 
remainder1_hardware_ok_l:
fprem ; and finally do a remainder
 
CHECKSW
 
add esp, STACK_SIZE
pop edx
ret
__fprem1_chk ENDP
; end fprem1_chk
 
ifdef DEBUG
public fpinit
fpinit PROC NEAR
fninit
ret
fpinit ENDP
endif
 
CODE32 ENDS
END
/programs/develop/open watcom/trunk/clib/src/chipt32.asm
0,0 → 1,167
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
 
 
; static char sccs_id[] = "@(#)fptan32.asm 1.4 12/20/94 16:51:51";
;
; This code is being published by Intel to users of the Pentium(tm)
; processor. Recipients are authorized to copy, modify, compile, use and
; distribute the code.
;
; Intel makes no warranty of any kind with regard to this code, including
; but not limited to, implied warranties or merchantability and fitness for
; a particular purpose. Intel assumes no responsibility for any errors that
; may appear in this code.
;
; No patent licenses are granted, express or implied.
;
;
; The following code is a PRELIMINARY IMPLEMENTATION of a
; software patch for the floating point divide instructions.
;
;
include mdef.inc
 
.386
.387
 
PATCH_CW EQU 00ch
PREV_CW EQU 010h
COSINE EQU 0 ; These two are overlaid because they
ANGLE EQU 0 ; are not live at the same time.
 
 
STACK_SIZE EQU 014h
 
ONESMASK EQU 0e000000h
 
 
DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
 
fdiv_risk_table DB 0, 1, 0, 0, 4, 0, 0, 7, 0, 0, 10, 0, 0, 13, 0, 0
fdiv_scale DD 03f700000h ; 0.9375
one_shl_63 DD 05f000000h
 
DATA32 ENDS
 
DGROUP GROUP DATA32
 
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
 
 
assume cs:_TEXT, ds:DGROUP, es:DGROUP, ss:nothing
public __fptan_chk
 
;
; PRELIMINARY VERSION for register-register divides.
;
 
 
defpe __fptan_chk
 
push eax
sub esp, STACK_SIZE
fstp tbyte ptr [esp+ANGLE]
mov eax, [esp+ANGLE+8]
and eax, 07fffh
jz use_hardware ; denormals, ...
cmp eax, 07fffh
je use_hardware ; NaNs, infinities, ...
mov eax, [esp+ANGLE+4]
add eax, eax
jnc use_hardware ; unnormals (explicit 1 missing)
fld tbyte ptr [esp+ANGLE]
 
;
; Check for proper parameter range ( |<angle>| < 2^63)
;
fabs
fcomp one_shl_63
fstsw ax
sahf
jae use_hardware
 
fld tbyte ptr [esp+ANGLE]
fsincos
fstp tbyte ptr [esp+COSINE]
fld tbyte ptr [esp+COSINE] ; load the denominator (cos(x))
mov eax, [esp+COSINE+4] ; get mantissa bits 32-64
add eax,eax ; shift the one's bit onto carry
xor eax, ONESMASK ; invert the bits that must be ones
test eax, ONESMASK ; and make sure they are all ones
jz scale_if_needed ; if all are one scale numbers
fdivp st(1), st ; use of hardware is OK.
fld1 ; push 1.0 onto FPU stack
add esp, STACK_SIZE
pop eax
ret
 
scale_if_needed:
shr eax, 28 ; keep first 4 bits after point
cmp fdiv_risk_table[eax], ah ; check for (1,4,7,a,d)
jnz divide_scaled ; are in potential problem area
fdivp st(1), st ; use of hardware is OK.
fld1 ; push 1.0 onto FPU stack
add esp, STACK_SIZE
pop eax
ret
 
divide_scaled:
fwait ; catch preceding exceptions
fstcw [esp+PREV_CW] ; save caller's control word
mov eax, [esp+PREV_CW]
or eax, 033fh ; mask exceptions, pc=80
mov [esp+PATCH_CW], eax
fldcw [esp+PATCH_CW] ; mask exceptions & pc=80
fmul fdiv_scale ; scale denominator by 15/16
fxch
fmul fdiv_scale ; scale numerator by 15/16
fxch
 
; This assures correctly rounded result if pc=64 as well
 
fldcw [esp+PREV_CW] ; restore caller's control word
fdivp st(1), st ; use of hardware is OK.
fld1 ; push 1.0 onto FPU stack
add esp, STACK_SIZE
pop eax
ret
 
use_hardware:
fld tbyte ptr [esp+ANGLE]
fptan
add esp, STACK_SIZE
pop eax
ret
__fptan_chk ENDP
 
_TEXT ENDS
end
/programs/develop/open watcom/trunk/clib/src/chipvar.asm
0,0 → 1,47
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
 
 
include mdef.inc
 
xref "C",__verify_pentium_fdiv_bug
 
name chipvar
 
datasegment
xdefp ___chipbug
xdefp __chipbug
___chipbug label byte
__chipbug label byte
dd 0
enddata
 
end
/programs/develop/open watcom/trunk/clib/src/itoa.c
0,0 → 1,106
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of itoa() and utoa().
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include <stdlib.h>
 
extern const char __based(__segname("_CONST")) __Alphabet[];
 
unsigned __udiv( unsigned, unsigned _WCNEAR * );
#if defined(__386__)
#pragma aux __udiv = \
"xor edx,edx" \
"div dword ptr [ebx]" \
"mov [ebx],eax" \
parm caller [eax] [ebx] \
modify exact [eax edx] \
value [edx];
#elif defined(M_I86) && defined(__BIG_DATA__)
#pragma aux __udiv = \
"xor dx,dx" \
"div word ptr ss:[bx]" \
"mov ss:[bx],ax" \
parm caller [ax] [bx] \
modify exact [ax dx] \
value [dx];
#elif defined(M_I86) && defined(__SMALL_DATA__)
#pragma aux __udiv = \
"xor dx,dx" \
"div word ptr [bx]" \
"mov [bx],ax" \
parm caller [ax] [bx] \
modify exact [ax dx] \
value [dx];
#endif
 
 
_WCRTLINK CHAR_TYPE *__F_NAME(utoa,_utow)( unsigned value, CHAR_TYPE *buffer, int radix )
{
CHAR_TYPE *p = buffer;
char *q;
unsigned rem;
unsigned quot;
char buf[34]; // only holds ASCII so 'char' is OK
 
buf[0] = '\0';
q = &buf[1];
do {
#if defined(_M_IX86) && defined(__WATCOMC__)
quot = radix;
rem = __udiv( value, (unsigned _WCNEAR *) &quot );
#else
rem = value % radix;
quot = value / radix;
#endif
*q = __Alphabet[rem];
++q;
value = quot;
} while( value != 0 );
while( (*p++ = (CHAR_TYPE)*--q) )
;
return( buffer );
}
 
 
_WCRTLINK CHAR_TYPE *__F_NAME(itoa,_itow)( int value, CHAR_TYPE *buffer, int radix )
{
CHAR_TYPE *p = buffer;
 
if( radix == 10 ) {
if( value < 0 ) {
*p++ = '-';
value = - value;
}
}
__F_NAME(utoa,_utow)( value, p, radix );
return( buffer );
}
/programs/develop/open watcom/trunk/clib/src/lltoa.c
0,0 → 1,212
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Long long integer to ASCII conversion routines.
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include "watcom.h"
#include "clibi64.h"
#include <stdlib.h>
 
extern const char __based(__segname("_CONST")) __Alphabet[];
 
#if defined(__386__) || defined(M_I86)
unsigned long long __ulldiv( unsigned long long, unsigned _WCNEAR *);
#if defined(__386__)
#pragma aux __ulldiv = \
"xor ecx,ecx" /* set high word of quotient to 0 */ \
"cmp edx,dword ptr[ebx]" /* if quotient will be >= 4G */ \
"jb less4g" /* then */ \
"mov ecx,eax" /* - save low word of dividend */ \
"mov eax,edx" /* - get high word of dividend */ \
"xor edx,edx" /* - zero high part */ \
"div dword ptr[ebx]" /* - divide into high part of dividend */ \
"xchg eax,ecx" /* - swap high part of quot,low word of dvdnd */ \
"less4g:" \
"div dword ptr[ebx]" /* calculate low part */ \
"mov [ebx],edx" /* store remainder */ \
parm [eax edx] [ebx] value [eax ecx];
#elif defined(M_I86) && defined(__BIG_DATA__)
#pragma aux __ulldiv = \
"mov di,dx" /* initial dividend = ax:bx:cx:dx(di); save dx */ \
"test ax,ax" /* less work to do if ax == 0 */ \
"jz skip1" \
"mov dx,ax" /* dx:ax = ax:bx */ \
"mov ax,bx" \
"xor bx,bx" /* set word 3 of quotient to 0 */ \
"cmp dx,word ptr ss:[si]" /* if quotient will be >= 64K */ \
"jb div2" /* then */ \
"mov bx,ax" /* restore word 2 of dividend */ \
"mov ax,dx" /* restore word 3 of dividend */ \
"xor dx,dx" /* - zero high part */ \
"div word ptr ss:[si]" /* - divide into word 3 of dividend */ \
"xchg ax,bx" /* - swap word 3,word 2 of dvdnd */ \
"div2:" \
"div word ptr ss:[si]" /* - divide into word 2 of dividend */ \
"xchg ax,cx" /* - swap word 2,word 1 of dvdnd */ \
"div3:" \
"div word ptr ss:[si]" /* - divide into word 1 of dividend */ \
"xchg ax,di" /* - swap word 1,word 0 of dvdnd */ \
"div4:" \
"div word ptr ss:[si]" /* calculate low part */ \
"mov ss:[si],dx" /* store remainder */ \
"mov dx,ax" /* dx is word 0 */ \
"mov ax,bx" /* ax:bx:cx:dx = bx:cx:di:ax */ \
"mov bx,cx" \
"mov cx,di" \
"jmp end_div" \
"skip1:" /* ax==0 */ \
"test bx,bx" /* even less work to do if bx == 0 too */ \
"jz skip2" \
"mov dx,bx" /* dx:ax = bx:cx */ \
"mov ax,cx" \
"xor bx,bx" /* set word 3 of quotient to 0 */ \
"xor cx,cx" /* set word 2 of quotient to 0 */ \
"cmp dx,word ptr ss:[si]" /* if quotient will be < 64K */ \
"jb div3" /* then need to do two divisions */ \
"mov cx,ax" /* restore word 1 of dividend */ \
"mov ax,dx" /* restore word 2 of dividend */ \
"xor dx,dx" /* zero high part */ \
"jmp div2" /* do three divisions*/ \
"skip2:" /* ax==bx==0 */ \
"mov dx,cx" /* dx:ax = cx:di */ \
"mov ax,di" \
"xor cx,cx" /* set word 2 of quotient to 0 */ \
"xor di,di" /* set word 1 of quotient to 0 */ \
"cmp dx,word ptr ss:[si]" /* if quotient will be < 64K */ \
"jb div4" /* then only one division to do */ \
"mov di,ax" /* restore word 0 of dividend */ \
"mov ax,dx" /* restore word 1 of dividend */ \
"xor dx,dx" /* zero high part */ \
"jmp div3" /* do two divisions */ \
"end_div:" \
parm [ax bx cx dx] [si] modify [di] value [ax bx cx dx];
#elif defined(M_I86) && defined(__SMALL_DATA__)
#pragma aux __ulldiv = \
"mov di,dx" /* initial dividend = ax:bx:cx:dx(di); save dx */ \
"test ax,ax" /* less work to do if ax == 0 */ \
"jz skip1" \
"mov dx,ax" /* dx:ax = ax:bx */ \
"mov ax,bx" \
"xor bx,bx" /* set word 3 of quotient to 0 */ \
"cmp dx,word ptr[si]" /* if quotient will be >= 64K */ \
"jb div2" /* then */ \
"mov bx,ax" /* restore word 2 of dividend */ \
"mov ax,dx" /* restore word 3 of dividend */ \
"xor dx,dx" /* - zero high part */ \
"div word ptr[si]" /* - divide into word 3 of dividend */ \
"xchg ax,bx" /* - swap word 3,word 2 of dvdnd */ \
"div2:" \
"div word ptr[si]" /* - divide into word 2 of dividend */ \
"xchg ax,cx" /* - swap word 2,word 1 of dvdnd */ \
"div3:" \
"div word ptr[si]" /* - divide into word 1 of dividend */ \
"xchg ax,di" /* - swap word 1,word 0 of dvdnd */ \
"div4:" \
"div word ptr[si]" /* calculate low part */ \
"mov [si],dx" /* store remainder */ \
"mov dx,ax" /* dx is word 0 */ \
"mov ax,bx" /* ax:bx:cx:dx = bx:cx:di:ax */ \
"mov bx,cx" \
"mov cx,di" \
"jmp end_div" \
"skip1:" /* dx==0 */ \
"test bx,bx" /* even less work to do if bx == 0 too */ \
"jz skip2" \
"mov dx,bx" /* dx:ax = bx:cx */ \
"mov ax,cx" \
"xor bx,bx" /* set word 3 of quotient to 0 */ \
"xor cx,cx" /* set word 2 of quotient to 0 */ \
"cmp dx,word ptr[si]" /* if quotient will be < 64K */ \
"jb div3" /* then need to do two divisions */ \
"mov cx,ax" /* restore word 1 of dividend */ \
"mov ax,dx" /* restore word 2 of dividend */ \
"xor dx,dx" /* zero high part */ \
"jmp div2" /* do three divisions*/ \
"skip2:" /* ax==bx==0 */ \
"mov dx,cx" /* dx:ax = cx:di */ \
"mov ax,di" \
"xor cx,cx" /* set word 2 of quotient to 0 */ \
"xor di,di" /* set word 1 of quotient to 0 */ \
"cmp dx,word ptr[si]" /* if quotient will be < 64K */ \
"jb div4" /* then only one division to do */ \
"mov di,ax" /* restore word 0 of dividend */ \
"mov ax,dx" /* restore word 1 of dividend */ \
"xor dx,dx" /* zero high part */ \
"jmp div3" /* do two divisions */ \
"end_div:" \
parm [ax bx cx dx] [si] modify [di] value [ax bx cx dx];
#endif
#endif
 
_WCRTLINK CHAR_TYPE *__F_NAME(ulltoa,_ulltow)(
unsigned long long int value,
CHAR_TYPE *buffer,
int radix )
{
CHAR_TYPE *p = buffer;
char *q;
unsigned rem;
auto char buf[66]; // only holds ASCII so 'char' is OK
 
buf[0] = '\0';
q = &buf[1];
do {
#if defined(__386__) || defined(M_I86)
rem = radix;
value = __ulldiv( value, (unsigned _WCNEAR *) &rem );
#else
rem = value % radix;
value = value / radix;
#endif
*q = __Alphabet[ rem ];
++q;
} while( value );
while( *p++ = (CHAR_TYPE)*--q );
return( buffer );
}
 
 
_WCRTLINK CHAR_TYPE *__F_NAME(lltoa,_lltow)(
long long int value,
CHAR_TYPE *buffer,
int radix )
{
register CHAR_TYPE *p = buffer;
 
if( radix == 10 ) {
if( value < 0 ) {
*p++ = '-';
value = -value;
}
}
__F_NAME(ulltoa,_ulltow)( value, p, radix );
return( buffer );
}
/programs/develop/open watcom/trunk/clib/src/ltoa.c
0,0 → 1,120
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of ltoa().
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include <stdlib.h>
 
extern const char __based(__segname("_CONST")) __Alphabet[];
 
unsigned long __uldiv( unsigned long, unsigned _WCNEAR * );
#if defined(__386__)
#pragma aux __uldiv = \
"xor edx,edx" \
"div dword ptr [ebx]" \
"mov [ebx],edx" \
parm caller [eax] [ebx] \
modify exact [eax edx] \
value [eax];
#elif defined(M_I86) && defined(__BIG_DATA__)
#pragma aux __uldiv = \
"xor cx,cx" \
"cmp dx,ss:[bx]" \
"jb short SMALL_ENOUGH" \
"xchg ax,dx" \
"xchg cx,dx" \
"div word ptr ss:[bx]" \
"xchg ax,cx" \
"SMALL_ENOUGH:" \
"div word ptr ss:[bx]" \
"mov ss:[bx],dx" \
"mov dx,cx" \
parm caller [ax dx] [bx] \
modify exact [ax cx dx] \
value [ax dx];
#elif defined(M_I86) && defined(__SMALL_DATA__)
#pragma aux __uldiv = \
"xor cx,cx" \
"cmp dx,[bx]" \
"jb short SMALL_ENOUGH" \
"xchg ax,dx" \
"xchg cx,dx" \
"div word ptr [bx]" \
"xchg ax,cx" \
"SMALL_ENOUGH:" \
"div word ptr [bx]" \
"mov [bx],dx" \
"mov dx,cx" \
parm caller [ax dx] [bx] \
modify exact [ax cx dx] \
value [ax dx];
#endif
 
 
_WCRTLINK CHAR_TYPE *__F_NAME(ultoa,_ultow)( unsigned long value, CHAR_TYPE *buffer, int radix )
{
CHAR_TYPE *p = buffer;
char *q;
unsigned rem;
char buf[34]; // only holds ASCII so 'char' is OK
 
buf[0] = '\0';
q = &buf[1];
do {
#if defined(_M_IX86) && defined(__WATCOMC__)
rem = radix;
value = __uldiv( value, (unsigned _WCNEAR *) &rem );
#else
rem = value % radix;
value = value / radix;
#endif
*q = __Alphabet[rem];
++q;
} while( value != 0 );
while( (*p++ = (CHAR_TYPE)*--q) )
;
return( buffer );
}
 
 
_WCRTLINK CHAR_TYPE *__F_NAME(ltoa,_ltow)( long value, CHAR_TYPE *buffer, int radix )
{
CHAR_TYPE *p = buffer;
 
if( radix == 10 ) {
if( value < 0 ) {
*p++ = '-';
value = - value;
}
}
__F_NAME(ultoa,_ultow)( value, p, radix );
return( buffer );
}
/programs/develop/open watcom/trunk/clib/src/tolower.c
0,0 → 1,45
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of tolower().
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include <ctype.h>
#ifdef __WIDECHAR__
#include <wchar.h>
#endif
 
_WCRTLINK INTCHAR_TYPE __F_NAME(tolower,towlower)( INTCHAR_TYPE c )
{
if( c >= 'A' && c <= 'Z' ) {
c = c - 'A' + 'a';
}
return( c );
}
/programs/develop/open watcom/trunk/clib/src/toupper.c
0,0 → 1,46
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of toupper().
*
****************************************************************************/
 
 
#include "variety.h"
#include "widechar.h"
#include <ctype.h>
#ifdef __WIDECHAR__
#include <wchar.h>
#endif
 
_WCRTLINK INTCHAR_TYPE __F_NAME(toupper,towupper)( INTCHAR_TYPE c )
{
if( c >= 'a' && c <= 'z' ) {
c = c - 'a' + 'A';
}
return( c );
}