[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bugs in copy-bytes



Bill St. Clair recently posted the following useful macro, but I think
there are two bugs in it.  Instead of copying from the macptr in FROM to
the macptr in TO, it copies the other way around.  Also, when it is copying
by words instead of by bytes, it should be doubling the offset values.

Here's Bill's code:
-----------------------------------------------------------------
; Copy COUNT bytes from the macptr in FROM to the macptr in TO.
; if ASSUME-EVEN-ADDRESSES is specified and non-NIL, will generate
; word moves which is almost twice as fast (and will generate an odd
; address trap on a 68000, if the address from FROM or TO is not even).
; Assumes that FROM and TO are macptrs, will crash if not.
; Assumes that COUNT is a fixnum. If it is a constant fixnum at
; macroexpand time, will generate significantly faster code.
; Not good for copying large buffers. For that, use #_BlockMove.
(defmacro copy-bytes (from to count &optional assume-even-addresses)
  (let ((from-var (gensym))
          (to-var (gensym)))
    `(let ((,from-var ,from)
           (,to-var ,to))
       (declare (type macptr ,from-var ,to-var))
       ,(if (fixnump count)
          (if assume-even-addresses
            `(progn
               ,@(let ((res nil))
                   (dotimes (i (floor count 2) (nreverse res))
                     (push `(setf (%get-word ,from-var ,i)
                                  (%get-word ,to-var ,i))
                           res)))
               ,@(unless (eql 0 (mod count 2))
                   `(setf (%get-byte ,from-var ,(1- count))
                          (%get-byte ,to-var ,(1- count))))
               nil)
            `(progn
               ,@(let ((res nil))
                   (dotimes (i count (nreverse res))
                     (push `(setf (%get-byte ,from-var ,i)
                                  (%get-byte ,to-var ,i))
                           res)))
               nil))
          (let ((i (gensym)))
            `(dotimes (,i (the fixnum ,count))
               (setf (%get-byte ,from-var ,i) (%get-byte ,to-var ,i))))))))
-------------------------------------------------------
Here's my fixed code:
-------------------------------------------------------
; Copy COUNT bytes from the macptr in FROM to the macptr in TO.
; if ASSUME-EVEN-ADDRESSES is specified and non-NIL, will generate
; word moves which is almost twice as fast (and will generate an odd
; address trap on a 68000, if the address from FROM or TO is not even).
; Assumes that FROM and TO are macptrs, will crash if not.
; Assumes that COUNT is a fixnum. If it is a constant fixnum at
; macroexpand time, will generate significantly faster code.
; Not good for copying large buffers. For that, use #_BlockMove.
(defmacro copy-bytes (from to count &optional assume-even-addresses)
  (let ((from-var (gensym))
          (to-var (gensym)))
    `(let ((,from-var ,from)
           (,to-var ,to))
       (declare (type macptr ,from-var ,to-var))
       ,(if (fixnump count)
          (if assume-even-addresses
            `(progn
               ,@(let ((res nil))
                   (dotimes (i (floor count 2) (nreverse res))
                     (push `(setf (%get-word ,to-var ,(* 2 i))
                                  (%get-word ,from-var ,(* 2 i)))
                           res)))
               ,@(unless (eql 0 (mod count 2))
                   `(setf (%get-byte ,to-var ,(1- count))
                          (%get-byte ,from-var ,(1- count))))
               nil)
            `(progn
               ,@(let ((res nil))
                   (dotimes (i count (nreverse res))
                     (push `(setf (%get-byte ,to-var ,i)
                                  (%get-byte ,from-var ,i))
                           res)))
               nil))
          (let ((i (gensym)))
            `(dotimes (,i (the fixnum ,count))
               (setf (%get-byte ,to-var ,i) (%get-byte ,from-var ,i))))))))

Dale J. Skrien   	       	       	       	       	djskrien@colby.edu
Dept. of Mathematics & Computer Science 	       	207-872-3256
Colby College, Waterville  ME  04901