[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

LDB



; The following goes into the autoloadable LODBYT file, or in Lisp itself.

(lap-a-list
  '((lap ldb subr)
	(push p (% 0 0 fix1))
	(jsp t fxnv1)
	(jsp t fxnv2)
	(caia)
    (entry +internal-ldb subr)
	(push p (% 0 0 fix1))
	(hrlz d 0 a)
	(lsh d 6)
	(tlo d b)
	(ldb tt d)
	(popj p)
    nil))

; You might note that +INTERNAL-LDB has the same number of instructions as
; *LDB.  If it were lisp-internal, it could have an ACS property of 2.

; The following goes into a file which gets loaded into the compiler
; (presumably it would be pre-loaded):

(defun ldb-hacker (form)
  (let* (((ppss n) (cdr form))
	 (foo (lsb:constantp ppss)))
    (cond ((or (null foo) (not (fixp foo))) `(+internal-ldb ,ppss ,n))
	  (t `(boole 1 (lsh n ,(- (lsh foo -6.))) ,(ldb-make-mask foo))))))

(push '(ldb . ldb-hacker) macrolist)

(defun ldb-make-mask (ppss)
    (lsh -1 (- (boole 1 ppss #o77) 36.)))

This division keeps the interpreter from bloating (after all, all it needs
is a subr, not code which knows how to compile LDB) and lets one have
easy LDBs hacked nicely by the compiler.  If the compiler were ever to
hack LDB then you just flush the compile-time file.
P.s:  LSB:CONSTANTP returns the constant if the thing is a constant, with
(QUOTE number) being canonicalized to the number.

As a side comment, it is fine to have things be macros, but if there
are lots of them they cause the size of interpreted code to blow up
badly, increasing paging and gc time, and maybe making one run out
of core.