Will one of the low level wizards show an example of efficiently
packing and unpacking multiple fixnum integers in and out of a single
datapoint using Common Lisp?
e.g.
I have values A, B, C, and D (all fixnum integers). I want to be able
to combine them to create integer E and later pull A, B, C, or D out
of E
I know it's simple but I'm sure I'll do it naively if left to my own
ways...
Thanks
Nick
········@gmail.com writes:
> Will one of the low level wizards show an example of efficiently
> packing and unpacking multiple fixnum integers in and out of a single
> datapoint using Common Lisp?
>
> e.g.
>
> I have values A, B, C, and D (all fixnum integers). I want to be able
> to combine them to create integer E and later pull A, B, C, or D out
> of E
>
> I know it's simple but I'm sure I'll do it naively if left to my own
> ways...
Not a wizard but an ex-assembler programmer. I'd go for
CL-USER> (defun pack (b01 b234 b5678)
(logior b01 (ash b234 2) (ash b5678 5)))
PACK
CL-USER> (write (pack 1 5 10) :base 2)
101010101
341
CL-USER> (defun unpack (i)
(values (ldb (byte 2 0) i)
(ldb (byte 3 2) i)
(ldb (byte 4 5) i)))
UNPACK
CL-USER> (unpack #b101010101)
1
5
10
CL-USER> (multiple-value-call #'pack (unpack #b101010101))
341
CL-USER> (multiple-value-call #'pack (unpack 341))
341
CL-USER> (unpack (pack 1 5 10))
1
5
10
and so on. I'd probably give my fields names with
defconstant
(defconstant alu-op (byte 5 11))
Alan Crowe
Edinburgh
Scotland
Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
+---------------
| ········@gmail.com writes:
| > I have values A, B, C, and D (all fixnum integers). I want to
| > be able to combine them to create integer E and later pull
| > A, B, C, or D out of E
| >
| > I know it's simple but I'm sure I'll do it naively if left
| > to my own ways...
|
| Not a wizard but an ex-assembler programmer. I'd go for
|
| CL-USER> (defun pack (b01 b234 b5678)
| (logior b01 (ash b234 2) (ash b5678 5)))
| PACK
|
| CL-USER> (write (pack 1 5 10) :base 2)
| 101010101
| 341
+---------------
As an ex-*PDP-10*[1] assembler programmer, ;-}
I'd probably go for this:
> (defun pack (b01 b234 b5678)
(dpb b5678 (byte 5 5)
(dpb b234 (byte 3 2)
b01)))
PACK
> (write (pack 1 5 10) :base 2)
101010101
341
>
Or the more-imperative equivalent:
(defun pack (b01 b234 b5678)
(setf (ldb (byte 3 2) b01) b234)
(setf (ldb (byte 5 5) b01) b5678)
b01)
[I'm not sure which one is faster.]
+---------------
| CL-USER> (defun unpack (i)
| (values (ldb (byte 2 0) i)
| (ldb (byte 3 2) i)
| (ldb (byte 4 5) i)))
| UNPACK
+---------------
Yup, just so!
-Rob
[1] See CLHS LBD & DPB:
Historically, the name ``ldb'' comes from a DEC PDP-10
assembly language instruction meaning ``load byte.''
...
Historically, the name ``dpb'' comes from a DEC PDP-10
assembly language instruction meaning ``deposit byte.''
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
On Mar 10, 3:14 am, ····@rpw3.org (Rob Warnock) wrote:
> Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
> +---------------| ········@gmail.com writes:
>
> | > I have values A, B, C, and D (all fixnum integers). I want to
> | > be able to combine them to create integer E and later pull
> | > A, B, C, or D out of E
> | >
> | > I know it's simple but I'm sure I'll do it naively if left
> | > to my own ways...
> |
> | Not a wizard but an ex-assembler programmer. I'd go for
> |
> | CL-USER> (defun pack (b01 b234 b5678)
> | (logior b01 (ash b234 2) (ash b5678 5)))
> | PACK
> |
> | CL-USER> (write (pack 1 5 10) :base 2)
> | 101010101
> | 341
> +---------------
>
> As an ex-*PDP-10*[1] assembler programmer, ;-}
> I'd probably go for this:
>
> > (defun pack (b01 b234 b5678)
> (dpb b5678 (byte 5 5)
> (dpb b234 (byte 3 2)
> b01)))
> PACK
> > (write (pack 1 5 10) :base 2)
> 101010101
> 341
> >
>
> Or the more-imperative equivalent:
>
> (defun pack (b01 b234 b5678)
> (setf (ldb (byte 3 2) b01) b234)
> (setf (ldb (byte 5 5) b01) b5678)
> b01)
>
> [I'm not sure which one is faster.]
>
> +---------------
> | CL-USER> (defun unpack (i)
> | (values (ldb (byte 2 0) i)
> | (ldb (byte 3 2) i)
> | (ldb (byte 4 5) i)))
> | UNPACK
> +---------------
>
> Yup, just so!
>
> -Rob
>
> [1] See CLHS LBD & DPB:
>
> Historically, the name ``ldb'' comes from a DEC PDP-10
> assembly language instruction meaning ``load byte.''
> ...
> Historically, the name ``dpb'' comes from a DEC PDP-10
> assembly language instruction meaning ``deposit byte.''
>
OMG what does any of this goat barf mean? ;-) I guess I've got some
reading to do...
thanks for the pointers
Nick
<········@gmail.com> wrote:
+---------------
| On Mar 10, 3:14 am, ····@rpw3.org (Rob Warnock) wrote:
| > As an ex-*PDP-10*[1] assembler programmer, ;-}
| > I'd probably go for this: ...
| > (defun pack (b01 b234 b5678)
| > (dpb b5678 (byte 5 5)
| > (dpb b234 (byte 3 2)
| > b01)))
...
| > Or the more-imperative equivalent:
| > (defun pack (b01 b234 b5678)
| > (setf (ldb (byte 3 2) b01) b234)
| > (setf (ldb (byte 5 5) b01) b5678)
| > b01)
...
| > [1] See CLHS LBD & DPB:
| > Historically, the name ``ldb'' comes from a DEC PDP-10
| > assembly language instruction meaning ``load byte.''
| > Historically, the name ``dpb'' comes from a DEC PDP-10
| > assembly language instruction meaning ``deposit byte.''
|
| OMG what does any of this goat barf mean? ;-) I guess I've got some
| reading to do...
+---------------
A good quick reference on PDP-10 byte stuff is here:
http://pdp10.nocrew.org/docs/instruction-set/Byte.html
Byte instructions
In the PDP-10 a "byte" is some number of contiguous bits within
one word. A byte pointer is a quantity (which occupies a whole
word) which describes the location of a byte. There are three
parts to the description of a byte: the word (i.e., address) in
which the byte occurs, the position of the byte within the word,
and the length of the byte.
A byte pointer has the following format: ...
The Common Lisp LDB & DPB functions [together with BYTE, which
makes byte specifiers, though reversing the order of P & S]
were modelled on the PDP-10 byte instructions, though providing
a functional interface rather than a purely imperative one.
Very useful for low-level bit-banging of hardware registers
and protocol blocks...
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607