Index: /branches/arm/lisp-kernel/ARM-notes.txt
===================================================================
--- /branches/arm/lisp-kernel/ARM-notes.txt	(revision 13733)
+++ /branches/arm/lisp-kernel/ARM-notes.txt	(revision 13734)
@@ -220,2 +220,84 @@
 fault handler and unprotect pages there.)
 
+
+ - consing & pc-lusering
+
+The magic consing sequence (that pc_luser_xp() and maybe handle_alloc_trap()
+will have to recognize) is basically:
+
+1: decrement allocptr by an amount that'll leave it tagged as either
+   tag_misc or tag_cons.  
+
+  a) CONSes:
+   (sub allocptr allocptr (:$ (- arm::cons.size arm::fulltag-cons)))
+
+  b) UVECTORs whose aligned size is known and <= 64K
+   (sub allocptr allocptr (:$ (logand (- size arm::fulltag-misc) #xff)))
+   (sub allocptr allocptr (:$ (logandc2 (- size arm::fulltag-misc)) #xff))
+
+   Note that the second instruction above can be omitted if (<= size 256);
+   if two instructions are used to decrement allocptr, they should be
+   done in this order.
+
+  c) UVECTORs whose size is > 64K or computed; this should be preceded
+  something which loads (- size arm::fulltag-misc) into some imm reg REG:
+
+   (sub allocptr allocptr REG)
+ 
+After this instruction (after the first in case (b)), allocptr is tagged
+and the entire sequence needs to be completed or restarted by pc_luser_xp().
+
+2: Load (:@ rcontext (:$ arm::tcr.allocbase)) into some available GPR.
+We can't afford to dedicate a register to contain allocbase, and 
+tcr.allobase can ordinarily change on any instruction boundardy so we
+can only do this after decrementing and tagging allocptr in step 1 above.
+
+   (ldr reg2 (:@ rcontext (:$ arm::tcr.allocbase)))
+
+"reg2" can't be the same register used in 1c and shouldn't conflict with
+anything used to contain headers/CAR/CDR values, but can otherwise be
+any GPR.
+
+3: Compare allocptr to the register holding allocbase; do a uuo-alloc-trap
+if allocptr is U< allocbase.  (We could encode the "lo" condition in
+uuo-alloc-trap if we wanted to>)
+
+   (cmp allocptr reg2)
+   (uuo-alloc-trap (:? lo))
+
+If the trap is taken, the handler should be able to determine the size
+and tag of the allocation and resume execution at the next instruction
+with allocptr pointing at zeroed memory.  The register used to hold
+allocbase won't change, but its value may or may not have anything to
+do with tcr.allocbase at this point.
+
+4: Initialize the object; if a UVECTOR, set its header.  If a CONS, set
+its CAR and CDR.
+
+    (str header (:@ allocptr (:$ arm::misc-header-offset)))
+
+    or
+
+    (str Rcar (:@ allocptr (:$ arm::cons.car)))
+    (str Rcdr (:@ allocptr (:$ arm::cons.cdr)))
+
+5: Copy allocptr to the destination register.  (In the CONS case, this may
+have been one of Rcar/Rcdr);
+
+    (mov dest allocptr)
+
+6: Clear the low 3 bits of allocptr.
+
+     (bic allocptr allocptr (:$ arm::fulltagmask))
+
+This is basically the same sequence as is used on the PPC; the differences
+are:
+
+  a) We might decrement allocptr twice in (1b)
+  b) We don't use a dedicated register to contain allocbase, and have
+     to load it from the TCR into a temp register after allocptr's been
+     decremented.
+  c) We don't exactly have conditional traps, so we have to do a compare
+     followed by a conditional UUO.
+
+
