2026-04-19 21:17 UTC
CDR-coding might be practical on modern architectures after all.
for example, on x86, put these CDR bits at the top of a word:
00 EOL cdr of this cell is NIL
01 NEXT cdr of this cell is next cell
10 ATOM this is not a list cell
11 GONE this cell has moved elsewhere
and use the following access code
fwd mov eax,[eax*4] ; don't let FWDs into regs
cmp eax,$C000000
jae fwd
ret
car mov edx,[eax*4] ; guaranteed not FWD
test eax,eax ; so if MSB set,
jc rtn ; must be ATOM
mov eax,edx
cmp edx,$C000000
jae fwd
rtn ret
cdr mov edx,[eax*4+4]
shl eax,1
jns NIL
mov eax,edx
cmp edx,$C000000
jae fwd
ret
by and large, the mov will shadow the cost of testing - so that essentially the latter will be free
note that there's no code to denote a CONS cell. i'm not sure when i realised that you don't need one - that it's sufficient to have CDR-NEXT and FWD, because you can make a CONS cell out of [ NEXT FWD ], and as long as you always follow FWDs somewhere (a good strategy, which is implemented above, is to never allow them into CPU registers), they're transparent.
it might make sense - and save some space - to put $C0000000 into a register - say, ebp - so comparing it takes two bytes instead of 6. especially when open-coding functions
(gods, i wish Intel hadn't removed the conditionall calls and returns from the 8080 instruction set...!)
Replies (1)
-
@SpindleyQ@gamemaking.social 2026-04-21 02:51
@millihertz wrapping my head around this... should the `JC rtn` in `car` be a JNGE? CF is always 0 after a TEST, you want to check SF, right?