[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bugs in copy-bytes
- Subject: bugs in copy-bytes
- From: djskrien@COLBY.EDU (Dale Skrien)
- Date: Tue, 11 May 93 10:16:27 -0400
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