home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / arilev1.d < prev    next >
Encoding:
Text File  |  1994-12-20  |  7.5 KB  |  250 lines

  1. # Arithmetik, Level 1
  2. # operiert auf Digit Sequences (DS) und Unsigned Digit Sequences (UDS).
  3.  
  4.  
  5. # Aus LISPBIBL.D importiere:
  6. # intDsize        Anzahl Bits in einem Digit
  7. # uintD, sintD    Integer-Typen fⁿr ein Digit
  8. # log2_intDsize   log2(intDsize)
  9. # HAVE_DD         Flag, das anzeigt, ob ein Integertyp fⁿr Doppel-Digits da ist
  10. # intDDsize       Anzahl Bits in einem Doppel-Digit
  11. # uintDD,sintDD   Integer-Typen fⁿr ein Doppel-Digit
  12.  
  13. #if !((32%intDsize)==0)
  14.   #error "intDsize sollte ein Teiler von 32 sein!"
  15. #endif
  16.  
  17.  
  18. # Vorzeichen eines Digit bestimmen
  19. # sign_of_sintD(wert)
  20. # > wert: ein Digit
  21. # < sintD ergebnis: 0 falls wert>=0, -1 falls wert<0.
  22.   global sint32 sign_of_sintD (sintD wert);
  23. #if (intDsize==8)
  24.   #define sign_of_sintD(x)  (sintD)(sign_of_sint16((sint16)(sint8)(x)))
  25. #endif
  26. #if (intDsize==16)
  27.   #define sign_of_sintD(x)  (sintD)(sign_of_sint16(x))
  28. #endif
  29. #if (intDsize==32)
  30.   #define sign_of_sintD(x)  (sintD)(sign_of_sint32(x))
  31. #endif
  32.  
  33. # High-Digit eines Doppel-Digit bestimmen
  34. # highD(wert)
  35. #if HAVE_DD
  36.   #if (!(intDsize==16))
  37.     #define highD(x)  ((uintD)((uintDD)(x)>>intDsize))
  38.   #else
  39.     #define highD  high16
  40.   #endif
  41. #endif
  42.  
  43. # Low-Digit eines Doppel-Digit bestimmen
  44. # lowD(wert)
  45. #if HAVE_DD
  46.   #define lowD(x)  ((uintD)(uintDD)(x))
  47. #endif
  48.  
  49. # Ein Doppel-Digit aus ihrem High-Digit und ihrem Low-Digit bestimmen:
  50. # highlowDD(uintD high, uintD low)
  51. #if HAVE_DD
  52.   #if (!(intDsize==16))
  53.     #define highlowDD(x,y)  (((uintDD)(uintD)(x)<<intDsize)|(uintDD)(uintD)(y))
  54.   #else
  55.     #define highlowDD  highlow32
  56.   #endif
  57. #endif
  58.  
  59. # Ein Doppel-Digit aus ihrem High-Digit und ihrem Low-Digit 0 bestimmen:
  60. # highlowDD_0(uintD high)
  61. #if HAVE_DD
  62.   #if (!(intDsize==16))
  63.     #define highlowDD_0(x)  ((uintDD)(uintD)(x)<<intDsize)
  64.   #else
  65.     #define highlowDD_0  highlow32_0
  66.   #endif
  67. #endif
  68.  
  69. # Zwei Digits multiplizieren:
  70. # (uintDD)hilo = muluD(uintD arg1, uintD arg2)
  71. # bzw.
  72. # muluD(uintD arg1, uintD arg2, uintD hi =, uintD lo =);
  73. #if HAVE_DD
  74.   #if (intDsize==8)
  75.     #ifdef GNU
  76.       #define muluD(arg1,arg2)  ((uintDD)((uintD)(arg1)*(uintD)(arg2)))
  77.     #else
  78.       #define muluD(arg1,arg2)  ((uintDD)(uintD)(arg1)*(uintDD)(uintD)(arg2))
  79.     #endif
  80.   #endif
  81.   #if (intDsize==16)
  82.     #define muluD  mulu16
  83.   #endif
  84. #else
  85.   #if (intDsize==32)
  86.     #define muluD  mulu32
  87.   #endif
  88. #endif
  89.  
  90. # Zwei Digits multiplizieren, mit einem Digit als Ergebnis.
  91. # (uintD)lo = muluD_unchecked(uintD arg1, uintD arg2)
  92. # Es wird vorausgesetzt, da▀ arg1*arg2 < 2^intDsize.
  93.   #if (intDsize==8) || (intDsize==16)
  94.     #define muluD_unchecked(arg1,arg2)  ((uintD)((uintD)(arg1)*(uintD)(arg2)))
  95.   #endif
  96.   #if (intDsize==32)
  97.     #define muluD_unchecked(arg1,arg2)  mulu32_unchecked(arg1,arg2)
  98.   #endif
  99.  
  100. # Durch ein Digit dividieren:
  101. # divuD(uintDD x, uintD y, uintD q =, uintD r =);
  102. # bzw.
  103. # divuD(uintD xhi, uintD xlo, uintD y, uintD q =, uintD r =);
  104. # dividiert x/y und liefert q = floor(x/y) und r = (x mod y). x = q*y+r.
  105. # Es wird vorausgesetzt, da▀ 0 <= x < 2^intDsize*y.
  106. #if HAVE_DD
  107.   #if (intDsize==8)
  108.     #define divuD  divu_1616_1616
  109.   #endif
  110.   #if (intDsize==16)
  111.     #define divuD  divu_3216_1616
  112.   #endif
  113. #else
  114.   #if (intDsize==32)
  115.     #define divuD  divu_6432_3232
  116.   #endif
  117. #endif
  118.  
  119. # Durch ein Digit dividieren:
  120. # floorD(uintD x, uintD y)
  121. # dividiert x/y und liefert q = floor(x/y).
  122. # Es wird vorausgesetzt, da▀ y > 0.
  123.   #if (intDsize==8) || (intDsize==16)
  124.     #define floorD(arg1,arg2)  (floor((uintD)(arg1),(uintD)(arg2)))
  125.   #endif
  126.   #if (intDsize==32)
  127.     #define floorD  divu_3232_3232_
  128.   #endif
  129.  
  130. # Digit sequence (DS) - nur intern verwendet -
  131. # ZusammenhΣngender Speicherbereich mit n (ein uintC) Digits,
  132. # zwischen zwei Pointer MSDptr und LSDptr.
  133. #  MSDptr                  LSDptr
  134. # | MSD ............. LSW |
  135. # [abgekⁿrzt: MSDptr/n/LSDptr ]
  136. # In 68000-Manier (vgl. ADDX, SUBX) ist das Most significant Digit an der
  137. # untersten Adresse, nΣmlich MSDptr. LSDptr = MSDptr + n zeigt hinter die DS.
  138. # Falls n = 0, wird die Zahl 0 dargestellt.
  139. # Falls n > 0, ist das h÷chstwertige Bit (nΣmlich  Bit (intDsize-1) von
  140. #              *MSDptr) das Vorzeichenbit. Schreibt man es noch unendlich
  141. #              oft an, so erhΣlt man die "unendliche Bitfolge".
  142. # Normalisierte Digit sequence (NDS) ist eine solche, bei der das MSD n÷tig
  143. # ist, also n = 0 oder (n > 0 und nicht alle h÷chstwertigen intDsize+1 Bits
  144. # sind gleich).
  145. # In C:
  146. #   uintD* MSWptr und uintC len.
  147. #   MSWptr[0] ... MSWptr[(uintL)len-1] sind die Digits.
  148.  
  149. # Unsigned Digit sequence (UDS) - nur intern verwendet -
  150. # wie DS (MSD unten, LSD oben), nur ohne Vorzeichen.
  151. # Normalized Unsigned Digit sequence (NUDS):
  152. # wie UDS, nur ist entweder n=0 (Zahl 0) oder bei n>0 : *MSDptr >0.
  153. # (d.h. die Zahl >=0 kann nicht mit weniger Digits als UDS dargestellt werden).
  154. # In C:
  155. #   uintD* MSWptr und uintC len.
  156. #   MSWptr[0] ... MSWptr[(uintL)len-1] sind die Digits.
  157.  
  158. # Zur Konstruktion konstanter DS: D(byte0,byte1,byte2,byte3,) liefert
  159. # die 32 Bits von {byte0,byte1,byte2,byte3} als 32/intDsize Digits.
  160.   #if (intDsize==8)
  161.     #define D(byte0,byte1,byte2,byte3,dummy)  byte0,byte1,byte2,byte3,
  162.   #endif
  163.   #if (intDsize==16)
  164.     #define D(byte0,byte1,byte2,byte3,dummy)  ((byte0<<8)|byte1),((byte2<<8)|byte3),
  165.   #endif
  166.   #if (intDsize==32)
  167.     #define D(byte0,byte1,byte2,byte3,dummy)  \
  168.       (((uintD)(byte0)<<24)|((uintD)(byte1)<<16)|((uintD)(byte2)<<8)|((uintD)(byte3))),
  169.   #endif
  170.  
  171. typedef struct { uintD* MSDptr; uintC len; uintD* LSDptr; } DS;
  172.  
  173.  
  174. # Es gibt fⁿr die innersten Schleifen vier M÷glichkeiten:
  175. # LOOP_EXTERN_C     Alle Schleifen als externe C-compilierte Routinen.
  176. #                   Portabel, aber evtl. ineffizient.
  177. # LOOP_INLINE_C     Schleifen ohne Wert (mit GNU-Compiler: alle Schleifen)
  178. #                   als Macros.
  179. #                   Portabel, aber evtl. ineffizient.
  180. # LOOP_EXTERN_ASM   Alle Schleifen als externe Assembler-Routinen.
  181. #                   Effizienter, aber immer noch Function-Call-Overhead.
  182. # LOOP_INLINE_ASM   Schleifen ohne Wert (mit GNU-Compiler: alle Schleifen)
  183. #                   als macroexpandierte Assembler-Routinen inline.
  184. #                   Ganz effizient.
  185.  
  186. #if (defined(MC680X0) || defined(SPARC) || (defined(I80Z86) && !defined(WATCOM)) || defined(MIPS) || defined(VAX) || defined(ARM)) && (SAFETY < 3)
  187.   # diese Assembler beherrsche ich
  188.   #if (defined(GNU) && defined(WANT_LOOP_INLINE))
  189.     # der GNU-Compiler kann Inline-Assembler
  190.     #define LOOP_INLINE_ASM
  191.   #else
  192.     # sonst mit externen Routinen arbeiten
  193.     #define LOOP_EXTERN_ASM
  194.   #endif
  195. #else
  196.   # sonst die portable L÷sung
  197.   #define LOOP_INLINE_C
  198. #endif
  199.  
  200.  
  201. #ifdef LOOP_EXTERN_C
  202.   # Die Definitionen samt portablem C-Code:
  203.   #include "arilev1c.c"
  204. #endif
  205.  
  206. # Die Inline-Macros
  207. #ifdef LOOP_INLINE_ASM
  208.   # sind momentan nicht implementiert
  209.   #define LOOP_EXTERN_ASM  # stattdessen extern in Assembler
  210. #endif
  211.  
  212. #ifdef LOOP_EXTERN_ASM
  213.   # Die Assembler-Definitionen:
  214.     #define INCLUDED_FROM_C
  215.     #if defined(MC680X0)
  216.       #if !defined(MC680Y0)
  217.         #include "ari68000.c"
  218.       #else
  219.         #include "ari68020.c"
  220.       #endif
  221.     #endif
  222.     #if defined(SPARC)
  223.       #include "arisparc.c"
  224.     #endif
  225.     #if defined(I80Z86)
  226.       #include "ari80386.c"
  227.     #endif
  228.     #if defined(MIPS)
  229.       #include "arimips.c"
  230.     #endif
  231.     #if defined(VAX)
  232.       #include "arivaxunix.c"
  233.     #endif
  234.     #if defined(ARM)
  235.       #include "ariarm.c"
  236.     #endif
  237.     #undef INCLUDED_FROM_C
  238.   # Die Extern-Deklarationen:
  239.     #include "arilev1e.c"
  240.   # Die nicht in Assembler geschriebenen Teile nehmen wir vom portablen C-Code:
  241.     #define LOOP_INLINE_C
  242. #endif
  243.  
  244. #ifdef LOOP_INLINE_C
  245.   # Die Definitionen samt portablem C-Code und
  246.   # - fⁿr den GNU-Compiler - Inline-Deklarationen:
  247.   #include "arilev1i.c"
  248. #endif
  249.  
  250.