Machine-Independent MDL for TOPS-20 and VAX.
[pdp10-muddle.git] / mim / development / mim / vaxc / lookahead.mud
diff --git a/mim/development/mim/vaxc/lookahead.mud b/mim/development/mim/vaxc/lookahead.mud
new file mode 100644 (file)
index 0000000..67e08c0
--- /dev/null
@@ -0,0 +1,1172 @@
+
+<GDECL (LOOKAHEAD?) <OR ATOM FALSE>>
+
+<SETG ARITH
+      '[ADD!-MIMOP
+       SUB!-MIMOP
+       MUL!-MIMOP
+       DIV!-MIMOP
+       ADDF!-MIMOP
+       SUBF!-MIMOP
+       MULF!-MIMOP
+       DIVF!-MIMOP
+       AND!-MIMOP
+       OR!-MIMOP
+       XOR!-MIMOP
+       EQV!-MIMOP]>
+
+<SETG EMPU '[EMPUV?!-MIMOP EMPUU?!-MIMOP EMPUS?!-MIMOP EMPUB?!-MIMOP]>
+
+<SETG LENU '[LENUV!-MIMOP LENUU!-MIMOP LENUS!-MIMOP LENUB!-MIMOP]>
+
+<SETG NTHU '[NTHUV!-MIMOP NTHUU!-MIMOP NTHUS!-MIMOP NTHUB!-MIMOP]>
+
+<SETG PUTU '[PUTUV!-MIMOP PUTUU!-MIMOP PUTUS!-MIMOP PUTUB!-MIMOP]>
+
+<SETG RESTU '[RESTUV!-MIMOP RESTUU!-MIMOP RESTUS!-MIMOP RESTUB!-MIMOP]>
+
+<PUTPROP RESTUV!-MIMOP PUT-PAIR PUTUV!-MIMOP>
+
+<PUTPROP PUTUV!-MIMOP PUT-PAIR RESTUV!-MIMOP>
+
+<PUTPROP RESTUU!-MIMOP PUT-PAIR PUTUU!-MIMOP>
+
+<PUTPROP PUTUU!-MIMOP PUT-PAIR RESTUU!-MIMOP>
+
+<PUTPROP RESTUS!-MIMOP PUT-PAIR PUTUS!-MIMOP>
+
+<PUTPROP PUTUS!-MIMOP PUT-PAIR RESTUS!-MIMOP>
+
+<PUTPROP RESTUB!-MIMOP PUT-PAIR PUTUB!-MIMOP>
+
+<PUTPROP PUTUB!-MIMOP PUT-PAIR RESTUB!-MIMOP>
+
+<PUTPROP RESTUV!-MIMOP PAIR NTHUV!-MIMOP>
+
+<PUTPROP NTHUV!-MIMOP PAIR RESTUV!-MIMOP>
+
+<PUTPROP RESTUU!-MIMOP PAIR NTHUU!-MIMOP>
+
+<PUTPROP NTHUU!-MIMOP PAIR RESTUU!-MIMOP>
+
+<PUTPROP RESTUS!-MIMOP PAIR NTHUS!-MIMOP>
+
+<PUTPROP NTHUS!-MIMOP PAIR RESTUS!-MIMOP>
+
+<PUTPROP RESTUB!-MIMOP PAIR NTHUB!-MIMOP>
+
+<PUTPROP NTHUB!-MIMOP PAIR RESTUB!-MIMOP>
+
+<GDECL (ARITH NTHU PUTU RESTU LENU EMPU) <VECTOR [REST ATOM]>>
+
+<NEWSTRUC OP-INFO (VECTOR)
+         OP-ARGS VECTOR
+         OP-RES <OR ATOM VARTBL>
+         OP-HINT <OR LIST ATOM FALSE>
+         OP-BRANCH <OR ATOM FALSE>
+         OP-DIR ATOM>
+
+<SETG OP-INFO [<IVECTOR 5 <>> T <> <> T]>
+
+<DEFINE NTH-LOOK-AHEAD NLA (CINS STRUC1 OFF1 RES
+                           "OPTIONAL" (HINT <>) (STYPE1 <>)
+                           "AUX" (L .CODPTR) INCINS NXT (OP-INFO ,OP-INFO)
+                                 (ADDVAL 0) STRUC2 OFF2 (ELTYPE1 <>)
+                                 (ELTYPE2 <>) (EMPTY? <>)
+                                 (ARGVEC <OP-ARGS .OP-INFO>) (ARITH? <>)
+                                 (ILDB? <>) OL (IDPB? <>) NINS RES1 RES2
+                                 (RES1? <>) (RES2? <>) PINS (STYPE2 <>) AMT
+                                 CMPINS TMIML (NOPUT? <>))
+   #DECL ((CINS) ATOM (RES) <OR VARTBL ATOM> (NXT) <OR ATOM FORM>
+         (L) <SPECIAL <LIST [REST <OR ATOM FORM>]>> (OP-INFO) OP-INFO)
+   <COND (<NOT ,LOOKAHEAD?> <RETURN <> .NLA>)>
+   <COND (.STYPE1 <SET STYPE1 <PARSE-HINT .STYPE1 STRUCTURE-TYPE>>)
+        (T
+         <COND (<==? .CINS NTHUV!-MIMOP> <SET STYPE1 VECTOR>)
+               (<==? .CINS NTHUU!-MIMOP> <SET STYPE1 UVECTOR>)
+               (<==? .CINS NTHUS!-MIMOP> <SET STYPE1 STRING>)
+               (<==? .CINS NTHUB!-MIMOP> <SET STYPE1 BYTES>)
+               (<==? .CINS NTHL!-MIMOP> <SET STYPE1 LIST>)>)>
+   <COND (<==? .CINS ILDB!-MIMOP> <SET ILDB? .OFF1> <SET OFF1 1>)>
+   <COND
+    (<AND <OR <MEMQ .CINS ,NTHU>
+             <==? .CINS ILDB!-MIMOP>
+             <==? .CINS NTHL!-MIMOP>>
+         <G=? <LENGTH .L> 3>
+         <TYPE? .RES VARTBL>
+         <TYPE? .STRUC1 VARTBL>
+         <N==? .RES .STRUC1>
+         <TYPE? <SET NXT <GET-NEXT-INST .L>> FORM>
+         <COND (<OR <SET ARITH? <MEMQ <SET INCINS <1 .NXT>> ,ARITH>>
+                    <MEMQ .INCINS ,RESTU>>
+                <AND <PARSE-OP .NXT .OP-INFO>
+                     <==? <1 <OP-ARGS .OP-INFO>> .RES>
+                     <==? <OP-RES .OP-INFO> .RES>
+                     <SET ADDVAL <2 <OP-ARGS .OP-INFO>>>
+                     <TYPE? <SET NXT <GET-NEXT-INST .L>> FORM>>)
+               (T <SET INCINS <>> T)>
+         <OR <NOT .ARITH?>
+             <NOT <MEMQ .INCINS ,LOGIC>>
+             <NOT <MEMQ .STYPE1 '[STRING BYTES]>>>
+         <OR <MEMQ <SET PINS <1 .NXT>> ,PUTU>
+             <==? .PINS PUTL!-MIMOP>
+             <SET IDPB? <==? .PINS IDPB!-MIMOP>>
+             <COND (.ARITH? <SET PINS <>> <SET NOPUT? T> <SET STRUC2 .RES>)>>
+        ;"In case of CHTYPE here (for rest), will fall into
+           normal code"
+         <COND (<NOT .NOPUT?>
+                <PARSE-OP .NXT .OP-INFO>
+                <SET ARGVEC <OP-ARGS .OP-INFO>>
+                <COND (.IDPB? <==? <2 .ARGVEC> .RES>)
+                      (<==? <3 .ARGVEC> .RES>)>)
+               (T)>
+         <COND (<NOT .NOPUT?>
+                <COND (<WILL-DIE? .RES .L>)
+                      (.ARITH?
+                       ; "Work for NTH ? ADD when NTH ? ADD ? PUT can't
+                          because of life/death"
+                       <SET NOPUT? T>
+                       <SET PINS <>>
+                       <SET STRUC2 .RES>)>)
+               (T)>>
+     <COND (<NOT .NOPUT?> <SET STRUC2 <1 .ARGVEC>>) (T)>
+     <COND (.NOPUT? <PROTECT-VAL .STRUC2>)
+          (.IDPB? <SET STYPE2 <PARSE-HINT <OP-HINT .OP-INFO> STRUCTURE-TYPE>>)
+          (<==? .PINS PUTUV!-MIMOP> <SET STYPE2 VECTOR>)
+          (<==? .PINS PUTL!-MIMOP> <SET STYPE2 LIST>)
+          (<==? .PINS PUTUU!-MIMOP> <SET STYPE2 UVECTOR> <SET ELTYPE2 FIX>)
+          (<==? .PINS PUTUS!-MIMOP>
+           <SET STYPE2 STRING>
+           <SET ELTYPE2 CHARACTER>)
+          (<==? .PINS PUTUB!-MIMOP> <SET ELTYPE2 FIX> <SET STYPE2 BYTES>)>
+     <COND (.IDPB? <SET OFF2 1> <SET IDPB? <3 .ARGVEC>>)
+          (.NOPUT?)
+          (T
+           <SET OFF2 <2 .ARGVEC>>
+           <COND (<OP-HINT .OP-INFO>
+                  <SET ELTYPE2 <PARSE-HINT <OP-HINT .OP-INFO> TYPE>>)>)>
+     <COND (.HINT
+           <COND (<TYPE? .HINT ATOM> <SET ELTYPE1 .HINT>)
+                 (<SET ELTYPE1 <PARSE-HINT .HINT TYPE>>)>)
+          (<==? .STYPE1 BYTES> <SET ELTYPE1 FIX>)
+          (<==? .STYPE1 STRING> <SET ELTYPE1 CHARACTER>)
+          (<==? .STYPE1 UVECTOR> <SET ELTYPE1 FIX>)>
+     <COND (<AND <MEMQ .INCINS ,RESTU>
+                <OR <NOT .ELTYPE1> <NOT .ELTYPE2> <N==? .ELTYPE1 .ELTYPE2>>
+                <OR .ILDB? .IDPB? <N==? .STRUC1 .STRUC2> <N==? .OFF1 .OFF2>>>
+           <>)
+          (<NTH-AOS-PUT-GEN .CINS
+                            .INCINS
+                            .PINS
+                            .STRUC1
+                            .OFF1
+                            .STRUC2
+                            <COND (<NOT .NOPUT?> .OFF2)>
+                            .ADDVAL
+                            .L
+                            .ILDB?
+                            .IDPB?
+                            .STYPE1
+                            <COND (<NOT .NOPUT?> .STYPE2)>
+                            .ELTYPE1
+                            <COND (<NOT .NOPUT?> .ELTYPE2)>>
+           NORMAL)>)
+    (<AND <SET L .CODPTR>
+         <OR <==? .CINS ILDB!-MIMOP>
+             <MEMQ .CINS ,NTHU>
+             <==? .CINS NTHL!-MIMOP>>
+         <G? <LENGTH .L> 1>
+         <TYPE? <SET NXT <GET-NEXT-INST .L>> FORM>>
+     <COND
+      (<AND <OR <MEMQ <1 .NXT> ,LENU>
+               <SET EMPTY?
+                    <OR <==? <1 .NXT> EMPL?!-MIMOP> <MEMQ <1 .NXT> ,EMPU>>>>
+           <PARSE-OP .NXT .OP-INFO>
+           <==? <1 <SET ARGVEC <OP-ARGS .OP-INFO>>> .RES>
+           <OR <==? <1 .ARGVEC> <OP-RES .OP-INFO>>
+               <AND <WILL-DIE? .RES .L>
+                    <OR <NOT .EMPTY?>
+ ;
+"If empty?, make sure <3 .x> isn't used after
+                           the branch.  WILL-DIE? on .L won't find this,
+                           because L has already been rested past the branch."
+                        <AND <SET TMIML <MEMQ <OP-BRANCH .OP-INFO> .L>>
+                             <WILL-DIE? .RES .TMIML>>>>>>
+                                    ;"Have <length <3 .x>> or <empty? <3 .x>>"
+       <SET OL .L>
+       <COND (.EMPTY?
+             <FLUSH-TO .L .CODPTR>
+             <NTH-LENGTH-COMP-GEN .CINS
+                                  .STRUC1
+                                  .OFF1
+                                  .STYPE1
+                                  0
+                                  <1 .NXT>
+                                  .OP-INFO>
+             CONDITIONAL-BRANCH)
+            (T
+             <SET ADDVAL <OP-RES .OP-INFO>>
+             <COND (<AND <G? <LENGTH .L> 2>
+                         <TYPE? <SET NXT <GET-NEXT-INST .L>> FORM>
+                         <MEMQ <1 .NXT>
+                               '[LESS?!-MIMOP GRTR?!-MIMOP VEQUAL?!-MIMOP]>
+                         <PARSE-OP .NXT .OP-INFO>
+                         <COND (<==? .ADDVAL
+                                     <1 <SET ARGVEC <OP-ARGS .OP-INFO>>>>
+                                <SET CMPINS <1 .NXT>>
+                                <SET AMT <2 .ARGVEC>>)
+                               (<==? .ADDVAL <2 .ARGVEC>>
+                                <SET AMT <1 .ARGVEC>>
+                                <COND (<==? <SET CMPINS <1 .NXT>>
+                                            LESS?!-MIMOP>
+                                       <SET CMPINS GRTR?!-MIMOP>)
+                                      (<==? .CMPINS GRTR?!-MIMOP>
+                                       <SET CMPINS LESS?!-MIMOP>)
+                                      (T)>)>
+                         <WILL-DIE? .ADDVAL <REST .L>>>
+                                            ;"Have length comparison of nth.."
+                    <FLUSH-TO .L .CODPTR>
+                    <NTH-LENGTH-COMP-GEN .CINS
+                                         .STRUC1
+                                         .OFF1
+                                         .STYPE1
+                                         .AMT
+                                         .CMPINS
+                                         .OP-INFO>
+                    CONDITIONAL-BRANCH)
+                   (T
+                    <FLUSH-TO .OL .CODPTR>
+                    <NTH-LENGTH-GEN .CINS .STRUC1 .OFF1 .STYPE1 .ADDVAL>
+                    NORMAL)>)>)
+      (<AND <OR <==? <SET NINS <1 .NXT>> ILDB!-MIMOP>
+               <MEMQ .NINS ,NTHU>
+               <==? .NINS NTHL!-MIMOP>>
+           <NOT <EMPTY? <REST .L>>>
+           <PARSE-OP .NXT .OP-INFO>
+           <COND (<==? .NINS ILDB!-MIMOP>
+                  <SET STYPE2 <PARSE-HINT <OP-HINT .OP-INFO> STRUCTURE-TYPE>>)
+                 (<==? .NINS NTHL!-MIMOP> <SET STYPE2 LIST>)
+                 (<SET STYPE2
+                       <2 <MEMBER <REST <SPNAME .NINS> 3>
+                                  '["UV"
+                                    VECTOR
+                                    "UU"
+                                    UVECTOR
+                                    "US"
+                                    STRING
+                                    "UB"
+                                    BYTES]>>>)>
+           <SET STRUC2 <1 <SET ARGVEC <OP-ARGS .OP-INFO>>>>
+           <OR <==? .STYPE1 .STYPE2>
+               <AND <MEMQ .STYPE1 '[VECTOR UVECTOR LIST]>
+                    <MEMQ .STYPE2 '[VECTOR UVECTOR LIST]>>
+               <AND <MEMQ .STYPE1 '[STRING BYTES]>
+                    <MEMQ .STYPE2 '[STRING BYTES]>>>
+           <SET OFF2 <2 .ARGVEC>>
+           <SET RES2 <OP-RES .OP-INFO>>
+           <WILL-DIE? .RES2 <REST .L>>
+           <TYPE? <SET NXT <GET-NEXT-INST .L>> FORM>
+           <MEMQ <1 .NXT> '[LESS?!-MIMOP GRTR?!-MIMOP VEQUAL?!-MIMOP]>
+           <OR <MEMQ .RES .NXT> <MEMQ .RES2 .NXT>>>
+       <PARSE-OP .NXT .OP-INFO>
+       <COND (<OR <NOT <SET TMIML <MEMQ <OP-BRANCH .OP-INFO> .L>>>
+                 <NOT <WILL-DIE? .RES2 .TMIML>>>
+                                               ;"See comment above for EMPTY?"
+             <RETURN <> .NLA>)>
+       <FLUSH-TO .L .CODPTR>
+       <SLOT-COMPARE <COND (<==? <1 .ARGVEC> .RES> <SET RES1? 1> .STRUC1)
+                          (<==? <1 .ARGVEC> .RES2> <SET RES2? 1> .STRUC2)
+                          (<1 .ARGVEC>)>
+                    <COND (<==? <2 .ARGVEC> .RES> <SET RES1? 2> .STRUC1)
+                          (<==? <2 .ARGVEC> .RES2> <SET RES2? 2> .STRUC2)
+                          (<2 .ARGVEC>)>
+                    <1 .NXT>
+                    .OP-INFO
+                    <COND (<==? .RES1? 1> .OFF1) (<==? .RES2? 1> .OFF2)>
+                    <COND (<==? .RES1? 1> .STYPE1) (<==? .RES2? 1> .STYPE2)>
+                    <COND (<==? .RES1? 2> .OFF1) (<==? .RES2? 2> .OFF2)>
+                    <COND (<==? .RES1? 2> .STYPE1) (<==? .RES2? 2> .STYPE2)>>
+       CONDITIONAL-BRANCH)
+      (<AND <MEMQ <1 .NXT> '[GRTR?!-MIMOP LESS?!-MIMOP VEQUAL?!-MIMOP]>
+           <PARSE-OP .NXT .OP-INFO>
+           <OR <==? <1 .ARGVEC> .RES> <==? <2 .ARGVEC> .RES>>
+           <AND <WILL-DIE? .RES .L>
+                <SET TMIML <MEMQ <OP-BRANCH .OP-INFO> .L>>
+                <WILL-DIE? .RES .TMIML>>>
+       <COND (<==? <1 .ARGVEC> .RES> <SET RES1? T>)
+            (<==? <2 .ARGVEC> .RES> <SET RES2? T>)>
+       <FLUSH-TO .L .CODPTR>
+       <SLOT-COMPARE <COND (.RES1? .STRUC1) (<1 .ARGVEC>)>
+                    <COND (.RES2? .STRUC1) (<2 .ARGVEC>)>
+                    <1 .NXT>
+                    .OP-INFO
+                    <COND (.RES1? .OFF1)>
+                    <COND (.RES1? .STYPE1)>
+                    <COND (.RES2? .OFF1)>
+                    <COND (.RES2? .STYPE1)>>
+       CONDITIONAL-BRANCH)>)>>
+
+<DEFINE FLUSH-TO (NL OL)
+       #DECL ((NL OL) LIST)
+       <SETG FLUSH-NEXT <- <LENGTH .OL> <LENGTH .NL>>>>
+
+<DEFINE GET-NEXT-INST (LL) 
+       #DECL ((LL) LIST)
+       <REPEAT (FROB)
+               <COND (<NOT <GETPROP <SET FROB <1 .LL>> DONE>>
+                      <SET L <REST .LL>>
+                      <RETURN .FROB>)>
+               <COND (<EMPTY? <SET LL <REST .LL>>> <RETURN <>>)>>>
+
+<DEFINE PARSE-OP (FRM OP-INFO
+                 "AUX" (ARGVEC <OP-ARGS .OP-INFO>) (RES? <>) HINT
+                       (BRANCH? <>))
+       #DECL ((FRM) FORM (OP-INFO) OP-INFO)
+       <OP-HINT .OP-INFO <>>
+       <OP-BRANCH .OP-INFO <>>
+       <OP-RES .OP-INFO T>
+       <MAPF <>
+             <FUNCTION (X) 
+                     <COND (<OR <NOT <TYPE? .X LIST>> <EMPTY? .X>>
+                            <COND (.RES? <SET RES? <>> <OP-RES .OP-INFO .X>)
+                                  (.BRANCH?
+                                   <SET BRANCH? <>>
+                                   <OP-BRANCH .OP-INFO .X>)
+                                  (<OR <==? .X -> <==? .X +>>
+                                   <OP-DIR .OP-INFO .X>
+                                   <SET BRANCH? T>)
+                                  (<TYPE? .X RES-IND> <SET RES? T>)
+                                  (<EMPTY? .ARGVEC>)
+                                  (T
+                                   <1 .ARGVEC .X>
+                                   <SET ARGVEC <REST .ARGVEC>>)>)
+                           (<OR <==? <1 .X> TYPE> <==? <1 .X> STRUCTURE-TYPE>>
+                            <OP-HINT .OP-INFO .X>)
+                           (<==? <1 .X> BRANCH-FALSE>
+                            <OP-BRANCH .OP-INFO <2 .X>>
+                            <OP-DIR .OP-INFO ->)
+                           (<==? <1 .X> BRANCH-TRUE>
+                            <OP-BRANCH .OP-INFO <2 .X>>
+                            <OP-DIR .OP-INFO +>)>>
+             <REST .FRM>>
+       .OP-INFO>
+
+<DEFINE WILL-DIE? (ARG
+                  "OPT" (MIML .CODPTR) (BEG-LABEL T) "AUX" FOO (CP .CODPTR)
+                        LR LABEL
+                        (N
+                         <COND (<==? .CP .MIML> ,FLUSH-NEXT)
+                               (<- ,FLUSH-NEXT
+                                   <- <LENGTH .CP> <LENGTH .MIML>>>)>))
+   #DECL ((BEG-LABEL) ATOM (ARG) ANY (MIML) LIST (N) FIX)
+ <COND
+  (,LOOKAHEAD?
+   <REPEAT LEAVE (NXT ITM JMP?)
+     #DECL ((NXT) <OR ATOM FORM LIST>)
+     <COND
+      (<EMPTY? .MIML> <RETURN T>)
+      (<AND <L=? <LENGTH .MIML> 1>
+           <OR <NOT <TYPE? <SET ITM <1 .MIML>> FORM>>
+               <AND <N==? <1 .ITM> JUMP!-MIMOP>
+                    <NOT <MEMQ + .ITM>>
+                    <NOT <MEMQ - .ITM>>>>>
+       <COND (<AND <TYPE? .ITM FORM>
+                  <==? <1 .ITM> RETURN!-MIMOP>
+                  <==? <2 .ITM> .ARG>>
+             <RETURN <>>)
+            (T
+             <RETURN T>)>)
+      (<TYPE? <SET NXT <1 .MIML>> ATOM>
+       <SET LR <GET-LREF .NXT T>>
+       <COND (<MEMQ .ARG <LABEL-REF-LIVE-VARS .LR>> <RETURN <>>)
+            (<MEMQ .ARG <LABEL-REF-DEAD-VARS .LR>> <RETURN T>)>
+       <COND (<WILL-DIE? .ARG <REST .MIML> .NXT>
+             <LABEL-REF-DEAD-VARS .LR (.ARG !<LABEL-REF-DEAD-VARS .LR>)>
+             <RETURN T>)
+            (T
+             <LABEL-REF-LIVE-VARS .LR (.ARG !<LABEL-REF-LIVE-VARS .LR>)>
+             <RETURN <>>)>)
+      (<AND <TYPE?  .NXT FORM>
+           <L? <SET N <- .N 1>> 0>
+           <NOT <GETPROP .NXT DONE>>>
+       <COND (<==? <SET ITM <1 .NXT>> DEAD!-MIMOP>
+             <COND (<MEMQ .ARG <REST .NXT>>
+                    ; "Definitely dies if DEADed"
+                    <RETURN T>)>)
+            (<==? .ITM RETURN!-MIMOP>
+             ; "Dies if not returned"
+             <RETURN <N==? <2 .NXT> .ARG>>)
+            (<==? .ITM END!-MIMOP>
+             ; "Dies if run out of code"
+             <RETURN T>)
+            (<==? .ITM SET!-MIMOP>
+             <COND (<==? <2 .NXT> .ARG>
+                    ; "Dies if SET"
+                    <RETURN T>)
+                   (<==? <3 .NXT> .ARG>
+                    ; "Doesn't die if something set to this"
+                    <RETURN <>>)>)
+            (<AND <==? .ITM SETLR!-MIMOP>
+                  <==? <2 .NXT> .ARG>>
+             ; "If doing SETLR, current value is dead"
+             <RETURN T>)
+            (T
+             <COND
+              (<==? .ITM JUMP!-MIMOP> <SET JMP? T>)
+              (T <SET JMP? <>>)>
+             ; "Unconditional jump is special case, slightly"
+             <MAPR <>
+                <FUNCTION (XP "AUX" (X <1 .XP>)) 
+                        <COND (<TYPE? .X RES-IND>
+                               <COND (<==? <SET X <2 .XP>> .ARG>
+                                      ; "Result of something, so dead"
+                                      <RETURN T .LEAVE>)
+                                     (T <MAPLEAVE>)>)
+                              (<==? .X .ARG>
+                               ; "Arg to something, so not dead"
+                               <RETURN <> .LEAVE>)>>
+                .NXT>
+             <COND (<==? .ITM DISPATCH!-MIMOP>
+                    <MAPF <>
+                      <FUNCTION (LAB)
+                        <COND (<==? .LAB .BEG-LABEL>)
+                              (<SET FOO <MEMQ .LAB .MIML>>
+                               <SET LR <GET-LREF .LAB T>>
+                               <COND (<MEMQ .ARG <LABEL-REF-LIVE-VARS .LR>>
+                                      <RETURN <> .LEAVE>)
+                                     (<MEMQ .ARG <LABEL-REF-DEAD-VARS .LR>>)
+                                     (<WILL-DIE? .ARG <REST .FOO>>
+                                      <LABEL-REF-DEAD-VARS
+                                       .LR (.ARG !<LABEL-REF-DEAD-VARS .LR>)>)
+                                     (T
+                                      <LABEL-REF-LIVE-VARS .LR
+                                       (.ARG !<LABEL-REF-LIVE-VARS .LR>)>
+                                      <RETURN <> .LEAVE>)>)
+                              (T
+                               <RETURN <> .LEAVE>)>>
+                      <REST .NXT 3>>)
+                   (<OR <AND <==? .ITM ICALL!-MIMOP>
+                             <SET FOO .NXT>>
+                        <SET FOO <MEMQ + <SET NXT <REST .NXT>>>>
+                        <SET FOO <MEMQ - .NXT>>
+                        <AND <==? .ITM NTHR!-MIMOP>
+                             <TYPE? <SET ITM <NTH .NXT <LENGTH .NXT>>> LIST>
+                             <==? <1 .ITM> BRANCH-FALSE>
+                             <SET FOO <REST .ITM>>>>
+                    ; "Jump"
+                    <COND (<SET FOO <MEMQ <SET LABEL <2 .FOO>> .MIML>>
+                           ; "Hair to remember who's alive/dead at each place"
+                           <SET LR <GET-LREF .LABEL T>>
+                           <COND (<==? .LABEL .BEG-LABEL>
+                                  ; "If you hit a jump to the label where you
+                                     started, and you don't know the variable
+                                     is alive, then the jump won't make it live
+                                     either.  If the jump is unconditional,
+                                     the variable is dead."
+                                  <COND (.JMP? <RETURN T>)>)
+                                 (<MEMQ .ARG <LABEL-REF-LIVE-VARS .LR>>
+                                  <RETURN <>>)
+                                 (<MEMQ .ARG <LABEL-REF-DEAD-VARS .LR>>
+                                  <COND (.JMP? <RETURN T>)>)
+                                 (<WILL-DIE? .ARG <REST .FOO>>
+                                  <LABEL-REF-DEAD-VARS
+                                   .LR (.ARG !<LABEL-REF-DEAD-VARS .LR>)>
+                                  ; "If dies at branch loc, might die here"
+                                  <COND (.JMP?
+                                         ; "Unconditional jump, definitely dead"
+                                         <RETURN T>)>)
+                                 (T
+                                  <LABEL-REF-LIVE-VARS
+                                   .LR (.ARG !<LABEL-REF-LIVE-VARS .LR>)>
+                                  <RETURN <>>)>)
+                          (T
+                           ; "Lose, so not dead"
+                           <RETURN <>>)>)>)>)>
+     <SET MIML <REST .MIML>>>)>>
+
+\\f 
+
+<DEFINE NTH-AOS-PUT-GEN NG 
+       (NTHINS INCINS PUTINS STRUC1 OFFSET1 STRUC2 OFFSET2 AMOUNT CODELIST
+        ILDB? IDPB? STYPE1 STYPE2 ELTYPE1 ELTYPE2
+        "AUX" SAC1 SAC2 (ADDRTUP1 <ITUPLE 4 <>>) (ADDRTUP2 <ITUPLE 4 <>>)
+              TMPAC (SELF? <>))
+       #DECL ((NTHINS) ATOM (INCINS) <OR ATOM FALSE> (STRUC) VARTBL)
+       <SET SELF?
+            <AND <==? .STRUC1 .STRUC2>
+                 <==? .OFFSET1 .OFFSET2>
+                 <NOT .ILDB?>
+                 <NOT .IDPB?>>>
+       <COND (<OR <AND .OFFSET2
+                       <NOT .SELF?>
+                       .INCINS
+                       <OR <AND .ILDB? <==? .STYPE1 VECTOR>>
+                           <AND .IDPB? <==? .STYPE2 VECTOR>>
+                           <AND <MEMQ .STYPE1 '[VECTOR LIST UVECTOR]>
+                                <NOT <MEMQ .STYPE2 '[VECTOR LIST UVECTOR]>>>
+                           <AND <MEMQ .STYPE2 '[VECTOR LIST UVECTOR]>
+                                <NOT <MEMQ .STYPE1 '[VECTOR
+                                                     LIST
+                                                     UVECTOR]>>>>>
+                  <AND .ILDB?
+                       .IDPB?
+                       <NOT <OR <==? .STYPE1 .STYPE2>
+                                <AND <MEMQ .STYPE1 '[STRING BYTES UVECTOR]>
+                                     <MEMQ .STYPE2
+                                           '[STRING BYTES UVECTOR]>>>>>
+                  <AND .ILDB? <NOT <TYPE? .OFFSET2 FIX>>>
+                  <AND .IDPB? <NOT <TYPE? .OFFSET1 FIX>>>>
+ ;
+"When we're dealing with the first element of a vector
+ via ILDB/IDPB, might as well not try anything fancy here."
+              <RETURN <> .NG>)>
+       <COND (.PUTINS <FLUSH-TO .CODELIST .CODPTR>)
+             (T
+              <FLUSH-TO <REST .CODPTR
+                              <- <LENGTH .CODPTR> <LENGTH .CODELIST> 1>>
+                        .CODPTR>)>
+       <COND (<NOT <SET SAC1 <VAR-VALUE-IN-AC? .STRUC1>>>
+              <SET SAC1 <LOAD-VAR .STRUC1 VALUE <> PREF-VAL>>)>
+       <PROTECT-USE .SAC1>
+       <COND (<AND .PUTINS <NOT .SELF?>>
+              <COND (<AND <==? .STRUC1 .STRUC2> <N==? .STYPE1 LIST>>
+                     <SET SAC2 .SAC1>)
+                    (<NOT <SET SAC2 <VAR-VALUE-IN-AC? .STRUC2>>>
+                     <SET SAC2 <LOAD-VAR .STRUC2 VALUE <> PREF-VAL>>
+                     <PROTECT-USE .SAC2>)>)>
+ ;
+"Struc1 is now in sac1, appropriately rested; struc2 is in sac2,
+          also rested.  (Two may be same, if struc1==struc2 and not rested"
+       <GET-ADDR .ADDRTUP1
+                 .STRUC1
+                 .SAC1
+                 .OFFSET1
+                 .STYPE1
+                 .ILDB?
+                 <>
+                 <NOT .INCINS>>
+       <COND (<AND .PUTINS <NOT .SELF?>>
+              <COND (<AND <3 .ADDRTUP1>
+                          <==? .OFFSET1 .OFFSET2>
+                          <OR <AND <==? .STYPE1 VECTOR> <==? .STYPE2 VECTOR>>
+                              <AND <N==? .STYPE1 VECTOR>
+                                   <N==? .STYPE2 VECTOR>>>>
+                     <GET-ADDR .ADDRTUP2
+                               .STRUC2
+                               .SAC2
+                               .OFFSET2
+                               .STYPE2
+                               .IDPB?
+                               <3 .ADDRTUP1>
+                               <NOT .INCINS>>)
+                    (<GET-ADDR .ADDRTUP2
+                               .STRUC2
+                               .SAC2
+                               .OFFSET2
+                               .STYPE2
+                               .IDPB?
+                               <>
+                               <NOT .INCINS>>)>)>
+       <COND (<NOT .INCINS>
+              <MOVE-ELT .ADDRTUP1
+                        .ADDRTUP2
+                        .STYPE1
+                        .STYPE2
+                        .ELTYPE1
+                        .ELTYPE2
+                        .IDPB?>)
+             (<MEMQ .INCINS ,ARITH>
+              <DO-ARITH .INCINS
+                        .AMOUNT
+                        <1 .ADDRTUP1>
+                        <COND (.PUTINS <1 .ADDRTUP2>) (T .STRUC2)>
+                        .SELF?
+                        .STYPE1>)
+             (T
+              <DO-ARITH SUB!-MIMOP
+                        .AMOUNT
+                        <2 .ADDRTUP1>
+                        <2 .ADDRTUP2>
+                        .SELF?
+                        WORD>                     ;"Decrement count on length"
+              <COND (<TYPE? .AMOUNT FIX>
+                     <DO-ARITH ADD!-MIMOP
+                               <COND (<==? .INCINS RESTUV!-MIMOP>
+                                      <MA-IMM <* 8 .AMOUNT>>)
+                                     (<==? .INCINS RESTUU!-MIMOP>
+                                      <MA-IMM <* 4 .AMOUNT>>)
+                                     (<MA-IMM .AMOUNT>)>
+                               <1 .ADDRTUP1>
+                               <1 .ADDRTUP2>
+                               .SELF?
+                               VECTOR>)
+                    (T
+                     <COND (<OR <==? .INCINS RESTUS!-MIMOP>
+                                <==? .INCINS RESTUB!-MIMOP>>
+                            <SET TMPAC <VAR-VALUE-ADDRESS .AMOUNT>>)
+                           (<SET TMPAC <VAR-VALUE-IN-AC? .AMOUNT>>
+                            <MUNG-AC .TMPAC T>
+                            <SET TMPAC <MA-REG .TMPAC>>
+                            <EMIT ,INST-ASHL
+                                  <COND (<==? .INCINS RESTUV!-MIMOP>
+                                         <MA-IMM 3>)
+                                        (<MA-IMM 2>)>
+                                  .TMPAC
+                                  .TMPAC>)
+                           (T
+                            <SET TMPAC <GET-AC PREF-VAL>>
+                            <EMIT ,INST-ASHL
+                                  <COND (<==? .INCINS RESTUV!-MIMOP>
+                                         <MA-IMM 3>)
+                                        (<MA-IMM 2>)>
+                                  <VAR-VALUE-ADDRESS .AMOUNT>
+                                  <SET TMPAC <MA-REG .TMPAC>>>)>
+                     <DO-ARITH ADD!-MIMOP
+                               .TMPAC
+                               <1 .ADDRTUP1>
+                               <1 .ADDRTUP2>
+                               .SELF?
+                               VECTOR>)>)>
+       <COND (.ILDB? <REST-BLOCK-GEN .STRUC1 1 .ILDB? 0 .STYPE1 T>)>
+       <COND (.IDPB? <REST-BLOCK-GEN .STRUC2 1 .IDPB? 0 .STYPE2 T>)>
+       NORMAL>
+
+<DEFINE MOVE-ELT (TUP1 TUP2 ST1 ST2 EL1 EL2 IDPB? "AUX" INS ADDR1 ADDR2) 
+       #DECL ((TUP1 TUP2) TUPLE (ST1 ST2 EL1 EL2) <OR ATOM FALSE>)
+       <COND (<AND <MEMQ .ST1 '[VECTOR LIST]> <MEMQ .ST2 '[VECTOR LIST]>>
+              <SET INS ,INST-MOVQ>
+              <SET ADDR1 <4 .TUP1>>
+              <SET ADDR2 <4 .TUP2>>)
+             (T
+              <SET ADDR1 <1 .TUP1>>
+              <SET ADDR2 <1 .TUP2>>
+              <COND (<MEMQ .ST1 '[VECTOR LIST]>
+                     <COND (<==? .ST2 UVECTOR>
+                            <SET EL2 FIX>
+                            <SET INS ,INST-MOVL>)
+                           (<MEMQ .ST2 '[STRING BYTES]>
+                            <COND (<==? .ST2 STRING> <SET EL2 CHARACTER>)
+                                  (<SET EL2 FIX>)>
+                            <SET INS ,INST-CVTLB>)>)
+                    (<==? .ST1 UVECTOR>
+                     <COND (<AND .IDPB?
+                                 <==? .ST2 VECTOR>>
+                            <EMIT ,INST-MOVL <TYPE-WORD FIX> !.ADDR2>)>
+                     <COND (<MEMQ .ST2 '[VECTOR LIST UVECTOR]>
+                            <SET EL2 FIX>
+                            <SET INS ,INST-MOVL>)
+                           (T
+                            <COND (<==? .ST2 STRING> <SET EL2 CHARACTER>)
+                                  (<SET EL2 FIX>)>
+                            <SET INS ,INST-CVTLB>)>)
+                    (T
+                     <COND (<AND .IDPB?
+                                 <==? .ST2 VECTOR>>
+                            <EMIT ,INST-MOVL <TYPE-WORD FIX> !.ADDR2>)>
+                     <COND (<MEMQ .ST2 '[VECTOR UVECTOR LIST]>
+                            <COND (<==? .ST2 UVECTOR> <SET EL2 FIX>)>
+                            <SET INS ,INST-MOVZBL>)
+                           (T
+                            <COND (<==? .ST2 STRING> <SET EL2 CHARACTER>)
+                                  (<SET EL2 FIX>)>
+                            <SET INS ,INST-MOVB>)>)>)>
+       <EMIT .INS !.ADDR1 !.ADDR2>
+       <COND (<NOT .EL2>
+              <COND (.EL1 <EMIT ,INST-MOVW <TYPE-WORD .EL1> !<2 .TUP2>>)>)>>
+
+<DEFINE DO-ARITH (INS AMOUNT ADDR1 ADDR2 SELF? STYPE1 "AUX" (VAC <>) RAC) 
+   <COND (.SELF? <SET ADDR2 .ADDR1>)>
+   <COND (<TYPE? .ADDR2 VARTBL>
+         <COND (<NOT <SET RAC <VAR-VALUE-IN-AC? .ADDR2>>>
+                <SET RAC <GET-AC PREF-VAL T>>
+                <PROTECT .RAC>)>
+         <DEST-DECL .RAC .ADDR2 <COND (<MEMQ .INS ,FLOATS> FLOAT)
+                                      (T FIX)>>)>
+   <COND
+    (<MEMQ .INS ,LOGIC>
+     <COND (<TYPE? .AMOUNT FIX>
+           <COND (<==? .INS EQV!-MIMOP>
+                  <SET AMOUNT <CHTYPE <XORB .AMOUNT -1> FIX>>
+                  <SET INS XOR!-MIMOP>)
+                 (<==? .INS AND!-MIMOP>
+                  <SET AMOUNT <CHTYPE <XORB .AMOUNT -1> FIX>>)>)
+          (<OR <==? .INS EQV!-MIMOP> <==? .INS AND!-MIMOP>>
+           <EMIT ,INST-MCOML !.ADDR1 <SET VAC <GET-AC PREF-VAL T>>>
+           <COND (<==? .INS EQV!-MIMOP> <SET INS XOR!-MIMOP>)>)>
+     <COND (.VAC
+           <COND (<TYPE? .ADDR2 VARTBL>
+                  <EMIT <COND (<==? .INS AND!-MIMOP> ,INST-BICL3)
+                              (<==? .INS XOR!-MIMOP> ,INST-XORL3)
+                              (<==? .INS OR!-MIMOP> ,INST-BISL3)>
+                        <MA-REG .VAC>
+                        <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                              (<VAR-VALUE-ADDRESS .AMOUNT>)>
+                        <MA-REG .RAC>>)
+                 (T
+                  <EMIT <COND (<==? .INS AND!-MIMOP> ,INST-BICL3)
+                              (<==? .INS XOR!-MIMOP> ,INST-XORL3)
+                              (<==? .INS OR!-MIMOP> ,INST-BISL3)>
+                        <MA-REG .VAC>
+                        <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                              (<VAR-VALUE-ADDRESS .AMOUNT>)>
+                        !.ADDR2>)>)
+          (.SELF?
+           <EMIT <COND (<==? .INS AND!-MIMOP> ,INST-BICL2)
+                       (<==? .INS XOR!-MIMOP> ,INST-XORL2)
+                       (<==? .INS OR!-MIMOP> ,INST-BISL2)>
+                 <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                       (<VAR-VALUE-ADDRESS .AMOUNT>)>
+                 !.ADDR1>)
+          (T
+           <COND (<TYPE? .ADDR2 VARTBL>
+                  <EMIT <COND (<==? .INS AND!-MIMOP> ,INST-BICL3)
+                              (<==? .INS XOR!-MIMOP> ,INST-XORL3)
+                              (<==? .INS OR!-MIMOP> ,INST-BISL3)>
+                        !.ADDR1
+                        <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                              (<VAR-VALUE-ADDRESS .AMOUNT>)>
+                        <MA-REG .RAC>>)
+                 (T
+                  <EMIT <COND (<==? .INS AND!-MIMOP> ,INST-BICL3)
+                              (<==? .INS XOR!-MIMOP> ,INST-XORL3)
+                              (<==? .INS OR!-MIMOP> ,INST-BISL3)>
+                        !.ADDR1
+                        <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                              (<VAR-VALUE-ADDRESS .AMOUNT>)>
+                        !.ADDR2>)>)>)
+    (<AND .SELF? <==? .AMOUNT 1>> <EMIT <PICK-ARITH .INS .STYPE1 1> !.ADDR1>)
+    (.SELF?
+     <EMIT <PICK-ARITH .INS .STYPE1 2>
+          <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                (<TYPE? .AMOUNT FLOAT> <FLOAT-IMM <FLOATCONVERT .AMOUNT>>)
+                (<TYPE? .AMOUNT VARTBL> <VAR-VALUE-ADDRESS .AMOUNT>)
+                (.AMOUNT)>
+          !.ADDR1>)
+    (T
+     <COND (<TYPE? .ADDR2 VARTBL>
+           <EMIT <PICK-ARITH .INS .STYPE1 3>
+                 <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                       (<TYPE? .AMOUNT FLOAT>
+                        <FLOAT-IMM <FLOATCONVERT .AMOUNT>>)
+                       (<TYPE? .AMOUNT VARTBL> <VAR-VALUE-ADDRESS .AMOUNT>)
+                       (.AMOUNT)>
+                 !.ADDR1
+                 <VAR-VALUE-ADDRESS .ADDR2>>)
+          (T
+           <EMIT <PICK-ARITH .INS .STYPE1 3>
+                 <COND (<TYPE? .AMOUNT FIX> <MA-IMM .AMOUNT>)
+                       (<TYPE? .AMOUNT FLOAT>
+                        <FLOAT-IMM <FLOATCONVERT .AMOUNT>>)
+                       (<TYPE? .AMOUNT VARTBL> <VAR-VALUE-ADDRESS .AMOUNT>)
+                       (.AMOUNT)>
+                 !.ADDR1
+                 !.ADDR2>)>)>>
+
+<SETG ADDS
+      [[,INST-INCB ,INST-INCW ,INST-INCL]
+       [,INST-ADDB2 ,INST-ADDW2 ,INST-ADDL2]
+       [,INST-ADDB3 ,INST-ADDW3 ,INST-ADDL3]]>
+
+<SETG SUBS
+      [[,INST-DECB ,INST-DECW ,INST-DECL]
+       [,INST-SUBB2 ,INST-SUBW2 ,INST-SUBL2]
+       [,INST-SUBB3 ,INST-SUBW3 ,INST-SUBL3]]>
+
+<SETG MULS
+      [[]
+       [,INST-MULB2 ,INST-MULW2 ,INST-MULL2]
+       [,INST-MULB3 ,INST-MULW3 ,INST-MULL3]]>
+
+<SETG DIVS
+      [[]
+       [,INST-DIVB2 ,INST-DIVW2 ,INST-DIVL2]
+       [,INST-DIVB3 ,INST-DIVW3 ,INST-DIVL3]]>
+
+<SETG FLOAT-OPS
+      [[]
+       [,INST-ADDF2 ,INST-SUBF2 ,INST-MULF2 ,INST-DIVF2]
+       [,INST-ADDF3 ,INST-SUBF3 ,INST-MULF3 ,INST-DIVF3]]>
+
+<GDECL (LOGIC) VECTOR (FLOAT-OPS ADDS SUBS MULS DIVS) <VECTOR [REST VECTOR]>>
+
+<SETG LOGIC '[AND!-MIMOP OR!-MIMOP XOR!-MIMOP EQV!-MIMOP]>
+
+<SETG FLOATS '[ADDF!-MIMOP SUBF!-MIMOP MULF!-MIMOP DIVF!-MIMOP]>
+
+<DEFINE PICK-ARITH (OP STYPE NUMOPS "AUX" TV) 
+       #DECL ((NUMOPS) FIX (OP) ATOM (STYPE) ATOM (TV) VECTOR)
+       <COND (<==? .OP ADD!-MIMOP> <SET TV <NTH ,ADDS .NUMOPS>>)
+             (<==? .OP SUB!-MIMOP> <SET TV <NTH ,SUBS .NUMOPS>>)
+             (<==? .OP MUL!-MIMOP> <SET TV <NTH ,MULS .NUMOPS>>)
+             (<==? .OP DIV!-MIMOP> <SET TV <NTH ,DIVS .NUMOPS>>)
+             (T
+              <SET TV <NTH ,FLOAT-OPS .NUMOPS>>)>
+       <COND (<MEMQ .OP ,FLOATS>
+              <COND (<==? .OP ADDF!-MIMOP> <1 .TV>)
+                    (<==? .OP SUBF!-MIMOP> <2 .TV>)
+                    (<==? .OP MULF!-MIMOP> <3 .TV>)
+                    (<==? .OP DIVF!-MIMOP> <4 .TV>)>)
+             (<MEMQ .STYPE '[VECTOR UVECTOR LIST]> <3 .TV>)
+             (<==? .STYPE WORD> <2 .TV>)
+             (<1 .TV>)>>
+
+<DEFINE GET-ADDR (TUP STRUC SAC OFFSET STYPE AINC?
+                 "OPTIONAL" (RIDXAC <>) (FULL? <>)
+                 "AUX" IDXAC)
+       #DECL ((TUP) <TUPLE [3 ANY]> (SAC) AC (OFFSET) <OR FIX VARTBL>
+              (STYPE) ATOM)
+       <COND (<AND <==? .STYPE LIST> <N==? .OFFSET 1>>
+              <COND (<TYPE? .OFFSET FIX>
+                     <SET SAC <LIST-REST-CONSTANT-GEN .STRUC <- .OFFSET 1>>>)
+                    (<SET SAC <LIST-REST-VAR-GEN .STRUC .OFFSET NTH>>)>
+              <SET OFFSET 1>)>
+       <COND (.AINC? <1 .TUP (<MA-AINC .SAC>)>)
+             (<TYPE? .OFFSET FIX>
+              <COND (<1? .OFFSET>
+                     <COND (<OR <==? .STYPE VECTOR> <==? .STYPE LIST>>
+                            <4 .TUP (<MA-REGD .SAC>)>
+                            <2 .TUP (<MA-DISP .SAC 2>)>
+                            <1 .TUP (<MA-DISP .SAC 4>)>)
+                           (<1 .TUP (<MA-REGD .SAC>)>)>)
+                    (T
+                     <COND (<==? .STYPE VECTOR>
+                            <4 .TUP (<MA-DISP .SAC <* 8 <- .OFFSET 1>>>)>
+                            <2 .TUP
+                               (<MA-DISP .SAC <+ 2 <* 8 <- .OFFSET 1>>>>)>
+                            <1 .TUP
+                               (<MA-DISP .SAC <+ 4 <* 8 <- .OFFSET 1>>>>)>)
+                           (<==? .STYPE UVECTOR>
+                            <1 .TUP (<MA-DISP .SAC <* 4 <- .OFFSET 1>>>)>)
+                           (T <1 .TUP (<MA-DISP .SAC <- .OFFSET 1>>)>)>)>)
+             (T
+              <COND (<AND <NOT .RIDXAC>
+                          <NOT <SET IDXAC <VAR-VALUE-IN-AC? .OFFSET>>>>
+                     <COND (<OR <N==? .STYPE VECTOR> .FULL?>
+                            <SET IDXAC <LOAD-VAR .OFFSET VALUE <> PREF-VAL>>)
+                           (T
+                            <SET IDXAC <GET-AC PREF-VAL>>
+                            <EMIT ,INST-ASHL
+                                  <MA-IMM 1>
+                                  <VAR-VALUE-ADDRESS .OFFSET>
+                                  <MA-REG .IDXAC>>)>
+                     <PROTECT-USE .IDXAC>
+                     <3 .TUP .IDXAC>)
+                    (<AND <NOT .RIDXAC> <NOT .FULL?> <==? .STYPE VECTOR>>
+                     <EMIT ,INST-ASHL
+                           <MA-IMM 1>
+                           <MA-REG .IDXAC>
+                           <MA-REG .IDXAC>>
+                     <MUNG-AC .IDXAC T>
+                     <3 .TUP .IDXAC>)>
+              <COND (<==? .STYPE VECTOR>
+                     <4 .TUP (<MA-INDX .IDXAC> <MA-DISP .SAC -8>)>
+                     <2 .TUP (<MA-INDX .IDXAC> <MA-DISP .SAC -6>)>
+                     <1 .TUP (<MA-INDX .IDXAC> <MA-DISP .SAC -4>)>)
+                    (<==? .STYPE UVECTOR>
+                     <1 .TUP (<MA-INDX .IDXAC> <MA-DISP .SAC -4>)>)
+                    (T <1 .TUP (<MA-INDX .IDXAC> <MA-DISP .SAC -1>)>)>)>>
+
+\\f 
+
+<DEFINE ILDB-LOOKAHEAD (L) 
+   #DECL ((L) <LIST [REST <OR ATOM FORM>]>)
+   <COND
+    (,LOOKAHEAD?
+     <MAPR <>
+      <FUNCTION (LL "AUX" (FROB <1 .LL>) INS (REST? <>) (PUT? <>) NINS) 
+             <COND (<AND <TYPE? .FROB FORM> <NOT <GETPROP .FROB DONE>>>
+                    <COND (<==? <SET INS <1 .FROB>> SETLR!-MIMOP>
+                           <COND (<AND <NOT <EMPTY? <REST .LL>>>
+                                       <TYPE? <SET NINS <2 .LL>> FORM>
+                                       <==? <1 .NINS> PUSH!-MIMOP>
+                                       <==? <2 .NINS> <2 .FROB>>
+                                       <WILL-DIE? <2 .FROB> <REST .LL 2>>>
+                                  <2 .FROB STACK>
+                                  <PUTPROP .NINS DONE T>)>)
+                          (<AND <OR <SET REST? <MEMQ .INS ,RESTU>>
+                                    <SET PUT? <MEMQ .INS ,PUTU>>
+                                    <MEMQ .INS ,NTHU>>
+                                <==? <3 .FROB> 1>>
+                                        ;"This could be something interesting"
+                           <ILDB-LOOKAHEAD-ONE .LL .REST? .PUT?>)>)>>
+      .L>)>>
+
+;
+"Find ILDB/IDPB case, put MIMA code for it into list, kill other half of
+   operation.  Form of ops is:
+<ILDB STRUC NTHRES RESTRES (STRUCTURE-TYPE FOO)>
+<IDPB STRUC NEWVAL RESTRES (STRUCTURE-TYPE FOO)>"
+
+<DEFINE ILDB-LOOKAHEAD-ONE (L REST? PUT?
+                           "AUX" (OP-INFO ,OP-INFO)
+                                 (ARGVEC <OP-ARGS .OP-INFO>) STRUC RES OP
+                                 OTHOP PUTOP)
+   #DECL ((L) <LIST [REST <OR ATOM FORM>]> (OP-INFO) OP-INFO)
+   <PARSE-OP <1 .L> .OP-INFO>
+   <SET OP <1 <1 .L>>>
+   <SET OTHOP <GETPROP .OP PAIR>>
+   <SET PUTOP <GETPROP .OP PUT-PAIR>>
+   <SET STRUC <1 .ARGVEC>>
+   <SET RES <OP-RES .OP-INFO>>
+   <MAPR <>
+    <FUNCTION (LL "AUX" (FROB <1 .LL>) INS HINT) 
+           <COND (<TYPE? .FROB ATOM> <MAPLEAVE>)>
+           <COND (<AND <OR <==? <1 .FROB> .OTHOP>
+                           <AND <OR .PUT? .REST?> <==? <1 .FROB> .PUTOP>>>
+                       <==? <2 .FROB> .STRUC>
+                       <==? <3 .FROB> 1>>        ;"We now have the paired guy"
+                  <COND (<MEMQ .OP ,RESTU> <SET HINT <REST <SPNAME .OP> 4>>)
+                        (<SET HINT <REST <SPNAME .OP> 3>>)>
+                  <COND (<=? .HINT "UV"> <SET HINT '(STRUCTURE-TYPE VECTOR)>)
+                        (<=? .HINT "UU"> <SET HINT '(STRUCTURE-TYPE
+                                                     UVECTOR)>)
+                        (<=? .HINT "US"> <SET HINT '(STRUCTURE-TYPE STRING)>)
+                        (T <SET HINT '(STRUCTURE-TYPE BYTES)>)>
+                  <PARSE-OP .FROB .OP-INFO>
+                  <COND (<OR .PUT? <MEMQ <1 .FROB> ,PUTU>>
+                         <1 .L
+                            <FORM IDPB!-MIMOP
+                                  .STRUC
+                                  <COND (.PUT? <4 <1 .L>>) (<3 .ARGVEC>)>
+                                  <COND (.PUT? <OP-RES .OP-INFO>) (.RES)>
+                                  .HINT>>
+                         <PUTPROP .FROB DONE T>)
+                        (<1 .L
+                            <FORM ILDB!-MIMOP
+                                  .STRUC
+                                  <COND (.REST? <OP-RES .OP-INFO>) (.RES)>
+                                  <COND (.REST? .RES) (<OP-RES .OP-INFO>)>
+                                  .HINT>>
+                         <PUTPROP .FROB DONE T>)>
+                  <MAPLEAVE>)
+                 (<OR <MEMQ .STRUC .FROB>
+                      <MEMQ + .FROB>
+                      <MEMQ - .FROB>
+                      <AND <PARSE-OP .FROB .OP-INFO> <OP-BRANCH .OP-INFO>>>
+                  <MAPLEAVE>)>>
+    <REST .L>>>
+
+"Generate ILDB/IDPB-like stuff.  Call with NTH/PUT inst, structure,
+ result of nth/put, result of rest, flag, new value for put"
+
+<DEFINE IDPB-GEN (STRUC ELVAL STRES HINT) 
+       <ILDB-GEN .STRUC .ELVAL .STRES .HINT T>>
+
+<DEFINE ILDB-GEN IG (STRUC ELVAL STRES HINT
+                    "OPTIONAL" (PUT? <>)
+                    "AUX" EHINT VINS STRAC ELAC (ELTAC <>) (DOUBLE? <>) LVAR
+                          TAC VAC ELADDR (NO-TYPE? <>))
+   #DECL ((STRUC) VARTBL (ELVAL) ANY)
+   <COND (<AND <TYPE? .ELVAL ATOM VARTBL>
+              <NTH-LOOK-AHEAD ILDB!-MIMOP .STRUC .STRES .ELVAL <> .HINT>>
+         <RETURN NORMAL .IG>)>
+   <SET HINT <PARSE-HINT .HINT STRUCTURE-TYPE>>
+   <COND (<==? .HINT VECTOR>
+         <SET DOUBLE? T>
+         <SET VINS ,INST-MOVQ>
+         <SET EHINT <>>)
+        (<==? .HINT UVECTOR> <SET VINS ,INST-MOVL> <SET EHINT FIX>)
+        (<==? .HINT BYTES>
+         <SET EHINT FIX>
+         <COND (.PUT? <SET VINS ,INST-MOVB>) (<SET VINS ,INST-MOVZBL>)>)
+        (<==? .HINT STRING>
+         <SET EHINT CHARACTER>
+         <COND (.PUT? <SET VINS ,INST-MOVB>) (<SET VINS ,INST-MOVZBL>)>)>
+   <COND (<NOT <SET STRAC <VAR-VALUE-IN-AC? .STRUC>>>
+         <SET STRAC <LOAD-VAR .STRUC VALUE <> PREF-VAL>>)>
+                                                      ;"Get structure into AC"
+   <PROTECT .STRAC>
+   <COND (<N==? .STRAC ,AC-0> <PROTECT <PREV-AC .STRAC>>)>
+   <COND
+    (.PUT?
+     <COND
+      (<TYPE? .ELVAL VARTBL>
+                         ;"Get the address to use for the thing we're putting"
+       <COND
+       (<SET LVAR <FIND-CACHE-VAR .ELVAL>>
+        <COND (.DOUBLE? <SET TAC <LINKVAR-TYPE-WORD-AC .LVAR>>)
+              (<SET TAC <>>)>
+        <SET VAC <LINKVAR-VALUE-AC .LVAR>>
+        <COND (<OR <NOT .DOUBLE?>
+                   <AND .VAC .TAC <==? .VAC <NEXT-AC .TAC>>>
+                   <AND <NOT .VAC> <NOT .TAC>>>
+                                    ;"Case where all in acs or all not in acs"
+               <COND (.DOUBLE? <SET ELADDR <VAR-TYPE-ADDRESS .ELVAL>>)
+                     (T <SET ELADDR <VAR-VALUE-ADDRESS .ELVAL>>)>)
+              (<AND <OR <NOT .TAC> <LINKVAR-TYPE-STORED .LVAR>>
+                    <OR <NOT .VAC> <LINKVAR-VALUE-STORED .LVAR>>>
+                                                 ;"Everything safely on stack"
+               <SET ELADDR <ADDR-VAR-TYPE .ELVAL>>)
+              (T         ;"Type and value live in separate places, can't MOVQ"
+               <COND (<AND .LVAR
+                           <NOT <LINKVAR-TYPE-STORED .LVAR>>
+                           <NOT .TAC>
+                           <VARTBL-DECL .ELVAL>>
+                      <SET NO-TYPE? <TYPE-WORD <VARTBL-DECL .ELVAL>>>)
+                     (T <SET NO-TYPE? <VAR-TYPE-ADDRESS .ELVAL>>)>
+               <SET ELADDR <VAR-VALUE-ADDRESS .ELVAL>>)>)
+       (.DOUBLE? <SET ELADDR <VAR-TYPE-ADDRESS .ELVAL>>)
+       (<SET ELADDR <VAR-VALUE-ADDRESS .ELVAL>>)>)
+      (.DOUBLE? <SET ELADDR <ADDR-TYPE-MQUOTE .ELVAL>>)
+      (<SET ELADDR <MA-IMM .ELVAL>>)>)
+    (<==? .ELVAL STACK>                                    ;"Only happens in NTH case"
+     <COND (<NOT .DOUBLE?> <EMIT-PUSH <TYPE-WORD .EHINT> LONG>)>
+     <SET ELAC <MA-AINC ,AC-TP>>)
+    (<==? .ELVAL .STRUC>
+     <COND (.DOUBLE? <SET ELAC <GET-AC DOUBLE T>>)
+          (<SET ELAC <GET-AC PREF-VAL T>>)>)
+    (<NOT <AND <SET ELAC <VAR-VALUE-IN-AC? .ELVAL>>
+              <OR <NOT .DOUBLE?>
+                  <AND <SET ELTAC <VAR-TYPE-WORD-IN-AC? .ELVAL>>
+                       <==? <NEXT-AC .ELTAC> .ELAC>>>>>
+     <DEAD-VAR .ELVAL>
+     <COND (.DOUBLE? <SET ELAC <GET-AC DOUBLE T>>)
+          (<SET ELAC <GET-AC PREF-VAL T>>)>)
+    (T
+     <DEAD-VAR .ELVAL>
+     <COND (.DOUBLE?
+           <STORE-AC .ELTAC T <FIND-CACHE-VAR .ELVAL>>
+           <STORE-AC .ELAC T <FIND-CACHE-VAR .ELVAL>>
+           <SET ELAC .ELTAC>)
+          (T <STORE-AC .ELAC T <FIND-CACHE-VAR .ELVAL>>)>)>
+                                                       ;"Get AC[s] for result"
+   <REST-BLOCK-GEN .STRUC
+                  1
+                  .STRES
+                  0
+                  <>
+                  .VINS
+                  <COND (.PUT? .ELADDR) (.ELAC)>
+                  .PUT?
+                  .NO-TYPE?>
+   <COND (<AND <NOT .PUT?> <N==? .ELVAL STACK>>
+         <COND (.DOUBLE? <DEST-PAIR <NEXT-AC .ELAC> .ELAC .ELVAL>)
+               (<LINK-VAR-TO-AC .ELVAL .ELAC VALUE <>>)>
+         <COND (.EHINT <DEST-DECL .ELAC .ELVAL .EHINT>)>)>
+   NORMAL>
+
+\\f 
+
+<DEFINE NTH-LENGTH-GEN (CINS STRUC OFF STYPE RES
+                       "AUX" SAC (TUP <ITUPLE 5 <>>) RAC)
+       <COND (<NOT <SET SAC <VAR-VALUE-IN-AC? .STRUC>>>
+              <SET SAC <LOAD-VAR .STRUC VALUE <> PREF-VAL>>)>
+       <PROTECT-USE .SAC>
+       <GET-ADDR .TUP .STRUC .SAC .OFF .STYPE <> <> T>
+       <COND (<NOT <SET RAC <VAR-VALUE-IN-AC? .RES>>>
+              <SET RAC <GET-AC PREF-VAL T>>)>
+       <EMIT ,INST-MOVW !<2 .TUP> <MA-REG .RAC>>
+       <LINK-VAR-TO-AC .RES .RAC VALUE <>>
+       <DEST-DECL .RAC .RES FIX>
+       NORMAL>
+
+<DEFINE NTH-LENGTH-COMP-GEN (CINS STRUC OFF STYPE AMT CMPINS OP-INFO
+                            "AUX" SAC (TUP <ITUPLE 5 <>>))
+       #DECL ((OP-INFO) OP-INFO)
+       <COND (<NOT <SET SAC <VAR-VALUE-IN-AC? .STRUC>>>
+              <SET SAC <LOAD-VAR .STRUC VALUE <> PREF-VAL>>)>
+       <PROTECT-USE .SAC>
+       <GET-ADDR .TUP .STRUC .SAC .OFF .STYPE <> <> T>
+       <COND (<==? .AMT 0>
+              <COND (<==? .CMPINS EMPL?!-MIMOP>
+                     <EMIT ,INST-TSTL !<1 .TUP>>)
+                    (<EMIT ,INST-TSTW !<2 .TUP>>)>)
+             (<TYPE? .AMT FIX> <EMIT ,INST-CMPW !<2 .TUP> <MA-IMM .AMT>>)
+             (T <EMIT ,INST-CMPW !<2 .TUP> <VAR-VALUE-ADDRESS .AMT>>)>
+       <GEN-TEST-INST
+        <COMPUTE-DIRECTION <OP-DIR .OP-INFO>
+                           <COND (<MEMQ .CMPINS ,EMPU> ,CEQ-CODE)
+                                 (<==? .CMPINS EMPL?!-MIMOP> ,CEQ-CODE)
+                                 (<==? .CMPINS VEQUAL?!-MIMOP> ,CEQ-CODE)
+                                 (<==? .CMPINS LESS?!-MIMOP> ,CLT-CODE)
+                                 (<==? .CMPINS GRTR?!-MIMOP> ,CGT-CODE)>>
+        <OP-BRANCH .OP-INFO>
+        <>>
+       CONDITIONAL-BRANCH>
+
+<DEFINE SLOT-COMPARE (STRUC1 STRUC2 CMPINS OP-INFO OFF1 STYPE1 OFF2 STYPE2
+                     "AUX" (SAC1 <>) (SAC2 <>) (ADDR1 <ITUPLE 5 <>>)
+                           (ADDR2 <ITUPLE 5 <>>) (SHORT? <>) TMP FC)
+       #DECL ((ADDR1 ADDR2) <OR TUPLE EFF-ADDR LADDR>)
+       <COND (<OR <MEMQ .STYPE1 '[STRING BYTES]>
+                  <MEMQ .STYPE2 '[STRING BYTES]>>
+              <SET SHORT? T>)>
+       <COND (<AND .OFF2 <NOT .OFF1>>
+              <SET OFF1 .OFF2>
+              <SET OFF2 <>>
+              <SET STYPE1 .STYPE2>
+              <SET STYPE2 <>>
+              <SET TMP .STRUC2>
+              <SET STRUC2 .STRUC1>
+              <SET STRUC1 .TMP>
+              <SET CMPINS <COND (<==? .CMPINS GRTR?!-MIMOP>
+                                 LESS?!-MIMOP)
+                                (<==? .CMPINS LESS?!-MIMOP>
+                                 GRTR?!-MIMOP)
+                                (T .CMPINS)>>)>
+       <COND (.OFF1
+              <COND (<NOT <SET SAC1 <VAR-VALUE-IN-AC? .STRUC1>>>
+                     <SET SAC1 <LOAD-VAR .STRUC1 VALUE <> PREF-VAL>>)>
+              <PROTECT-USE .SAC1>)>
+       <COND (.OFF2
+              <COND (<N==? .STRUC1 .STRUC2>
+                     <COND (<NOT <SET SAC2 <VAR-VALUE-IN-AC? .STRUC2>>>
+                            <SET SAC2 <LOAD-VAR .STRUC2 VALUE <> PREF-VAL>>)>
+                     <PROTECT-USE .SAC2>)
+                    (T <SET SAC2 .SAC1>)>)>
+       <COND (.OFF1 <GET-ADDR .ADDR1 .STRUC1 .SAC1 .OFF1 .STYPE1 <>>)
+             (<TYPE? .STRUC1 VARTBL>
+              <SET ADDR1 <VAR-VALUE-ADDRESS .STRUC1>>)
+             (<FIX-CONSTANT? .STRUC1>
+              <COND (<NOT <TYPE? .STRUC1 FLOAT>>
+                     <SET ADDR1 <MA-IMM .STRUC1>>)
+                    (T
+                     <SET ADDR1 <FLOAT-IMM <FLOATCONVERT .STRUC1>>>)>)
+             (<AND <==? <PRIMTYPE .STRUC1> LIST>
+                   <EMPTY? .STRUC1>>
+              <SET STRUC1 0>
+              <SET ADDR1 <MA-IMM 0>>)
+             (T
+              <SET ADDR1 <ADDR-VALUE-MQUOTE .STRUC1>>)>
+       <COND (<NOT .OFF2>
+              <COND (<TYPE? .STRUC2 VARTBL>
+                     <SET ADDR2 <VAR-VALUE-ADDRESS .STRUC2>>)
+                    (<FIX-CONSTANT? .STRUC2>
+                     <COND (<NOT <TYPE? .STRUC2 FLOAT>>
+                            <SET ADDR2 <MA-IMM .STRUC2>>)
+                           (T
+                            <SET ADDR2 <FLOAT-IMM <FLOATCONVERT .STRUC2>>>)>)
+                    (<AND <==? <PRIMTYPE .STRUC2> LIST>
+                          <EMPTY? .STRUC2>>
+                     <SET STRUC2 0>
+                     <SET ADDR2 <MA-IMM 0>>)
+                    (T
+                     <SET ADDR2 <ADDR-VALUE-MQUOTE .STRUC2>>)>)
+             (<AND <3 .ADDR1>                  ;"First guy had index register"
+                   <==? .OFF1 .OFF2>
+                   <TYPE? .OFF2 VARTBL>
+                   <OR <==? .STYPE1 .STYPE2> .SHORT?>>
+              <GET-ADDR .ADDR2 .STRUC2 .SAC2 .OFF2 .STYPE2 <> <3 .ADDR1>>)
+             (T <GET-ADDR .ADDR2 .STRUC2 .SAC2 .OFF2 .STYPE2 <>>)>
+       <COND (<OR <==? .STRUC1 0> <==? .STRUC2 0>>
+              <EMIT <COND (.SHORT? ,INST-TSTB) (,INST-TSTL)>
+                    !<COND (<==? .STRUC1 0> <1 .ADDR2>) (<1 .ADDR1>)>>)
+             (<OR <==? .STRUC1 0.0> <==? .STRUC2 0.0>>
+              <EMIT ,INST-TSTF
+                    !<COND (<==? .STRUC1 0.0> <1 .ADDR2>) (<1 .ADDR1>)>>)
+             (<OR <TYPE? .STRUC1 FLOAT> <TYPE? .STRUC2 FLOAT>>
+              <EMIT ,INST-CMPF
+                    !<COND (<TYPE? .ADDR1 TUPLE> <1 .ADDR1>)((.ADDR1))>
+                    !<COND (<TYPE? .ADDR2 TUPLE> <1 .ADDR2>)((.ADDR2))>>)
+             (T
+              <EMIT <COND (.SHORT? ,INST-CMPB) (T ,INST-CMPL)>
+                    !<COND (<TYPE? .ADDR1 TUPLE> <1 .ADDR1>) ((.ADDR1))>
+                    !<COND (<TYPE? .ADDR2 TUPLE> <1 .ADDR2>) ((.ADDR2))>>)>
+       <GEN-TEST-INST
+        <COMPUTE-DIRECTION <OP-DIR .OP-INFO>
+                           <COND (<==? .CMPINS VEQUAL?!-MIMOP> ,CEQ-CODE)
+                                 (<==? .CMPINS LESS?!-MIMOP> ,CLT-CODE)
+                                 (<==? .CMPINS GRTR?!-MIMOP> ,CGT-CODE)>>
+        <OP-BRANCH .OP-INFO>
+        <>>
+       CONDITIONAL-BRANCH>
\ No newline at end of file