/programs/network/netsurf/netsurf/objs/divdi3.c |
---|
0,0 → 1,345 |
/* 64-bit multiplication and division |
Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003, 2004 |
Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
The GNU C Library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
The GNU C Library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
You should have received a copy of the GNU Lesser General Public |
License along with the GNU C Library; if not, write to the Free |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
02111-1307 USA. */ |
#include <endian.h> |
#include <stdlib.h> |
#define __WORDSIZE 32 |
#define __i386__ |
#if __WORDSIZE == 32 |
typedef unsigned int UQItype __attribute__ ((mode (QI))); |
typedef int SItype __attribute__ ((mode (SI))); |
typedef unsigned int USItype __attribute__ ((mode (SI))); |
typedef int DItype __attribute__ ((mode (DI))); |
typedef unsigned int UDItype __attribute__ ((mode (DI))); |
#define Wtype SItype |
#define HWtype SItype |
#define DWtype DItype |
#define UWtype USItype |
#define UHWtype USItype |
#define UDWtype UDItype |
#define W_TYPE_SIZE 32 |
#include "longlong.h" |
const |
unsigned char __clz_tab[] = |
{ |
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, |
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
}; |
#if __BYTE_ORDER == __BIG_ENDIAN |
struct DWstruct { Wtype high, low;}; |
#elif __BYTE_ORDER == __LITTLE_ENDIAN |
struct DWstruct { Wtype low, high;}; |
#else |
#error Unhandled endianity |
#endif |
typedef union { struct DWstruct s; DWtype ll; } DWunion; |
/* Prototypes of exported functions. */ |
extern DWtype __divdi3 (DWtype u, DWtype v); |
extern DWtype __moddi3 (DWtype u, DWtype v); |
extern UDWtype __udivdi3 (UDWtype u, UDWtype v); |
extern UDWtype __umoddi3 (UDWtype u, UDWtype v); |
static UDWtype |
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) |
{ |
DWunion ww; |
DWunion nn, dd; |
DWunion rr; |
UWtype d0, d1, n0, n1, n2; |
UWtype q0, q1; |
UWtype b, bm; |
nn.ll = n; |
dd.ll = d; |
d0 = dd.s.low; |
d1 = dd.s.high; |
n0 = nn.s.low; |
n1 = nn.s.high; |
#if !UDIV_NEEDS_NORMALIZATION |
if (d1 == 0) |
{ |
if (d0 > n1) |
{ |
/* 0q = nn / 0D */ |
udiv_qrnnd (q0, n0, n1, n0, d0); |
q1 = 0; |
/* Remainder in n0. */ |
} |
else |
{ |
/* qq = NN / 0d */ |
if (d0 == 0) |
d0 = 1 / d0; /* Divide intentionally by zero. */ |
udiv_qrnnd (q1, n1, 0, n1, d0); |
udiv_qrnnd (q0, n0, n1, n0, d0); |
/* Remainder in n0. */ |
} |
if (rp != 0) |
{ |
rr.s.low = n0; |
rr.s.high = 0; |
*rp = rr.ll; |
} |
} |
#else /* UDIV_NEEDS_NORMALIZATION */ |
if (d1 == 0) |
{ |
if (d0 > n1) |
{ |
/* 0q = nn / 0D */ |
count_leading_zeros (bm, d0); |
if (bm != 0) |
{ |
/* Normalize, i.e. make the most significant bit of the |
denominator set. */ |
d0 = d0 << bm; |
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); |
n0 = n0 << bm; |
} |
udiv_qrnnd (q0, n0, n1, n0, d0); |
q1 = 0; |
/* Remainder in n0 >> bm. */ |
} |
else |
{ |
/* qq = NN / 0d */ |
if (d0 == 0) |
d0 = 1 / d0; /* Divide intentionally by zero. */ |
count_leading_zeros (bm, d0); |
if (bm == 0) |
{ |
/* From (n1 >= d0) /\ (the most significant bit of d0 is set), |
conclude (the most significant bit of n1 is set) /\ (the |
leading quotient digit q1 = 1). |
This special case is necessary, not an optimization. |
(Shifts counts of W_TYPE_SIZE are undefined.) */ |
n1 -= d0; |
q1 = 1; |
} |
else |
{ |
/* Normalize. */ |
b = W_TYPE_SIZE - bm; |
d0 = d0 << bm; |
n2 = n1 >> b; |
n1 = (n1 << bm) | (n0 >> b); |
n0 = n0 << bm; |
udiv_qrnnd (q1, n1, n2, n1, d0); |
} |
/* n1 != d0... */ |
udiv_qrnnd (q0, n0, n1, n0, d0); |
/* Remainder in n0 >> bm. */ |
} |
if (rp != 0) |
{ |
rr.s.low = n0 >> bm; |
rr.s.high = 0; |
*rp = rr.ll; |
} |
} |
#endif /* UDIV_NEEDS_NORMALIZATION */ |
else |
{ |
if (d1 > n1) |
{ |
/* 00 = nn / DD */ |
q0 = 0; |
q1 = 0; |
/* Remainder in n1n0. */ |
if (rp != 0) |
{ |
rr.s.low = n0; |
rr.s.high = n1; |
*rp = rr.ll; |
} |
} |
else |
{ |
/* 0q = NN / dd */ |
count_leading_zeros (bm, d1); |
if (bm == 0) |
{ |
/* From (n1 >= d1) /\ (the most significant bit of d1 is set), |
conclude (the most significant bit of n1 is set) /\ (the |
quotient digit q0 = 0 or 1). |
This special case is necessary, not an optimization. */ |
/* The condition on the next line takes advantage of that |
n1 >= d1 (true due to program flow). */ |
if (n1 > d1 || n0 >= d0) |
{ |
q0 = 1; |
sub_ddmmss (n1, n0, n1, n0, d1, d0); |
} |
else |
q0 = 0; |
q1 = 0; |
if (rp != 0) |
{ |
rr.s.low = n0; |
rr.s.high = n1; |
*rp = rr.ll; |
} |
} |
else |
{ |
UWtype m1, m0; |
/* Normalize. */ |
b = W_TYPE_SIZE - bm; |
d1 = (d1 << bm) | (d0 >> b); |
d0 = d0 << bm; |
n2 = n1 >> b; |
n1 = (n1 << bm) | (n0 >> b); |
n0 = n0 << bm; |
udiv_qrnnd (q0, n1, n2, n1, d1); |
umul_ppmm (m1, m0, q0, d0); |
if (m1 > n1 || (m1 == n1 && m0 > n0)) |
{ |
q0--; |
sub_ddmmss (m1, m0, m1, m0, d1, d0); |
} |
q1 = 0; |
/* Remainder in (n1n0 - m1m0) >> bm. */ |
if (rp != 0) |
{ |
sub_ddmmss (n1, n0, n1, n0, m1, m0); |
rr.s.low = (n1 << b) | (n0 >> bm); |
rr.s.high = n1 >> bm; |
*rp = rr.ll; |
} |
} |
} |
} |
ww.s.low = q0; |
ww.s.high = q1; |
return ww.ll; |
} |
DWtype |
__divdi3 (DWtype u, DWtype v) |
{ |
Wtype c = 0; |
DWtype w; |
if (u < 0) |
{ |
c = ~c; |
u = -u; |
} |
if (v < 0) |
{ |
c = ~c; |
v = -v; |
} |
w = __udivmoddi4 (u, v, NULL); |
if (c) |
w = -w; |
return w; |
} |
DWtype |
__moddi3 (DWtype u, DWtype v) |
{ |
Wtype c = 0; |
DWtype w; |
if (u < 0) |
{ |
c = ~c; |
u = -u; |
} |
if (v < 0) |
v = -v; |
__udivmoddi4 (u, v, &w); |
if (c) |
w = -w; |
return w; |
} |
UDWtype |
__udivdi3 (UDWtype u, UDWtype v) |
{ |
return __udivmoddi4 (u, v, NULL); |
} |
UDWtype |
__umoddi3 (UDWtype u, UDWtype v) |
{ |
UDWtype w; |
__udivmoddi4 (u, v, &w); |
return w; |
} |
#endif |
/programs/network/netsurf/netsurf/objs/longlong.h |
---|
0,0 → 1,1333 |
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. |
Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 |
Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
The GNU C Library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
The GNU C Library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
You should have received a copy of the GNU Lesser General Public |
License along with the GNU C Library; if not, write to the Free |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
02111-1307 USA. */ |
/* You have to define the following before including this file: |
UWtype -- An unsigned type, default type for operations (typically a "word") |
UHWtype -- An unsigned type, at least half the size of UWtype. |
UDWtype -- An unsigned type, at least twice as large a UWtype |
W_TYPE_SIZE -- size in bits of UWtype |
UQItype -- Unsigned 8 bit type. |
SItype, USItype -- Signed and unsigned 32 bit types. |
DItype, UDItype -- Signed and unsigned 64 bit types. |
On a 32 bit machine UWtype should typically be USItype; |
on a 64 bit machine, UWtype should typically be UDItype. |
*/ |
#define __BITS4 (W_TYPE_SIZE / 4) |
#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) |
#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) |
#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) |
#ifndef W_TYPE_SIZE |
#define W_TYPE_SIZE 32 |
#define UWtype USItype |
#define UHWtype USItype |
#define UDWtype UDItype |
#endif |
/* Define auxiliary asm macros. |
1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two |
UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype |
word product in HIGH_PROD and LOW_PROD. |
2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a |
UDWtype product. This is just a variant of umul_ppmm. |
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, |
denominator) divides a UDWtype, composed by the UWtype integers |
HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient |
in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less |
than DENOMINATOR for correct operation. If, in addition, the most |
significant bit of DENOMINATOR must be 1, then the pre-processor symbol |
UDIV_NEEDS_NORMALIZATION is defined to 1. |
4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, |
denominator). Like udiv_qrnnd but the numbers are signed. The quotient |
is rounded towards 0. |
5) count_leading_zeros(count, x) counts the number of zero-bits from the |
msb to the first nonzero bit in the UWtype X. This is the number of |
steps X needs to be shifted left to set the msb. Undefined for X == 0, |
unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. |
6) count_trailing_zeros(count, x) like count_leading_zeros, but counts |
from the least significant end. |
7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, |
high_addend_2, low_addend_2) adds two UWtype integers, composed by |
HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 |
respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow |
(i.e. carry out) is not stored anywhere, and is lost. |
8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, |
high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, |
composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and |
LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE |
and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, |
and is lost. |
If any of these macros are left undefined for a particular CPU, |
C macros are used. */ |
/* The CPUs come in alphabetical order below. |
Please add support for more CPUs here, or improve the current support |
for the CPUs below! |
(E.g. WE32100, IBM360.) */ |
#if defined (__GNUC__) && !defined (NO_ASM) |
/* We sometimes need to clobber "cc" with gcc2, but that would not be |
understood by gcc1. Use cpp to avoid major code duplication. */ |
#if __GNUC__ < 2 |
#define __CLOBBER_CC |
#define __AND_CLOBBER_CC |
#else /* __GNUC__ >= 2 */ |
#define __CLOBBER_CC : "cc" |
#define __AND_CLOBBER_CC , "cc" |
#endif /* __GNUC__ < 2 */ |
#if defined (__alpha) && W_TYPE_SIZE == 64 |
#define umul_ppmm(ph, pl, m0, m1) \ |
do { \ |
UDItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("umulh %r1,%2,%0" \ |
: "=r" ((UDItype) ph) \ |
: "%rJ" (__m0), \ |
"rI" (__m1)); \ |
(pl) = __m0 * __m1; \ |
} while (0) |
#define UMUL_TIME 46 |
#ifndef LONGLONG_STANDALONE |
#define udiv_qrnnd(q, r, n1, n0, d) \ |
do { UDItype __r; \ |
(q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ |
(r) = __r; \ |
} while (0) |
extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); |
#define UDIV_TIME 220 |
#endif /* LONGLONG_STANDALONE */ |
#ifdef __alpha_cix__ |
#define count_leading_zeros(COUNT,X) \ |
__asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X)) |
#define count_trailing_zeros(COUNT,X) \ |
__asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X)) |
#define COUNT_LEADING_ZEROS_0 64 |
#else |
extern const UQItype __clz_tab[]; |
#define count_leading_zeros(COUNT,X) \ |
do { \ |
UDItype __xr = (X), __t, __a; \ |
__asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ |
__a = __clz_tab[__t ^ 0xff] - 1; \ |
__asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ |
(COUNT) = 64 - (__clz_tab[__t] + __a*8); \ |
} while (0) |
#define count_trailing_zeros(COUNT,X) \ |
do { \ |
UDItype __xr = (X), __t, __a; \ |
__asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ |
__t = ~__t & -~__t; \ |
__a = ((__t & 0xCC) != 0) * 2; \ |
__a += ((__t & 0xF0) != 0) * 4; \ |
__a += ((__t & 0xAA) != 0); \ |
__asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ |
__a <<= 3; \ |
__t &= -__t; \ |
__a += ((__t & 0xCC) != 0) * 2; \ |
__a += ((__t & 0xF0) != 0) * 4; \ |
__a += ((__t & 0xAA) != 0); \ |
(COUNT) = __a; \ |
} while (0) |
#endif /* __alpha_cix__ */ |
#endif /* __alpha */ |
#if defined (__arc__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%r" ((USItype) (ah)), \ |
"rIJ" ((USItype) (bh)), \ |
"%r" ((USItype) (al)), \ |
"rIJ" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "r" ((USItype) (ah)), \ |
"rIJ" ((USItype) (bh)), \ |
"r" ((USItype) (al)), \ |
"rIJ" ((USItype) (bl))) |
/* Call libgcc routine. */ |
#define umul_ppmm(w1, w0, u, v) \ |
do { \ |
DWunion __w; \ |
__w.ll = __umulsidi3 (u, v); \ |
w1 = __w.s.high; \ |
w0 = __w.s.low; \ |
} while (0) |
#define __umulsidi3 __umulsidi3 |
UDItype __umulsidi3 (USItype, USItype); |
#endif |
#if defined (__arm__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%r" ((USItype) (ah)), \ |
"rI" ((USItype) (bh)), \ |
"%r" ((USItype) (al)), \ |
"rI" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "r" ((USItype) (ah)), \ |
"rI" ((USItype) (bh)), \ |
"r" ((USItype) (al)), \ |
"rI" ((USItype) (bl))) |
#define umul_ppmm(xh, xl, a, b) \ |
{register USItype __t0, __t1, __t2; \ |
__asm__ ("%@ Inlined umul_ppmm\n" \ |
" mov %2, %5, lsr #16\n" \ |
" mov %0, %6, lsr #16\n" \ |
" bic %3, %5, %2, lsl #16\n" \ |
" bic %4, %6, %0, lsl #16\n" \ |
" mul %1, %3, %4\n" \ |
" mul %4, %2, %4\n" \ |
" mul %3, %0, %3\n" \ |
" mul %0, %2, %0\n" \ |
" adds %3, %4, %3\n" \ |
" addcs %0, %0, #65536\n" \ |
" adds %1, %1, %3, lsl #16\n" \ |
" adc %0, %0, %3, lsr #16" \ |
: "=&r" ((USItype) (xh)), \ |
"=r" ((USItype) (xl)), \ |
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ |
: "r" ((USItype) (a)), \ |
"r" ((USItype) (b)));} |
#define UMUL_TIME 20 |
#define UDIV_TIME 100 |
#endif /* __arm__ */ |
#if defined (__hppa) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%rM" ((USItype) (ah)), \ |
"rM" ((USItype) (bh)), \ |
"%rM" ((USItype) (al)), \ |
"rM" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "rM" ((USItype) (ah)), \ |
"rM" ((USItype) (bh)), \ |
"rM" ((USItype) (al)), \ |
"rM" ((USItype) (bl))) |
#if defined (_PA_RISC1_1) |
#define umul_ppmm(w1, w0, u, v) \ |
do { \ |
union \ |
{ \ |
UDItype __f; \ |
struct {USItype __w1, __w0;} __w1w0; \ |
} __t; \ |
__asm__ ("xmpyu %1,%2,%0" \ |
: "=x" (__t.__f) \ |
: "x" ((USItype) (u)), \ |
"x" ((USItype) (v))); \ |
(w1) = __t.__w1w0.__w1; \ |
(w0) = __t.__w1w0.__w0; \ |
} while (0) |
#define UMUL_TIME 8 |
#else |
#define UMUL_TIME 30 |
#endif |
#define UDIV_TIME 40 |
#define count_leading_zeros(count, x) \ |
do { \ |
USItype __tmp; \ |
__asm__ ( \ |
"ldi 1,%0\n" \ |
" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ |
" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ |
" ldo 16(%0),%0 ; Yes. Perform add.\n" \ |
" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ |
" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ |
" ldo 8(%0),%0 ; Yes. Perform add.\n" \ |
" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ |
" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ |
" ldo 4(%0),%0 ; Yes. Perform add.\n" \ |
" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ |
" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ |
" ldo 2(%0),%0 ; Yes. Perform add.\n" \ |
" extru %1,30,1,%1 ; Extract bit 1.\n" \ |
" sub %0,%1,%0 ; Subtract it.\n" \ |
: "=r" (count), "=r" (__tmp) : "1" (x)); \ |
} while (0) |
#endif |
#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 |
#define umul_ppmm(xh, xl, m0, m1) \ |
do { \ |
union {UDItype __ll; \ |
struct {USItype __h, __l;} __i; \ |
} __xx; \ |
USItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mr %0,%3" \ |
: "=r" (__xx.__i.__h), \ |
"=r" (__xx.__i.__l) \ |
: "%1" (__m0), \ |
"r" (__m1)); \ |
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ |
(xh) += ((((SItype) __m0 >> 31) & __m1) \ |
+ (((SItype) __m1 >> 31) & __m0)); \ |
} while (0) |
#define smul_ppmm(xh, xl, m0, m1) \ |
do { \ |
union {DItype __ll; \ |
struct {USItype __h, __l;} __i; \ |
} __xx; \ |
__asm__ ("mr %0,%3" \ |
: "=r" (__xx.__i.__h), \ |
"=r" (__xx.__i.__l) \ |
: "%1" (m0), \ |
"r" (m1)); \ |
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ |
} while (0) |
#define sdiv_qrnnd(q, r, n1, n0, d) \ |
do { \ |
union {DItype __ll; \ |
struct {USItype __h, __l;} __i; \ |
} __xx; \ |
__xx.__i.__h = n1; __xx.__i.__l = n0; \ |
__asm__ ("dr %0,%2" \ |
: "=r" (__xx.__ll) \ |
: "0" (__xx.__ll), "r" (d)); \ |
(q) = __xx.__i.__l; (r) = __xx.__i.__h; \ |
} while (0) |
#endif |
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("addl %5,%1\n\tadcl %3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%0" ((USItype) (ah)), \ |
"g" ((USItype) (bh)), \ |
"%1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subl %5,%1\n\tsbbl %3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "0" ((USItype) (ah)), \ |
"g" ((USItype) (bh)), \ |
"1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("mull %3" \ |
: "=a" ((USItype) (w0)), \ |
"=d" ((USItype) (w1)) \ |
: "%0" ((USItype) (u)), \ |
"rm" ((USItype) (v))) |
#define udiv_qrnnd(q, r, n1, n0, dv) \ |
__asm__ ("divl %4" \ |
: "=a" ((USItype) (q)), \ |
"=d" ((USItype) (r)) \ |
: "0" ((USItype) (n0)), \ |
"1" ((USItype) (n1)), \ |
"rm" ((USItype) (dv))) |
#define count_leading_zeros(count, x) \ |
do { \ |
USItype __cbtmp; \ |
__asm__ ("bsrl %1,%0" \ |
: "=r" (__cbtmp) : "rm" ((USItype) (x))); \ |
(count) = __cbtmp ^ 31; \ |
} while (0) |
#define count_trailing_zeros(count, x) \ |
__asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) |
#define UMUL_TIME 40 |
#define UDIV_TIME 40 |
#endif /* 80x86 */ |
#if defined (__i960__) && W_TYPE_SIZE == 32 |
#define umul_ppmm(w1, w0, u, v) \ |
({union {UDItype __ll; \ |
struct {USItype __l, __h;} __i; \ |
} __xx; \ |
__asm__ ("emul %2,%1,%0" \ |
: "=d" (__xx.__ll) \ |
: "%dI" ((USItype) (u)), \ |
"dI" ((USItype) (v))); \ |
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) |
#define __umulsidi3(u, v) \ |
({UDItype __w; \ |
__asm__ ("emul %2,%1,%0" \ |
: "=d" (__w) \ |
: "%dI" ((USItype) (u)), \ |
"dI" ((USItype) (v))); \ |
__w; }) |
#endif /* __i960__ */ |
#if defined (__M32R__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
/* The cmp clears the condition bit. */ \ |
__asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%0" ((USItype) (ah)), \ |
"r" ((USItype) (bh)), \ |
"%1" ((USItype) (al)), \ |
"r" ((USItype) (bl)) \ |
: "cbit") |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
/* The cmp clears the condition bit. */ \ |
__asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "0" ((USItype) (ah)), \ |
"r" ((USItype) (bh)), \ |
"1" ((USItype) (al)), \ |
"r" ((USItype) (bl)) \ |
: "cbit") |
#endif /* __M32R__ */ |
#if defined (__mc68000__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ |
: "=d" ((USItype) (sh)), \ |
"=&d" ((USItype) (sl)) \ |
: "%0" ((USItype) (ah)), \ |
"d" ((USItype) (bh)), \ |
"%1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ |
: "=d" ((USItype) (sh)), \ |
"=&d" ((USItype) (sl)) \ |
: "0" ((USItype) (ah)), \ |
"d" ((USItype) (bh)), \ |
"1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */ |
#if defined (__mc68020__) || defined(mc68020) \ |
|| defined(__mc68030__) || defined(mc68030) \ |
|| defined(__mc68040__) || defined(mc68040) \ |
|| defined(__mcpu32__) || defined(mcpu32) |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("mulu%.l %3,%1:%0" \ |
: "=d" ((USItype) (w0)), \ |
"=d" ((USItype) (w1)) \ |
: "%0" ((USItype) (u)), \ |
"dmi" ((USItype) (v))) |
#define UMUL_TIME 45 |
#define udiv_qrnnd(q, r, n1, n0, d) \ |
__asm__ ("divu%.l %4,%1:%0" \ |
: "=d" ((USItype) (q)), \ |
"=d" ((USItype) (r)) \ |
: "0" ((USItype) (n0)), \ |
"1" ((USItype) (n1)), \ |
"dmi" ((USItype) (d))) |
#define UDIV_TIME 90 |
#define sdiv_qrnnd(q, r, n1, n0, d) \ |
__asm__ ("divs%.l %4,%1:%0" \ |
: "=d" ((USItype) (q)), \ |
"=d" ((USItype) (r)) \ |
: "0" ((USItype) (n0)), \ |
"1" ((USItype) (n1)), \ |
"dmi" ((USItype) (d))) |
#else /* not mc68020 */ |
#if !defined(__mcf5200__) |
/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ |
#define umul_ppmm(xh, xl, a, b) \ |
__asm__ ("| Inlined umul_ppmm\n" \ |
" move%.l %2,%/d0\n" \ |
" move%.l %3,%/d1\n" \ |
" move%.l %/d0,%/d2\n" \ |
" swap %/d0\n" \ |
" move%.l %/d1,%/d3\n" \ |
" swap %/d1\n" \ |
" move%.w %/d2,%/d4\n" \ |
" mulu %/d3,%/d4\n" \ |
" mulu %/d1,%/d2\n" \ |
" mulu %/d0,%/d3\n" \ |
" mulu %/d0,%/d1\n" \ |
" move%.l %/d4,%/d0\n" \ |
" eor%.w %/d0,%/d0\n" \ |
" swap %/d0\n" \ |
" add%.l %/d0,%/d2\n" \ |
" add%.l %/d3,%/d2\n" \ |
" jcc 1f\n" \ |
" add%.l %#65536,%/d1\n" \ |
"1: swap %/d2\n" \ |
" moveq %#0,%/d0\n" \ |
" move%.w %/d2,%/d0\n" \ |
" move%.w %/d4,%/d2\n" \ |
" move%.l %/d2,%1\n" \ |
" add%.l %/d1,%/d0\n" \ |
" move%.l %/d0,%0" \ |
: "=g" ((USItype) (xh)), \ |
"=g" ((USItype) (xl)) \ |
: "g" ((USItype) (a)), \ |
"g" ((USItype) (b)) \ |
: "d0", "d1", "d2", "d3", "d4") |
#define UMUL_TIME 100 |
#define UDIV_TIME 400 |
#endif /* not mcf5200 */ |
#endif /* not mc68020 */ |
/* The '020, '030, '040 and '060 have bitfield insns. */ |
#if defined (__mc68020__) || defined(mc68020) \ |
|| defined(__mc68030__) || defined(mc68030) \ |
|| defined(__mc68040__) || defined(mc68040) \ |
|| defined(__mc68060__) || defined(mc68060) |
#define count_leading_zeros(count, x) \ |
__asm__ ("bfffo %1{%b2:%b2},%0" \ |
: "=d" ((USItype) (count)) \ |
: "od" ((USItype) (x)), "n" (0)) |
#endif |
#endif /* mc68000 */ |
#if defined (__m88000__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%rJ" ((USItype) (ah)), \ |
"rJ" ((USItype) (bh)), \ |
"%rJ" ((USItype) (al)), \ |
"rJ" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "rJ" ((USItype) (ah)), \ |
"rJ" ((USItype) (bh)), \ |
"rJ" ((USItype) (al)), \ |
"rJ" ((USItype) (bl))) |
#define count_leading_zeros(count, x) \ |
do { \ |
USItype __cbtmp; \ |
__asm__ ("ff1 %0,%1" \ |
: "=r" (__cbtmp) \ |
: "r" ((USItype) (x))); \ |
(count) = __cbtmp ^ 31; \ |
} while (0) |
#define COUNT_LEADING_ZEROS_0 63 /* sic */ |
#if defined (__mc88110__) |
#define umul_ppmm(wh, wl, u, v) \ |
do { \ |
union {UDItype __ll; \ |
struct {USItype __h, __l;} __i; \ |
} __xx; \ |
__asm__ ("mulu.d %0,%1,%2" \ |
: "=r" (__xx.__ll) \ |
: "r" ((USItype) (u)), \ |
"r" ((USItype) (v))); \ |
(wh) = __xx.__i.__h; \ |
(wl) = __xx.__i.__l; \ |
} while (0) |
#define udiv_qrnnd(q, r, n1, n0, d) \ |
({union {UDItype __ll; \ |
struct {USItype __h, __l;} __i; \ |
} __xx; \ |
USItype __q; \ |
__xx.__i.__h = (n1); __xx.__i.__l = (n0); \ |
__asm__ ("divu.d %0,%1,%2" \ |
: "=r" (__q) \ |
: "r" (__xx.__ll), \ |
"r" ((USItype) (d))); \ |
(r) = (n0) - __q * (d); (q) = __q; }) |
#define UMUL_TIME 5 |
#define UDIV_TIME 25 |
#else |
#define UMUL_TIME 17 |
#define UDIV_TIME 150 |
#endif /* __mc88110__ */ |
#endif /* __m88000__ */ |
#if defined (__mips__) && W_TYPE_SIZE == 32 |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("multu %2,%3" \ |
: "=l" ((USItype) (w0)), \ |
"=h" ((USItype) (w1)) \ |
: "d" ((USItype) (u)), \ |
"d" ((USItype) (v))) |
#define UMUL_TIME 10 |
#define UDIV_TIME 100 |
#endif /* __mips__ */ |
#if defined (__ns32000__) && W_TYPE_SIZE == 32 |
#define umul_ppmm(w1, w0, u, v) \ |
({union {UDItype __ll; \ |
struct {USItype __l, __h;} __i; \ |
} __xx; \ |
__asm__ ("meid %2,%0" \ |
: "=g" (__xx.__ll) \ |
: "%0" ((USItype) (u)), \ |
"g" ((USItype) (v))); \ |
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) |
#define __umulsidi3(u, v) \ |
({UDItype __w; \ |
__asm__ ("meid %2,%0" \ |
: "=g" (__w) \ |
: "%0" ((USItype) (u)), \ |
"g" ((USItype) (v))); \ |
__w; }) |
#define udiv_qrnnd(q, r, n1, n0, d) \ |
({union {UDItype __ll; \ |
struct {USItype __l, __h;} __i; \ |
} __xx; \ |
__xx.__i.__h = (n1); __xx.__i.__l = (n0); \ |
__asm__ ("deid %2,%0" \ |
: "=g" (__xx.__ll) \ |
: "0" (__xx.__ll), \ |
"g" ((USItype) (d))); \ |
(r) = __xx.__i.__l; (q) = __xx.__i.__h; }) |
#define count_trailing_zeros(count,x) \ |
do { \ |
__asm__ ("ffsd %2,%0" \ |
: "=r" ((USItype) (count)) \ |
: "0" ((USItype) 0), \ |
"r" ((USItype) (x))); \ |
} while (0) |
#endif /* __ns32000__ */ |
/* FIXME: We should test _IBMR2 here when we add assembly support for the |
system vendor compilers. |
FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good |
enough, since that hits ARM and m68k too. */ |
#if (defined (_ARCH_PPC) /* AIX */ \ |
|| defined (_ARCH_PWR) /* AIX */ \ |
|| defined (_ARCH_COM) /* AIX */ \ |
|| defined (__powerpc__) /* gcc */ \ |
|| defined (__POWERPC__) /* BEOS */ \ |
|| defined (__ppc__) /* Darwin */ \ |
|| defined (PPC) /* GNU/Linux, SysV */ \ |
) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
do { \ |
if (__builtin_constant_p (bh) && (bh) == 0) \ |
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ |
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ |
else \ |
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ |
: "=r" (sh), "=&r" (sl) \ |
: "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ |
} while (0) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
do { \ |
if (__builtin_constant_p (ah) && (ah) == 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ |
else \ |
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ |
: "=r" (sh), "=&r" (sl) \ |
: "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ |
} while (0) |
#define count_leading_zeros(count, x) \ |
__asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) |
#define COUNT_LEADING_ZEROS_0 32 |
#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ |
|| defined (__ppc__) || defined (PPC) || defined (__vxworks__) |
#define umul_ppmm(ph, pl, m0, m1) \ |
do { \ |
USItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ |
(pl) = __m0 * __m1; \ |
} while (0) |
#define UMUL_TIME 15 |
#define smul_ppmm(ph, pl, m0, m1) \ |
do { \ |
SItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ |
(pl) = __m0 * __m1; \ |
} while (0) |
#define SMUL_TIME 14 |
#define UDIV_TIME 120 |
#elif defined (_ARCH_PWR) |
#define UMUL_TIME 8 |
#define smul_ppmm(xh, xl, m0, m1) \ |
__asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) |
#define SMUL_TIME 4 |
#define sdiv_qrnnd(q, r, nh, nl, d) \ |
__asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) |
#define UDIV_TIME 100 |
#endif |
#endif /* 32-bit POWER architecture variants. */ |
/* We should test _IBMR2 here when we add assembly support for the system |
vendor compilers. */ |
#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
do { \ |
if (__builtin_constant_p (bh) && (bh) == 0) \ |
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ |
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ |
else \ |
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ |
: "=r" (sh), "=&r" (sl) \ |
: "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ |
} while (0) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
do { \ |
if (__builtin_constant_p (ah) && (ah) == 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ |
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ |
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ |
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ |
else \ |
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ |
: "=r" (sh), "=&r" (sl) \ |
: "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ |
} while (0) |
#define count_leading_zeros(count, x) \ |
__asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) |
#define COUNT_LEADING_ZEROS_0 64 |
#define umul_ppmm(ph, pl, m0, m1) \ |
do { \ |
UDItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ |
(pl) = __m0 * __m1; \ |
} while (0) |
#define UMUL_TIME 15 |
#define smul_ppmm(ph, pl, m0, m1) \ |
do { \ |
DItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ |
(pl) = __m0 * __m1; \ |
} while (0) |
#define SMUL_TIME 14 /* ??? */ |
#define UDIV_TIME 120 /* ??? */ |
#endif /* 64-bit PowerPC. */ |
#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("a %1,%5\n\tae %0,%3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%0" ((USItype) (ah)), \ |
"r" ((USItype) (bh)), \ |
"%1" ((USItype) (al)), \ |
"r" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("s %1,%5\n\tse %0,%3" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "0" ((USItype) (ah)), \ |
"r" ((USItype) (bh)), \ |
"1" ((USItype) (al)), \ |
"r" ((USItype) (bl))) |
#define umul_ppmm(ph, pl, m0, m1) \ |
do { \ |
USItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ( \ |
"s r2,r2\n" \ |
" mts r10,%2\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" m r2,%3\n" \ |
" cas %0,r2,r0\n" \ |
" mfs r10,%1" \ |
: "=r" ((USItype) (ph)), \ |
"=r" ((USItype) (pl)) \ |
: "%r" (__m0), \ |
"r" (__m1) \ |
: "r2"); \ |
(ph) += ((((SItype) __m0 >> 31) & __m1) \ |
+ (((SItype) __m1 >> 31) & __m0)); \ |
} while (0) |
#define UMUL_TIME 20 |
#define UDIV_TIME 200 |
#define count_leading_zeros(count, x) \ |
do { \ |
if ((x) >= 0x10000) \ |
__asm__ ("clz %0,%1" \ |
: "=r" ((USItype) (count)) \ |
: "r" ((USItype) (x) >> 16)); \ |
else \ |
{ \ |
__asm__ ("clz %0,%1" \ |
: "=r" ((USItype) (count)) \ |
: "r" ((USItype) (x))); \ |
(count) += 16; \ |
} \ |
} while (0) |
#endif |
#if defined (__sh2__) && W_TYPE_SIZE == 32 |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ( \ |
"dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ |
: "=r" ((USItype)(w1)), \ |
"=r" ((USItype)(w0)) \ |
: "r" ((USItype)(u)), \ |
"r" ((USItype)(v)) \ |
: "macl", "mach") |
#define UMUL_TIME 5 |
#endif |
#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 |
#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) |
#define count_leading_zeros(count, x) \ |
do \ |
{ \ |
UDItype x_ = (USItype)(x); \ |
SItype c_; \ |
\ |
__asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ |
(count) = c_ - 31; \ |
} \ |
while (0) |
#define COUNT_LEADING_ZEROS_0 32 |
#endif |
#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ |
&& W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "%rJ" ((USItype) (ah)), \ |
"rI" ((USItype) (bh)), \ |
"%rJ" ((USItype) (al)), \ |
"rI" ((USItype) (bl)) \ |
__CLOBBER_CC) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ |
: "=r" ((USItype) (sh)), \ |
"=&r" ((USItype) (sl)) \ |
: "rJ" ((USItype) (ah)), \ |
"rI" ((USItype) (bh)), \ |
"rJ" ((USItype) (al)), \ |
"rI" ((USItype) (bl)) \ |
__CLOBBER_CC) |
#if defined (__sparc_v8__) |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("umul %2,%3,%1;rd %%y,%0" \ |
: "=r" ((USItype) (w1)), \ |
"=r" ((USItype) (w0)) \ |
: "r" ((USItype) (u)), \ |
"r" ((USItype) (v))) |
#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ |
__asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ |
: "=&r" ((USItype) (__q)), \ |
"=&r" ((USItype) (__r)) \ |
: "r" ((USItype) (__n1)), \ |
"r" ((USItype) (__n0)), \ |
"r" ((USItype) (__d))) |
#else |
#if defined (__sparclite__) |
/* This has hardware multiply but not divide. It also has two additional |
instructions scan (ffs from high bit) and divscc. */ |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("umul %2,%3,%1;rd %%y,%0" \ |
: "=r" ((USItype) (w1)), \ |
"=r" ((USItype) (w0)) \ |
: "r" ((USItype) (u)), \ |
"r" ((USItype) (v))) |
#define udiv_qrnnd(q, r, n1, n0, d) \ |
__asm__ ("! Inlined udiv_qrnnd\n" \ |
" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ |
" tst %%g0\n" \ |
" divscc %3,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%%g1\n" \ |
" divscc %%g1,%4,%0\n" \ |
" rd %%y,%1\n" \ |
" bl,a 1f\n" \ |
" add %1,%4,%1\n" \ |
"1: ! End of inline udiv_qrnnd" \ |
: "=r" ((USItype) (q)), \ |
"=r" ((USItype) (r)) \ |
: "r" ((USItype) (n1)), \ |
"r" ((USItype) (n0)), \ |
"rI" ((USItype) (d)) \ |
: "g1" __AND_CLOBBER_CC) |
#define UDIV_TIME 37 |
#define count_leading_zeros(count, x) \ |
do { \ |
__asm__ ("scan %1,1,%0" \ |
: "=r" ((USItype) (count)) \ |
: "r" ((USItype) (x))); \ |
} while (0) |
/* Early sparclites return 63 for an argument of 0, but they warn that future |
implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 |
undefined. */ |
#else |
/* SPARC without integer multiplication and divide instructions. |
(i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ |
#define umul_ppmm(w1, w0, u, v) \ |
__asm__ ("! Inlined umul_ppmm\n" \ |
" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ |
" sra %3,31,%%o5 ! Don't move this insn\n" \ |
" and %2,%%o5,%%o5 ! Don't move this insn\n" \ |
" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,%3,%%g1\n" \ |
" mulscc %%g1,0,%%g1\n" \ |
" add %%g1,%%o5,%0\n" \ |
" rd %%y,%1" \ |
: "=r" ((USItype) (w1)), \ |
"=r" ((USItype) (w0)) \ |
: "%rI" ((USItype) (u)), \ |
"r" ((USItype) (v)) \ |
: "g1", "o5" __AND_CLOBBER_CC) |
#define UMUL_TIME 39 /* 39 instructions */ |
/* It's quite necessary to add this much assembler for the sparc. |
The default udiv_qrnnd (in C) is more than 10 times slower! */ |
#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ |
__asm__ ("! Inlined udiv_qrnnd\n" \ |
" mov 32,%%g1\n" \ |
" subcc %1,%2,%%g0\n" \ |
"1: bcs 5f\n" \ |
" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ |
" sub %1,%2,%1 ! this kills msb of n\n" \ |
" addx %1,%1,%1 ! so this can't give carry\n" \ |
" subcc %%g1,1,%%g1\n" \ |
"2: bne 1b\n" \ |
" subcc %1,%2,%%g0\n" \ |
" bcs 3f\n" \ |
" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ |
" b 3f\n" \ |
" sub %1,%2,%1 ! this kills msb of n\n" \ |
"4: sub %1,%2,%1\n" \ |
"5: addxcc %1,%1,%1\n" \ |
" bcc 2b\n" \ |
" subcc %%g1,1,%%g1\n" \ |
"! Got carry from n. Subtract next step to cancel this carry.\n" \ |
" bne 4b\n" \ |
" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ |
" sub %1,%2,%1\n" \ |
"3: xnor %0,0,%0\n" \ |
" ! End of inline udiv_qrnnd" \ |
: "=&r" ((USItype) (__q)), \ |
"=&r" ((USItype) (__r)) \ |
: "r" ((USItype) (__d)), \ |
"1" ((USItype) (__n1)), \ |
"0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) |
#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ |
#endif /* __sparclite__ */ |
#endif /* __sparc_v8__ */ |
#endif /* sparc32 */ |
#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ |
&& W_TYPE_SIZE == 64 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("addcc %r4,%5,%1\n\t" \ |
"add %r2,%3,%0\n\t" \ |
"bcs,a,pn %%xcc, 1f\n\t" \ |
"add %0, 1, %0\n" \ |
"1:" \ |
: "=r" ((UDItype)(sh)), \ |
"=&r" ((UDItype)(sl)) \ |
: "%rJ" ((UDItype)(ah)), \ |
"rI" ((UDItype)(bh)), \ |
"%rJ" ((UDItype)(al)), \ |
"rI" ((UDItype)(bl)) \ |
__CLOBBER_CC) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subcc %r4,%5,%1\n\t" \ |
"sub %r2,%3,%0\n\t" \ |
"bcs,a,pn %%xcc, 1f\n\t" \ |
"sub %0, 1, %0\n\t" \ |
"1:" \ |
: "=r" ((UDItype)(sh)), \ |
"=&r" ((UDItype)(sl)) \ |
: "rJ" ((UDItype)(ah)), \ |
"rI" ((UDItype)(bh)), \ |
"rJ" ((UDItype)(al)), \ |
"rI" ((UDItype)(bl)) \ |
__CLOBBER_CC) |
#define umul_ppmm(wh, wl, u, v) \ |
do { \ |
UDItype tmp1, tmp2, tmp3, tmp4; \ |
__asm__ __volatile__ ( \ |
"srl %7,0,%3\n\t" \ |
"mulx %3,%6,%1\n\t" \ |
"srlx %6,32,%2\n\t" \ |
"mulx %2,%3,%4\n\t" \ |
"sllx %4,32,%5\n\t" \ |
"srl %6,0,%3\n\t" \ |
"sub %1,%5,%5\n\t" \ |
"srlx %5,32,%5\n\t" \ |
"addcc %4,%5,%4\n\t" \ |
"srlx %7,32,%5\n\t" \ |
"mulx %3,%5,%3\n\t" \ |
"mulx %2,%5,%5\n\t" \ |
"sethi %%hi(0x80000000),%2\n\t" \ |
"addcc %4,%3,%4\n\t" \ |
"srlx %4,32,%4\n\t" \ |
"add %2,%2,%2\n\t" \ |
"movcc %%xcc,%%g0,%2\n\t" \ |
"addcc %5,%4,%5\n\t" \ |
"sllx %3,32,%3\n\t" \ |
"add %1,%3,%1\n\t" \ |
"add %5,%2,%0" \ |
: "=r" ((UDItype)(wh)), \ |
"=&r" ((UDItype)(wl)), \ |
"=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ |
: "r" ((UDItype)(u)), \ |
"r" ((UDItype)(v)) \ |
__CLOBBER_CC); \ |
} while (0) |
#define UMUL_TIME 96 |
#define UDIV_TIME 230 |
#endif /* sparc64 */ |
#if defined (__vax__) && W_TYPE_SIZE == 32 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ |
: "=g" ((USItype) (sh)), \ |
"=&g" ((USItype) (sl)) \ |
: "%0" ((USItype) (ah)), \ |
"g" ((USItype) (bh)), \ |
"%1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ |
: "=g" ((USItype) (sh)), \ |
"=&g" ((USItype) (sl)) \ |
: "0" ((USItype) (ah)), \ |
"g" ((USItype) (bh)), \ |
"1" ((USItype) (al)), \ |
"g" ((USItype) (bl))) |
#define umul_ppmm(xh, xl, m0, m1) \ |
do { \ |
union { \ |
UDItype __ll; \ |
struct {USItype __l, __h;} __i; \ |
} __xx; \ |
USItype __m0 = (m0), __m1 = (m1); \ |
__asm__ ("emul %1,%2,$0,%0" \ |
: "=r" (__xx.__ll) \ |
: "g" (__m0), \ |
"g" (__m1)); \ |
(xh) = __xx.__i.__h; \ |
(xl) = __xx.__i.__l; \ |
(xh) += ((((SItype) __m0 >> 31) & __m1) \ |
+ (((SItype) __m1 >> 31) & __m0)); \ |
} while (0) |
#define sdiv_qrnnd(q, r, n1, n0, d) \ |
do { \ |
union {DItype __ll; \ |
struct {SItype __l, __h;} __i; \ |
} __xx; \ |
__xx.__i.__h = n1; __xx.__i.__l = n0; \ |
__asm__ ("ediv %3,%2,%0,%1" \ |
: "=g" (q), "=g" (r) \ |
: "g" (__xx.__ll), "g" (d)); \ |
} while (0) |
#endif /* __vax__ */ |
#if defined (__z8000__) && W_TYPE_SIZE == 16 |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
__asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ |
: "=r" ((unsigned int)(sh)), \ |
"=&r" ((unsigned int)(sl)) \ |
: "%0" ((unsigned int)(ah)), \ |
"r" ((unsigned int)(bh)), \ |
"%1" ((unsigned int)(al)), \ |
"rQR" ((unsigned int)(bl))) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
__asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ |
: "=r" ((unsigned int)(sh)), \ |
"=&r" ((unsigned int)(sl)) \ |
: "0" ((unsigned int)(ah)), \ |
"r" ((unsigned int)(bh)), \ |
"1" ((unsigned int)(al)), \ |
"rQR" ((unsigned int)(bl))) |
#define umul_ppmm(xh, xl, m0, m1) \ |
do { \ |
union {long int __ll; \ |
struct {unsigned int __h, __l;} __i; \ |
} __xx; \ |
unsigned int __m0 = (m0), __m1 = (m1); \ |
__asm__ ("mult %S0,%H3" \ |
: "=r" (__xx.__i.__h), \ |
"=r" (__xx.__i.__l) \ |
: "%1" (__m0), \ |
"rQR" (__m1)); \ |
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ |
(xh) += ((((signed int) __m0 >> 15) & __m1) \ |
+ (((signed int) __m1 >> 15) & __m0)); \ |
} while (0) |
#endif /* __z8000__ */ |
#endif /* __GNUC__ */ |
/* If this machine has no inline assembler, use C macros. */ |
#if !defined (add_ssaaaa) |
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ |
do { \ |
UWtype __x; \ |
__x = (al) + (bl); \ |
(sh) = (ah) + (bh) + (__x < (al)); \ |
(sl) = __x; \ |
} while (0) |
#endif |
#if !defined (sub_ddmmss) |
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ |
do { \ |
UWtype __x; \ |
__x = (al) - (bl); \ |
(sh) = (ah) - (bh) - (__x > (al)); \ |
(sl) = __x; \ |
} while (0) |
#endif |
#if !defined (umul_ppmm) |
#define umul_ppmm(w1, w0, u, v) \ |
do { \ |
UWtype __x0, __x1, __x2, __x3; \ |
UHWtype __ul, __vl, __uh, __vh; \ |
\ |
__ul = __ll_lowpart (u); \ |
__uh = __ll_highpart (u); \ |
__vl = __ll_lowpart (v); \ |
__vh = __ll_highpart (v); \ |
\ |
__x0 = (UWtype) __ul * __vl; \ |
__x1 = (UWtype) __ul * __vh; \ |
__x2 = (UWtype) __uh * __vl; \ |
__x3 = (UWtype) __uh * __vh; \ |
\ |
__x1 += __ll_highpart (__x0);/* this can't give carry */ \ |
__x1 += __x2; /* but this indeed can */ \ |
if (__x1 < __x2) /* did we get it? */ \ |
__x3 += __ll_B; /* yes, add it in the proper pos. */ \ |
\ |
(w1) = __x3 + __ll_highpart (__x1); \ |
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ |
} while (0) |
#endif |
#if !defined (__umulsidi3) |
#define __umulsidi3(u, v) \ |
({DWunion __w; \ |
umul_ppmm (__w.s.high, __w.s.low, u, v); \ |
__w.ll; }) |
#endif |
/* Define this unconditionally, so it can be used for debugging. */ |
#define __udiv_qrnnd_c(q, r, n1, n0, d) \ |
do { \ |
UWtype __d1, __d0, __q1, __q0; \ |
UWtype __r1, __r0, __m; \ |
__d1 = __ll_highpart (d); \ |
__d0 = __ll_lowpart (d); \ |
\ |
__r1 = (n1) % __d1; \ |
__q1 = (n1) / __d1; \ |
__m = (UWtype) __q1 * __d0; \ |
__r1 = __r1 * __ll_B | __ll_highpart (n0); \ |
if (__r1 < __m) \ |
{ \ |
__q1--, __r1 += (d); \ |
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ |
if (__r1 < __m) \ |
__q1--, __r1 += (d); \ |
} \ |
__r1 -= __m; \ |
\ |
__r0 = __r1 % __d1; \ |
__q0 = __r1 / __d1; \ |
__m = (UWtype) __q0 * __d0; \ |
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \ |
if (__r0 < __m) \ |
{ \ |
__q0--, __r0 += (d); \ |
if (__r0 >= (d)) \ |
if (__r0 < __m) \ |
__q0--, __r0 += (d); \ |
} \ |
__r0 -= __m; \ |
\ |
(q) = (UWtype) __q1 * __ll_B | __q0; \ |
(r) = __r0; \ |
} while (0) |
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through |
__udiv_w_sdiv (defined in libgcc or elsewhere). */ |
#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) |
#define udiv_qrnnd(q, r, nh, nl, d) \ |
do { \ |
USItype __r; \ |
(q) = __udiv_w_sdiv (&__r, nh, nl, d); \ |
(r) = __r; \ |
} while (0) |
#endif |
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ |
#if !defined (udiv_qrnnd) |
#define UDIV_NEEDS_NORMALIZATION 1 |
#define udiv_qrnnd __udiv_qrnnd_c |
#endif |
#if !defined (count_leading_zeros) |
extern const UQItype __clz_tab[]; |
#define count_leading_zeros(count, x) \ |
do { \ |
UWtype __xr = (x); \ |
UWtype __a; \ |
\ |
if (W_TYPE_SIZE <= 32) \ |
{ \ |
__a = __xr < ((UWtype)1<<2*__BITS4) \ |
? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ |
: (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ |
} \ |
else \ |
{ \ |
for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ |
if (((__xr >> __a) & 0xff) != 0) \ |
break; \ |
} \ |
\ |
(count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ |
} while (0) |
#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE |
#endif |
#if !defined (count_trailing_zeros) |
/* Define count_trailing_zeros using count_leading_zeros. The latter might be |
defined in asm, but if it is not, the C version above is good enough. */ |
#define count_trailing_zeros(count, x) \ |
do { \ |
UWtype __ctz_x = (x); \ |
UWtype __ctz_c; \ |
count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ |
(count) = W_TYPE_SIZE - 1 - __ctz_c; \ |
} while (0) |
#endif |
#ifndef UDIV_NEEDS_NORMALIZATION |
#define UDIV_NEEDS_NORMALIZATION 0 |
#endif |
/programs/network/netsurf/netsurf/objs/make.all |
---|
0,0 → 1,32 |
OBJS = about.o base64.o bitmap_fbtk.o bitmap.o bmp.o box_construct.o \ |
box_normalise.o box.o browser.o caret_image.o challenge.o clipboard.o \ |
content-disposition.o content_factory.o content.o content-type.o \ |
cookies.o corestrings.o css.o curl.o data.o dirlist.o download.o \ |
dump.o event.o fbtk.o fetch.o filename.o file.o filepath.o filetype.o \ |
fill.o findfile.o font_freetype.o font.o form.o framebuffer.o frames.o \ |
generics.o gif.o gui.o hand_image.o hashtable.o history_core.o \ |
history_global_core.o history_image_g.o history_image.o hlcache.o \ |
hotlist.o html_forms.o html_interaction.o html.o html_redraw.o \ |
html_script.o ico.o image_cache.o imagemap.o image.o internal.o \ |
jpeg.o knockout.o layout.o left_arrow_g.o left_arrow.o libdom.o \ |
list.o llcache.o locale.o localhistory.o login.o log.o menu_image.o \ |
messages.o mimesniff.o misc.o mouse.o move_image.o netsurf.o none.o \ |
nsfont_bold.o nsfont_italic_bold.o nsfont_italic.o nsfont_regular.o \ |
nsurl.o options.o osk_image.o osk.o parameter.o plot_style.o png.o \ |
pointer_image.o primitives.o print.o progress_image.o reload_g.o \ |
reload.o resource.o right_arrow_g.o right_arrow.o save_complete.o \ |
save_text.o schedule.o scrollbar.o scrolld.o scrolll.o scroll.o \ |
scrollr.o scrollu.o search.o search_ren.o searchweb.o selection.o \ |
select.o sslcert.o stop_image_g.o stop_image.o system_colour.o \ |
table.o talloc.o textarea.o textinput.o textinput_r.o text.o \ |
textplain.o throbber0.o throbber1.o throbber2.o throbber3.o \ |
throbber4.o throbber5.o throbber6.o throbber7.o throbber8.o \ |
thumb_ddesk.o thumbnail.o tree_ddesk.o tree.o tree_url_node.o \ |
urldb.o url.o useragent.o user.o utf8.o utils.o utils_utils.o \ |
version.o window.o www-authenticate.o snprintf.o stubs.o divdi3.o |
LIBS += -lm -lcurl -liconv -lnsbmp -lnsgif -lpng -ljpeg -lz -lnsfb -lSDL -lwapcaplet -lcss -ldom -lhubbub -lparserutils -lfreetype2 |
OUTFILE = _netsurf |
include $(MENUETDEV)/makefiles/Makefile_for_program |
/programs/network/netsurf/netsurf/objs/snprintf.c |
---|
0,0 → 1,1025 |
/* |
* snprintf.c - a portable implementation of snprintf |
* |
* AUTHOR |
* Mark Martinec <mark.martinec@ijs.si>, April 1999. |
* |
* Copyright 1999, Mark Martinec. All rights reserved. |
* |
* TERMS AND CONDITIONS |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the "Frontier Artistic License" which comes |
* with this Kit. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty |
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
* See the Frontier Artistic License for more details. |
* |
* You should have received a copy of the Frontier Artistic License |
* with this Kit in the file named LICENSE.txt . |
* If not, I'll be glad to provide one. |
* |
* FEATURES |
* - careful adherence to specs regarding flags, field width and precision; |
* - good performance for large string handling (large format, large |
* argument or large paddings). Performance is similar to system's sprintf |
* and in several cases significantly better (make sure you compile with |
* optimizations turned on, tell the compiler the code is strict ANSI |
* if necessary to give it more freedom for optimizations); |
* - return value semantics per ISO/IEC 9899:1999 ("ISO C99"); |
* - written in standard ISO/ANSI C - requires an ANSI C compiler. |
* |
* SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES |
* |
* This snprintf only supports the following conversion specifiers: |
* s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below) |
* with flags: '-', '+', ' ', '0' and '#'. |
* An asterisk is supported for field width as well as precision. |
* |
* Length modifiers 'h' (short int), 'l' (long int), |
* and 'll' (long long int) are supported. |
* NOTE: |
* If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the |
* length modifier 'll' is recognized but treated the same as 'l', |
* which may cause argument value truncation! Defining |
* SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also |
* handles length modifier 'll'. long long int is a language extension |
* which may not be portable. |
* |
* Conversion of numeric data (conversion specifiers d, u, o, x, X, p) |
* with length modifiers (none or h, l, ll) is left to the system routine |
* sprintf, but all handling of flags, field width and precision as well as |
* c and s conversions is done very carefully by this portable routine. |
* If a string precision (truncation) is specified (e.g. %.8s) it is |
* guaranteed the string beyond the specified precision will not be referenced. |
* |
* Length modifiers h, l and ll are ignored for c and s conversions (data |
* types wint_t and wchar_t are not supported). |
* |
* The following common synonyms for conversion characters are supported: |
* - i is a synonym for d |
* - D is a synonym for ld, explicit length modifiers are ignored |
* - U is a synonym for lu, explicit length modifiers are ignored |
* - O is a synonym for lo, explicit length modifiers are ignored |
* The D, O and U conversion characters are nonstandard, they are supported |
* for backward compatibility only, and should not be used for new code. |
* |
* The following is specifically NOT supported: |
* - flag ' (thousands' grouping character) is recognized but ignored |
* - numeric conversion specifiers: f, e, E, g, G and synonym F, |
* as well as the new a and A conversion specifiers |
* - length modifier 'L' (long double) and 'q' (quad - use 'll' instead) |
* - wide character/string conversions: lc, ls, and nonstandard |
* synonyms C and S |
* - writeback of converted string length: conversion character n |
* - the n$ specification for direct reference to n-th argument |
* - locales |
* |
* It is permitted for str_m to be zero, and it is permitted to specify NULL |
* pointer for resulting string argument if str_m is zero (as per ISO C99). |
* |
* The return value is the number of characters which would be generated |
* for the given input, excluding the trailing null. If this value |
* is greater or equal to str_m, not all characters from the result |
* have been stored in str, output bytes beyond the (str_m-1) -th character |
* are discarded. If str_m is greater than zero it is guaranteed |
* the resulting string will be null-terminated. |
* |
* NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1, |
* but is different from some older and vendor implementations, |
* and is also different from XPG, XSH5, SUSv2 specifications. |
* For historical discussion on changes in the semantics and standards |
* of snprintf see printf(3) man page in the Linux programmers manual. |
* |
* Routines asprintf and vasprintf return a pointer (in the ptr argument) |
* to a buffer sufficiently large to hold the resulting string. This pointer |
* should be passed to free(3) to release the allocated storage when it is |
* no longer needed. If sufficient space cannot be allocated, these functions |
* will return -1 and set ptr to be a NULL pointer. These two routines are a |
* GNU C library extensions (glibc). |
* |
* Routines asnprintf and vasnprintf are similar to asprintf and vasprintf, |
* yet, like snprintf and vsnprintf counterparts, will write at most str_m-1 |
* characters into the allocated output string, the last character in the |
* allocated buffer then gets the terminating null. If the formatted string |
* length (the return value) is greater than or equal to the str_m argument, |
* the resulting string was truncated and some of the formatted characters |
* were discarded. These routines present a handy way to limit the amount |
* of allocated memory to some sane value. |
* |
* AVAILABILITY |
* http://www.ijs.si/software/snprintf/ |
* |
* REVISION HISTORY |
* 1999-04 V0.9 Mark Martinec |
* - initial version, some modifications after comparing printf |
* man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, |
* and checking how Perl handles sprintf (differently!); |
* 1999-04-09 V1.0 Mark Martinec <mark.martinec@ijs.si> |
* - added main test program, fixed remaining inconsistencies, |
* added optional (long long int) support; |
* 1999-04-12 V1.1 Mark Martinec <mark.martinec@ijs.si> |
* - support the 'p' conversion (pointer to void); |
* - if a string precision is specified |
* make sure the string beyond the specified precision |
* will not be referenced (e.g. by strlen); |
* 1999-04-13 V1.2 Mark Martinec <mark.martinec@ijs.si> |
* - support synonyms %D=%ld, %U=%lu, %O=%lo; |
* - speed up the case of long format string with few conversions; |
* 1999-06-30 V1.3 Mark Martinec <mark.martinec@ijs.si> |
* - fixed runaway loop (eventually crashing when str_l wraps |
* beyond 2^31) while copying format string without |
* conversion specifiers to a buffer that is too short |
* (thanks to Edwin Young <edwiny@autonomy.com> for |
* spotting the problem); |
* - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) |
* to snprintf.h |
* 2000-02-14 V2.0 (never released) Mark Martinec <mark.martinec@ijs.si> |
* - relaxed license terms: The Artistic License now applies. |
* You may still apply the GNU GENERAL PUBLIC LICENSE |
* as was distributed with previous versions, if you prefer; |
* - changed REVISION HISTORY dates to use ISO 8601 date format; |
* - added vsnprintf (patch also independently proposed by |
* Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) |
* 2000-06-27 V2.1 Mark Martinec <mark.martinec@ijs.si> |
* - removed POSIX check for str_m<1; value 0 for str_m is |
* allowed by ISO C99 (and GNU C library 2.1) - (pointed out |
* on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). |
* Besides relaxed license this change in standards adherence |
* is the main reason to bump up the major version number; |
* - added nonstandard routines asnprintf, vasnprintf, asprintf, |
* vasprintf that dynamically allocate storage for the |
* resulting string; these routines are not compiled by default, |
* see comments where NEED_V?ASN?PRINTF macros are defined; |
* - autoconf contributed by Caolan McNamara |
* 2000-10-06 V2.2 Mark Martinec <mark.martinec@ijs.si> |
* - BUG FIX: the %c conversion used a temporary variable |
* that was no longer in scope when referenced, |
* possibly causing incorrect resulting character; |
* - BUG FIX: make precision and minimal field width unsigned |
* to handle huge values (2^31 <= n < 2^32) correctly; |
* also be more careful in the use of signed/unsigned/size_t |
* internal variables - probably more careful than many |
* vendor implementations, but there may still be a case |
* where huge values of str_m, precision or minimal field |
* could cause incorrect behaviour; |
* - use separate variables for signed/unsigned arguments, |
* and for short/int, long, and long long argument lengths |
* to avoid possible incompatibilities on certain |
* computer architectures. Also use separate variable |
* arg_sign to hold sign of a numeric argument, |
* to make code more transparent; |
* - some fiddling with zero padding and "0x" to make it |
* Linux compatible; |
* - systematically use macros fast_memcpy and fast_memset |
* instead of case-by-case hand optimization; determine some |
* breakeven string lengths for different architectures; |
* - terminology change: 'format' -> 'conversion specifier', |
* 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', |
* 'alternative form' -> 'alternate form', |
* 'data type modifier' -> 'length modifier'; |
* - several comments rephrased and new ones added; |
* - make compiler not complain about 'credits' defined but |
* not used; |
*/ |
/* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf. |
* |
* If HAVE_SNPRINTF is defined this module will not produce code for |
* snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, |
* causing this portable version of snprintf to be called portable_snprintf |
* (and portable_vsnprintf). |
*/ |
/* #define HAVE_SNPRINTF */ |
/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and |
* vsnprintf but you would prefer to use the portable routine(s) instead. |
* In this case the portable routine is declared as portable_snprintf |
* (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') |
* is defined to expand to 'portable_v?snprintf' - see file snprintf.h . |
* Defining this macro is only useful if HAVE_SNPRINTF is also defined, |
* but does does no harm if defined nevertheless. |
*/ |
/* #define PREFER_PORTABLE_SNPRINTF */ |
/* Define SNPRINTF_LONGLONG_SUPPORT if you want to support |
* data type (long long int) and length modifier 'll' (e.g. %lld). |
* If undefined, 'll' is recognized but treated as a single 'l'. |
* |
* If the system's sprintf does not handle 'll' |
* the SNPRINTF_LONGLONG_SUPPORT must not be defined! |
* |
* This is off by default as (long long int) is a language extension. |
*/ |
/* #define SNPRINTF_LONGLONG_SUPPORT */ |
/* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf. |
* If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly, |
* otherwise both snprintf and vsnprintf routines will be defined |
* and snprintf will be a simple wrapper around vsnprintf, at the expense |
* of an extra procedure call. |
*/ |
/* #define NEED_SNPRINTF_ONLY */ |
/* Define NEED_V?ASN?PRINTF macros if you need library extension |
* routines asprintf, vasprintf, asnprintf, vasnprintf respectively, |
* and your system library does not provide them. They are all small |
* wrapper routines around portable_vsnprintf. Defining any of the four |
* NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY |
* and turns on PREFER_PORTABLE_SNPRINTF. |
* |
* Watch for name conflicts with the system library if these routines |
* are already present there. |
* |
* NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as |
* specified by C99, to be able to traverse the same list of arguments twice. |
* I don't know of any other standard and portable way of achieving the same. |
* With some versions of gcc you may use __va_copy(). You might even get away |
* with "ap2 = ap", in this case you must not call va_end(ap2) ! |
* #define va_copy(ap2,ap) ap2 = ap |
*/ |
/* #define NEED_ASPRINTF */ |
/* #define NEED_ASNPRINTF */ |
/* #define NEED_VASPRINTF */ |
/* #define NEED_VASNPRINTF */ |
/* Define the following macros if desired: |
* SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE, |
* HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE, |
* DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE, |
* PERL_COMPATIBLE, PERL_BUG_COMPATIBLE, |
* |
* - For portable applications it is best not to rely on peculiarities |
* of a given implementation so it may be best not to define any |
* of the macros that select compatibility and to avoid features |
* that vary among the systems. |
* |
* - Selecting compatibility with more than one operating system |
* is not strictly forbidden but is not recommended. |
* |
* - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE . |
* |
* - 'x'_COMPATIBLE refers to (and enables) a behaviour that is |
* documented in a sprintf man page on a given operating system |
* and actually adhered to by the system's sprintf (but not on |
* most other operating systems). It may also refer to and enable |
* a behaviour that is declared 'undefined' or 'implementation specific' |
* in the man page but a given implementation behaves predictably |
* in a certain way. |
* |
* - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf |
* that contradicts the sprintf man page on the same operating system. |
* |
* - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE |
* conditionals take into account all idiosyncrasies of a particular |
* implementation, there may be other incompatibilities. |
*/ |
/* ============================================= */ |
/* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */ |
/* ============================================= */ |
#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 |
#define PORTABLE_SNPRINTF_VERSION_MINOR 2 |
#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) |
# if defined(NEED_SNPRINTF_ONLY) |
# undef NEED_SNPRINTF_ONLY |
# endif |
# if !defined(PREFER_PORTABLE_SNPRINTF) |
# define PREFER_PORTABLE_SNPRINTF |
# endif |
#endif |
#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) |
#define SOLARIS_COMPATIBLE |
#endif |
#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) |
#define HPUX_COMPATIBLE |
#endif |
#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) |
#define DIGITAL_UNIX_COMPATIBLE |
#endif |
#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) |
#define PERL_COMPATIBLE |
#endif |
#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) |
#define LINUX_COMPATIBLE |
#endif |
#include <sys/types.h> |
#include <string.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <stdarg.h> |
#include <assert.h> |
#include <errno.h> |
#ifdef isdigit |
#undef isdigit |
#endif |
#define isdigit(c) ((c) >= '0' && (c) <= '9') |
/* For copying strings longer or equal to 'breakeven_point' |
* it is more efficient to call memcpy() than to do it inline. |
* The value depends mostly on the processor architecture, |
* but also on the compiler and its optimization capabilities. |
* The value is not critical, some small value greater than zero |
* will be just fine if you don't care to squeeze every drop |
* of performance out of the code. |
* |
* Small values favor memcpy, large values favor inline code. |
*/ |
#if defined(__alpha__) || defined(__alpha) |
# define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */ |
#endif |
#if defined(__i386__) || defined(__i386) |
# define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */ |
#endif |
#if defined(__hppa) |
# define breakeven_point 10 /* HP-PA - gcc */ |
#endif |
#if defined(__sparc__) || defined(__sparc) |
# define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ |
#endif |
/* some other values of possible interest: */ |
/* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ |
/* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ |
#ifndef breakeven_point |
# define breakeven_point 6 /* some reasonable one-size-fits-all value */ |
#endif |
#define fast_memcpy(d,s,n) \ |
{ register size_t nn = (size_t)(n); \ |
if (nn >= breakeven_point) memcpy((d), (s), nn); \ |
else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ |
register char *dd; register const char *ss; \ |
for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } |
#define fast_memset(d,c,n) \ |
{ register size_t nn = (size_t)(n); \ |
if (nn >= breakeven_point) memset((d), (int)(c), nn); \ |
else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ |
register char *dd; register const int cc=(int)(c); \ |
for (dd=(d); nn>0; nn--) *dd++ = cc; } } |
/* prototypes */ |
#if defined(NEED_ASPRINTF) |
int asprintf (char **ptr, const char *fmt, /*args*/ ...); |
#endif |
#if defined(NEED_VASPRINTF) |
int vasprintf (char **ptr, const char *fmt, va_list ap); |
#endif |
#if defined(NEED_ASNPRINTF) |
int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); |
#endif |
#if defined(NEED_VASNPRINTF) |
int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); |
#endif |
#if defined(HAVE_SNPRINTF) |
/* declare our portable snprintf routine under name portable_snprintf */ |
/* declare our portable vsnprintf routine under name portable_vsnprintf */ |
#else |
/* declare our portable routines under names snprintf and vsnprintf */ |
#define portable_snprintf snprintf |
#if !defined(NEED_SNPRINTF_ONLY) |
#define portable_vsnprintf vsnprintf |
#endif |
#endif |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); |
#if !defined(NEED_SNPRINTF_ONLY) |
int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); |
#endif |
#endif |
/* declarations */ |
static char credits[] = "\n\ |
@(#)snprintf.c, v2.2: Mark Martinec, <mark.martinec@ijs.si>\n\ |
@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ |
@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; |
#if defined(NEED_ASPRINTF) |
int asprintf(char **ptr, const char *fmt, /*args*/ ...) { |
va_list ap; |
size_t str_m; |
int str_l; |
*ptr = NULL; |
va_start(ap, fmt); /* measure the required size */ |
str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); |
va_end(ap); |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
else { |
int str_l2; |
va_start(ap, fmt); |
str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
va_end(ap); |
assert(str_l2 == str_l); |
} |
return str_l; |
} |
#endif |
#if defined(NEED_VASPRINTF) |
int vasprintf(char **ptr, const char *fmt, va_list ap) { |
size_t str_m; |
int str_l; |
*ptr = NULL; |
{ va_list ap2; |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ |
va_end(ap2); |
} |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
else { |
int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
assert(str_l2 == str_l); |
} |
return str_l; |
} |
#endif |
#if defined(NEED_ASNPRINTF) |
int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { |
va_list ap; |
int str_l; |
*ptr = NULL; |
va_start(ap, fmt); /* measure the required size */ |
str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); |
va_end(ap); |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ |
/* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ |
if (str_m == 0) { /* not interested in resulting string, just return size */ |
} else { |
*ptr = (char *) malloc(str_m); |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
else { |
int str_l2; |
va_start(ap, fmt); |
str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
va_end(ap); |
assert(str_l2 == str_l); |
} |
} |
return str_l; |
} |
#endif |
#if defined(NEED_VASNPRINTF) |
int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) { |
int str_l; |
*ptr = NULL; |
{ va_list ap2; |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ |
va_end(ap2); |
} |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ |
/* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ |
if (str_m == 0) { /* not interested in resulting string, just return size */ |
} else { |
*ptr = (char *) malloc(str_m); |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
else { |
int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
assert(str_l2 == str_l); |
} |
} |
return str_l; |
} |
#endif |
/* |
* If the system does have snprintf and the portable routine is not |
* specifically required, this module produces no code for snprintf/vsnprintf. |
*/ |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
#if !defined(NEED_SNPRINTF_ONLY) |
int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
va_list ap; |
int str_l; |
va_start(ap, fmt); |
str_l = portable_vsnprintf(str, str_m, fmt, ap); |
va_end(ap); |
return str_l; |
} |
#endif |
#if defined(NEED_SNPRINTF_ONLY) |
int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
#else |
int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { |
#endif |
#if defined(NEED_SNPRINTF_ONLY) |
va_list ap; |
#endif |
size_t str_l = 0; |
const char *p = fmt; |
/* In contrast with POSIX, the ISO C99 now says |
* that str can be NULL and str_m can be 0. |
* This is more useful than the old: if (str_m < 1) return -1; */ |
#if defined(NEED_SNPRINTF_ONLY) |
va_start(ap, fmt); |
#endif |
if (!p) p = ""; |
while (*p) { |
if (*p != '%') { |
/* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */ |
/* but the following code achieves better performance for cases |
* where format string is long and contains few conversions */ |
const char *q = strchr(p+1,'%'); |
size_t n = !q ? strlen(p) : (q-p); |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memcpy(str+str_l, p, (n>avail?avail:n)); |
} |
p += n; str_l += n; |
} else { |
const char *starting_p; |
size_t min_field_width = 0, precision = 0; |
int zero_padding = 0, precision_specified = 0, justify_left = 0; |
int alternate_form = 0, force_sign = 0; |
int space_for_positive = 1; /* If both the ' ' and '+' flags appear, |
the ' ' flag should be ignored. */ |
char length_modifier = '\0'; /* allowed values: \0, h, l, L */ |
char tmp[32];/* temporary buffer for simple numeric->string conversion */ |
const char *str_arg; /* string address in case of string argument */ |
size_t str_arg_l; /* natural field width of arg without padding |
and sign */ |
unsigned char uchar_arg; |
/* unsigned char argument value - only defined for c conversion. |
N.B. standard explicitly states the char argument for |
the c conversion is unsigned */ |
size_t number_of_zeros_to_pad = 0; |
/* number of zeros to be inserted for numeric conversions |
as required by the precision or minimal field width */ |
size_t zero_padding_insertion_ind = 0; |
/* index into tmp where zero padding is to be inserted */ |
char fmt_spec = '\0'; |
/* current conversion specifier character */ |
str_arg = credits;/* just to make compiler happy (defined but not used)*/ |
str_arg = NULL; |
starting_p = p; p++; /* skip '%' */ |
/* parse flags */ |
while (*p == '0' || *p == '-' || *p == '+' || |
*p == ' ' || *p == '#' || *p == '\'') { |
switch (*p) { |
case '0': zero_padding = 1; break; |
case '-': justify_left = 1; break; |
case '+': force_sign = 1; space_for_positive = 0; break; |
case ' ': force_sign = 1; |
/* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ |
#ifdef PERL_COMPATIBLE |
/* ... but in Perl the last of ' ' and '+' applies */ |
space_for_positive = 1; |
#endif |
break; |
case '#': alternate_form = 1; break; |
case '\'': break; |
} |
p++; |
} |
/* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ |
/* parse field width */ |
if (*p == '*') { |
int j; |
p++; j = va_arg(ap, int); |
if (j >= 0) min_field_width = j; |
else { min_field_width = -j; justify_left = 1; } |
} else if (isdigit((int)(*p))) { |
/* size_t could be wider than unsigned int; |
make sure we treat argument like common implementations do */ |
unsigned int uj = *p++ - '0'; |
while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); |
min_field_width = uj; |
} |
/* parse precision */ |
if (*p == '.') { |
p++; precision_specified = 1; |
if (*p == '*') { |
int j = va_arg(ap, int); |
p++; |
if (j >= 0) precision = j; |
else { |
precision_specified = 0; precision = 0; |
/* NOTE: |
* Solaris 2.6 man page claims that in this case the precision |
* should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page |
* claim that this case should be treated as unspecified precision, |
* which is what we do here. |
*/ |
} |
} else if (isdigit((int)(*p))) { |
/* size_t could be wider than unsigned int; |
make sure we treat argument like common implementations do */ |
unsigned int uj = *p++ - '0'; |
while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); |
precision = uj; |
} |
} |
/* parse 'h', 'l' and 'll' length modifiers */ |
if (*p == 'h' || *p == 'l') { |
length_modifier = *p; p++; |
if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
length_modifier = '2'; /* double l encoded as '2' */ |
#else |
length_modifier = 'l'; /* treat it as a single 'l' */ |
#endif |
p++; |
} |
} |
fmt_spec = *p; |
/* common synonyms: */ |
switch (fmt_spec) { |
case 'i': fmt_spec = 'd'; break; |
case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; |
case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; |
case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; |
default: break; |
} |
/* get parameter value, do initial processing */ |
switch (fmt_spec) { |
case '%': /* % behaves similar to 's' regarding flags and field widths */ |
case 'c': /* c behaves similar to 's' regarding flags and field widths */ |
case 's': |
length_modifier = '\0'; /* wint_t and wchar_t not supported */ |
/* the result of zero padding flag with non-numeric conversion specifier*/ |
/* is undefined. Solaris and HPUX 10 does zero padding in this case, */ |
/* Digital Unix and Linux does not. */ |
#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) |
zero_padding = 0; /* turn zero padding off for string conversions */ |
#endif |
str_arg_l = 1; |
switch (fmt_spec) { |
case '%': |
str_arg = p; break; |
case 'c': { |
int j = va_arg(ap, int); |
uchar_arg = (unsigned char) j; /* standard demands unsigned char */ |
str_arg = (const char *) &uchar_arg; |
break; |
} |
case 's': |
str_arg = va_arg(ap, const char *); |
if (!str_arg) str_arg_l = 0; |
/* make sure not to address string beyond the specified precision !!! */ |
else if (!precision_specified) str_arg_l = strlen(str_arg); |
/* truncate string if necessary as requested by precision */ |
else if (precision == 0) str_arg_l = 0; |
else { |
/* memchr on HP does not like n > 2^31 !!! */ |
const char *q = memchr(str_arg, '\0', |
precision <= 0x7fffffff ? precision : 0x7fffffff); |
str_arg_l = !q ? precision : (q-str_arg); |
} |
break; |
default: break; |
} |
break; |
case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { |
/* NOTE: the u, o, x, X and p conversion specifiers imply |
the value is unsigned; d implies a signed value */ |
int arg_sign = 0; |
/* 0 if numeric argument is zero (or if pointer is NULL for 'p'), |
+1 if greater than zero (or nonzero for unsigned arguments), |
-1 if negative (unsigned argument is never negative) */ |
int int_arg = 0; unsigned int uint_arg = 0; |
/* only defined for length modifier h, or for no length modifiers */ |
long int long_arg = 0; unsigned long int ulong_arg = 0; |
/* only defined for length modifier l */ |
void *ptr_arg = NULL; |
/* pointer argument value -only defined for p conversion */ |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
long long int long_long_arg = 0; |
unsigned long long int ulong_long_arg = 0; |
/* only defined for length modifier ll */ |
#endif |
if (fmt_spec == 'p') { |
/* HPUX 10: An l, h, ll or L before any other conversion character |
* (other than d, i, u, o, x, or X) is ignored. |
* Digital Unix: |
* not specified, but seems to behave as HPUX does. |
* Solaris: If an h, l, or L appears before any other conversion |
* specifier (other than d, i, u, o, x, or X), the behavior |
* is undefined. (Actually %hp converts only 16-bits of address |
* and %llp treats address as 64-bit data which is incompatible |
* with (void *) argument on a 32-bit system). |
*/ |
#ifdef SOLARIS_COMPATIBLE |
# ifdef SOLARIS_BUG_COMPATIBLE |
/* keep length modifiers even if it represents 'll' */ |
# else |
if (length_modifier == '2') length_modifier = '\0'; |
# endif |
#else |
length_modifier = '\0'; |
#endif |
ptr_arg = va_arg(ap, void *); |
if (ptr_arg != NULL) arg_sign = 1; |
} else if (fmt_spec == 'd') { /* signed */ |
switch (length_modifier) { |
case '\0': |
case 'h': |
/* It is non-portable to specify a second argument of char or short |
* to va_arg, because arguments seen by the called function |
* are not char or short. C converts char and short arguments |
* to int before passing them to a function. |
*/ |
int_arg = va_arg(ap, int); |
if (int_arg > 0) arg_sign = 1; |
else if (int_arg < 0) arg_sign = -1; |
break; |
case 'l': |
long_arg = va_arg(ap, long int); |
if (long_arg > 0) arg_sign = 1; |
else if (long_arg < 0) arg_sign = -1; |
break; |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
case '2': |
long_long_arg = va_arg(ap, long long int); |
if (long_long_arg > 0) arg_sign = 1; |
else if (long_long_arg < 0) arg_sign = -1; |
break; |
#endif |
} |
} else { /* unsigned */ |
switch (length_modifier) { |
case '\0': |
case 'h': |
uint_arg = va_arg(ap, unsigned int); |
if (uint_arg) arg_sign = 1; |
break; |
case 'l': |
ulong_arg = va_arg(ap, unsigned long int); |
if (ulong_arg) arg_sign = 1; |
break; |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
case '2': |
ulong_long_arg = va_arg(ap, unsigned long long int); |
if (ulong_long_arg) arg_sign = 1; |
break; |
#endif |
} |
} |
str_arg = tmp; str_arg_l = 0; |
/* NOTE: |
* For d, i, u, o, x, and X conversions, if precision is specified, |
* the '0' flag should be ignored. This is so with Solaris 2.6, |
* Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. |
*/ |
#ifndef PERL_COMPATIBLE |
if (precision_specified) zero_padding = 0; |
#endif |
if (fmt_spec == 'd') { |
if (force_sign && arg_sign >= 0) |
tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; |
/* leave negative numbers for sprintf to handle, |
to avoid handling tricky cases like (short int)(-32768) */ |
#ifdef LINUX_COMPATIBLE |
} else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { |
tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; |
#endif |
} else if (alternate_form) { |
if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) |
{ tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } |
/* alternate form should have no effect for p conversion, but ... */ |
#ifdef HPUX_COMPATIBLE |
else if (fmt_spec == 'p' |
/* HPUX 10: for an alternate form of p conversion, |
* a nonzero result is prefixed by 0x. */ |
#ifndef HPUX_BUG_COMPATIBLE |
/* Actually it uses 0x prefix even for a zero value. */ |
&& arg_sign != 0 |
#endif |
) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } |
#endif |
} |
zero_padding_insertion_ind = str_arg_l; |
if (!precision_specified) precision = 1; /* default precision is 1 */ |
if (precision == 0 && arg_sign == 0 |
#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) |
&& fmt_spec != 'p' |
/* HPUX 10 man page claims: With conversion character p the result of |
* converting a zero value with a precision of zero is a null string. |
* Actually HP returns all zeroes, and Linux returns "(nil)". */ |
#endif |
) { |
/* converted to null string */ |
/* When zero value is formatted with an explicit precision 0, |
the resulting formatted string is empty (d, i, u, o, x, X, p). */ |
} else { |
char f[5]; int f_l = 0; |
f[f_l++] = '%'; /* construct a simple format string for sprintf */ |
if (!length_modifier) { } |
else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } |
else f[f_l++] = length_modifier; |
f[f_l++] = fmt_spec; f[f_l++] = '\0'; |
if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); |
else if (fmt_spec == 'd') { /* signed */ |
switch (length_modifier) { |
case '\0': |
case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break; |
case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; |
#endif |
} |
} else { /* unsigned */ |
switch (length_modifier) { |
case '\0': |
case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break; |
case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; |
#ifdef SNPRINTF_LONGLONG_SUPPORT |
case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; |
#endif |
} |
} |
/* include the optional minus sign and possible "0x" |
in the region before the zero padding insertion point */ |
if (zero_padding_insertion_ind < str_arg_l && |
tmp[zero_padding_insertion_ind] == '-') { |
zero_padding_insertion_ind++; |
} |
if (zero_padding_insertion_ind+1 < str_arg_l && |
tmp[zero_padding_insertion_ind] == '0' && |
(tmp[zero_padding_insertion_ind+1] == 'x' || |
tmp[zero_padding_insertion_ind+1] == 'X') ) { |
zero_padding_insertion_ind += 2; |
} |
} |
{ size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; |
if (alternate_form && fmt_spec == 'o' |
#ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ |
&& (str_arg_l > 0) |
#endif |
#ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ |
#else |
/* unless zero is already the first character */ |
&& !(zero_padding_insertion_ind < str_arg_l |
&& tmp[zero_padding_insertion_ind] == '0') |
#endif |
) { /* assure leading zero for alternate-form octal numbers */ |
if (!precision_specified || precision < num_of_digits+1) { |
/* precision is increased to force the first character to be zero, |
except if a zero value is formatted with an explicit precision |
of zero */ |
precision = num_of_digits+1; precision_specified = 1; |
} |
} |
/* zero padding to specified precision? */ |
if (num_of_digits < precision) |
number_of_zeros_to_pad = precision - num_of_digits; |
} |
/* zero padding to specified minimal field width? */ |
if (!justify_left && zero_padding) { |
int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); |
if (n > 0) number_of_zeros_to_pad += n; |
} |
break; |
} |
default: /* unrecognized conversion specifier, keep format string as-is*/ |
zero_padding = 0; /* turn zero padding off for non-numeric convers. */ |
#ifndef DIGITAL_UNIX_COMPATIBLE |
justify_left = 1; min_field_width = 0; /* reset flags */ |
#endif |
#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) |
/* keep the entire format string unchanged */ |
str_arg = starting_p; str_arg_l = p - starting_p; |
/* well, not exactly so for Linux, which does something inbetween, |
* and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ |
#else |
/* discard the unrecognized conversion, just keep * |
* the unrecognized conversion character */ |
str_arg = p; str_arg_l = 0; |
#endif |
if (*p) str_arg_l++; /* include invalid conversion specifier unchanged |
if not at end-of-string */ |
break; |
} |
if (*p) p++; /* step over the just processed conversion specifier */ |
/* insert padding to the left as requested by min_field_width; |
this does not include the zero padding in case of numerical conversions*/ |
if (!justify_left) { /* left padding with blank or zero */ |
int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); |
if (n > 0) { |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); |
} |
str_l += n; |
} |
} |
/* zero padding as requested by the precision or by the minimal field width |
* for numeric conversions required? */ |
if (number_of_zeros_to_pad <= 0) { |
/* will not copy first part of numeric right now, * |
* force it to be copied later in its entirety */ |
zero_padding_insertion_ind = 0; |
} else { |
/* insert first part of numerics (sign or '0x') before zero padding */ |
int n = zero_padding_insertion_ind; |
if (n > 0) { |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); |
} |
str_l += n; |
} |
/* insert zero padding as requested by the precision or min field width */ |
n = number_of_zeros_to_pad; |
if (n > 0) { |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memset(str+str_l, '0', (n>avail?avail:n)); |
} |
str_l += n; |
} |
} |
/* insert formatted string |
* (or as-is conversion specifier for unknown conversions) */ |
{ int n = str_arg_l - zero_padding_insertion_ind; |
if (n > 0) { |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, |
(n>avail?avail:n)); |
} |
str_l += n; |
} |
} |
/* insert right padding */ |
if (justify_left) { /* right blank padding to the field width */ |
int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); |
if (n > 0) { |
if (str_l < str_m) { |
size_t avail = str_m-str_l; |
fast_memset(str+str_l, ' ', (n>avail?avail:n)); |
} |
str_l += n; |
} |
} |
} |
} |
#if defined(NEED_SNPRINTF_ONLY) |
va_end(ap); |
#endif |
if (str_m > 0) { /* make sure the string is null-terminated |
even at the expense of overwriting the last character |
(shouldn't happen, but just in case) */ |
str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; |
} |
/* Return the number of characters formatted (excluding trailing null |
* character), that is, the number of characters that would have been |
* written to the buffer if it were large enough. |
* |
* The value of str_l should be returned, but str_l is of unsigned type |
* size_t, and snprintf is int, possibly leading to an undetected |
* integer overflow, resulting in a negative return value, which is illegal. |
* Both XSH5 and ISO C99 (at least the draft) are silent on this issue. |
* Should errno be set to EOVERFLOW and EOF returned in this case??? |
*/ |
return (int) str_l; |
} |
#endif |
/programs/network/netsurf/netsurf/objs/snprintf.h |
---|
0,0 → 1,26 |
#ifndef _PORTABLE_SNPRINTF_H_ |
#define _PORTABLE_SNPRINTF_H_ |
#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 |
#define PORTABLE_SNPRINTF_VERSION_MINOR 2 |
#ifdef HAVE_SNPRINTF |
#include <stdio.h> |
#else |
extern int snprintf(char *, size_t, const char *, /*args*/ ...); |
extern int vsnprintf(char *, size_t, const char *, va_list); |
#endif |
#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF) |
extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); |
extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); |
#define snprintf portable_snprintf |
#define vsnprintf portable_vsnprintf |
#endif |
extern int asprintf (char **ptr, const char *fmt, /*args*/ ...); |
extern int vasprintf (char **ptr, const char *fmt, va_list ap); |
extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); |
extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); |
#endif |
/programs/network/netsurf/netsurf/objs/src |
---|
0,0 → 1,26 |
OBJS = about.o base64.o bitmap_fbtk.o bitmap.o bmp.o box_construct.o \ |
box_normalise.o box.o browser.o caret_image.o challenge.o clipboard.o \ |
content-disposition.o content_factory.o content.o content-type.o \ |
cookies.o corestrings.o css.o curl.o data.o dirlist.o download.o \ |
dump.o event.o fbtk.o fetch.o filename.o file.o filepath.o filetype.o \ |
fill.o findfile.o font_internal.o font.o form.o framebuffer.o frames.o \ |
generics.o gif.o gui.o hand_image.o hashtable.o history_core.o \ |
history_global_core.o history_image_g.o history_image.o hlcache.o \ |
hotlist.o html_forms.o html_interaction.o html.o html_redraw.o \ |
html_script.o ico.o image_cache.o imagemap.o image.o internal.o \ |
jpeg.o knockout.o layout.o left_arrow_g.o left_arrow.o libdom.o \ |
list.o llcache.o locale.o localhistory.o login.o log.o menu_image.o \ |
messages.o mimesniff.o misc.o mouse.o move_image.o netsurf.o none.o \ |
nsfont_bold.o nsfont_italic_bold.o nsfont_italic.o nsfont_regular.o \ |
nsurl.o options.o osk_image.o osk.o parameter.o plot_style.o png.o \ |
pointer_image.o primitives.o print.o progress_image.o reload_g.o \ |
reload.o resource.o right_arrow_g.o right_arrow.o save_complete.o \ |
save_text.o schedule.o scrollbar.o scrolld.o scrolll.o scroll.o \ |
scrollr.o scrollu.o search.o search_ren.o searchweb.o selection.o \ |
select.o sslcert.o stop_image_g.o stop_image.o system_colour.o \ |
table.o talloc.o textarea.o textinput.o textinput_r.o text.o \ |
textplain.o throbber0.o throbber1.o throbber2.o throbber3.o \ |
throbber4.o throbber5.o throbber6.o throbber7.o throbber8.o \ |
thumb_ddesk.o thumbnail.o tree_ddesk.o tree.o tree_url_node.o \ |
urldb.o url.o useragent.o user.o utf8.o utils.o utils_utils.o \ |
version.o window.o www-authenticate.o |
/programs/network/netsurf/netsurf/objs/stubs.c |
---|
0,0 → 1,151 |
#include <menuet/os.h> |
#include <math.h> |
#include <time.h> |
/* |
long int __divdi3(long int a, long int b) { |
//__menuet__debug_out("divdi3\n"); |
return 0;} |
*/ |
/* |
long long int __divdi3(long long int a, long long int b) { |
__menuet__debug_out("divdi3\n"); |
return a/b;} |
*/ |
char * locale_charset(){ |
__menuet__debug_out("Charset is US\n"); |
return "US-ASCII";} |
float strtof(const char* str, char** endptr){ |
__menuet__debug_out("STRTOOOF\n"); |
return 0.0f;} |
char *realpath(const char *path, char *resolved_path){ |
char zuup[1024]; |
int i; |
char *zoo; |
char *boo; |
char n, s; |
if (resolved_path==0) { |
__menuet__debug_out("ResPath is null"); |
resolved_path=malloc(strlen(path)+1); |
} |
zoo=resolved_path; |
boo=path; |
memcpy(zoo,boo,strlen(boo)); |
zoo[strlen(boo)]=0; |
for (i=0; i<strlen(boo); i++) { |
n=*path; |
path++; |
s=*path; |
if ((n=='/' && s!='/') || (n!='/') ) { |
*resolved_path=n; |
resolved_path++; |
} |
} |
*resolved_path=0; |
__menuet__debug_out("Real path is... \n"); |
sprintf (zuup, "A:%s\n", boo); |
__menuet__debug_out(zuup); |
sprintf (zuup, "B:%s\n", zoo); |
__menuet__debug_out(zuup); |
//memcpy(resolved_path, path, strlen(path)); |
return zoo; |
} |
#include <stdint.h> |
#include <netinet/in.h> |
int inet_aton(const char *cp, struct in_addr *inp){ |
__menuet__debug_out("No IP\n"); |
return 0; |
} |
#include <stdarg.h> |
void va_copy(va_list dest, va_list src){ //WHAA |
dest=src; |
__menuet__debug_out("Some shit...\n"); |
} |
void timeradd(struct timeval *a, struct timeval *b, |
struct timeval *res){ |
(res)->tv_sec = (a)->tv_sec + (b)->tv_sec; |
(res)->tv_usec = (a)->tv_usec + (b)->tv_usec; |
if ((res)->tv_usec >= 1000000) { |
(res)->tv_sec++; |
(res)->tv_usec -= 1000000; |
} |
//__menuet__debug_out("Timeradd\n"); |
} |
void timersub(struct timeval *a, struct timeval *b, |
struct timeval *res){ |
res->tv_sec=a->tv_sec - b->tv_sec; |
res->tv_usec=a->tv_usec - b->tv_usec; |
if ((res)->tv_usec < 0) { |
(res)->tv_sec--; |
(res)->tv_usec += 1000000; |
} |
// __menuet__debug_out("Timersub\n"); |
} |
int timerisset(struct timeval *tvp){ |
//__menuet__debug_out("Timer is set?\n"); |
return ((tvp)->tv_sec || (tvp)->tv_usec); |
} |
int timercmp(struct timeval *a, struct timeval *b, int z){ |
//__menuet__debug_out("Timercmp is a MACRO \n"); |
if (a->tv_sec > b->tv_sec) return 1; //was 1 |
return 0;} |
int wctomb(char *s, int wchar){ |
__menuet__debug_out("wctomb\n"); |
return 0;} |
int wcrtomb(char * s, int wc, int * ps){ |
__menuet__debug_out("wcrtomb\n"); |
return 0; |
} |
int mbrtowc(int * pwc, const char * s, |
int n, int * ps){ |
__menuet__debug_out("mbrtowc\n"); |
return 0;} |
int johab_hangul_decompose( const char * s){ |
__menuet__debug_out("hanguul?\n"); |
return 0;} |