;-*- Mode:LISP; Base:8 -*- ;;; (C) Copyright 1983,1984,1985, Mats Carlsson, UPMAIL. ;;; Version for Lambda (release 2.1 or newer) and Explorer. ;;; Microcode for LM-Prolog. ;;; Potentially dangerous POPJs are marked with ***, ;;; since they could start a macro insn cycle. However, the corresponding MISCs ;;; are pretty useless with D-IGNORE. ;;; Wired in assumptions on storage conventions: ;;; >> Fill-pointers are at offset -2 from the array pointer. ;;; >> Flavor instances look like
;;; Not using "carcdr-direct", since the calling conventions are slightly awkward. (defconst uc-prolog '( #+lambda (begin-pagable-ucode) (mc-linkage (;;the following are needed for A mem communication. a-unify-dispatch a-lmp-vector a-lmp-trail a-lmp-area a-lmp-mode ;;the following are needed because of LAST-ARG-IN-T properties lmp-cell lmp-reference lmp-dereference lmp-updl lmp-centry #-lexical lmp-invoke ;;the following are needed for our unify-dispatch-table lmp-pop-fail lmpu-x-x lmpu-instance-x lmpu-x-instance lmpu-var-x lmpu-x-var lmpu-var-var lmpu-var-list lmpu-list-var lmpu-list-list )) ;;Exit vector offsets. (assign lmpoff-unify 765) (assign lmpoff-occurs-in 766) (assign lmpoff-unify-term-with-template 767) (assign lmpoff-construct 770) (assign lmpoff-unify-term-with-term 771) (assign lmpoff-array-push-extend 772) (assign lmpoff-read-only-variable-flavor 773) (assign lmpoff-true 774) (assign lmpoff-false 775) (assign lmpoff-find-and-cache 776) (assign lmpoff-universe 777) (locality d-mem) ;;Tail-recursive calls. (start-dispatch 0 0) d-lmp-mmjcall (mmjcall inhibit-xct-next-bit) ;tail recursive call (end-dispatch) ;;%UNIFY-TERM-WITH-TEMPLATE (start-dispatch 3 0) ;PPSS 2503: what kind of occurrence. d-lmp-unify (lmp-put-frame inhibit-xct-next-bit) ;first occurrence (lmp-updl) ;subsequent occurrence (lmp-pop-succeed inhibit-xct-next-bit) ;void occurrence (illop inhibit-xct-next-bit) (lmp-ro-unify-1 inhibit-xct-next-bit) ; read-only first occurrence (lmp-ro-unify-2) ; read-only subsequent occurrence (lmp-ro-uvoid inhibit-xct-next-bit) ; read-only void occurrence (illop inhibit-xct-next-bit) (end-dispatch) ;;%CONSTRUCT (start-dispatch 3 0) ;PPSS 2503: what kind of occurrence. d-lmp-construct (lmp-put-cell-frame) ;first occurrence (lmp-get-frame inhibit-xct-next-bit) ;subsequent occurrence (lmp-cell inhibit-xct-next-bit) ;void occurrence (illop inhibit-xct-next-bit) (lmp-ro-construct-1) ; read-only first occurrence (lmp-ro-construct-2 inhibit-xct-next-bit) ; read-only subsequent occurrence (lmp-ro-construct-void inhibit-xct-next-bit) ; read-only void occurrence (illop inhibit-xct-next-bit) (end-dispatch) ;;First occurrences. (start-dispatch 2 0) ;PPSS 2302: base reg ;PPSS 0023: offset d-lmp-put-frame (lmp-put-vector) ;interpreter's vector (qstarg) ;argument block (qstloc) ;local block (#-lexical illop #+lexical lmp-xstore) ;higher context. (end-dispatch) ;;Subsequent occurrences. (start-dispatch 2 0) ;PPSS 2302: base reg ;PPSS 0023: offset d-lmp-get-frame (lmp-get-vector) ;interpreter's vector (qadarg1) ;argument block (qadloc1) ;local block (#-lexical illop #+lexical lmp-xload) ;higher context. (end-dispatch) ;;Special va:s in A-MEM. (locality a-mem) ;a-unify-dispatch (0) ;moved to UC-PARAMETERS, following A-FLOATING-ZERO. ;a-lmp-vector (0) ;a-lmp-trail (0) a-lmp-area (0) a-lmp-mode (0) ;;And now for the actual code. (locality i-mem) (misc-inst-entry occurs-in) ((m-a) q-typed-pointer pdl-pop) ((m-k) q-typed-pointer pdl-pop) lmp-occurs-in (jump-data-type-not-equal m-a (a-constant (byte-value q-data-type dtp-list)) lmp-occurs-in-atom) lmp-occurs-in-list (call-xct-next lmp-carcdr) ((m-t) m-a) (jump-data-type-not-equal-xct-next m-a (a-constant (byte-value q-data-type dtp-list)) lmp-occurs-in-simple-recurse) ((pdl-push) m-t) #+lambda (jump-greater-than micro-stack-pntr-and-data (a-constant 20._24.) lmp-occurs-in-slow-recurse) ;Ustack filling up? #+exp (jump-greater-than micro-stack-pntr (a-constant 10.) lmp-occurs-in-slow-recurse) (jump-xct-next lmp-occurs-in-join) ;No, proceed. (Should check stack frame too.) (call lmp-occurs-in-list) lmp-occurs-in-atom ((m-t) a-v-nil) (popj-after-next popj-not-equal m-k a-a) ((m-t) a-v-true) lmp-occurs-in-simple-recurse (call lmp-occurs-in-atom) lmp-occurs-in-join ;Here with key in K and term on stack ((m-a) q-typed-pointer pdl-pop) (popj-not-equal m-t a-v-nil) (jump lmp-occurs-in) lmp-occurs-in-slow-recurse ((pdl-push) m-k) (dispatch-call (i-arg lmpoff-occurs-in) d-call-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer m-k (a-constant (byte-value q-cdr-code cdr-next))) ((pdl-push) q-typed-pointer m-a (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch-call (i-arg 2) d-mmcall i-dont-chain) (jump-xct-next lmp-occurs-in-join) ((m-k) q-typed-pointer pdl-pop) (misc-inst-entry %reference) ((m-t) q-typed-pointer pdl-pop) lmp-reference ;Inviz. T if it is a variable. (popj-after-next popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative))) ((m-t) q-pointer m-t (a-constant (byte-value q-data-type dtp-external-value-cell-pointer))) (misc-inst-entry %dereference) ((m-t) q-typed-pointer pdl-pop) lmp-dereference ;Read T if it is a variable. (popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative))) ((vma-start-read) m-t) (check-page-read) (popj-after-next dispatch transport md) ((m-t) q-typed-pointer md) (begin-comment) (end-comment) lmp-cell (jump-not-equal m-t a-v-nil lmp-cell-named) (misc-inst-entry %cell0) ;Make an unnamed value cell. lmp-cell0 ((m-b) (a-constant 1)) ;Cons 1 word (call-xct-next allocate-list-storage) ((m-s) a-lmp-area) ;in *PROLOG-WORK-AREA* ((m-t vma) q-pointer m-t (a-constant (byte-value q-data-type dtp-locative))) ((md-start-write) q-typed-pointer m-t (a-constant (byte-value q-cdr-code cdr-nil))) (check-page-write) ;Store a self-reference. (popj-after-next) (gc-write-test) lmp-cell-named ((pdl-push) m-t) (misc-inst-entry %cell) ;Make a named value cell. ((m-b) (a-constant 2)) ;Cons 2 words (call-xct-next allocate-list-storage) ((m-s) a-lmp-area) ;in *PROLOG-WORK-AREA* ((m-t vma) q-pointer m-t (a-constant (byte-value q-data-type dtp-locative))) ((md-start-write) q-typed-pointer m-t (a-constant (byte-value q-cdr-code cdr-normal))) (check-page-write) ;Store a self-reference. (gc-write-test) ((vma) m+1 vma) ((md-start-write) q-typed-pointer pdl-pop (a-constant (byte-value q-cdr-code cdr-error))) (check-page-write) ;Store the name. (popj-after-next) (gc-write-test) lmp-list ((m-b) m-r) ;Cons R words ((m-s) a-lmp-area) ;in *PROLOG-WORK-AREA* (jump-xct-next xlist0) (call allocate-list-storage) lmp-list* ((m-b) m-r) ;Cons R words ((m-s) a-lmp-area) ;in *PROLOG-WORK-AREA* (jump-xct-next xlistr0) (call allocate-list-storage) (misc-inst-entry %unify-term-with-template) lmp-utemplate ;Here with template in K. ((m-k) q-typed-pointer pdl-pop) (call-data-type-equal-xct-next pdl-top (a-constant (byte-value q-data-type dtp-locative)) qcar3) ((m-t) q-typed-pointer pdl-pop) ((pdl-push) m-t) lmp-utemplate-nd ;Here if we don't need to dereference. (jump-equal m-k a-v-nil lmp-unil) (jump-data-type-equal m-k (a-constant (byte-value q-data-type dtp-list)) lmp-uconstruct) (jump-data-type-equal m-k (a-constant (byte-value q-data-type dtp-locative)) lmp-uconstant) (call-data-type-equal-xct-next m-k (a-constant (byte-value q-data-type dtp-symbol)) lmp-symeval-a) ((m-a) m-k) (dispatch (byte-field 3 25) m-a d-lmp-unify) ;XCT-NEXT only if subsequent occ. (call lmp-get-frame-d) lmp-uconstant ;Possible bum: ; (jump-xct-next lmp-updl) ; (open-qcar m-k) ((m-t) m-k) (jump-xct-next lmp-updl) (call qcar3) lmp-symeval-a ((vma-start-read) m+1 m-a) (check-page-read) (dispatch transport md) (popj-after-next (m-t) m-a) ((m-a) q-typed-pointer md) lmp-uconstruct ;X & construct ((m-t) m-k) (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-list)) lmp-uconstruct-1) (call lmp-carcdr) ;List & construct. ((m-k) m-a) ;Recurse, pushing cdrs. ((m-c) m-t) (call-xct-next lmp-carcdr) ((m-t) q-typed-pointer pdl-pop) ((pdl-push) m-t) ((pdl-push) m-c) (jump-equal-xct-next m-k a-v-nil lmp-unil-then-join) ((pdl-push) m-a) #+lambda (call-greater-than micro-stack-pntr-and-data (a-constant 20._24.) ;(Should check frame too.) lmp-utemplate-slow-recurse) #+lambda (call-less-or-equal micro-stack-pntr-and-data (a-constant 20._24.) lmp-utemplate-nd) #+exp (call-greater-than micro-stack-pntr (a-constant 10.) lmp-utemplate-slow-recurse) #+exp (call-less-or-equal micro-stack-pntr (a-constant 10.) lmp-utemplate-nd) lmp-uconstruct-join (jump-not-equal m-t a-v-nil lmp-utemplate) ;drop thru and fail otherwise lmp-pop2-fail ;Pop two and fail. (popj-after-next (m-t) seta pdl-pop a-v-nil) (pdl-pop) lmp-utemplate-slow-recurse ;MMcall %unify-term-with-template. (dispatch-call PDL-POP (i-arg lmpoff-unify-term-with-template) d-call-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer m-a (a-constant (byte-value q-cdr-code cdr-next))) ((pdl-push) q-typed-pointer m-k (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch (i-arg 2) d-lmp-mmjcall i-dont-chain) lmp-uconstruct-1 ;Atom & construct. (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-locative)) lmp-uconstruct-2) ;Variable & complex term. Construct it and bind. (call lmp-construct-t) (jump-xct-next lmpu-var-list) ((m-i) a-lmp-mode) lmp-uconstruct-2 (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-instance)) lmp-pop-fail) ;Instance & complex term. Construct it and send :unify msg. (jump-xct-next lmpu-instance-x) (call lmp-construct-t) (misc-inst-entry %construct) ((m-t) q-typed-pointer pdl-pop) (POPJ-EQUAL M-T A-V-NIL) lmp-construct-t (jump-data-type-equal m-t (a-constant (byte-value q-data-type dtp-list)) lmp-construct-list) lmp-construct-not-list (jump-data-type-equal m-t (a-constant (byte-value q-data-type dtp-locative)) qcar3) ((m-a) m-t) (call-data-type-equal-xct-next m-t (a-constant (byte-value q-data-type dtp-symbol)) lmp-symeval-a) ((m-t) a-v-nil) (dispatch (byte-field 3 25) m-a d-lmp-construct) ;XCT-NEXT if first occ. ((pdl-push) m-a) lmp-construct-list ;Construct the cons sitting in T. #+lambda (jump-greater-than micro-stack-pntr-and-data (a-constant 20._24.) lmp-construct-slow-recurse) ;Chicken out? #+exp (jump-greater-than micro-stack-pntr (a-constant 10.) lmp-construct-slow-recurse) ;Chicken out? (call-xct-next lmp-construct-list-rest) ((pdl-push) (a-constant (byte-value q-data-type dtp-fix))) ;Push count first. (jump-equal-xct-next m-t a-v-nil lmp-list) ;LIST* the elements. ((m-r) q-pointer pdl-pop) ;R long. (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative)) lmp-construct-exit) ((m-t) q-pointer m-t (a-constant (byte-value q-data-type dtp-external-value-cell-pointer))) lmp-construct-exit ((pdl-push) m-t) (jump-xct-next lmp-list*) ((m-r) m+1 m-r) lmp-construct-list-rest (call lmp-carcdr) ((pdl-push) m-t) ((m-t) m-a) (jump-equal m-t a-v-nil lmp-construct-list-cdr) (call lmp-construct-t) ;Invz element if need be (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative)) lmp-construct-list-cdr) ((m-t) q-pointer m-t (a-constant (byte-value q-data-type dtp-external-value-cell-pointer))) lmp-construct-list-cdr ((m-k) q-typed-pointer pdl-pop) ;pop rest of template ((m-s) q-typed-pointer pdl-pop) ;pop count ((pdl-push) m-t) ;push element ((pdl-push) m+1 m-s) ;push incf count (popj-equal-xct-next m-k a-v-nil) ((m-t) m-k) (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-list)) lmp-construct-not-list) ((pdl-buffer-index) sub pdl-buffer-pointer a-ap) ;Stack frame filling up? (jump-less-or-equal pdl-buffer-index (a-constant 370) lmp-construct-list-rest) ;drop thru if frame is filling up lmp-construct-slow-recurse ((m-k) m-t) ;CALL-EXIT-VECTOR clobbers M-T... (dispatch-call (i-arg lmpoff-construct) d-call-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer m-k (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch (i-arg 1) d-lmp-mmjcall i-dont-chain) lmp-put-frame ;Store PDL-POP in local frame and succeed. ((m-t) q-typed-pointer pdl-top) ((micro-stack-data-push) (a-constant (i-mem-loc lmp-pop-succeed))) (dispatch-xct-next (byte-field 2 23) m-a d-lmp-put-frame) ((m-1) (byte-field 23 0) m-a) lmp-put-cell-frame ;Store a cell into local frame and return it. (call lmp-cell) ((m-a) pdl-pop) ;Was pushed at LMP-CONSTRUCT-LIST -1. (dispatch-xct-next (byte-field 2 23) m-a d-lmp-put-frame) ((m-1) (byte-field 23 0) m-a) lmp-get-frame-d ;Dereference after doing... ((micro-stack-data-push) (a-constant (i-mem-loc lmp-dereference))) lmp-get-frame ;Get from local frame into T (dispatch-xct-next (byte-field 2 23) m-a d-lmp-get-frame) ((m-1) (byte-field 23 0) m-a) lmp-put-vector ;Store in interpreter's vector. (call-xct-next qrar3) ((m-s) add m-1 a-lmp-vector) (popj-after-next (m-t) q-typed-pointer md) (no-op) lmp-get-vector ;Read from interpreter's vector. (jump-xct-next qcar3) ((m-t) add m-1 a-lmp-vector) lmp-ro-construct-void ;Make read-only void. (jump-xct-next lmp-ro-allocate) (call lmp-cell) lmp-ro-construct-1 ;Make read-only 1st occ. (jump-xct-next lmp-ro-allocate) (call lmp-put-cell-frame) lmp-ro-construct-2 ;Make read-only 2nd occ. (call lmp-get-frame-d) (popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative))) ;drop thru if we are a variable ;;(make-instance-in-area *prolog-work-area* read-only-variable ':cell ) lmp-ro-allocate ((pdl-push) m-t) ((m-b) (a-constant 2)) ;Cons 2 words ((m-a) (a-constant 2)) (call-xct-next allocate-structure-storage) ((m-s) a-lmp-area) ;in *PROLOG-WORK-AREA* (dispatch-call (i-arg lmpoff-read-only-variable-flavor) d-read-exit-vector i-dont-chain) ((write-memory-data) q-pointer md (a-constant (byte-value q-data-type dtp-instance-header))) ((vma-start-write m-t) q-pointer m-t (a-constant (byte-value q-data-type dtp-instance))) (check-page-write) (gc-write-test) ((md) q-typed-pointer pdl-pop (a-constant (byte-value q-cdr-code cdr-nil))) ((vma-start-write) add m-t (a-constant 1)) (check-page-write) (popj-after-next) (gc-write-test) lmp-ro-uvoid ;Unify with read-only void. (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-locative)) lmp-pop-fail) (jump-xct-next lmpu-var-x) (call lmp-ro-construct-void) lmp-ro-unify-1 ;Unify with read-only 1st occ. (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-locative)) lmp-pop-fail) (jump-xct-next lmpu-var-x) (call lmp-ro-construct-1) lmp-ro-unify-2 ;Unify with read-only 2nd occ. (jump-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-locative)) lmp-ro-unify-nonvar) (jump-xct-next lmpu-var-x) (call-data-type-equal m-t (a-constant (byte-value q-data-type dtp-locative)) lmp-ro-allocate) lmp-ro-unify-nonvar ;NV&V  fail, NV&NV  unify (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative)) lmp-updl) (jump lmp-pop-fail) lmp-unil-then-join ((micro-stack-data-push) (a-constant (i-mem-loc lmp-uconstruct-join))) lmp-unil ;Unify PDL with NIL. ((pdl-top m-tem) q-typed-pointer pdl-top) (jump-equal m-tem a-v-nil lmp-pop-succeed) (jump-data-type-equal-xct-next pdl-top (a-constant (byte-value q-data-type dtp-locative)) lmpu-var-x) ((m-t) a-v-nil) (jump-data-type-equal pdl-top (a-constant (byte-value q-data-type dtp-instance)) lmpu-instance-x) ;All other cases fail... lmp-pop-fail ;Pop one and fail. (popj-after-next (m-t) a-v-nil) (pdl-pop) (misc-inst-entry %unify-term-with-term) ((m-t) q-typed-pointer pdl-pop) lmp-updl ;Here to unify PDL with T. ((m-s pdl-top) q-typed-pointer pdl-top) ;Make S=PDL (jump-equal m-s a-t lmp-pop-succeed) ;Start of less strange code, as suggested by khs. ((m-i) a-lmp-mode output-selector-leftshift-1) lmp-updl-1 ;Unify S=PDL with T and ST. ;M-I has mode bits when recursing, ;gets bit 1 in bit 2 the first time. ((m-1) q-data-type m-s) ((m-2) q-data-type m-t) ;could save a cycle if table were on ((m-3) dpb m-1 (byte-field 5 5) a-2) ; 0 modulo 2000... ((vma-start-read) add m-3 a-unify-dispatch) (check-page-read) ;no transport since it's static ((m-i) selective-deposit m-i (byte-field 1 2) a-lmp-mode) ((oa-reg-low) dpb md oal-jump a-zero) (jump 0) lmpu-x-x ;Chicken out to EQUAL. ((pdl-push) m-t) (jump xequal) lmpu-var-var ;Variable & variable. (jump-xct-next lmpu-var-x) ((m-t) q-pointer m-t (a-constant (byte-value q-data-type dtp-external-value-cell-pointer))) lmpu-list-var ;List & variable. ((pdl-top) m-t) ((m-t) m-s) ;drop thru lmpu-var-list ;Variable & list. (call-if-bit-set (byte-field 1 0) m-i lmpu-var-list-check) ;drop thru lmpu-var-x (call-xct-next qrar3) ((m-s) q-typed-pointer pdl-pop) (call-not-equal-xct-next m-array-pointer a-lmp-trail decode-1d-array-uncached) ((m-array-pointer) dpb m-zero q-cdr-code a-lmp-trail) ((vma-start-read) sub m-array-pointer (a-constant 2)) (check-page-read) ;;m-array-pointer is not generally transported (dispatch transport md) ((m-q) q-pointer md) (jump-greater-or-equal-xct-next m-q a-array-length lmpu-var-x-ov) ;Check overflow. ((m-k) m-t) ((m-t md-start-write) m+1 md) ;Bump fill-pointer. (check-page-write) ((vma) add m-array-origin a-q) ((md-start-write) m-k) ;Store trail-item. (check-page-write) (gc-write-test) (popj) ;this can be D-IGNORE! lmpu-var-x-ov ;Overflow handling. (dispatch-call (i-arg lmpoff-array-push-extend) d-call-exit-vector i-dont-chain) ((pdl-push) a-lmp-trail) ;Don't worry about cdr code... ((pdl-push) q-typed-pointer m-k (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch (i-arg 2) d-lmp-mmjcall i-dont-chain) lmpu-x-var ;Non-variable & variable. ((pdl-top) m-t) (jump-xct-next lmpu-var-x) ((m-t) m-s) lmpu-x-instance ;Non-variable & instance. ((pdl-top) m-t) ((m-t) m-s) ;drop thru lmpu-instance-x ;Instance & non-variable. (call-xct-next p3zero) ;Escape to a :UNIFY method. ((m-s) pdl-pop) ((pdl-push) m-s) (dispatch-call (i-arg lmpoff-unify) d-read-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer md (a-constant (byte-value q-cdr-code cdr-next))) ((pdl-push) q-typed-pointer m-t (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch (i-arg 2) d-lmp-mmjcall i-dont-chain) lmpu-list-list ;Here to unify two lists. (call-if-bit-set (byte-field 1 2) m-i lmpu-unbind-later) ((m-c) m-s) ;C gets first arg, (call-xct-next lmp-carcdr) ;A and T get its parts. ((m-d) m-t) ;D gets second arg, ((m-b) m-a) ;B and S=TOP get its parts. ((m-s pdl-top) m-t) (call-xct-next lmp-carcdr) ((m-t) m-c) (jump-equal m-a a-b lmpu-equal-cars) (jump-equal m-s a-t lmpu-equal-cdrs) ((pdl-push) m-t) ((pdl-push m-s) m-a) ;Recurse on cars. (call-if-bit-set-xct-next (byte-field 1 1) m-i lmpu-llh-bind) ((m-t) m-b) #+lambda (call-greater-than micro-stack-pntr-and-data (a-constant 20._24.) lmpu-slow-recurse) #+lambda (call-less-or-equal micro-stack-pntr-and-data (a-constant 20._24.) lmp-updl-1) #+exp (call-greater-than micro-stack-pntr (a-constant 10.) lmpu-slow-recurse) #+exp (call-less-or-equal micro-stack-pntr (a-constant 10.) lmp-updl-1) (jump-equal m-t a-v-nil lmp-pop2-fail) ((pdl-buffer-index) sub pdl-buffer-pointer (a-constant 1)) ;Dereference cdrs. (call-data-type-equal-xct-next c-pdl-buffer-index (a-constant (byte-value q-data-type dtp-locative)) qcar3) ((m-t) c-pdl-buffer-index) ((m-s c-pdl-buffer-index) m-t) (call-data-type-equal-xct-next pdl-top (a-constant (byte-value q-data-type dtp-locative)) qcar3) ((m-t) q-typed-pointer pdl-pop) (jump-not-equal-xct-next m-s a-t lmp-updl-1) ;Iterate on cdrs if . ((m-i) a-lmp-mode) ;drop thru if cdrs eq. lmp-pop-succeed (popj-after-next (m-t) a-v-true) (pdl-pop) lmpu-slow-recurse ((m-a) pdl-pop) ;First arg pushed already. ((m-b) m-t) (dispatch-call (i-arg lmpoff-unify-term-with-term) d-call-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer m-a (a-constant (byte-value q-cdr-code cdr-next))) ((pdl-push) q-typed-pointer m-b (a-constant (byte-value q-cdr-code cdr-nil))) (dispatch (i-arg 2) d-lmp-mmjcall i-dont-chain) lmpu-equal-cars ;Just iterate. (jump-equal m-s a-t lmp-pop-succeed) (jump-xct-next lmp-updl-1) (call-if-bit-set (byte-field 1 1) m-i lmpu-llh-bind) lmpu-equal-cdrs ;Just iterate. ((m-t) m-a) ((pdl-top m-s) m-b) (jump-xct-next lmp-updl-1) (call-if-bit-set (byte-field 1 1) m-i lmpu-llh-bind) lmpu-var-list-check ((m-k) pdl-top) (call-xct-next lmp-occurs-in-list) ((pdl-push m-a) m-t) (popj-equal-xct-next m-t a-v-nil) ((m-t) q-typed-pointer pdl-pop) (jump-xct-next lmp-pop-fail) ;Occur check succeeded, cause failure. (micro-stack-data-pop) lmpu-llh-bind ;Bind the first cons to a RPLACD-FORWARD to the second cons. ((pdl-push) m-t) ((pdl-push) q-pointer m-c (a-constant (byte-value q-data-type dtp-locative))) ((m-t) q-pointer m-d (a-constant (byte-value q-data-type dtp-rplacd-forward))) (jump-xct-next poptj) (call xbind1) lmpu-unbind-later ;Save specPDL index and unwind before returning. ((m-3) a-qlbndp) ((pdl-top) q-pointer m-3 (a-constant (byte-value q-data-type dtp-locative))) ((pdl-push) m-s) (popj-after-next (m-i) a-lmp-mode) ;Turn off M-I<2>. ((micro-stack-data-push) (a-constant (i-mem-loc xunbind-to-index))) lmp-carcdr ;A := car(T), T := cdr(T) ((vma-start-read) m-t) (check-page-read) (dispatch transport md) #+lambda (micro-fault-ok-here) (jump-not-equal-xct-next vma a-t qcdr3) ;Full cdr if the car was forwarded ((m-a) q-typed-pointer md) (dispatch q-cdr-code md cdr-cdr-dispatch) ;XCT-NEXT on CDR-NEXT ((m-t) add vma (a-constant 1)) (misc-inst-entry %untrail) ;;Scratchpad registers used here: ;;PDL-TOP is MARK ;;M-I is transported array-pointer ;;M-K is *TRAIL* ;;M-E is 1+last trail item address ((pdl-top) q-typed-pointer pdl-top) lmp-untrail-restart ;Initialize. (call-not-equal-xct-next m-array-pointer a-lmp-trail decode-1d-array-uncached) ((m-array-pointer) dpb m-zero q-cdr-code a-lmp-trail) ((vma-start-read) sub m-array-pointer (a-constant 2)) (check-page-read) ;;m-array-pointer is not generally transported (dispatch transport md) ((m-i) add vma (a-constant 2)) ((m-k) q-typed-pointer md) ((m-e) add m-array-origin a-k) lmp-untrail-loop (jump-greater-or-equal pdl-top a-k lmp-pop-fail) ((m-k md) sub m-k (a-constant 1)) ;*TRAIL* := *TRAIL*-1 ((vma-start-write) sub m-i (a-constant 2)) (check-page-write) ((m-e vma-start-read) sub m-e (a-constant 1)) ;Get next item. (check-page-read) (dispatch transport md) ;Transport to newspace. ((m-t) q-typed-pointer md) ((md-start-write) a-v-nil) ;Clobber item with NIL. (check-page-write) (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-locative)) lmp-untrail-invoke) ((vma-start-read) m-t) (check-page-read) ;Transporting done already, just want the cdr code. ((md-start-write) selective-deposit md q-cdr-code a-t) (check-page-write) (jump-xct-next lmp-untrail-loop) (gc-write-test) lmp-untrail-invoke (jump-xct-next lmp-untrail-restart) ;Re-initialize after invoking, (call lmp-invoke) ; since it can have side-effects. #-lexical (misc-inst-entry %invoke) ;; This is as #-LEXICAL (apply (car x) (cdr x)) #+LEXICAL (funcall x), ;; but checks for TRUE and FALSE first, which are frequent cases in continuations. #-lexical ((m-t) q-typed-pointer pdl-pop) lmp-invoke #-lexical (call-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-list)) illop) #-lexical (call lmp-carcdr) ;A := fctn, T := args. #-lexical (dispatch-call (i-arg lmpoff-true) d-read-exit-vector i-dont-chain) #-lexical ((md) q-typed-pointer md) #-lexical (jump-equal md a-a xtrue) ;Succeed if fctn is TRUE. #-lexical (dispatch-call (i-arg lmpoff-false) d-read-exit-vector i-dont-chain) #-lexical ((md) q-typed-pointer md) #-lexical (popj-equal md a-a) ;Fail if fctn is FALSE. #-lexical ((pdl-push) m-a) #-lexical (jump-xct-next uaply) ;APPLY otherwise. #-lexical ((pdl-push) m-t) #+LEXICAL (call p3zero) #+LEXICAL ((pdl-push) m-t) #+LEXICAL (dispatch (i-arg 0) d-lmp-mmjcall i-dont-chain) (misc-inst-entry %current-entrypoint) ((m-t) q-typed-pointer pdl-pop) lmp-centry ((vma-start-read) m-t) ;K := definitions alist. (check-page-read) (dispatch transport md) ((m-k) q-typed-pointer md) (dispatch-call (i-arg lmpoff-universe) d-read-exit-vector i-dont-chain) ;B := *universe*. ((m-b) q-typed-pointer md) (jump-equal m-k a-v-nil lmp-nodef) ;Any definitions at all? ((vma-start-read) m-k) ;K := cache item. (check-page-read) (dispatch transport md) (call-xct-next lmp-carcdr) ;A := latest universe, T := defn. ((m-t) q-typed-pointer md) (jump-equal-xct-next m-b a-a qcar3) lmp-nodef ((m-a) q-typed-pointer pdl-pop) ;A := predicator (dispatch-call (i-arg lmpoff-find-and-cache) d-call-exit-vector i-dont-chain) ((pdl-push) q-typed-pointer m-k (a-constant (byte-value q-cdr-code cdr-next))) ;defs ((pdl-push) q-typed-pointer m-b (a-constant (byte-value q-cdr-code cdr-next))) ;worlds ((pdl-push) q-typed-pointer m-a (a-constant (byte-value q-cdr-code cdr-nil))) ;name (dispatch-call (i-arg 3) d-mmcall i-dont-chain) (jump qcar) ; Micro-Paging crock doesn't like the following. -- should be OK now. ; (jump-xct-next qcar) ;Full CAR since arg may become NIL. ; (dispatch-call (i-arg 3) d-mmcall i-dont-chain) ;;STORE IN LOCAL BLOCK QSTLOC (POPJ-AFTER-NEXT (PDL-BUFFER-INDEX) ADD M-1 A-LOCALP) ((C-PDL-BUFFER-INDEX) M-T) ;;STORE IN ARGUMENT BLOCK QSTARG (POPJ-AFTER-NEXT (PDL-BUFFER-INDEX) ADD M-AP A-1 ALU-CARRY-IN-ONE) ((C-PDL-BUFFER-INDEX) M-T) ;;STORE IN HIGHER CONTEXT #+LEXICAL lmp-xstore #+LEXICAL ((pdl-push) dpb m-zero (byte-field 5 23) a-a) #+LEXICAL (jump xstore-in-higher-context) ;;REF LOCAL BLOCK QADLOC1 (POPJ-AFTER-NEXT (PDL-BUFFER-INDEX) ADD M-1 A-LOCALP) ((M-T) Q-TYPED-POINTER C-PDL-BUFFER-INDEX) ;;REF ARGUMENT BLOCK. CANNOT BE INVISIBLE POINTER. QADARG1 (POPJ-AFTER-NEXT (PDL-BUFFER-INDEX) ADD M-AP A-1 ALU-CARRY-IN-ONE) ((M-T) Q-TYPED-POINTER C-PDL-BUFFER-INDEX) ;;LOAD FROM HIGHER CONTEXT #+LEXICAL lmp-xload #+LEXICAL ((pdl-push) dpb m-zero (byte-field 5 23) a-a) #+LEXICAL (jump xload-from-higher-context) #+lambda (end-pagable-ucode) ))