From: ········@gmail.com
Subject: packing multiple datapoints into a single fixnum
Date: 
Message-ID: <1173464697.239734.138010@n33g2000cwc.googlegroups.com>
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

From: Alan Crowe
Subject: Re: packing multiple datapoints into a single fixnum
Date: 
Message-ID: <86hcsuksix.fsf@cawtech.freeserve.co.uk>
········@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
From: Rob Warnock
Subject: Re: packing multiple datapoints into a single fixnum
Date: 
Message-ID: <0dqdnaf738OHDm_YnZ2dnUVZ_qWvnZ2d@speakeasy.net>
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
From: ········@gmail.com
Subject: Re: packing multiple datapoints into a single fixnum
Date: 
Message-ID: <1173546952.027898.56590@t69g2000cwt.googlegroups.com>
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
From: Rob Warnock
Subject: Re: packing multiple datapoints into a single fixnum
Date: 
Message-ID: <DKGdnf9MQMtCEWvYnZ2dnUVZ_uuqnZ2d@speakeasy.net>
<········@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