home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / libs / dlibs.patch < prev    next >
Internet Message Format  |  1998-01-19  |  4KB

  1. From corona!pbinfo!unido!mcvax!uunet!ncrlnk!ncrcae!hubcap!gatech!rutgers!apple!oliveb!pyramid!ncc!myrias!mj Tue Mar 21 13:34:12 MET 1989
  2. Article 9791 of comp.sys.atari.st:
  3. Path: corona!pbinfo!unido!mcvax!uunet!ncrlnk!ncrcae!hubcap!gatech!rutgers!apple!oliveb!pyramid!ncc!myrias!mj
  4. >From: mj@myrias.UUCP (Michal Jaegermann)
  5. Newsgroups: comp.sys.atari.st
  6. Subject: More on bugs in dLibs
  7. Keywords: Sozobon, dLibs, lmemcpy
  8. Message-ID: <947@myrias.UUCP>
  9. Date: 13 Mar 89 17:53:27 GMT
  10. Organization: Myrias Research, Edmonton
  11. Lines: 94
  12. Posted: Mon Mar 13 18:53:27 1989
  13.  
  14.  
  15. Seeing David Brooks posting, relayed by Steve Yelvington, gave me
  16. enough of incentive to look a little bit closer also at lmemcpy
  17. code, as distributed with dLibs 1.2.  Sure enough I found that
  18. it exhibited the same set of problems as memcpy.  So here is
  19. a replacement code, quite obviously derived from a code by David.
  20.  
  21. * lmemcpy.s - replacement for a code in dLibs 1.2
  22. *
  23. * After memcpy by David Brooks  - Michal Jaegermann, 11 Mar 89
  24. *
  25. *       char *lmemcpy(dest, source, len)
  26. *               char *dest              at 4(sp)
  27. *               char *source            at 8(sp)
  28. *               unsigned long len       at 12(sp)
  29. *
  30. * Avoid "btst #n,dn" because of a bug in the Sozobon assembler.
  31. * If parity of both adresses the same - copies in 16 byte blocks.
  32. * One has to stop loop unrolling somewhere.
  33.  
  34. .text
  35. .globl _lmemcpy
  36. _lmemcpy:
  37.         lea     4(a7),a2        ; Point to argument list
  38.         move.l  (a2)+,a1        ; a1 = dest
  39.         move.l  (a2)+,a0        ; a0 = source
  40.         move.l  (a2),d2         ; d2 = len
  41.         beq     lmemcpy6        ; return if zero
  42.  
  43.         move.l  a0,d1           ; Check for odd/even alignment
  44.         add.w   a1,d1           ; This is really eor.w on the lsb.  Really.
  45.         asr.w   #1,d1           ; Get lsb into C.  If it's 1, alignment is off.
  46.         bcs     lmemcpy7        ; Go do it slowly
  47.  
  48.         move.l  a0,d1           ; Check for initial odd byte
  49.         asr.w   #1,d1           ; Get lsb
  50.         bcc     lmemcpy1
  51.         subq.l  #1,d2           ; Move initial byte
  52.         move.b  (a0)+,(a1)+     ; 
  53. lmemcpy1:
  54.         moveq.l #15,d1          ; Split into a longword count and remainder
  55.         and.w   d2,d1
  56.         lsr.l   #4,d2           ; for 16 bytes at a time
  57.         move.l  d2,d0           ; a second counter for dbra
  58.         swap    d0
  59.         bra     lmemcpy3        ; Words (!!) d2 and d0 could equal 0.
  60. lmemcpy2:
  61.         move.l  (a0)+,(a1)+     ; Copy 16 bytes
  62.         move.l  (a0)+,(a1)+
  63.         move.l  (a0)+,(a1)+
  64.         move.l  (a0)+,(a1)+
  65. lmemcpy3:
  66.         dbra    d2,lmemcpy2
  67.         dbra    d0,lmemcpy2
  68.  
  69.         bra     lmemcpy5        ; Enter final loop.  Again d1 could equal 0.
  70. lmemcpy4:
  71.         move.b  (a0)+,(a1)+     ; Up to 15 trailing bytes
  72. lmemcpy5:
  73.         dbra    d1,lmemcpy4
  74. lmemcpy6:
  75.         move.l  4(a7),d0        ; stick return value into d0
  76.         rts                     ; All done.
  77.  
  78. lmemcpy7:                       ; Handle the odd/even aligned case
  79.         move.l  a1,d0           ; d0 = dest, ready to return
  80.         subq    #1,d2           ; here d2 was positive!
  81.         move.l  d2,d1
  82.         swap    d1              ; second dbra counter
  83. lmemcpy8:
  84.         move.b  (a0)+,(a1)+    ; move byte-by-byte
  85.         dbra    d2,lmemcpy8
  86.         dbra    d1,lmemcpy8
  87.         rts                     ; and exit normally
  88.  
  89.  
  90. lmemcpy is used internally by realloc.  Since malloc has to return
  91. nicely aligned addresses, hence in this case we luckied out and an old
  92. version of lmemcpy will work for realloc, maybe even a little bit
  93. faster. :-).  Unless your program will pass to realloc some funny argument.
  94.  
  95. And one more thing.  dLibs documentation claims that length parameter
  96. to memcpy and lmemcpy is either int or long.  Code documents and works
  97. with - more logically, but with some discrepancy with U*IX library -
  98. unsigned quantities.  Accordingly to ANSI standard specification
  99. length parameter to memcpy has to be of size_t type, where size_t is
  100. an integral type specified by an implementation.  This means that
  101. unsigned int, or unsigned long, are ok, if you said so.  Watch out for
  102. these until things get fixed.
  103.  
  104.     Michal Jaegermann
  105.     Myrias Research Corporation
  106.     Edmonton, Alberta, CANADA
  107.     ...{alberta,ncc}!myrias!mj
  108.  
  109.  
  110.