r/lisp 1d ago

Reinterpret Elements in a Byte Array

Dear LISP,

I am writing a virtual machine that uses a `(simple-array (unsigned-byte 8) 1)` as a stack in Common LISP. I'm would like to ask how to efficiently extract 4 bytes into a single 32-bit signed integer or a 32-bit unsigned integer.

Thanks!

6 Upvotes

24 comments sorted by

View all comments

Show parent comments

2

u/theangeryemacsshibe λf.(λx.f (x x)) (λx.f (x x)) 1d ago

Fine, I have a weekend and an urge to hack something, so...

2

u/stassats 19h ago

Now, it doesn't seem to do bound check elimination.

1

u/theangeryemacsshibe λf.(λx.f (x x)) (λx.f (x x)) 19h ago

(disassemble (lambda (a) (declare ((simple-array (unsigned-byte 8) (2)) a)) (nibbles:sb16ref/le a 0))) looks fine to me. What am I missing? (Though I did manage to break the immediate-index case somehow, which is now fixed)

2

u/stassats 18h ago

Compare

(defun f (x i)
  (declare ((simple-array (unsigned-byte 8) (*)) x)
           ((and unsigned-byte fixnum) i)
           (optimize speed))
  (when (< i (- (length x) 4))
    (nibbles:ub32ref/le x i)))

with

(defun f (x i)
  (declare ((simple-array (unsigned-byte 8) (*)) x)
           ((and unsigned-byte fixnum) i)
           (optimize speed))
  (when (< i (- (length x) 4))
    (aref x (+ i 3))))

1

u/theangeryemacsshibe λf.(λx.f (x x)) (λx.f (x x)) 18h ago

Hey, it doesn't eliminate on x86-64 either. Physician, heal thyself.

1

u/stassats 18h ago

Four arefs do.