home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-21 | 76.3 KB | 1,775 lines |
- # Elementare Grundfunktionen beim Arbeiten mit Integers
-
- # Umwandlungsroutinen Digit-Sequence-Teil <--> Longword:
-
- # get_32_Dptr(ptr)
- # holt die nächsten 32 Bits aus den 32/intDsize Digits ab ptr.
- # set_32_Dptr(ptr,wert);
- # speichert den Wert wert (32 Bits) in die 32/intDsize Digits ab ptr.
- # get_max32_Dptr(count,ptr)
- # holt die nächsten count Bits aus den ceiling(count/intDsize) Digits ab ptr.
- # set_max32_Dptr(count,ptr,wert)
- # speichert wert (count Bits) in die ceiling(count/intDsize) Digits ab ptr.
- # Jeweils ptr eine Variable vom Typ uintD*,
- # wert eine Variable vom Typ uint32,
- # count eine Variable oder constant-expression mit Wert >=0, <=32.
- #if (intDsize==32)
- #define get_32_Dptr(ptr) ((uint32)((ptr)[0]))
- #define set_32_Dptr(ptr,wert) ((ptr)[0] = (uintD)(wert))
- #define get_max32_Dptr(count,ptr) \
- ((count)==0 ? 0 : \
- (uint32)((ptr)[0]) \
- )
- #define set_max32_Dptr(count,ptr,wert) \
- ((count)==0 ? 0 : \
- ((ptr)[0] = (uintD)(wert)) \
- )
- #endif
- #if (intDsize==16)
- # define get_32_Dptr(ptr) (((uint32)((ptr)[0])<<16) | ((uint32)((ptr)[1])))
- #define get_32_Dptr(ptr) highlow32_at(ptr)
- # define set_32_Dptr(ptr,wert) ((ptr)[0] = (uintD)((wert)>>16), (ptr)[1] = (uintD)(wert))
- #define set_32_Dptr(ptr,wert) set_highlow32_at(ptr,wert)
- #define get_max32_Dptr(count,ptr) \
- ((count)==0 ? 0 : \
- (count)<=16 ? (uint32)((ptr)[0]) : \
- highlow32_at(ptr) \
- )
- #define set_max32_Dptr(count,ptr,wert) \
- ((count)==0 ? 0 : \
- (count)<=16 ? ((ptr)[0] = (uintD)(wert)) : \
- set_highlow32_at(ptr,wert) \
- )
- #endif
- #if (intDsize==8)
- #define get_32_Dptr(ptr) (((((( (uint32)((ptr)[0]) <<8) | (uint32)((ptr)[1])) <<8) | (uint32)((ptr)[2])) <<8) | (uint32)((ptr)[3]))
- #define set_32_Dptr(ptr,wert) ((ptr)[0] = (uintD)((wert)>>24), (ptr)[1] = (uintD)((wert)>>16), (ptr)[2] = (uintD)((wert)>>8), (ptr)[3] = (uintD)(wert))
- #define get_max32_Dptr(count,ptr) \
- ((count)==0 ? 0 : \
- (count)<=8 ? (uint32)((ptr)[0]) : \
- (count)<=16 ? (( (uint32)((ptr)[0]) <<8) | (uint32)((ptr)[1])) : \
- (count)<=24 ? (((( (uint32)((ptr)[0]) <<8) | (uint32)((ptr)[1])) <<8) | (uint32)((ptr)[2])) : \
- (((((( (uint32)((ptr)[0]) <<8) | (uint32)((ptr)[1])) <<8) | (uint32)((ptr)[2])) <<8) | (uint32)((ptr)[3])) \
- )
- #define set_max32_Dptr(count,ptr,wert) \
- ((count)==0 ? 0 : \
- (count)<=8 ? ((ptr)[0] = (uintD)(wert)) : \
- (count)<=16 ? ((ptr)[0] = (uintD)((wert)>>8), (ptr)[1] = (uintD)(wert)) : \
- (count)<=24 ? ((ptr)[0] = (uintD)((wert)>>16), (ptr)[1] = (uintD)((wert)>>8), (ptr)[2] = (uintD)(wert)) : \
- ((ptr)[0] = (uintD)((wert)>>24), (ptr)[1] = (uintD)((wert)>>16), (ptr)[2] = (uintD)((wert)>>8), (ptr)[3] = (uintD)(wert)) \
- )
- #endif
-
- # get_uint1D_Dptr(ptr) holt 1 Digit (unsigned) ab ptr
- # get_uint2D_Dptr(ptr) holt 2 Digits (unsigned) ab ptr
- # get_uint3D_Dptr(ptr) holt 3 Digits (unsigned) ab ptr
- # get_uint4D_Dptr(ptr) holt 4 Digits (unsigned) ab ptr
- # get_sint1D_Dptr(ptr) holt 1 Digit (signed) ab ptr
- # get_sint2D_Dptr(ptr) holt 2 Digits (signed) ab ptr
- # get_sint3D_Dptr(ptr) holt 3 Digits (signed) ab ptr
- # get_sint4D_Dptr(ptr) holt 4 Digits (signed) ab ptr
- # Jeweils ptr eine Variable vom Typ uintD*.
- #define get_uint1D_Dptr(ptr) ((uint32)((ptr)[0]))
- #define get_uint2D_Dptr(ptr) (((uint32)((ptr)[0]) << intDsize) | (uint32)((ptr)[1]))
- #define get_uint3D_Dptr(ptr) (((((uint32)((ptr)[0]) << intDsize) | (uint32)((ptr)[1])) << intDsize) | (uint32)((ptr)[2]))
- #define get_uint4D_Dptr(ptr) (((((((uint32)((ptr)[0]) << intDsize) | (uint32)((ptr)[1])) << intDsize) | (uint32)((ptr)[2])) << intDsize) | (uint32)((ptr)[3]))
- #define get_sint1D_Dptr(ptr) ((sint32)(sintD)((ptr)[0]))
- #define get_sint2D_Dptr(ptr) (((sint32)(sintD)((ptr)[0]) << intDsize) | (uint32)((ptr)[1]))
- #define get_sint3D_Dptr(ptr) (((((sint32)(sintD)((ptr)[0]) << intDsize) | (uint32)((ptr)[1])) << intDsize) | (uint32)((ptr)[2]))
- #define get_sint4D_Dptr(ptr) (((((((sint32)(sintD)((ptr)[0]) << intDsize) | (uint32)((ptr)[1])) << intDsize) | (uint32)((ptr)[2])) << intDsize) | (uint32)((ptr)[3]))
- #if (intDsize==16) && (defined(MC680X0) && !defined(MC680Y0)) # Verbesserung:
- #undef get_uint2D_Dptr
- #undef get_sint2D_Dptr
- #define get_uint2D_Dptr(ptr) highlow32_at(ptr)
- #define get_sint2D_Dptr(ptr) (sint32)highlow32_at(ptr)
- #endif
- #if (intDsize==16)
- #undef get_uint3D_Dptr
- #undef get_uint4D_Dptr
- #undef get_sint3D_Dptr
- #undef get_sint4D_Dptr
- #define get_uint3D_Dptr(ptr) get_uint2D_Dptr(&(ptr)[1])
- #define get_uint4D_Dptr(ptr) get_uint2D_Dptr(&(ptr)[2])
- #define get_sint3D_Dptr get_uint3D_Dptr
- #define get_sint4D_Dptr get_uint4D_Dptr
- #endif
- #if (intDsize==32)
- #undef get_uint2D_Dptr
- #undef get_uint3D_Dptr
- #undef get_uint4D_Dptr
- #undef get_sint2D_Dptr
- #undef get_sint3D_Dptr
- #undef get_sint4D_Dptr
- #define get_uint2D_Dptr(ptr) get_uint1D_Dptr(&(ptr)[1])
- #define get_uint3D_Dptr(ptr) get_uint1D_Dptr(&(ptr)[2])
- #define get_uint4D_Dptr(ptr) get_uint1D_Dptr(&(ptr)[3])
- #define get_sint2D_Dptr get_uint2D_Dptr
- #define get_sint3D_Dptr get_uint3D_Dptr
- #define get_sint4D_Dptr get_uint4D_Dptr
- #endif
-
- # Umwandlungsroutinen Integer <--> Longword:
-
- # Wandelt Fixnum in Longword um.
- # FN_to_L(obj)
- # > obj: ein Fixnum
- # < ergebnis: der Wert des Fixnum als 32-Bit-Zahl.
- local sint32 FN_to_L (object obj);
- #if 1
- #define FN_to_L(obj) fixnum_to_L(obj)
- #else
- local sint32 FN_to_L(obj)
- var reg1 object obj;
- { if (R_minusp(obj))
- # negativ: mit 1-Bits füllen
- return (as_oint(obj) >> oint_data_shift) | ~ (FN_value_mask >> oint_data_shift);
- else
- # >=0: mit 0-Bits füllen
- return (as_oint(obj) >> oint_data_shift) & (FN_value_mask >> oint_data_shift);
- }
- #endif
-
- # FN_L_zerop(x,x_) stellt fest, ob x = 0 ist.
- # Dabei ist x ein Fixnum und x_ = FN_to_L(x).
- #if (oint_data_len<intLsize)
- #define FN_L_zerop(x,x_) (x_==0)
- #else
- #define FN_L_zerop(x,x_) (eq(x,Fixnum_0))
- #endif
-
- # FN_L_minusp(x,x_) stellt fest, ob x < 0 ist.
- # Dabei ist x ein Fixnum und x_ = FN_to_L(x).
- #if (oint_data_len<intLsize)
- #define FN_L_minusp(x,x_) (x_<0)
- #else
- #define FN_L_minusp(x,x_) (R_minusp(x))
- #endif
-
- #ifdef intQsize
- # Wandelt Fixnum in Quadword um.
- # FN_to_Q(obj)
- # > obj: ein Fixnum
- # < ergebnis: der Wert des Fixnum als 64-Bit-Zahl.
- local sint64 FN_to_Q (object obj);
- #define FN_to_Q(obj) fixnum_to_Q(obj)
- #endif
-
- # Wandelt Integer >=0 in Unsigned Longword um.
- # I_to_UL(obj)
- # > obj: ein Objekt, sollte ein Integer >=0, <2^32 sein
- # < ergebnis: der Wert des Integer als 32-Bit-Zahl.
- global uint32 I_to_UL (object obj);
- global uint32 I_to_UL(obj)
- var reg2 object obj;
- { switch (typecode(obj))
- { case_posfixnum: # Fixnum >=0
- return posfixnum_to_L(obj);
- case_posbignum: # Bignum >0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) \
- if ( (i*intDsize-1 > 32) \
- && ( ((i-1)*intDsize-1 >= 32) \
- || (bn->data[0] >= (uintD)bitc(32-(i-1)*intDsize)) \
- ) ) \
- goto bad; \
- else
- IF_LENGTH(1)
- return get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return get_uint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return get_uint4D_Dptr(bn->data);
- IF_LENGTH(5)
- return get_uint4D_Dptr(&bn->data[1]);
- #undef IF_LENGTH
- }
- default:
- bad: # unpassendes Objekt
- pushSTACK(obj); # Wert für Slot DATUM von TYPE-ERROR
- pushSTACK(O(type_uint32)); # Wert für Slot EXPECTED-TYPE von TYPE-ERROR
- pushSTACK(obj);
- //: DEUTSCH "Das ist keine 32-Bit-Zahl: ~"
- //: ENGLISH "not a 32-bit integer: ~"
- //: FRANCAIS "Ceci n'est pas un nombre à 32 bits : ~"
- fehler(type_error, GETTEXT("not a 32-bit integer: ~"));
- } }
-
- # Wandelt Integer in Signed Longword um.
- # I_to_L(obj)
- # > obj: ein Objekt, sollte ein Integer >=-2^31, <2^31 sein
- # < ergebnis: der Wert des Integer als 32-Bit-Zahl.
- global sint32 I_to_L (object obj);
- global sint32 I_to_L(obj)
- var reg2 object obj;
- { switch (typecode(obj))
- { case_posfixnum: # Fixnum >=0
- { var reg1 sintL wert = posfixnum_to_L(obj);
- if ((oint_data_len+1 > intLsize) && (wert < 0)) goto bad;
- return wert;
- }
- case_posbignum: # Bignum >0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) \
- if ( (i*intDsize > 32) \
- && ( ((i-1)*intDsize >= 32) \
- || (bn->data[0] >= (uintD)bitc(31-(i-1)*intDsize)) \
- ) ) \
- goto bad; \
- else
- IF_LENGTH(1)
- return get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return get_uint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return get_uint4D_Dptr(bn->data);
- #undef IF_LENGTH
- goto bad;
- }
- case_negfixnum: # Fixnum <0
- { var reg1 sintL wert = negfixnum_to_L(obj);
- if ((oint_data_len+1 > intLsize) && (wert >= 0)) goto bad;
- return wert;
- }
- case_negbignum: # Bignum <0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) \
- if ( (i*intDsize > 32) \
- && ( ((i-1)*intDsize >= 32) \
- || (bn->data[0] < (uintD)(-bitc(31-(i-1)*intDsize))) \
- ) ) \
- goto bad; \
- else
- IF_LENGTH(1)
- return get_sint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return get_sint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return get_sint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return get_sint4D_Dptr(bn->data);
- #undef IF_LENGTH
- goto bad;
- }
- default:
- bad: # unpassendes Objekt
- pushSTACK(obj); # Wert für Slot DATUM von TYPE-ERROR
- pushSTACK(O(type_sint32)); # Wert für Slot EXPECTED-TYPE von TYPE-ERROR
- pushSTACK(obj);
- //: DEUTSCH "Das ist keine 32-Bit-Zahl: ~"
- //: ENGLISH "not a 32-bit integer: ~"
- //: FRANCAIS "Ceci n'est pas un nombre à 32 bits : ~"
- fehler(type_error, GETTEXT("not a 32-bit integer: ~"));
- } }
-
- #if (defined(HAVE_FFI) || defined(HAVE_AFFI)) && defined(HAVE_LONGLONG)
-
- # Wandelt Integer >=0 in Unsigned Quadword um.
- # I_to_UQ(obj)
- # > obj: ein Objekt, sollte ein Integer >=0, <2^64 sein
- # < ergebnis: der Wert des Integer als 64-Bit-Zahl.
- global uint64 I_to_UQ (object obj);
- global uint64 I_to_UQ(obj)
- var reg2 object obj;
- { switch (typecode(obj))
- { case_posfixnum: # Fixnum >=0
- return (uint64)posfixnum_to_L(obj);
- case_posbignum: # Bignum >0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) \
- if ( (i*intDsize-1 > 64) \
- && ( ((i-1)*intDsize-1 >= 64) \
- || (bn->data[0] >= (uintD)bitc(64-(i-1)*intDsize)) \
- ) ) \
- goto bad; \
- else
- #if (intDsize==32)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint1D_Dptr(&bn->data[1]);
- IF_LENGTH(3)
- return ((uint64)get_uint1D_Dptr(&bn->data[1]) << 32) | (uint64)get_uint1D_Dptr(&bn->data[2]);
- #endif
- #if (intDsize==16)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (uint64)get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[1]);
- IF_LENGTH(4)
- return ((uint64)get_uint2D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[2]);
- IF_LENGTH(5)
- return ((uint64)get_uint2D_Dptr(&bn->data[1]) << 32) | (uint64)get_uint2D_Dptr(&bn->data[3]);
- #endif
- #if (intDsize==8)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (uint64)get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return (uint64)get_uint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return (uint64)get_uint4D_Dptr(bn->data);
- IF_LENGTH(5)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[1]);
- IF_LENGTH(6)
- return ((uint64)get_uint2D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[2]);
- IF_LENGTH(7)
- return ((uint64)get_uint3D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[3]);
- IF_LENGTH(8)
- return ((uint64)get_uint4D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[4]);
- IF_LENGTH(9)
- return ((uint64)get_uint4D_Dptr(&bn->data[1]) << 32) | (uint64)get_uint4D_Dptr(&bn->data[5]);
- #endif
- #undef IF_LENGTH
- }
- default:
- bad: # unpassendes Objekt
- pushSTACK(obj); # Wert für Slot DATUM von TYPE-ERROR
- pushSTACK(O(type_uint64)); # Wert für Slot EXPECTED-TYPE von TYPE-ERROR
- pushSTACK(obj);
- //: DEUTSCH "Das ist keine 64-Bit-Zahl: ~"
- //: ENGLISH "not a 64-bit integer: ~"
- //: FRANCAIS "Ceci n'est pas un nombre à 64 bits : ~"
- fehler(type_error, GETTEXT("not a 64-bit integer: ~"));
- } }
-
- #endif
- #if defined(HAVE_FFI) && defined(HAVE_LONGLONG)
-
- # Wandelt Integer in Signed Quadword um.
- # I_to_Q(obj)
- # > obj: ein Objekt, sollte ein Integer >=-2^63, <2^63 sein
- # < ergebnis: der Wert des Integer als 64-Bit-Zahl.
- global sint64 I_to_Q (object obj);
- global sint64 I_to_Q(obj)
- var reg2 object obj;
- { switch (typecode(obj))
- { case_posfixnum: # Fixnum >=0
- return (uint64)posfixnum_to_L(obj);
- case_posbignum: # Bignum >0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) \
- if ( (i*intDsize > 64) \
- && ( ((i-1)*intDsize >= 64) \
- || (bn->data[0] >= (uintD)bitc(63-(i-1)*intDsize)) \
- ) ) \
- goto bad; \
- else
- #if (intDsize==32)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint1D_Dptr(&bn->data[1]);
- #endif
- #if (intDsize==16)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (uint64)get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[1]);
- IF_LENGTH(4)
- return ((uint64)get_uint2D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[2]);
- #endif
- #if (intDsize==8)
- IF_LENGTH(1)
- return (uint64)get_uint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (uint64)get_uint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return (uint64)get_uint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return (uint64)get_uint4D_Dptr(bn->data);
- IF_LENGTH(5)
- return ((uint64)get_uint1D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[1]);
- IF_LENGTH(6)
- return ((uint64)get_uint2D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[2]);
- IF_LENGTH(7)
- return ((uint64)get_uint3D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[3]);
- IF_LENGTH(8)
- return ((uint64)get_uint4D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[4]);
- #endif
- #undef IF_LENGTH
- goto bad;
- }
- case_negfixnum: # Fixnum <0
- return (uint64)(uintL)negfixnum_to_L(obj) | (-wbitm(intLsize));
- case_negbignum: # Bignum <0
- { var reg1 Bignum bn = TheBignum(obj);
- var reg3 uintC len = bn->length;
- #define IF_LENGTH(i) \
- if (bn_minlength <= i) # genau i Digits überhaupt möglich? \
- if (len == i) # genau i Digits? \
- # - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) \
- if ( (i*intDsize > 64) \
- && ( ((i-1)*intDsize >= 64) \
- || (bn->data[0] < (uintD)(-bitc(63-(i-1)*intDsize))) \
- ) ) \
- goto bad; \
- else
- #if (intDsize==32)
- IF_LENGTH(1)
- return (sint64)get_sint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return ((sint64)get_sint1D_Dptr(bn->data) << 32) | (uint64)get_uint1D_Dptr(&bn->data[1]);
- #endif
- #if (intDsize==16)
- IF_LENGTH(1)
- return (sint64)get_sint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (sint64)get_sint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return ((sint64)get_sint1D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[1]);
- IF_LENGTH(4)
- return ((sint64)get_sint2D_Dptr(bn->data) << 32) | (uint64)get_uint2D_Dptr(&bn->data[2]);
- #endif
- #if (intDsize==8)
- IF_LENGTH(1)
- return (sint64)get_sint1D_Dptr(bn->data);
- IF_LENGTH(2)
- return (sint64)get_sint2D_Dptr(bn->data);
- IF_LENGTH(3)
- return (sint64)get_sint3D_Dptr(bn->data);
- IF_LENGTH(4)
- return (sint64)get_sint4D_Dptr(bn->data);
- IF_LENGTH(5)
- return ((sint64)get_sint1D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[1]);
- IF_LENGTH(6)
- return ((sint64)get_sint2D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[2]);
- IF_LENGTH(7)
- return ((sint64)get_sint3D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[3]);
- IF_LENGTH(8)
- return ((sint64)get_sint4D_Dptr(bn->data) << 32) | (uint64)get_uint4D_Dptr(&bn->data[4]);
- #endif
- #undef IF_LENGTH
- goto bad;
- }
- default:
- bad: # unpassendes Objekt
- pushSTACK(obj); # Wert für Slot DATUM von TYPE-ERROR
- pushSTACK(O(type_sint64)); # Wert für Slot EXPECTED-TYPE von TYPE-ERROR
- pushSTACK(obj);
- //: DEUTSCH "Das ist keine 64-Bit-Zahl: ~"
- //: ENGLISH "not a 64-bit integer: ~"
- //: FRANCAIS "Ceci n'est pas un nombre à 64 bits : ~"
- fehler(type_error, GETTEXT("not a 64-bit integer: ~"));
- } }
-
- #endif
-
- # Wandelt Longword in Fixnum um.
- # L_to_FN(wert)
- # > wert: Wert des Fixnums, ein signed 32-Bit-Integer
- # >= -2^oint_data_len, < 2^oint_data_len
- # < ergebnis: Fixnum mit diesem Wert.
- # wert sollte eine Variable sein.
- #if (oint_data_shift <= vorz_bit_o)
- #define L_to_FN(wert) \
- as_object((( (soint)(sint32)(wert) \
- & (FN_value_vz_mask>>oint_data_shift) # Unnötiges wegmaskieren \
- ) << oint_data_shift \
- ) \
- | ((oint)fixnum_type<<oint_type_shift) # dafür Typinfo rein \
- )
- #else # (oint_data_shift > vorz_bit_o)
- #define L_to_FN(wert) \
- as_object((( (soint)(sint32)(wert) << oint_data_shift ) \
- & FN_value_mask # Unnötiges wegmaskieren \
- ) \
- | ((soint)(sint32)sign_of_sint32((sint32)(wert)) & bit(vorz_bit_o)) \
- | ((oint)fixnum_type<<oint_type_shift) # dafür Typinfo rein \
- )
- #endif
-
- # Wandelt Longword in Integer um.
- # L_to_I(wert)
- # > wert: Wert des Integers, ein signed 32-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- global object L_to_I (sint32 wert);
- #if (oint_data_len+1 >= intLsize)
- inline global object L_to_I(wert)
- var reg2 sint32 wert;
- { return L_to_FN(wert); }
- #else
- global object L_to_I(wert)
- var reg2 sint32 wert;
- {{var reg1 uint32 test = wert & (uint32)(~(FN_value_mask >> oint_data_shift));
- # test enthält die Bits, die nicht in den Fixnum-Wert reinpassen.
- if (test == (uint32)0) # alle =0 ?
- return as_object(((oint)fixnum_type<<oint_type_shift) | ((oint)wert<<oint_data_shift));
- if (test == (uint32)(~(FN_value_mask >> oint_data_shift))) # alle =1 ?
- return as_object(((((oint)fixnum_vz_type<<oint_type_shift)+FN_value_mask) & ((oint)wert<<oint_data_shift))
- |(((oint)fixnum_vz_type<<oint_type_shift) & (wbit(oint_data_shift)-1))
- );
- }
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling(32/intDsize) erfüllt)
- if (bn_minlength == ceiling(32,intDsize))
- #if (intDsize==8)
- { if (wert >= 0) goto pos4; else goto neg4; } # Bignum mit 32/intDsize = 4 Digits
- #endif
- #if (intDsize==16)
- { if (wert >= 0) goto pos2; else goto neg2; } # Bignum mit 32/intDsize = 2 Digits
- #endif
- #if (intDsize==32)
- { if (wert >= 0) goto pos1; else goto neg1; } # Bignum mit 32/intDsize = 1 Digits
- #endif
- else
- {
- #define FILL_1_DIGIT(from) \
- *ptr-- = (uintD)from;
- #define FILL_2_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_3_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_4_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_1 FILL_1_DIGIT(wert);
- #define FILL_2 FILL_2_DIGITS(wert);
- #define FILL_3 FILL_3_DIGITS(wert);
- #define FILL_4 FILL_4_DIGITS(wert);
- #define OK return new;
- if (wert >= 0)
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,0); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 32)) \
- if (!((i+1)*intDsize <= 32) \
- || ((uint32)wert < (uint32)bitc(i*intDsize-1)) \
- )
- #if (intDsize <= 32)
- IF_LENGTH(1)
- pos1:
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- #if (intDsize <= 16)
- IF_LENGTH(2)
- pos2:
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- #if (intDsize <= 8)
- IF_LENGTH(3)
- { ALLOC(3); FILL_3; OK; } # Bignum mit 3 Digits
- IF_LENGTH(4)
- pos4:
- { ALLOC(4); FILL_4; OK; } # Bignum mit 4 Digits
- #endif
- #endif
- #endif
- #undef IF_LENGTH
- #undef ALLOC
- }
- else
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,-1); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 32)) \
- if (!((i+1)*intDsize <= 32) \
- || ((uint32)wert >= (uint32)(-bitc(i*intDsize-1))) \
- )
- #if (intDsize <= 32)
- IF_LENGTH(1)
- neg1:
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- #if (intDsize <= 16)
- IF_LENGTH(2)
- neg2:
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- #if (intDsize <= 8)
- IF_LENGTH(3)
- { ALLOC(3); FILL_3; OK; } # Bignum mit 3 Digits
- IF_LENGTH(4)
- neg4:
- { ALLOC(4); FILL_4; OK; } # Bignum mit 4 Digits
- #endif
- #endif
- #endif
- #undef IF_LENGTH
- #undef ALLOC
- }
- #undef OK
- #undef FILL_4
- #undef FILL_3
- #undef FILL_2
- #undef FILL_1
- #undef FILL_4_DIGITS
- #undef FILL_3_DIGITS
- #undef FILL_2_DIGITS
- #undef FILL_1_DIGIT
- }
- }
- #endif
-
- # Wandelt Unsigned Longword in Integer >=0 um.
- # UL_to_I(wert)
- # > wert: Wert des Integers, ein unsigned 32-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- #ifndef UL_to_I # wenn nicht schon als Macro definiert
- global object UL_to_I (uint32 wert);
- global object UL_to_I(wert)
- var reg2 uint32 wert;
- { if ((wert & ~ (FN_value_mask >> oint_data_shift)) == 0)
- # alle Bits, die nicht in den Fixnum-Wert reinpassen, =0 ?
- return as_object(((oint)fixnum_type<<oint_type_shift) | (wert<<oint_data_shift));
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling((32+1)/intDsize) erfüllt)
- #define UL_maxlength ceiling(32+1,intDsize)
- #if (bn_minlength <= 1) && (UL_maxlength >= 1)
- if ((1*intDsize-1 < 32)
- ? (wert <= (uint32)(bitc(1*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 1 Digit
- { var reg1 object new = allocate_bignum(1,0);
- TheBignum(new)->data[0] = (uintD)wert;
- return new;
- }
- #endif
- #if (bn_minlength <= 2) && (UL_maxlength >= 2)
- if ((2*intDsize-1 < 32)
- ? (wert <= (uint32)(bitc(2*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 2 Digits
- { var reg2 object new = allocate_bignum(2,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[1];
- *ptr-- = (uintD)wert;
- #if (intDsize>=32)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 3) && (UL_maxlength >= 3)
- if ((3*intDsize-1 < 32)
- ? (wert <= (uint32)(bitc(3*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 3 Digits
- { var reg2 object new = allocate_bignum(3,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[2];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (2*intDsize>=32)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 4) && (UL_maxlength >= 4)
- if ((4*intDsize-1 < 32)
- ? (wert <= (uint32)(bitc(4*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 4 Digits
- { var reg2 object new = allocate_bignum(4,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[3];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (3*intDsize>=32)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 5) && (UL_maxlength >= 5)
- if (TRUE)
- # Bignum mit 5 Digits
- { var reg2 object new = allocate_bignum(5,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[4];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (4*intDsize>=32)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- }
- #endif
-
- # Wandelt Doppel-Longword in Integer um.
- # L2_to_I(wert_hi,wert_lo)
- # > wert_hi|wert_lo: Wert des Integers, ein signed 64-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- global object L2_to_I (sint32 wert_hi, uint32 wert_lo);
- global object L2_to_I(wert_hi,wert_lo)
- var reg2 sint32 wert_hi;
- var reg2 uint32 wert_lo;
- { if (wert_hi == 0)
- { if ((wert_lo & (uint32)(~(FN_value_mask >> oint_data_shift))) # Bits von wert_lo, die nicht in den Fixnum-Wert passen
- == (uint32)0 # alle =0 ?
- )
- return as_object(((oint)fixnum_type<<oint_type_shift) | ((oint)wert_lo<<oint_data_shift));
- }
- elif (wert_hi == ~(uintL)0)
- { if ((wert_lo & (uint32)(~(FN_value_mask >> oint_data_shift))) # Bits von wert_lo, die nicht in den Fixnum-Wert passen
- == (uint32)(~(FN_value_mask >> oint_data_shift)) # alle =1 ?
- )
- #ifndef WIDE
- return as_object(((((oint)fixnum_vz_type<<oint_type_shift)+FN_value_mask) & (wert_lo<<oint_data_shift))
- |(((oint)fixnum_vz_type<<oint_type_shift) & (wbit(oint_data_shift)-1))
- );
- #else
- return as_object(((oint)fixnum_vz_type<<oint_type_shift) | ((oint)(wert_lo & (uint32)(FN_value_mask >> oint_data_shift)) << oint_data_shift));
- #endif
- }
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling(64/intDsize) erfüllt)
- #define FILL_1_DIGIT(from) \
- *ptr-- = (uintD)from;
- #define FILL_2_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_3_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_4_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #if (32/intDsize==1)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_1_DIGIT(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_3
- #define FILL_4
- #define FILL_5
- #define FILL_6
- #define FILL_7
- #define FILL_8
- #endif
- #if (32/intDsize==2)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_2_DIGITS(wert_lo);
- #define FILL_3 FILL_2_DIGITS(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_4 FILL_2_DIGITS(wert_lo); FILL_2_DIGITS(wert_hi);
- #define FILL_5
- #define FILL_6
- #define FILL_7
- #define FILL_8
- #endif
- #if (32/intDsize==4)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_2_DIGITS(wert_lo);
- #define FILL_3 FILL_3_DIGITS(wert_lo);
- #define FILL_4 FILL_4_DIGITS(wert_lo);
- #define FILL_5 FILL_4_DIGITS(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_6 FILL_4_DIGITS(wert_lo); FILL_2_DIGITS(wert_hi);
- #define FILL_7 FILL_4_DIGITS(wert_lo); FILL_3_DIGITS(wert_hi);
- #define FILL_8 FILL_4_DIGITS(wert_lo); FILL_4_DIGITS(wert_hi);
- #endif
- #define OK return new;
- if (wert_hi >= 0)
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,0); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 64)) \
- if (!((i+1)*intDsize <= 64) \
- || (i*intDsize-1 < 32 \
- ? ((wert_hi == 0) && (wert_lo < (uint32)bitc(i*intDsize-1))) \
- : ((uint32)wert_hi < (uint32)bitc(i*intDsize-1-32)) \
- ) )
- IF_LENGTH(1)
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- IF_LENGTH(2)
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- IF_LENGTH(3)
- { ALLOC(3); FILL_3; OK; } # Bignum mit 3 Digits
- IF_LENGTH(4)
- { ALLOC(4); FILL_4; OK; } # Bignum mit 4 Digits
- IF_LENGTH(5)
- { ALLOC(5); FILL_5; OK; } # Bignum mit 5 Digits
- IF_LENGTH(6)
- { ALLOC(6); FILL_6; OK; } # Bignum mit 6 Digits
- IF_LENGTH(7)
- { ALLOC(7); FILL_7; OK; } # Bignum mit 7 Digits
- IF_LENGTH(8)
- { ALLOC(8); FILL_8; OK; } # Bignum mit 8 Digits
- #undef IF_LENGTH
- #undef ALLOC
- }
- else
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,-1); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 64)) \
- if (!((i+1)*intDsize <= 64) \
- || (i*intDsize-1 < 32 \
- ? ((wert_hi == ~(uint32)0) && (wert_lo >= (uint32)(-bitc(i*intDsize-1)))) \
- : ((uint32)wert_hi >= (uint32)(-bitc(i*intDsize-1-32))) \
- ) )
- IF_LENGTH(1)
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- IF_LENGTH(2)
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- IF_LENGTH(3)
- { ALLOC(3); FILL_3; OK; } # Bignum mit 3 Digits
- IF_LENGTH(4)
- { ALLOC(4); FILL_4; OK; } # Bignum mit 4 Digits
- IF_LENGTH(5)
- { ALLOC(5); FILL_5; OK; } # Bignum mit 5 Digits
- IF_LENGTH(6)
- { ALLOC(6); FILL_6; OK; } # Bignum mit 6 Digits
- IF_LENGTH(7)
- { ALLOC(7); FILL_7; OK; } # Bignum mit 7 Digits
- IF_LENGTH(8)
- { ALLOC(8); FILL_8; OK; } # Bignum mit 8 Digits
- #undef IF_LENGTH
- #undef ALLOC
- }
- #undef OK
- #undef FILL_8
- #undef FILL_7
- #undef FILL_6
- #undef FILL_5
- #undef FILL_4
- #undef FILL_3
- #undef FILL_2
- #undef FILL_1
- #undef FILL_4_DIGITS
- #undef FILL_3_DIGITS
- #undef FILL_2_DIGITS
- #undef FILL_1_DIGIT
- }
-
- #ifdef HAVE_FFI
- # Wandelt Unsigned Doppel-Longword in Integer um.
- # UL2_to_I(wert_hi,wert_lo)
- # > wert_hi|wert_lo: Wert des Integers, ein unsigned 64-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- global object UL2_to_I (uint32 wert_hi, uint32 wert_lo);
- global object UL2_to_I(wert_hi,wert_lo)
- var reg2 uint32 wert_hi;
- var reg2 uint32 wert_lo;
- { if ((wert_hi == 0)
- && ((wert_lo & (uint32)(~(FN_value_mask >> oint_data_shift))) # Bits von wert_lo, die nicht in den Fixnum-Wert passen
- == (uint32)0 # alle =0 ?
- ) )
- return as_object(((oint)fixnum_type<<oint_type_shift) | ((oint)wert_lo<<oint_data_shift));
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling((64+1)/intDsize) erfüllt)
- #define UL2_maxlength ceiling(64+1,intDsize)
- #define FILL_1_DIGIT(from) \
- *ptr-- = (uintD)from;
- #define FILL_2_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_3_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_4_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #if (32/intDsize==1)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_1_DIGIT(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_3 FILL_2 *ptr-- = 0;
- #define FILL_4
- #define FILL_5
- #define FILL_6
- #define FILL_7
- #define FILL_8
- #define FILL_9
- #endif
- #if (32/intDsize==2)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_2_DIGITS(wert_lo);
- #define FILL_3 FILL_2_DIGITS(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_4 FILL_2_DIGITS(wert_lo); FILL_2_DIGITS(wert_hi);
- #define FILL_5 FILL_4 *ptr-- = 0;
- #define FILL_6
- #define FILL_7
- #define FILL_8
- #define FILL_9
- #endif
- #if (32/intDsize==4)
- #define FILL_1 FILL_1_DIGIT(wert_lo);
- #define FILL_2 FILL_2_DIGITS(wert_lo);
- #define FILL_3 FILL_3_DIGITS(wert_lo);
- #define FILL_4 FILL_4_DIGITS(wert_lo);
- #define FILL_5 FILL_4_DIGITS(wert_lo); FILL_1_DIGIT(wert_hi);
- #define FILL_6 FILL_4_DIGITS(wert_lo); FILL_2_DIGITS(wert_hi);
- #define FILL_7 FILL_4_DIGITS(wert_lo); FILL_3_DIGITS(wert_hi);
- #define FILL_8 FILL_4_DIGITS(wert_lo); FILL_4_DIGITS(wert_hi);
- #define FILL_9 FILL_8 *ptr-- = 0;
- #endif
- #define OK return new;
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,0); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (UL2_maxlength >= i)) \
- if ((i*intDsize >= 64+1) \
- || (i*intDsize-1 < 32 \
- ? ((wert_hi == 0) && (wert_lo < (uint32)bitc(i*intDsize-1))) \
- : (wert_hi < (uint32)bitc(i*intDsize-1-32)) \
- ) )
- IF_LENGTH(1)
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- IF_LENGTH(2)
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- IF_LENGTH(3)
- { ALLOC(3); FILL_3; OK; } # Bignum mit 3 Digits
- IF_LENGTH(4)
- { ALLOC(4); FILL_4; OK; } # Bignum mit 4 Digits
- IF_LENGTH(5)
- { ALLOC(5); FILL_5; OK; } # Bignum mit 5 Digits
- IF_LENGTH(6)
- { ALLOC(6); FILL_6; OK; } # Bignum mit 6 Digits
- IF_LENGTH(7)
- { ALLOC(7); FILL_7; OK; } # Bignum mit 7 Digits
- IF_LENGTH(8)
- { ALLOC(8); FILL_8; OK; } # Bignum mit 8 Digits
- IF_LENGTH(8)
- { ALLOC(9); FILL_9; OK; } # Bignum mit 9 Digits
- #undef IF_LENGTH
- #undef ALLOC
- #undef OK
- #undef FILL_9
- #undef FILL_8
- #undef FILL_7
- #undef FILL_6
- #undef FILL_5
- #undef FILL_4
- #undef FILL_3
- #undef FILL_2
- #undef FILL_1
- #undef FILL_4_DIGITS
- #undef FILL_3_DIGITS
- #undef FILL_2_DIGITS
- #undef FILL_1_DIGIT
- }
- #endif
-
- #ifdef HAVE_FFI
- #ifdef intQsize
- # Wandelt Quadword in Integer um.
- # Q_to_I(wert)
- # > wert: Wert des Integers, ein signed 64-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- global object Q_to_I (sint64 wert);
- global object Q_to_I(wert)
- var reg2 sint64 wert;
- {{var reg1 uint64 test = wert & ~(uint64)(FN_value_mask >> oint_data_shift);
- # test enthält die Bits, die nicht in den Fixnum-Wert reinpassen.
- if (test == (uint64)0) # alle =0 ?
- return as_object(((oint)fixnum_type<<oint_type_shift) | ((oint)wert<<oint_data_shift));
- if (test == ~(uint64)(FN_value_mask >> oint_data_shift)) # alle =1 ?
- return as_object(((((oint)fixnum_vz_type<<oint_type_shift)+FN_value_mask) & ((oint)wert<<oint_data_shift))
- |(((oint)fixnum_vz_type<<oint_type_shift) & (wbit(oint_data_shift)-1))
- );
- }
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling(64/intDsize) = 2 erfüllt)
- #define FILL_1_DIGIT(from) \
- *ptr-- = (uintD)from;
- #define FILL_2_DIGITS(from) \
- *ptr-- = (uintD)from; from = from >> intDsize; \
- *ptr-- = (uintD)from;
- #define FILL_1 FILL_1_DIGIT(wert);
- #define FILL_2 FILL_2_DIGITS(wert);
- #define OK return new;
- if (wert >= 0)
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,0); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 64)) \
- if (!((i+1)*intDsize <= 64) \
- || ((uint64)wert < (uint64)bit(i*intDsize-1)) \
- )
- IF_LENGTH(1)
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- IF_LENGTH(2)
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- #undef IF_LENGTH
- #undef ALLOC
- }
- else
- {
- #define ALLOC(i) \
- var reg2 object new = allocate_bignum(i,-1); \
- var reg1 uintD* ptr = &TheBignum(new)->data[i-1];
- #define IF_LENGTH(i) \
- if ((bn_minlength <= i) && (i*intDsize <= 64)) \
- if (!((i+1)*intDsize <= 64) \
- || ((uint64)wert >= (uint64)(-bit(i*intDsize-1))) \
- )
- IF_LENGTH(1)
- { ALLOC(1); FILL_1; OK; } # Bignum mit 1 Digit
- IF_LENGTH(2)
- { ALLOC(2); FILL_2; OK; } # Bignum mit 2 Digits
- #undef IF_LENGTH
- #undef ALLOC
- }
- #undef OK
- #undef FILL_2
- #undef FILL_1
- #undef FILL_2_DIGITS
- #undef FILL_1_DIGIT
- }
- #endif
- #endif
-
- #if defined(intQsize) || defined(WIDE_HARD)
- # Wandelt Unsigned Quadword in Integer >=0 um.
- # UQ_to_I(wert)
- # > wert: Wert des Integers, ein unsigned 64-Bit-Integer.
- # < ergebnis: Integer mit diesem Wert.
- # kann GC auslösen
- global object UQ_to_I (uint64 wert);
- global object UQ_to_I(wert)
- var reg2 uint64 wert;
- { if ((wert & ~ (FN_value_mask >> oint_data_shift)) == 0)
- # alle Bits, die nicht in den Fixnum-Wert reinpassen, =0 ?
- return as_object(((oint)fixnum_type<<oint_type_shift) | (wert<<oint_data_shift));
- # Bignum erzeugen:
- # (dessen Länge bn_minlength <= n <= ceiling((64+1)/intDsize) erfüllt)
- #define UQ_maxlength ceiling(64+1,intDsize)
- #if (bn_minlength <= 1) && (UQ_maxlength >= 1)
- if ((1*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(1*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 1 Digit
- { var reg1 object new = allocate_bignum(1,0);
- TheBignum(new)->data[0] = (uintD)wert;
- return new;
- }
- #endif
- #if (bn_minlength <= 2) && (UQ_maxlength >= 2)
- if ((2*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(2*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 2 Digits
- { var reg2 object new = allocate_bignum(2,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[1];
- *ptr-- = (uintD)wert;
- #if (intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 3) && (UQ_maxlength >= 3)
- if ((3*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(3*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 3 Digits
- { var reg2 object new = allocate_bignum(3,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[2];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (2*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 4) && (UQ_maxlength >= 4)
- if ((4*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(4*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 4 Digits
- { var reg2 object new = allocate_bignum(4,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[3];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (3*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 5) && (UQ_maxlength >= 5)
- if ((5*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(5*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 5 Digits
- { var reg2 object new = allocate_bignum(5,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[4];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (4*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 6) && (UQ_maxlength >= 6)
- if ((6*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(6*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 6 Digits
- { var reg2 object new = allocate_bignum(6,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[5];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (5*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 7) && (UQ_maxlength >= 7)
- if ((7*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(7*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 7 Digits
- { var reg2 object new = allocate_bignum(7,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[6];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (6*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 8) && (UQ_maxlength >= 8)
- if ((8*intDsize-1 < 64)
- ? (wert <= (uint64)(bitc(8*intDsize-1)-1))
- : TRUE
- )
- # Bignum mit 8 Digits
- { var reg2 object new = allocate_bignum(8,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[7];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (7*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- #if (bn_minlength <= 9) && (UQ_maxlength >= 9)
- if (TRUE)
- # Bignum mit 9 Digits
- { var reg2 object new = allocate_bignum(9,0);
- var reg1 uintD* ptr = &TheBignum(new)->data[8];
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert; wert = wert >> intDsize;
- *ptr-- = (uintD)wert;
- #if (8*intDsize>=64)
- *ptr = 0;
- #else
- wert = wert >> intDsize; *ptr = (uintD)wert;
- #endif
- return new;
- }
- #endif
- }
- #endif
-
- # Liefert die Differenz x-y zweier Unsigned Longwords x,y als Integer.
- # UL_UL_minus_I(x,y)
- local object UL_UL_minus_I (object x, object y);
- #ifdef intQsize
- #define UL_UL_minus_I(x,y) Q_to_I((sintQ)(uintQ)(x)-(sintQ)(uintQ)(y))
- #else
- #define UL_UL_minus_I(x,y) L2_to_I( ((x)<(y) ? -1L : 0), (x)-(y) )
- #endif
-
- # Umwandlungsroutinen Digit sequence --> Integer:
-
- # Normalized Digit sequence to Integer
- # NDS_to_I(MSDptr,len)
- # Digit Sequence MSDptr/len/.. in Integer umwandeln.
- # kann GC auslösen
- local object NDS_to_I (uintD* MSDptr, uintC len);
- local object NDS_to_I(MSDptr,len)
- var reg2 uintD* MSDptr;
- var reg3 uintC len;
- { # Mehr als bn_minlength Digits -> Bignum.
- # Weniger als bn_minlength Digits -> Fixnum.
- # Genau bn_minlength Digits -> Bignum oder Fixnum.
- if (len < bn_minlength)
- { # 0..bn_minlength-1 Digits, paßt in ein Fixnum:
- if (bn_minlength>1 ? (len==0) : TRUE)
- # 0 Digits
- { return Fixnum_0; }
- {
- #ifndef intQsize
- var reg1 sint32 wert;
- if (bn_minlength>2 ? (len==1) : TRUE)
- # 1 Digit
- len_1:
- { wert = get_sint1D_Dptr(MSDptr); }
- elif (bn_minlength>3 ? (len==2) : TRUE)
- # 2 Digits
- len_2:
- { wert = get_sint2D_Dptr(MSDptr); }
- elif (bn_minlength>4 ? (len==3) : TRUE)
- # 3 Digits
- len_3:
- { wert = get_sint3D_Dptr(MSDptr); }
- elif (TRUE)
- # 4 Digits
- len_4:
- { wert = get_sint4D_Dptr(MSDptr); }
- elif (FALSE)
- # 5 Digits
- len_5:
- { wert = get_sint4D_Dptr(MSDptr); }
- #else # defined(intQsize) && (intDsize==32)
- var reg1 sint64 wert;
- if (TRUE)
- # 1 Digit
- len_1:
- { wert = (sint64)(sintD)MSDptr[0]; }
- elif (TRUE)
- # 2 Digits
- len_2:
- { wert = ((sint64)(sintD)MSDptr[0] << intDsize) | (uint64)(uintD)MSDptr[1]; }
- #endif
- return
- #if (oint_data_shift <= vorz_bit_o) && ((oint_data_len+1 <= intLsize) || defined(intQsize))
- as_object((( (soint)wert
- & (FN_value_vz_mask>>oint_data_shift) # Unnötiges wegmaskieren
- ) << oint_data_shift
- )
- | ((oint)fixnum_type<<oint_type_shift) # dafür Typinfo rein
- )
- #else # Falls (oint_data_shift > vorz_bit_o)
- # oder falls das Vorzeichenbit nicht in wert steckt
- as_object((( (soint)wert << oint_data_shift )
- & FN_value_mask # Unnötiges wegmaskieren
- )
- | ((soint)(sint32)sign_of_sintD(MSDptr[0]) & wbit(vorz_bit_o))
- | ((oint)fixnum_type<<oint_type_shift) # dafür Typinfo rein
- )
- #endif
- ;
- }}
- if (len == bn_minlength)
- # bn_minlength Digits, also (incl. Vorzeichen) zwischen
- # (bn_minlength-1)*intDsize+1 und bn_minlength*intDsize Bits.
- # Höchstens oint_data_len+1 Bits -> paßt in ein Fixnum:
- { if ( (MSDptr[0] <= (uintD)(bit(oint_data_len-(bn_minlength-1)*intDsize)-1)) # Fixnum >=0 ?
- ||(MSDptr[0] >= (uintD)(-bit(oint_data_len-(bn_minlength-1)*intDsize))) # Fixnum <0 ?
- )
- #if (bn_minlength==1)
- goto len_1;
- #endif
- #if (bn_minlength==2)
- goto len_2;
- #endif
- #if (bn_minlength==3)
- goto len_3;
- #endif
- #if (bn_minlength==4)
- goto len_4;
- #endif
- #if (bn_minlength==5)
- goto len_5;
- #endif
- }
- # mindestens bn_minlength Digits, mache ein Bignum
- { var reg4 object new = allocate_bignum(len,sign_of_sintD(MSDptr[0]));
- # neues Bignum mit dem Inhalt der NDS füllen:
- copy_loop_up(MSDptr,&TheBignum(new)->data[0],len);
- return new;
- } }
-
- # Bignum-Überlauf melden:
- nonreturning_function(local, BN_ueberlauf, (void));
- local void BN_ueberlauf()
- {
- //: DEUTSCH "Überlauf von Bignums"
- //: ENGLISH "bignum overflow"
- //: FRANCAIS "Dépassage de capacité des entiers BIGNUM"
- fehler(error, GETTEXT("bignum overflow"));
- }
-
- # Normalized Unsigned Digit Sequence to Integer
- # NUDS_to_I(MSDptr,len)
- # Normalized UDS MSDptr/len/.. in Integer >=0 umwandeln.
- # Unterhalb von MSDptr muß 1 Digit Platz sein.
- # kann GC auslösen
- local object NUDS_to_I (uintD* MSDptr, uintC len);
- local object NUDS_to_I(MSDptr,len)
- var reg1 uintD* MSDptr;
- var reg2 uintC len;
- { if ((!(len==0)) && ((sintD)MSDptr[0] < 0))
- # Falls die Länge >0 und das Most significant Bit = 1 sind,
- # die Digit Sequence um ein Nulldigit erweitern:
- { *--MSDptr = 0;
- len++;
- if (uintCoverflow(len)) { BN_ueberlauf(); } # Überlauf der Länge?
- }
- return NDS_to_I(MSDptr,len);
- }
-
- # Unsigned Digit Sequence to Integer
- # UDS_to_I(MSDptr,len)
- # UDS MSDptr/len/.. in Integer >=0 umwandeln.
- # Unterhalb von MSDptr muß 1 Digit Platz sein.
- # kann GC auslösen
- local object UDS_to_I (uintD* MSDptr, uintC len);
- local object UDS_to_I(MSDptr,len)
- var reg1 uintD* MSDptr;
- var reg2 uintC len;
- { while ( (!(len==0)) && (MSDptr[0]==0) ) # solange len>0 und MSD = 0,
- { MSDptr++; len--; } # Nulldigit streichen
- # Dann wie bei NUDS_to_I :
- if ((!(len==0)) && ((sintD)MSDptr[0] < 0))
- # Falls die Länge >0 und das Most significant Bit = 1 sind,
- # die Digit Sequence um ein Nulldigit erweitern:
- { *--MSDptr = 0;
- len++;
- if (uintCoverflow(len)) { BN_ueberlauf(); } # Überlauf der Länge?
- }
- return NDS_to_I(MSDptr,len);
- }
-
- # Digit Sequence to Integer
- # DS_to_I(MSDptr,len)
- # DS MSDptr/len/.. in Integer umwandeln.
- # kann GC auslösen
- local object DS_to_I (uintD* MSDptr, uintC len);
- local object DS_to_I(MSDptr,len)
- var reg1 uintD* MSDptr;
- var reg3 uintC len;
- { # erst normalisieren.
- # Dabei evtl. MSDptr erhöhen und len erniedrigen:
- if (!(len==0)) # leere DS ist normalisiert
- { var reg2 uintC count = len-1;
- if ((sintD)MSDptr[0] >= 0)
- # Zahl >= 0
- { # versuche maximal len-1 führende Nullen-Digits zu streichen:
- while (!(count==0) && (MSDptr[0]==0) && ((sintD)MSDptr[1]>=0))
- { MSDptr++; len--; count--; } # Nulldigit streichen
- }
- else
- # Zahl < 0
- # versuche maximal len-1 führende Einsen-Digits zu streichen:
- { while (!(count==0) && ((sintD)MSDptr[0]==-1) && ((sintD)MSDptr[1]<0))
- { MSDptr++; len--; count--; } # Einsen-digit streichen
- } }
- # Eventuell ist jetzt noch bei der DS 0 ausnahmsweise len=1,
- # aber NDS_to_I wird auch damit fertig.
- return NDS_to_I(MSDptr,len);
- }
-
- # Umwandlungsroutinen Integer --> Digit sequence:
-
- # Unterteilung eines Fixnums in Digits:
- # intDsize=8 -> MSD=LSD3,LSD2,LSD1,LSD0, sollte FN_maxlength=4 sein.
- # intDsize=16 -> MSD=LSD1,LSD0, sollte FN_maxlength=2 sein.
- # intDsize=32 -> MSD=LSD0, sollte FN_maxlength=1 sein.
- # WIDE -> ebenso, nur ist FN_maxlength noch eins größer.
-
- #if FN_maxlength>1
- #define FN_LSD0(obj) ((uintD)(as_oint(obj)>>oint_data_shift))
- #elif FN_maxlength==1
- #define FN_LSD0 FN_MSD
- #endif
- #if FN_maxlength>2
- #define FN_LSD1(obj) ((uintD)(as_oint(obj)>>(oint_data_shift+intDsize)))
- #elif FN_maxlength==2
- #define FN_LSD1 FN_MSD
- #else # FN_maxlength<2
- #define FN_LSD1(obj) 0; NOTREACHED # sollte nicht aufgerufen werden!
- #endif
- #if FN_maxlength>3
- #define FN_LSD2(obj) ((uintD)(as_oint(obj)>>(oint_data_shift+2*intDsize)))
- #elif FN_maxlength==3
- #define FN_LSD2 FN_MSD
- #else # FN_maxlength<3
- #define FN_LSD2(obj) 0; NOTREACHED # sollte nicht aufgerufen werden!
- #endif
- #if FN_maxlength>4
- #define FN_LSD3(obj) ((uintD)(as_oint(obj)>>(oint_data_shift+3*intDsize)))
- #elif FN_maxlength==4
- #define FN_LSD3 FN_MSD
- #else # FN_maxlength<4
- #define FN_LSD3(obj) 0; NOTREACHED # sollte nicht aufgerufen werden!
- #endif
- #if FN_maxlength==5
- #define FN_LSD4 FN_MSD
- #else # FN_maxlength<5
- #define FN_LSD4(obj) 0; NOTREACHED # sollte nicht aufgerufen werden!
- #endif
- # FN_MSD: insgesamt muß um (FN_maxlength-1)*intDsize+oint_data_shift Bits
- # nach rechts geshiftet werden.
- #if defined(WIDE)
- #define FN_MSD(obj) \
- ((uintD)( (sintD)(typecode(obj) << (intDsize-1-vorz_bit_t)) >> (intDsize-1)))
- #elif (vorz_bit_o == oint_data_len+oint_data_shift) || ((oint_data_len==(FN_maxlength-1)*intDsize) && (vorz_bit_o >= intDsize-1))
- #if HAVE_DD
- #define FN_MSD(obj) \
- ((sintD)((sintDD)(sintD)(as_oint(obj)>>(vorz_bit_o-(intDsize-1))) \
- >>(oint_data_shift-vorz_bit_o+FN_maxlength*intDsize-1) \
- ) )
- #elif (vorz_bit_o < intDsize)
- #define FN_MSD(obj) \
- (((sintD)as_oint(obj) << (intDsize-1-vorz_bit_o)) >> (FN_maxlength*intDsize-1-vorz_bit_o+oint_data_shift))
- #endif
- #else
- # signD_of_sintD(x,k) liefert das Vorzeichen von x als sintD; die hinteren
- # k Bit sind irrelevant.
- #if HAVE_DD
- #define signD_of_sintD(x,k) ((sintDD)(sintD)(x)>>intDsize)
- #else
- #define signD_of_sintD(x,k) ((sintD)(x)>>(intDsize-1-(k)))
- #endif
- #if (vorz_bit_o >= intDsize)
- #define FN_MSD(obj) \
- ( ((sintD)(as_oint(obj)>>(oint_data_shift+(FN_maxlength-1)*intDsize))&(bit(oint_data_len-(FN_maxlength-1)*intDsize)-1)) \
- |((sintD)signD_of_sintD(as_oint(obj)>>(vorz_bit_o-(intDsize-1)),oint_data_len-(FN_maxlength-1)*intDsize)&(-bit(oint_data_len-(FN_maxlength-1)*intDsize))) \
- )
- #else # (vorz_bit_o < intDsize)
- #define FN_MSD(obj) \
- ( ((sintD)(as_oint(obj)>>(oint_data_shift+(FN_maxlength-1)*intDsize))&(bit(oint_data_len-(FN_maxlength-1)*intDsize)-1)) \
- |((sintD)signD_of_sintD(as_oint(obj)<<((intDsize-1)-vorz_bit_o),oint_data_len-(FN_maxlength-1)*intDsize)&(-bit(oint_data_len-(FN_maxlength-1)*intDsize))) \
- )
- #endif
- #endif
-
- # Fixnum to Normalized Digit sequence
- # FN_to_NDS_nocopy(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Fixnum
- # < MSDptr/len/LSDptr: Normalized Digit sequence, im Maschinenstack
- #define FN_to_NDS_nocopy(obj,MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- FN_to_NDS_(nocopy,obj,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung)
- #if 0
- # Manche C-Compiler allozieren ihre Variablen auf dem Stack
- # überschneidungsfrei. Beispielsweise GCC 2.3.3 auf den meisten Systemen.
- # Coherent CC auf i386 und GCC 2.4.5 auf 680x0 allerdings nicht.
- # Wir gehen nun kein Risiko mehr ein.
- #define alloc_FNDS_nocopy(len,MSDptr_zuweisung,LSDptr_zuweisung) \
- { var uintD UDS_from_FN_to_NDS[FN_maxlength]; \
- MSDptr_zuweisung &UDS_from_FN_to_NDS[0]; \
- LSDptr_zuweisung &UDS_from_FN_to_NDS[len]; \
- }
- #elif !defined(NEED_MALLOCA)
- # Alloziere einen Array, der bis Funktionsende existieren muß, mit alloca().
- #define alloc_FNDS_nocopy(len,MSDptr_zuweisung,LSDptr_zuweisung) \
- { LSDptr_zuweisung \
- (MSDptr_zuweisung (uintD*)alloca(FN_maxlength*sizeof(uintD))) \
- + (len); \
- }
- #else
- # Benutze malloca(), siehe SPVW.D. Hoffen wir, daß das Fehlen von
- # freea()-Aufrufen sich nicht zu stark bemerkbar macht.
- #define alloc_FNDS_nocopy(len,MSDptr_zuweisung,LSDptr_zuweisung) \
- { LSDptr_zuweisung \
- (MSDptr_zuweisung (uintD*)malloca(FN_maxlength*sizeof(uintD))) \
- + (len); \
- }
- #endif
-
- # Fixnum to Normalized Digit sequence
- # FN_to_NDS(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Fixnum
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Dabei wird num_stack erniedrigt.
- #define FN_to_NDS(obj,MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- FN_to_NDS_(copy,obj,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung)
- #define alloc_FNDS_copy num_stack_need
-
- # Fixnum to Normalized Digit sequence
- # FN_to_NDS_1(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Fixnum
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Unterhalb von MSDptr ist noch 1 Digit Platz.
- # Dabei wird num_stack erniedrigt.
- #define FN_to_NDS_1(obj,MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- FN_to_NDS_(copy_1,obj,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung)
- #define alloc_FNDS_copy_1 num_stack_need_1
-
- #define FN_MSD1_mask # wird nur bei FN_maxlength >= 2 gebraucht, d.h. intDsize-1 < oint_data_len \
- (FN_value_vz_mask & ~((oint)(bitc(intDsize-1)-1)<<oint_data_shift))
- #define FN_MSD2_mask # wird nur bei FN_maxlength >= 3 gebraucht, d.h. 2*intDsize-1 < oint_data_len \
- (FN_value_vz_mask & ~((oint)(bitc(2*intDsize-1)-1)<<oint_data_shift))
- #define FN_MSD3_mask # wird nur bei FN_maxlength >= 4 gebraucht, d.h. 3*intDsize-1 < oint_data_len \
- (FN_value_vz_mask & ~((oint)(bitc(3*intDsize-1)-1)<<oint_data_shift))
- #define FN_MSD4_mask # wird nur bei FN_maxlength >= 5 gebraucht, d.h. 4*intDsize-1 < oint_data_len \
- (FN_value_vz_mask & ~((oint)(bitc(4*intDsize-1)-1)<<oint_data_shift))
- #define FN_to_NDS_(option, obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg1 oint fix_from_FN_to_NDS = as_oint(obj); \
- var reg3 uintC len_from_FN_to_NDS; \
- var reg2 uintD* ptr_from_FN_to_NDS; \
- # Länge der NDS bestimmen: \
- if (eq(as_object(fix_from_FN_to_NDS),Fixnum_0)) # mindestens 1 Digit nötig? \
- { len_from_FN_to_NDS=0; } \
- else \
- { var reg3 oint testMSD; # vordere Bits von fix_from_FN_to_NDS \
- if ((FN_maxlength<=1) || \
- (((testMSD = fix_from_FN_to_NDS & FN_MSD1_mask) == 0) || (testMSD == FN_MSD1_mask)) \
- ) \
- { len_from_FN_to_NDS=1; } # nur ein Digit abzulegen \
- elif ((FN_maxlength<=2) || \
- (((testMSD = fix_from_FN_to_NDS & FN_MSD2_mask) == 0) || (testMSD == FN_MSD2_mask)) \
- ) \
- { len_from_FN_to_NDS=2; } # zwei Digits abzulegen \
- elif ((FN_maxlength<=3) || \
- (((testMSD = fix_from_FN_to_NDS & FN_MSD3_mask) == 0) || (testMSD == FN_MSD3_mask)) \
- ) \
- { len_from_FN_to_NDS=3; } # drei Digits abzulegen \
- elif ((FN_maxlength<=4) || \
- (((testMSD = fix_from_FN_to_NDS & FN_MSD4_mask) == 0) || (testMSD == FN_MSD4_mask)) \
- ) \
- { len_from_FN_to_NDS=4; } # vier Digits abzulegen \
- else \
- { len_from_FN_to_NDS=5; } # fünf Digits abzulegen \
- } \
- len_zuweisung len_from_FN_to_NDS; \
- # Platz belegen: \
- CONCAT(alloc_FNDS_,option) \
- (len_from_FN_to_NDS, MSDptr_zuweisung ptr_from_FN_to_NDS =,_EMA_ LSDptr_zuweisung); \
- # Platz füllen: \
- if (len_from_FN_to_NDS > 0) \
- { if ((FN_maxlength>1) && (len_from_FN_to_NDS > 1)) \
- { if ((FN_maxlength>2) && (len_from_FN_to_NDS > 2)) \
- { if ((FN_maxlength>3) && (len_from_FN_to_NDS > 3)) \
- { if ((FN_maxlength>4) && (len_from_FN_to_NDS > 4)) \
- # fünf Digits abzulegen: \
- { *ptr_from_FN_to_NDS++ = FN_LSD4(as_object(fix_from_FN_to_NDS)); } \
- # noch vier Digits abzulegen: \
- *ptr_from_FN_to_NDS++ = FN_LSD3(as_object(fix_from_FN_to_NDS)); \
- } \
- # noch drei Digits abzulegen: \
- *ptr_from_FN_to_NDS++ = FN_LSD2(as_object(fix_from_FN_to_NDS)); \
- } \
- # noch zwei Digits abzulegen: \
- *ptr_from_FN_to_NDS++ = FN_LSD1(as_object(fix_from_FN_to_NDS)); \
- } \
- # noch ein Digit abzulegen: \
- *ptr_from_FN_to_NDS = FN_LSD0(as_object(fix_from_FN_to_NDS)); \
- } \
- }
-
- # Bignum to Normalized Digit sequence, Kopieren unnötig
- # BN_to_NDS_nocopy(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Bignum
- # < MSDptr/len/LSDptr: Normalized Digit sequence
- #define BN_to_NDS_nocopy(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg1 Bignum bn_from_BN_to_NDS_nocopy = TheBignum(obj); \
- unused (MSDptr_zuweisung &bn_from_BN_to_NDS_nocopy->data[0]); \
- LSDptr_zuweisung &bn_from_BN_to_NDS_nocopy->data[(uintP)( \
- len_zuweisung bn_from_BN_to_NDS_nocopy->length )]; \
- }
-
- # Bignum to Normalized Digit sequence
- # BN_to_NDS(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Bignum
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Dabei wird num_stack erniedrigt.
- #define BN_to_NDS(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg3 object obj_from_BN_to_NDS = (obj); \
- var reg1 uintD* MSDptr_from_BN_to_NDS; \
- var reg2 uintC len_from_BN_to_NDS; \
- len_zuweisung len_from_BN_to_NDS = TheBignum(obj_from_BN_to_NDS)->length; \
- num_stack_need(len_from_BN_to_NDS, MSDptr_zuweisung MSDptr_from_BN_to_NDS = ,_EMA_ LSDptr_zuweisung); \
- copy_loop_up(&TheBignum(obj_from_BN_to_NDS)->data[0],MSDptr_from_BN_to_NDS,len_from_BN_to_NDS); \
- }
-
- # Bignum to Normalized Digit sequence
- # BN_to_NDS_1(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Bignum
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Unterhalb von MSDptr ist noch 1 Digit Platz.
- # Dabei wird num_stack erniedrigt.
- #define BN_to_NDS_1(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg3 object obj_from_BN_to_NDS = (obj); \
- var reg1 uintD* MSDptr_from_BN_to_NDS; \
- var reg2 uintC len_from_BN_to_NDS; \
- len_zuweisung len_from_BN_to_NDS = TheBignum(obj_from_BN_to_NDS)->length; \
- num_stack_need_1(len_from_BN_to_NDS, MSDptr_zuweisung MSDptr_from_BN_to_NDS = ,_EMA_ LSDptr_zuweisung); \
- copy_loop_up(&TheBignum(obj_from_BN_to_NDS)->data[0],MSDptr_from_BN_to_NDS,len_from_BN_to_NDS); \
- }
-
- # Integer to Normalized Digit sequence, Kopieren unnötig.
- # I_to_NDS_nocopy(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Integer
- # < MSDptr/len/LSDptr: Normalized Digit sequence
- #define I_to_NDS_nocopy(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg3 object obj_from_I_to_NDS_nocopy = (obj); \
- if (I_fixnump(obj_from_I_to_NDS_nocopy)) \
- { FN_to_NDS_nocopy(obj_from_I_to_NDS_nocopy,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- else \
- { BN_to_NDS_nocopy(obj_from_I_to_NDS_nocopy,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- }
-
- # Integer to Normalized Digit sequence
- # I_to_NDS(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Integer
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Dabei wird num_stack erniedrigt.
- #define I_to_NDS(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg3 object obj_from_I_to_NDS = (obj); \
- if (I_fixnump(obj_from_I_to_NDS)) \
- { FN_to_NDS(obj_from_I_to_NDS,MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- else \
- { BN_to_NDS(obj_from_I_to_NDS,MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- }
-
- # Integer to Normalized Digit sequence
- # I_to_NDS_1(obj, MSDptr=,len=,LSDptr=);
- # > obj: ein Integer
- # < MSDptr/len/LSDptr: Normalized Digit sequence, darf modifiziert werden.
- # Unterhalb von MSDptr ist noch 1 Digit Platz.
- # Dabei wird num_stack erniedrigt.
- #define I_to_NDS_1(obj, MSDptr_zuweisung,len_zuweisung,LSDptr_zuweisung) \
- { var reg3 object obj_from_I_to_NDS = (obj); \
- if (I_fixnump(obj_from_I_to_NDS)) \
- { FN_to_NDS_1(obj_from_I_to_NDS,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- else \
- { BN_to_NDS_1(obj_from_I_to_NDS,_EMA_ MSDptr_zuweisung,len_zuweisung,_EMA_ LSDptr_zuweisung); } \
- }
-
- # Holt die nächsten pFN_maxlength Digits in ein uint32:
- # _ptr ist vom Typ uintD*.
- #if (pFN_maxlength==1)
- #define pFN_maxlength_digits_at(_ptr) \
- (uint32)(_ptr[0])
- #elif (pFN_maxlength==2) && (intDsize==16)
- #define pFN_maxlength_digits_at(_ptr) \
- highlow32_at(_ptr)
- #elif (pFN_maxlength==2)
- #define pFN_maxlength_digits_at(_ptr) \
- (((uint32)(_ptr[0])<<intDsize)| \
- (uint32)(_ptr[1]))
- #elif (pFN_maxlength==3)
- #define pFN_maxlength_digits_at(_ptr) \
- (((((uint32)(_ptr[0])<<intDsize)| \
- (uint32)(_ptr[1]))<<intDsize)| \
- (uint32)(_ptr[2]))
- #elif (pFN_maxlength==4)
- #define pFN_maxlength_digits_at(_ptr) \
- (((((((uint32)(_ptr[0])<<intDsize)| \
- (uint32)(_ptr[1]))<<intDsize)| \
- (uint32)(_ptr[2]))<<intDsize)| \
- (uint32)(_ptr[3]))
- #endif
-
- # Schreibt ein uint32 in die nächsten pFN_maxlength Digits:
- # _ptr ist vom Typ uintD*, _wert vom Typ uint32.
- #if (pFN_maxlength==1)
- #define set_pFN_maxlength_digits_at(_ptr,_wert) \
- (_ptr[0] = (uintD)_wert)
- #elif (pFN_maxlength==2) && (intDsize==16)
- #define set_pFN_maxlength_digits_at(_ptr,_wert) \
- set_highlow32_at(_ptr,_wert)
- #elif (pFN_maxlength==2)
- #define set_pFN_maxlength_digits_at(_ptr,_wert) \
- (_ptr[0] = (uintD)(_wert>>intDsize), \
- _ptr[1] = (uintD)(_wert) \
- )
- #elif (pFN_maxlength==3)
- #define set_pFN_maxlength_digits_at(_ptr,_wert) \
- (_ptr[0] = (uintD)(_wert>>(2*intDsize)), \
- _ptr[1] = (uintD)(_wert>>intDsize), \
- _ptr[2] = (uintD)(_wert) \
- )
- #elif (pFN_maxlength==4)
- #define set_pFN_maxlength_digits_at(_ptr,_wert) \
- (_ptr[0] = (uintD)(_wert>>(3*intDsize)), \
- _ptr[1] = (uintD)(_wert>>(2*intDsize)), \
- _ptr[2] = (uintD)(_wert>>intDsize), \
- _ptr[3] = (uintD)(_wert) \
- )
- #endif
-
-