Annotation of 40BSD/cmd/liszt/cddr.l, revision 1.1

1.1     ! root        1: (include "caspecs.l")
        !             2: (eval-when (compile)
        !             3:   (fasl 'camacs))
        !             4: 
        !             5: (setq sectioncddrid "@(#)cddr.l        5.4     11/11/80")  ; id for SCCS
        !             6: 
        !             7: ; cc-not :: compile a "not" or "null" expression               = cc-not =
        !             8: ;
        !             9: (defun cc-not nil
        !            10:   (makecomment '(beginning not))
        !            11:   (If (null g-loc)
        !            12:       then (let ((g-cc (cons (cdr g-cc) (car g-cc)))
        !            13:                 (g-ret nil))
        !            14:                (d-exp (cadr v-form)))
        !            15:       else (let ((finlab (d-genlab))
        !            16:                 (finlab2 (d-genlab))
        !            17:                 (g-ret nil))
        !            18:                ; eval arg and jump to finlab if nil
        !            19:                (let ((g-cc (cons finlab nil))
        !            20:                      g-loc)
        !            21:                     (d-exp (cadr v-form)))
        !            22:                ; didn't jump, answer must be t
        !            23:                (d-move 'T g-loc)
        !            24:                (If (car g-cc) then (e-goto (car g-cc))
        !            25:                               else (e-goto finlab2))
        !            26:                (e-label finlab)
        !            27:                ; answer is nil
        !            28:                (d-move 'Nil g-loc)
        !            29:                (If (cdr g-cc) then (e-goto (cdr g-cc)))
        !            30:                (e-label finlab2))))
        !            31: 
        !            32: 
        !            33: ;--- cc-numberp :: check for numberness                                = cc-numberp =
        !            34: ;
        !            35: (defun cc-numberp nil
        !            36:   (d-typecmplx (cadr v-form) 
        !            37:               '#.(concat '$ (plus 1_2 1_4 1_9))))
        !            38: 
        !            39: 
        !            40: ;--- cc-or :: compile an "or" expression                       = cc-or =
        !            41: ;
        !            42: (defun cc-or nil
        !            43:   (let ((finlab (d-genlab))
        !            44:        (finlab2)
        !            45:        (exps (If (cdr v-form) thenret else '(nil)))) ; (or) => nil
        !            46:        (If (null (car g-cc))
        !            47:           then (d-exp (do ((g-cc (cons finlab nil))
        !            48:                            (g-loc (If g-loc then 'reg))
        !            49:                            (g-ret nil)
        !            50:                            (ll exps (cdr ll)))
        !            51:                           ((null (cdr ll)) (car ll))
        !            52:                           (d-exp (car ll))))
        !            53:                (If g-loc then (setq finlab2 (d-genlab))
        !            54:                               (e-goto finlab2)
        !            55:                               (e-label finlab)
        !            56:                               (d-move 'reg g-loc)
        !            57:                               (e-label finlab2)
        !            58:                          else (e-label finlab))
        !            59:           else (If (null g-loc) then (setq finlab (car g-cc)))
        !            60:                (d-exp (do ((g-cc (cons finlab nil))
        !            61:                            (g-loc (If g-loc then 'reg))
        !            62:                            (g-ret nil)
        !            63:                            (ll exps (cdr ll)))
        !            64:                           ((null (cdr ll)) (car ll))
        !            65:                           (d-exp (car ll))))
        !            66:                (If g-loc then (setq finlab2 (d-genlab))
        !            67:                               (e-goto finlab2)
        !            68:                               (e-label finlab)
        !            69:                               (d-move 'reg g-loc)
        !            70:                               (e-goto (car g-cc))      ; result is t
        !            71:                               (e-label finlab2)))
        !            72:        (d-clearreg)))  ; we are not sure of the state due to possible branches.
        !            73:                               
        !            74: 
        !            75: ;--- c-prog :: compile a "prog" expression                     = c-prog =
        !            76: ;
        !            77: ; for interlisp compatibility, we allow the formal variable list to
        !            78: ; contain objects of this form (vrbl init) which gives the initial value
        !            79: ; for that variable (instead of nil)
        !            80: ;
        !            81: (defun c-prog nil
        !            82:   (let (g-loc g-cc seeninit initf ((spcs locs initsv . initsn) 
        !            83:                                   (d-classify (cadr v-form)))
        !            84:        (p-rettrue g-ret) (g-ret nil))
        !            85: 
        !            86:        (e-pushnil (length locs))       ; locals initially nil
        !            87:        (d-bindprg spcs locs)           ; bind locs and specs
        !            88: 
        !            89:        (cond (initsv (d-pushargs initsv)
        !            90:                     (mapc '(lambda (x)
        !            91:                                    (d-move 'unstack (d-loc x))
        !            92:                                    (decr g-loccnt)
        !            93:                                    (unpush g-locs))
        !            94:                           (nreverse initsn))))
        !            95:        
        !            96:        ; determine all possible labels
        !            97:        (do ((ll (cddr v-form) (cdr ll))
        !            98:            (labs nil))
        !            99:           ((null ll) (setq g-labs `((,(d-genlab) ,@labs)
        !           100:                                     ,@g-labs)))
        !           101:           (If (and (car ll) (symbolp (car ll)))
        !           102:               then (If (assq (car ll) labs)
        !           103:                        then (comp-err "label is mulitiply defined " (car ll))
        !           104:                        else (setq labs (cons (cons (car ll) (d-genlab))
        !           105:                                              labs)))))
        !           106:        
        !           107:        ; compile each form which is not a label
        !           108:        (d-clearreg)            ; unknown state after binding
        !           109:        (do ((ll (cddr v-form) (cdr ll)))
        !           110:           ((null ll))
        !           111:           (If (or (null (car ll)) (not (symbolp (car ll))))
        !           112:               then (d-exp (car ll))
        !           113:               else (e-label (cdr (assq (car ll) (cdar g-labs))))
        !           114:                    (d-clearreg))))             ; dont know state after label
        !           115:   
        !           116:   ; result is nil if fall out and care about value
        !           117:   (If (or g-cc g-loc) then (d-move 'Nil 'reg))
        !           118:   
        !           119:   (e-label (caar g-labs))              ; return to label
        !           120:   (setq g-labs (cdr g-labs))
        !           121:   (d-unbind))                  ; unbind our frame
        !           122: 
        !           123: 
        !           124: ;--- d-bindprg :: do binding for a prog expression
        !           125: ;      - spcs : list of special variables
        !           126: ;      - locs : list of local variables
        !           127: ;      - specinit : init values for specs (or nil if all are nil)
        !           128: ;
        !           129: (defun d-bindprg (spcs locs)
        !           130: 
        !           131: 
        !           132:        ; place the local vrbls and prog frame entry on the stack
        !           133:        (setq g-loccnt (+ g-loccnt (length locs))
        !           134:              g-locs (nconc locs `((prog . ,(length spcs)) ,@g-locs)))
        !           135:         
        !           136:        ; now bind the specials, if any, to nil
        !           137:        (If spcs then (e-setupbind)
        !           138:                      (mapc '(lambda (vrb)
        !           139:                                     (e-shallowbind vrb 'Nil))
        !           140:                            spcs)
        !           141:                      (e-unsetupbind)))
        !           142: 
        !           143: ;--- d-unbind :: remove one frame from g-locs
        !           144: ;
        !           145: (defun d-unbind nil
        !           146:   (do ((count 0 (1+ count)))
        !           147:       ((dtpr (car g-locs))
        !           148:        (If (not (zerop (cdar g-locs)))
        !           149:           then (e-unshallowbind (cdar g-locs)))
        !           150:        (cond ((not (zerop count))
        !           151:              (e-dropnp count)
        !           152:              
        !           153:              (setq g-loccnt (- g-loccnt count))))
        !           154:        (setq g-locs (cdr g-locs)))
        !           155:       (setq g-locs (cdr g-locs))))
        !           156:        
        !           157: 
        !           158: ;--- d-classify :: seperate variable list into special and non-special
        !           159: ;      - lst : list of variables
        !           160: ; returns ( xxx yyy zzz . aaa) 
        !           161: ;              where xxx is the list of special variables and
        !           162: ;              yyy is the list of local variables
        !           163: ;              zzz are the non nil initial values for prog variables
        !           164: ;              aaa are the names corresponding to the values in zzz
        !           165: ;
        !           166: (defun d-classify (lst)
        !           167:   (do ((ll lst (cdr ll))
        !           168:        (locs) (spcs) (init) (initsv) (initsn) 
        !           169:          (name))
        !           170:       ((null ll) (cons spcs (cons locs (cons initsv initsn))))
        !           171:       (If (atom (car ll)) then (setq name (car ll))
        !           172:                          else (setq name (caar ll))
        !           173:                               (Push initsn name)
        !           174:                               (Push initsv (cadar ll)))
        !           175:       (If (d-specialp name)
        !           176:          then (Push spcs name)
        !           177:          else (Push locs name))))
        !           178: 
        !           179: ; cm-progn :: compile a "progn" expression                     = cm-progn =
        !           180: ;
        !           181: (defun cm-progn nil
        !           182:   `((lambda nil ,@(cdr v-form))))
        !           183: 
        !           184: 
        !           185: ; cm-prog1 :: compile a "prog1" expression                     = cm-prog1 =
        !           186: ;
        !           187: (defun cm-prog1 nil
        !           188:   (let ((gl (d-genlab)))
        !           189:        `((lambda (,gl) 
        !           190:                 ,@(cddr v-form)
        !           191:                 ,gl)
        !           192:         ,(cadr v-form))))
        !           193: 
        !           194: 
        !           195: ; cm-prog2 :: compile a "prog2" expression                     = cm-prog2 =
        !           196: ;
        !           197: (defun cm-prog2 nil
        !           198:   (let ((gl (d-genlab)))
        !           199:        `((lambda (,gl) ,(cadr v-form)
        !           200:                       (setq ,gl ,(caddr v-form))
        !           201:                       ,@(cdddr v-form)
        !           202:                       ,gl)
        !           203:         nil)))
        !           204: 
        !           205: 
        !           206: ;--- cc-quote : compile a "quote" expression                   = cc-quote =
        !           207: ; 
        !           208: ; if we are just looking to set the ; cc, we just make sure 
        !           209: ; we set the cc depending on whether the expression quoted is
        !           210: ; nil or not.
        !           211: (defun cc-quote nil
        !           212:   (let ((arg (cadr v-form))
        !           213:        argloc)
        !           214: 
        !           215:        (If (null g-loc) 
        !           216:           then (If (and (null arg) (cdr g-cc)
        !           217:                    then (e-goto (cdr g-cc))
        !           218:                 elseif (and arg (car g-cc))
        !           219:                    then (e-goto (car g-cc)))
        !           220:                 elseif (null g-cc)
        !           221:                    then (comp-warn "losing the value of this expression " (or v-form)))
        !           222:        else (d-move (d-loclit arg nil) g-loc)
        !           223:             (d-handlecc))))
        !           224: 
        !           225: 
        !           226: ;--- d-loc :: return the location of the variable or value in IADR form 
        !           227: ;      - form : form whose value we are to locate
        !           228: ;
        !           229: ; if we are given a xxx as form, we check yyy;
        !           230: ;      xxx             yyy
        !           231: ;     --------      ---------
        !           232: ;      nil             Nil is always returned
        !           233: ;      symbol          return the location of the symbols value, first looking
        !           234: ;                   in the registers, then on the stack, then the bind list.
        !           235: ;                   If g-ingorereg is t then we don't check the registers.
        !           236: ;                   We would want to do this if we were interested in storing
        !           237: ;                   something in the symbol's value location.
        !           238: ;      number          always return the location of the number on the bind
        !           239: ;                   list (as a (lbind n))
        !           240: ;      other           always return the location of the other on the bind
        !           241: ;                   list (as a (lbind n))
        !           242: ;
        !           243: (defun d-loc (form)
        !           244:   (If (null form) then 'Nil
        !           245:    elseif (numberp form) then 
        !           246:           (If (and (fixp form) (greaterp form -1025) (lessp form 1024))
        !           247:              then `(fixnum ,form)              ; small fixnum
        !           248:              else (d-loclit form nil))
        !           249:    elseif (symbolp form) 
        !           250:        then (If (and (null g-ignorereg) (car (d-bestreg form nil))) thenret
        !           251:                else (If (d-specialp form) then (d-loclit form t)
        !           252:                                  else 
        !           253:                                    (do ((ll g-locs (cdr ll))   ; check stack
        !           254:                                         (n g-loccnt))  
        !           255:                                        ((null ll) 
        !           256:                                         (comp-warn (or form) " declared special by compiler")
        !           257:                                         (d-makespec form)
        !           258:                                         (d-loclit form t))
        !           259:                                        (If (atom (car ll))
        !           260:                                            then (If (eq form (car ll))
        !           261:                                                     then (return `(stack ,n))
        !           262:                                                     else (setq n (1- n)))))))
        !           263:     else (d-loclit form nil)))
        !           264: 
        !           265: 
        !           266: ;--- d-loclit :: locate or add litteral to bind list
        !           267: ;      - form : form to check for and add if not present
        !           268: ;      - flag : if t then if we are given a symbol, return the location of
        !           269: ;               its value, else return the location of the symbol itself
        !           270: ;
        !           271: ; scheme: we share the locations of atom (symbols,numbers,string) but always
        !           272: ;       create a fresh copy of anything else.
        !           273: (defun d-loclit (form flag)
        !           274:   (prog (loc onplist symboltype)
        !           275:        (If (null form) 
        !           276:            then (return 'Nil)
        !           277:         elseif (symbolp form)
        !           278:            then (setq symboltype t)
        !           279:                 (cond ((setq loc (get form g-bindloc))
        !           280:                        (setq onplist t)))
        !           281:         elseif (atom form)
        !           282:            then (do ((ll g-lits (cdr ll))      ; search for atom on list
        !           283:                      (n g-litcnt (1- n)))
        !           284:                     ((null ll))
        !           285:                     (If (eq form (car ll))
        !           286:                         then (setq loc n)      ; found it
        !           287:                         (return))))    ; leave do
        !           288:        (If (null loc)
        !           289:            then (Push g-lits form)
        !           290:                 (setq g-litcnt (1+ g-litcnt)
        !           291:                       loc g-litcnt)
        !           292:                 (cond ((and symboltype (null onplist))
        !           293:                        (putprop form loc g-bindloc))))
        !           294: 
        !           295:        (return (If (and flag symboltype) then `(bind ,loc)
        !           296:                                     else `(lbind ,loc)))))
        !           297:                             
        !           298: 
        !           299: 
        !           300: ;--- d-locv :: find the location of a value cell, and dont return a register
        !           301: ;
        !           302: (defun d-locv (sm)
        !           303:   (let ((g-ignorereg t))
        !           304:        (d-loc sm)))
        !           305: 
        !           306: 
        !           307: ;--- c-setarg :: set a lexpr's arg                             = cc-setarg  =
        !           308: ; form is (setarg index value)
        !           309: ;
        !           310: (defun c-setarg nil
        !           311:   (If (not (eq 'lexpr g-ftype))
        !           312:       then (comp-err "setarg only allowed in lexprs"))
        !           313:   (If (and fl-inter (eq (length (cdr v-form)) 3))      ; interlisp setarg
        !           314:       then (If (not (eq (cadr v-form) (car g-args)))
        !           315:               then (comp-err "setarg: can only compile local setargs " v-form)
        !           316:               else (setq v-form (cdr v-form))))
        !           317:    (d-pushargs (list (cadr v-form)))    ; stack index
        !           318:    (let ((g-loc 'reg)
        !           319:         (g-cc nil)
        !           320:         (g-ret nil))
        !           321:        (d-exp (caddr v-form)))
        !           322:    (d-clearreg 'r1)                    ; indicate we are clobbering r1
        !           323:    (e-write3 'movl `(* -4 #.Np-reg) 'r1)       ; actual number to r1
        !           324:    (e-write3 'movl 'r0 "*-4(fp)[r1]")  ; store value in
        !           325:    (e-pop 1)
        !           326:    (unpush g-locs)
        !           327:    (decr g-loccnt))
        !           328: 
        !           329: ;--- cc-stringp :: check for string ness                       = cc-stringp =
        !           330: ;
        !           331: (defun cc-stringp nil
        !           332:   (d-typesimp (cadr v-form) '$0))
        !           333: 
        !           334: 
        !           335: ;--- cc-symbolp :: check for symbolness                                = cc-symbolp =
        !           336: ;
        !           337: (defun cc-symbolp nil
        !           338:   (d-typesimp (cadr v-form) '$1))
        !           339: 
        !           340: 
        !           341: 
        !           342: ;--- c-return :: compile a "return" statement                  = c-return =
        !           343: ;
        !           344: (defun c-return nil
        !           345:   ; value is always put in r0
        !           346:   (let ((g-loc 'reg)
        !           347:        g-cc
        !           348:        g-ret)
        !           349:        (d-exp (cadr v-form)))
        !           350: 
        !           351:   ; if we are doing a non local return, compute number of specials to unbind
        !           352:   ; and locals to pop
        !           353:   (If (car g-labs) then (e-goto (caar g-labs))
        !           354:       else (do ((loccnt 0)
        !           355:                (speccnt 0)
        !           356:                (ll g-labs (cdr ll))
        !           357:                (locs g-locs))
        !           358:               ((null ll) (comp-err "return used not within a prog or do"))
        !           359:               (If (car ll) then  (comp-warn " non local return used ")
        !           360:                                      ; unbind down to but not including
        !           361:                                      ; this frame.
        !           362:                                      (If (greaterp loccnt 0)
        !           363:                                          then (e-pop loccnt))
        !           364:                                      (If (greaterp speccnt 0)
        !           365:                                          then (e-unshallowbind speccnt))
        !           366:                                     (e-goto (caar ll))
        !           367:                                     (return)
        !           368:                 else ; determine number of locals and special on 
        !           369:                      ; stack for this frame, add to running
        !           370:                      ; totals
        !           371:                      (do ()
        !           372:                          ((dtpr (car locs))
        !           373:                           (setq speccnt (+ speccnt (cdar locs))
        !           374:                                 locs (cdr locs)))
        !           375:                          (incr loccnt)
        !           376:                          (setq locs (cdr locs)))))))
        !           377:                                             
        !           378:         
        !           379: ; c-rplaca :: compile a "rplaca" expression                    = c-rplaca =
        !           380: ;
        !           381: (defun c-rplaca nil
        !           382:   (let ((ssimp (d-simple (caddr v-form)))
        !           383:        (g-ret nil))
        !           384:        (let ((g-loc (If ssimp then 'reg else 'stack))
        !           385:             (g-cc nil))
        !           386:            (d-exp (cadr v-form)))
        !           387:        (If (null ssimp) then (Push g-locs nil)
        !           388:                             (incr g-loccnt)
        !           389:                             (let ((g-loc 'r1)
        !           390:                                   (g-cc nil))
        !           391:                                  (d-exp (caddr v-form)))
        !           392:                             (d-move 'unstack 'reg)
        !           393:                             (unpush g-locs)
        !           394:                             (decr g-loccnt)
        !           395:                             (e-move 'r1 '(4 r0))
        !           396:           else (e-move (e-cvt ssimp)  '(4 r0)))
        !           397:        (d-clearreg)))          ; cant tell what we are clobbering
        !           398: 
        !           399: 
        !           400: ; c-rplacd :: compile a "rplacd" expression                    = c-rplacd =
        !           401: ;
        !           402: (defun c-rplacd nil
        !           403:   (let ((ssimp (d-simple (caddr v-form)))
        !           404:        (g-ret nil))
        !           405:        (let ((g-loc (If ssimp then 'reg else 'stack))
        !           406:             (g-cc nil))
        !           407:            (d-exp (cadr v-form)))
        !           408:        (If (null ssimp) then (Push g-locs nil)
        !           409:                             (incr g-loccnt)
        !           410:                             (let ((g-loc 'r1)
        !           411:                                   (g-cc nil))
        !           412:                                  (d-exp (caddr v-form)))
        !           413:                             (d-move 'unstack 'reg)
        !           414:                             (unpush g-locs)
        !           415:                             (decr g-loccnt)
        !           416:                             (e-move 'r1 '(0 r0))
        !           417:           else (e-move (e-cvt ssimp)  '(0 r0)))
        !           418:        (d-clearreg)))
        !           419: 
        !           420: ; c-set :: compile a "set" expression                          = c-set =
        !           421: 
        !           422: 
        !           423: ;--- cc-setq :: compile a "setq" expression                    = c-setq = 
        !           424: ;
        !           425: (defun cc-setq nil
        !           426:   (let (tmp)
        !           427:        (If (oddp (length (cdr v-form)))
        !           428:           then (comp-err "wrong number of args to setq "
        !           429:                          (or v-form))
        !           430:        elseif (cdddr v-form)           ; if multiple setq's
        !           431:           then (do ((ll (cdr v-form) (cddr ll))
        !           432:                     (g-loc)
        !           433:                     (g-cc nil))
        !           434:                    ((null (cddr ll)) (setq tmp ll))
        !           435:                    (setq g-loc (d-locv (car ll)))
        !           436:                    (d-exp (cadr ll))
        !           437:                    (d-clearuse (car ll)))
        !           438:        else (setq tmp (cdr v-form)))
        !           439: 
        !           440:        ; do final setq
        !           441:        (let ((g-loc (d-locv (car tmp)))
        !           442:             (g-cc (If g-loc then nil else g-cc))
        !           443:             (g-ret nil))
        !           444:            (d-exp (cadr tmp))
        !           445:            (d-clearuse (car tmp)))
        !           446:        (If g-loc then (d-move (d-locv (car tmp)) g-loc)
        !           447:                      (If g-cc then (d-handlecc)))))
        !           448: 
        !           449: 
        !           450: 
        !           451: ; cc-typep :: compile a "typep" expression                     = cc-typep =
        !           452: ; 
        !           453: ; this returns the type of the expression, it is always non nil
        !           454: ;
        !           455: (defun cc-typep nil
        !           456:   (let ((argloc (d-simple (cadr v-form)))
        !           457:        (g-ret))
        !           458:        (If (null argloc) then (let ((g-loc 'reg) g-cc)
        !           459:                                   (d-exp (cadr v-form)))
        !           460:                              (setq argloc 'reg))
        !           461:        (If g-loc then (e-write4 'ashl '$-9 (e-cvt argloc) 'r0)
        !           462:                      (e-write3 'cvtbl "_typetable+1[r0]" 'r0)
        !           463:                      (e-write3 'movl "_tynames+4[r0]" 'r0)
        !           464:                      (e-write3 'movl "(r0)" (e-cvt g-loc)))
        !           465:        (If (car g-cc) then (e-goto (car g-cc)))))
        !           466: 
        !           467: 
        !           468: 
        !           469: ; cm-symeval :: compile a symeval expression.
        !           470: ; the symbol cell in franz lisp is just the cdr.
        !           471: ;
        !           472: (defun cm-symeval nil
        !           473:   `(cdr ,(cadr v-form)))
        !           474: 
        !           475: 
        !           476: ; c-*throw :: compile a "*throw" expression                    =c-*throw =
        !           477: ;
        !           478: ; the form of *throw is (*throw 'tag 'val) .
        !           479: ; we calculate and stack the value of tag, then calculate val 
        !           480: ; we call Idothrow to do the actual work, and only return if the
        !           481: ; throw failed.
        !           482: ;
        !           483: (defun c-*throw nil
        !           484:   (let ((arg2loc (d-simple (caddr v-form)))
        !           485:        g-cc
        !           486:        g-ret
        !           487:        arg1loc)
        !           488:        (If arg2loc then (If (setq arg1loc (d-simple (cadr v-form)))
        !           489:                            then (e-write2 'pushl (e-cvt arg2loc))
        !           490:                                 (e-write2 'pushl (e-cvt arg1loc))
        !           491:                            else (let ((g-loc 'reg))
        !           492:                                      (d-exp (cadr v-form))     ; calc tag
        !           493:                                      (e-write2 'pushl (e-cvt arg2loc))
        !           494:                                      (e-write2 'pushl (e-cvt 'reg))))
        !           495:                   else (let ((g-loc 'stack))
        !           496:                             (d-exp (cadr v-form))      ; calc tag to stack
        !           497:                             (Push g-locs nil)
        !           498:                             (incr g-loccnt)
        !           499:                             (setq g-loc 'reg)  
        !           500:                             (d-exp (caddr v-form))     ; calc value into r0
        !           501:                             (e-write2 'pushl (e-cvt 'reg))
        !           502:                             (e-write2 'pushl (e-cvt 'unstack))
        !           503:                             (unpush g-locs)
        !           504:                             (decr g-loccnt)))
        !           505:        (e-write3 'calls '$0 '_Idothrow)
        !           506:        (e-write2 'clrl '"-(sp)")                       ; non contuable error
        !           507:        (e-write2 'pushab '__erthrow)           ; string to print
        !           508:        (e-write3 'calls '$2 '_error)))
        !           509: 
        !           510: 
        !           511: 
        !           512: ;--- cm-zerop ::  convert zerop to a quick test                        = cm-zerop =
        !           513: ; zerop is only allowed on fixnum and flonum arguments.  In both cases,
        !           514: ; if the value of the first 32 bits is zero, then we have a zero.
        !           515: ; thus we can define it as a macro:
        !           516: (defun cm-zerop nil
        !           517:   (cond ((atom (cadr v-form))
        !           518:         `(and (null (cdr ,(cadr v-form))) (not (bigp ,(cadr v-form)))))
        !           519:        (t (let ((gnsy (gensym)))
        !           520:                `((lambda (,gnsy)
        !           521:                          (and (null (cdr ,gnsy)) 
        !           522:                                (not (bigp ,gnsy))))
        !           523:                  ,(cadr v-form))))))
        !           524: 
        !           525: 
        !           526: 
        !           527: ;------- FIXNUM arithmetic section ---------
        !           528: ;  beware all ye who read this section 
        !           529: ;
        !           530: 
        !           531: 
        !           532: 
        !           533: (declare (localf d-upordown d-fixop))
        !           534: 
        !           535: ;--- c-1+ :: fixnum add1 function
        !           536: ;
        !           537: (defun c-1+ nil
        !           538:   (d-upordown 'addl3))
        !           539: 
        !           540: ;--- c-1- :: fixnum sub1 function
        !           541: ;
        !           542: (defun c-1- nil
        !           543:   (d-upordown 'subl3))
        !           544: 
        !           545: (defun d-upordown (opcode)
        !           546:   (let ((arg (cadr v-form))
        !           547:        argloc)
        !           548:        (If (setq argloc (d-simple `(cdr ,arg)))
        !           549:           then (e-write4 opcode '$1 (e-cvt argloc)  'r5)
        !           550:           else (let ((g-loc 'reg)
        !           551:                      g-ret
        !           552:                      g-cc)
        !           553:                     (d-exp arg))
        !           554:                (e-write4 opcode '$1 "(r0)" 'r5))
        !           555:        (e-write2 "jsb" "_qnewint")
        !           556:        (d-clearreg)))
        !           557: 
        !           558: 
        !           559: ;--- c-+  :: fixnum add                                                = c-+ =
        !           560: ;
        !           561: (defun c-+ nil
        !           562:   (d-fixop 'addl3 'plus))
        !           563: 
        !           564: (defun c-- nil
        !           565:   (d-fixop 'subl3 'difference))
        !           566: 
        !           567: (defun c-* nil
        !           568:   (d-fixop 'mull3 'times))
        !           569: 
        !           570: (defun c-/ nil
        !           571:   (d-fixop 'divl3 'quotient))
        !           572: 
        !           573: (defun c-\\ nil
        !           574:   (d-fixop 'ediv  'remainder))
        !           575: 
        !           576: (defun d-fixop (opcode lispopcode)
        !           577:  (prog (op1 op2 rop1 rop2 simpleop1)
        !           578:   (If (not (eq 3 (length v-form))) ; only handle two ops for now
        !           579:       then (d-callbig lispopcode (cdr v-form))
        !           580:       else (setq op1 (cadr v-form)
        !           581:                 op2 (caddr v-form))
        !           582:           (If (fixp op1)
        !           583:               then (setq rop1 (concat '$ op1)  ; simple int
        !           584:                          simpleop1 t)      
        !           585:               else (If (setq rop1 (d-simple `(cdr ,op1)))
        !           586:                        then (setq rop1 (e-cvt rop1))
        !           587:                        else (let ((g-loc 'reg) g-cc g-ret)
        !           588:                                  (d-exp op1))
        !           589:                             (setq rop1 '|(r0)|)))
        !           590:           (If (fixp op2)
        !           591:               then (setq rop2 (concat '$ op2))
        !           592:               else (If (setq rop2 (d-simple `(cdr ,op2)))
        !           593:                        then (setq rop2 (e-cvt rop2))
        !           594:                        else (e-write3 'movl rop1 "-(sp)")
        !           595:                             (setq rop1 "(sp)+")
        !           596:                             (let ((g-loc 'reg)
        !           597:                                   g-cc g-ret)
        !           598:                                  (d-exp op2))
        !           599:                             (setq rop2 '|(r0)|)))
        !           600:           (If (eq opcode 'ediv)
        !           601:            then (If (not simpleop1) then (e-write3 'movl rop1 'r2)  ; need quad
        !           602:                                          (e-write4 'ashq '$-32 'r1 'r1)
        !           603:                                          (setq rop1 'r1))      ; word div.
        !           604:                 (e-write5 'ediv rop2 rop1 'r0 'r5)
        !           605:            else (e-write4 opcode rop2 rop1 'r5))
        !           606: 
        !           607:           (e-write2 'jsb "_qnewint")
        !           608:           (d-clearreg))))
        !           609: 
        !           610: 
        !           611: 
        !           612: 
        !           613: ;---- d routines (general ones, others are near function using them)
        !           614: 
        !           615: 
        !           616: 
        !           617: ;--- d-cmp :: compare two IADR values
        !           618: ;
        !           619: (defun d-cmp (arg1 arg2)
        !           620:   (e-write3 'cmpl (e-cvt arg1) (e-cvt arg2)))
        !           621: 
        !           622: 
        !           623: ;--- d-handlecc :: handle g-cc
        !           624: ; at this point the Z condition code has been set up and if g-cc is
        !           625: ; non nil, we must jump on condition to the label given in g-cc
        !           626: ;
        !           627: (defun d-handlecc nil
        !           628:   (If (car g-cc) then (e-gotot (car g-cc))
        !           629:    elseif (cdr g-cc) then (e-gotonil (cdr g-cc))))
        !           630: 
        !           631: 
        !           632: ;--- d-invert :: handle inverted condition codes
        !           633: ; this routine is called if a result has just be computed which alters
        !           634: ; the condition codes such that Z=1 if the result is t, and Z=0 if the
        !           635: ; result is nil (this is the reverse of the usual sense).  The purpose
        !           636: ; of this routine is to handle g-cc and g-loc.  That is if g-loc is 
        !           637: ; specified, we must convert the value of the Z bit of the condition 
        !           638: ; code to t or nil and store that in g-loc.  After handling g-loc we
        !           639: ; must handle g-cc, that is if the part of g-cc is non nil which matches
        !           640: ; the inverse of the current condition code, we must jump to that.
        !           641: ;
        !           642: (defun d-invert nil
        !           643:   (If (null g-loc) 
        !           644:       then (If (car g-cc) then (e-gotonil (car g-cc))
        !           645:            elseif (cdr g-cc) then  (e-gotot (cdr g-cc)))
        !           646:       else (let ((lab1 (d-genlab))
        !           647:                 (lab2 (If (cdr g-cc) thenret else (d-genlab))))
        !           648:                (e-gotonil lab1)
        !           649:                ; Z=1, but remember that this implies nil due to inversion
        !           650:                (d-move 'Nil g-loc)
        !           651:                (e-goto lab2)
        !           652:                (e-label lab1)
        !           653:                ; Z=0, which means t
        !           654:                (d-move 'T g-loc)
        !           655:                (If (car g-cc) then (e-goto (car g-cc)))
        !           656:                (If (null (cdr g-cc)) then (e-label lab2)))))
        !           657:                        
        !           658: 
        !           659: ;--- d-noninvert :: handle g-cc and g-loc assuming cc non inverted
        !           660: ; 
        !           661: ; like d-invert except Z=0 implies nil, and Z=1 implies t
        !           662: ;
        !           663: (defun d-noninvert nil
        !           664:   (If (null g-loc) 
        !           665:       then (If (car g-cc) then (e-gotot (car g-cc))
        !           666:            elseif (cdr g-cc) then  (e-gotonil (cdr g-cc)))
        !           667:       else (let ((lab1 (d-genlab))
        !           668:                 (lab2 (If (cdr g-cc) thenret else (d-genlab))))
        !           669:                (e-gotot lab1)
        !           670:                ; Z=0, this implies nil
        !           671:                (d-move 'Nil g-loc)
        !           672:                (e-goto lab2)
        !           673:                (e-label lab1)
        !           674:                ; Z=1, which means t
        !           675:                (d-move 'T g-loc)
        !           676:                (If (car g-cc) then (e-goto (car g-cc)))
        !           677:                (If (null (cdr g-cc)) then (e-label lab2)))))
        !           678: 
        !           679: ;--- d-macroexpand :: macro expand a form as much as possible
        !           680: ;
        !           681: (defun d-macroexpand (form)
        !           682:   (prog nil
        !           683:        loop
        !           684:        (If (and (dtpr form) 
        !           685:                 (symbolp (car form))
        !           686:                 (eq 'macro (d-functyp (car form))))
        !           687:            then (setq form (apply (car form) form))
        !           688:            (go loop))
        !           689:        (return form)))
        !           690: 
        !           691: ;--- d-makespec :: declare a variable to be special
        !           692: ;
        !           693: (defun d-makespec (vrb)
        !           694:   (putprop vrb t g-spec))
        !           695: 
        !           696: 
        !           697: ;--- d-move :: emit instructions to move value from one place to another
        !           698: ;
        !           699: (defun d-move (from to)
        !           700:   (makecomment `(from ,(e-uncvt from) to ,(e-uncvt to)))
        !           701:   (cond ((eq 'Nil from) (e-write2 'clrl (e-cvt to)))
        !           702:        (t (e-write3 'movl (e-cvt from) (e-cvt to)))))
        !           703: 
        !           704: 
        !           705: ;--- d-simple :: see of arg can be addresses in one instruction
        !           706: ; we define simple and really simple as follows
        !           707: ;  <rsimple> ::= number
        !           708: ;               quoted anything
        !           709: ;               local symbol
        !           710: ;               t
        !           711: ;               nil
        !           712: ;  <simple>  ::= <rsimple>
        !           713: ;               (cdr <rsimple>)
        !           714: ;               global symbol
        !           715: ;
        !           716: (defun d-simple (arg)
        !           717:   (let (tmp)
        !           718:        (If (d-rsimple arg) thenret
        !           719:        elseif (symbolp arg) then (d-loc arg)
        !           720:        elseif (and (memq (car arg) '(cdr car cddr cdar))
        !           721:                       (setq tmp (d-rsimple (cadr arg))))
        !           722:           then (If (eq 'Nil tmp) then tmp
        !           723:                 elseif (atom tmp)
        !           724:                     then (If (eq 'car (car arg)) then `(racc 4 ,tmp)
        !           725:                           elseif (eq 'cdr (car arg)) then `(racc 0 ,tmp)
        !           726:                           elseif (eq 'cddr (car arg)) then `(racc * 0 ,tmp)
        !           727:                           elseif (eq 'cdar (car arg)) then `(racc * 4 ,tmp))
        !           728:                 elseif (not (eq 'cdr (car arg))) then nil
        !           729:                 elseif (eq 'lbind (car tmp)) then `(bind ,(cadr tmp))
        !           730:                 elseif (eq 'stack (car tmp)) then `(vstack ,(cadr tmp))
        !           731:                 elseif (eq 'fixnum (car tmp)) then `(immed ,(cadr tmp))
        !           732:                 elseif (atom (car tmp))    then `(0 ,(cadr tmp))
        !           733:                 else (comp-err "bad arg to d-simple: " (or arg))))))
        !           734: 
        !           735: (defun d-rsimple (arg)
        !           736:   (If (atom arg) then
        !           737:       (If (null arg) then 'Nil
        !           738:        elseif (eq t arg) then 'T
        !           739:        elseif (or (numberp arg)
        !           740:                  (memq arg g-locs)) 
        !           741:          then (d-loc arg)
        !           742:        else (car (d-bestreg arg nil)))
        !           743:    elseif (eq 'quote (car arg)) then (d-loclit (cadr arg) nil)))
        !           744: 
        !           745: ;--- d-movespec :: move from loc to loc where the first addr given is
        !           746: ;                 an EIADR
        !           747: ;      - from : EIADR 
        !           748: ;      - to   : IADR
        !           749: ;
        !           750: (defun d-movespec (from to)
        !           751:   (makecomment `(fromspec ,from to ,(e-uncvt to)))
        !           752:   (e-write3 'movl from (e-cvt to)))
        !           753: 
        !           754: 
        !           755: ;--- d-specialp :: check if a variable is special
        !           756: ; a varible is special if it has been declared as such, or if
        !           757: ; the variable special is t
        !           758: (defun d-specialp (vrb)
        !           759:   (or special (get vrb g-spec)))
        !           760: 
        !           761: 
        !           762: ;--- d-tst :: test the given value (set the cc)
        !           763: ;
        !           764: (defun d-tst (arg)
        !           765:   (e-write2 'tstl (e-cvt arg)))
        !           766: 
        !           767: ;--- d-typesimp ::  determine the type of the argument 
        !           768: ;
        !           769: (defun d-typesimp (arg val)
        !           770:   (let ((argloc (d-simple arg)))
        !           771:        (If (null argloc) then (let ((g-loc 'reg)
        !           772:                                     g-cc g-ret)
        !           773:                                    (d-exp arg))
        !           774:                               (setq argloc 'reg))
        !           775:        (e-write4 'ashl '$-9 (e-cvt argloc) 'r0)
        !           776:        (e-write3 'cmpb '"_typetable+1[r0]" val)
        !           777:        (d-invert)))
        !           778: 
        !           779: ;--- d-typecmplx  :: determine if arg has one of many types
        !           780: ;      - arg : lcode argument to be evaluated and checked
        !           781: ;      - vals : fixnum with a bit in position n if we are to check type n
        !           782: ;
        !           783: (defun d-typecmplx (arg vals)
        !           784:   (let ((argloc (d-simple arg))
        !           785:        (reg))
        !           786:        (If (null argloc) then (let ((g-loc 'reg)
        !           787:                                    g-cc g-ret)
        !           788:                                   (d-exp arg))
        !           789:                              (setq argloc 'reg))
        !           790:        (setq reg 'r0)
        !           791:        (e-write4 'ashl '$-9 (e-cvt argloc) reg)
        !           792:        (e-write3 'cvtbl (concat "_typetable+1[" reg "]") reg)
        !           793:        (e-write4 'ashl reg '$1 reg)
        !           794:        (e-write3 'bitw vals reg)
        !           795:        (d-noninvert)))
        !           796: 
        !           797:        
        !           798: ;---- register handling routines.
        !           799: 
        !           800: ;--- d-allocreg :: allocate a register 
        !           801: ;  name - the name of the register to allocate or nil if we should
        !           802: ;        allocate the least recently used.
        !           803: ;
        !           804: (defun d-allocreg (name)
        !           805:   (If name 
        !           806:       then (let ((av (assoc name g-reguse)))
        !           807:                (If av then (rplaca (cdr av) (1+ (cadr av)))) ; inc used count
        !           808:                name)
        !           809:       else ; find smallest used count
        !           810:           (do ((small (car g-reguse))
        !           811:                (smc (cadar g-reguse))
        !           812:                (lis (cdr g-reguse) (cdr lis)))
        !           813:               ((null lis)
        !           814:                (rplaca (cdr small) (1+ smc))
        !           815:                (car small))
        !           816:               (If (< (cadar lis) smc)
        !           817:                   then (setq small (car lis)
        !           818:                              smc   (cadr small))))))
        !           819: 
        !           820: 
        !           821: ;--- d-bestreg :: determine the register which is closest to what we have
        !           822: ;  name - name of variable whose subcontents we want
        !           823: ;  pat  - list of d's and a's which tell which part we want
        !           824: ;
        !           825: (defun d-bestreg (name pat)
        !           826:   (do ((ll g-reguse (cdr ll))
        !           827:        (val)
        !           828:        (best)
        !           829:        (tmp)
        !           830:        (bestv -1))
        !           831:       ((null ll) (If best then (rplaca (cdr best) (1+ (cadr best)))
        !           832:                               (list (car best)
        !           833:                                     (If (> bestv 0) 
        !           834:                                         then (rplacd (nthcdr (1- bestv) 
        !           835:                                                              (setq tmp 
        !           836:                                                                    (copy pat)))
        !           837:                                                      nil)
        !           838:                                              tmp
        !           839:                                         else nil)
        !           840:                                     (nthcdr bestv pat))))
        !           841:       (If (and (setq val (cddar ll))
        !           842:               (eq name (car val)))
        !           843:          then (If (> (setq tmp (d-matchcnt pat (cdr val)))
        !           844:                      bestv)
        !           845:                   then (setq bestv tmp
        !           846:                              best  (car ll))))))
        !           847: 
        !           848: ;--- d-matchcnt :: determine how many parts of a pattern match
        !           849: ; want - pattern we want to achieve
        !           850: ; have - pattern whose value exists in a register
        !           851: ; 
        !           852: ; we return a count of the number of parts of the pattern match.
        !           853: ; If this pattern will be any help at all, we return a value from 
        !           854: ; 0 to the length of the pattern.
        !           855: ; If this pattern will not work at all, we return a number smaller
        !           856: ; than -1.  
        !           857: ; For `have' to be useful for `want', `have' must be a substring of 
        !           858: ; `want'.  If it is a substring, we return the length of `have'.
        !           859: ; 
        !           860: (defun d-matchcnt (want have)
        !           861:   (let ((length 0))
        !           862:        (If (do ((hh have (cdr hh))
        !           863:                (ww want (cdr ww)))
        !           864:               ((null hh) t)
        !           865:               (If (or (null ww) (not (eq (car ww) (car hh))))
        !           866:                   then (return nil)
        !           867:                   else (incr length)))
        !           868:           then  length
        !           869:           else  -2)))
        !           870: 
        !           871: 
        !           872: 
        !           873: ;--- d-clearreg :: clear all values in registers or just one
        !           874: ; if no args are given, clear all registers.
        !           875: ; if an arg is given, clear that register
        !           876: ;
        !           877: (defun d-clearreg n
        !           878:   (cond ((zerop n) 
        !           879:         (mapc '(lambda (x) (rplaca (cdr x) 0)
        !           880:                     (rplacd (cdr x) nil))
        !           881:               g-reguse))
        !           882:        (t (let ((av (assoc (arg 1) g-reguse)))
        !           883:                (If av then (rplaca (cdr av) 0)
        !           884:                            (rplacd (cdr av) nil))))))
        !           885: 
        !           886: 
        !           887: ;--- d-clearuse :: clear all register which reference a given variable
        !           888: ;
        !           889: (defun d-clearuse (varib)
        !           890:   (mapc '(lambda (x)
        !           891:                 (If (eq (caddr x) varib) then (rplacd (cdr x) nil)))
        !           892:        g-reguse))
        !           893: 
        !           894: 
        !           895: ;--- d-inreg :: declare that a value is in a register
        !           896: ; name - register name
        !           897: ; value - value in a register
        !           898: ;
        !           899: (defun d-inreg (name value)
        !           900:   (let ((av (assoc name g-reguse)))
        !           901:        (If av then (rplacd (cdr av) value))
        !           902:        name))
        !           903: 
        !           904: 
        !           905: ;---- e routines 
        !           906: 
        !           907: 
        !           908: 
        !           909: (defun e-cvt (arg)
        !           910:   (If     (eq 'reg arg) then 'r0
        !           911:    elseif (eq 'Nil arg) then '$0
        !           912:    elseif (eq 'T arg) then (If g-trueloc thenret
        !           913:                               else (setq g-trueloc (e-cvt (d-loclit t nil))))
        !           914:    elseif (eq 'stack arg) then '(+ #.Np-reg)
        !           915:    elseif (eq 'unstack arg) then '(- #.Np-reg)
        !           916:    elseif (atom arg) then arg
        !           917:    elseif (dtpr arg) then (If     (eq 'stack (car arg))
        !           918:                              then `(,(* 4 (1- (cadr arg))) #.oLbot-reg)
        !           919:                           elseif (eq 'vstack (car arg))
        !           920:                              then `(* ,(* 4 (1- (cadr arg))) #.oLbot-reg)
        !           921:                           elseif (eq 'bind (car arg))
        !           922:                              then `(* ,(* 4 (1- (cadr arg))) #.bind-reg)
        !           923:                           elseif (eq 'lbind (car arg))
        !           924:                              then `( ,(* 4 (1- (cadr arg))) #.bind-reg)
        !           925:                           elseif (eq 'fixnum (car arg))
        !           926:                              then `(\# ,(cadr arg))
        !           927:                           elseif (eq 'immed (car arg))
        !           928:                              then `($ ,(cadr arg))
        !           929:                           elseif (eq 'racc (car arg))
        !           930:                              then (cdr arg)
        !           931:                           else (comp-err " bad arg to e-cvt : "
        !           932:                                          (or arg)))
        !           933:    else  (comp-warn "bad arg to e-cvt : " (or arg))))
        !           934: 
        !           935: 
        !           936: ;--- e-uncvt :: inverse of e-cvt, used for making comments pretty
        !           937: ;
        !           938: (defun e-uncvt (arg)
        !           939:   (If (atom arg) then (If (eq 'Nil arg) then nil
        !           940:                          else arg)
        !           941:    elseif (eq 'stack (car arg))
        !           942:          then (do ((i g-loccnt)
        !           943:                    (ll g-locs))
        !           944:                   ((and (equal i (cadr arg)) (atom (car ll))) (car ll))
        !           945:                   (If (atom (car ll)) then (setq ll (cdr ll)
        !           946:                                                  i (1- i))
        !           947:                                        else (setq ll (cdr ll))))
        !           948:    elseif (or (eq 'bind (car arg)) (eq 'lbind (car arg)))
        !           949:          then (do ((i g-litcnt (1- i))
        !           950:                    (ll g-lits (cdr ll)))
        !           951:                   ((equal i (cadr arg)) (cond ((eq 'lbind (car arg))
        !           952:                                                (list 'quote (car ll)))
        !           953:                                               (t (car ll)))))
        !           954:    else arg))
        !           955: 
        !           956: ;--- e-cvtas :: convert an EIADR to vax unix assembler fmt and print it
        !           957: ;      - form : an EIADR form
        !           958: ;
        !           959: (defun e-cvtas (form)
        !           960:   (If (atom form)
        !           961:       then (sfilewrite form)
        !           962:    else (If (eq '* (car form)) then (If (eq '\# (cadr form))
        !           963:                                        then (setq form `($ ,(caddr form)))
        !           964:                                        else (sfilewrite "*")
        !           965:                                             (setq form (cdr form))))
        !           966:        (If (numberp (car form))
        !           967:            then (sfilewrite (car form))
        !           968:                 (sfilewrite "(")
        !           969:                 (sfilewrite (cadr form))
        !           970:                 (sfilewrite ")")
        !           971:                 (If (caddr form)
        !           972:                     then (sfilewrite "[")
        !           973:                          (sfilewrite (caddr form))
        !           974:                          (sfilewrite "]"))
        !           975:        elseif (eq '+ (car form))
        !           976:            then (sfilewrite '"(")
        !           977:                 (sfilewrite (cadr form))
        !           978:                 (sfilewrite '")+")
        !           979:        elseif (eq '- (car form))
        !           980:            then (sfilewrite '"-(")
        !           981:                 (sfilewrite (cadr form))
        !           982:                 (sfilewrite '")")
        !           983:        elseif (eq '\# (car form))      ; 5120 is base of small fixnums
        !           984:            then (sfilewrite (concat "$" (+ (* (cadr form) 4) 5120)))
        !           985:        elseif (eq '$ (car form))
        !           986:            then (sfilewrite '"$")
        !           987:                 (sfilewrite (cadr form)))))
        !           988: ;--- e-cmp :: emit code to compare the two given args
        !           989: ;      - arg1, arg2 : EIADRs
        !           990: ;
        !           991: (defun e-cmp (arg1 arg2)
        !           992:   (e-write3 'cmpl arg1 arg2))
        !           993: 
        !           994: ;--- e-docomment :: print any comment lines
        !           995: ;
        !           996: (defun e-docomment nil
        !           997:   (If g-comments
        !           998:       then (do ((ll (nreverse g-comments) (cdr ll)))
        !           999:               ((null ll))
        !          1000:               (sfilewrite '"   #")
        !          1001:               (sfilewrite (car ll))
        !          1002:               (terpr vp-sfile))
        !          1003:           (setq g-comments nil)
        !          1004:       else (terpr vp-sfile)))
        !          1005: ;--- e-goto :: emit code to jump to the location given
        !          1006: ;
        !          1007: (defun e-goto (lbl)
        !          1008:   (e-jump lbl))
        !          1009: 
        !          1010: ;--- e-gotonil :: emit code to jump if nil was last computed
        !          1011: ;
        !          1012: (defun e-gotonil (lbl)
        !          1013:   (e-write2  'jeql lbl))
        !          1014: 
        !          1015: ;--- e-gotot :: emit code to jump if t was last computed
        !          1016: (defun e-gotot (lbl)
        !          1017:   (e-write2  'jneq lbl))
        !          1018: 
        !          1019: ;--- e-label :: emit a label
        !          1020: (defun e-label (lbl)
        !          1021:   (setq g-skipcode nil)
        !          1022:   (e-writel lbl))
        !          1023: 
        !          1024: ;--- e-move :: move value from one place to anther
        !          1025: ; this corresponds to d-move except the args are EIADRS
        !          1026: ;
        !          1027: (defun e-move (from to)
        !          1028:   (If (equal 0 from) then (e-write2 'clrl to)
        !          1029:                     else (e-write3 'movl from to)))
        !          1030: 
        !          1031: ;--- e-pop :: pop the given number of args from the stack
        !          1032: ; g-locs is not! fixed
        !          1033: ;
        !          1034: (defun e-pop (nargs)
        !          1035:   (If (greaterp nargs 0)
        !          1036:       then (e-dropnp nargs)))
        !          1037: 
        !          1038: 
        !          1039: ;--- e-pushnil :: push a given number of nils on the stack
        !          1040: ;
        !          1041: (defun e-pushnil (nargs)
        !          1042:   (do ((i nargs))
        !          1043:       ((zerop i))
        !          1044:       (If (greaterp i 1) then (e-write2  'clrq np-plus)
        !          1045:                              (setq i (- i 2))
        !          1046:        elseif (equal i 1) then (e-write2 'clrl np-plus)
        !          1047:                                (setq i (1- i)))))
        !          1048: 
        !          1049: ;--- e-tst :: test a value, arg is an EIADR
        !          1050: ;
        !          1051: (defun e-tst (arg)
        !          1052:   (e-write2 'tstl arg))
        !          1053: ;--- e-setupbind :: setup for shallow binding
        !          1054: ;
        !          1055: (defun e-setupbind nil
        !          1056:   (e-write3 'movl '#.Bnp-val '#.bNp-reg))
        !          1057: 
        !          1058: ;--- e-unsetupbind :: restore temp value of bnp to real loc
        !          1059: ;
        !          1060: (defun e-unsetupbind nil
        !          1061:   (e-write3 'movl '#.bNp-reg '#.Bnp-val))
        !          1062: 
        !          1063: ;--- e-shallowbind :: shallow bind value of variable and initialize it
        !          1064: ;      - name : variable name
        !          1065: ;      - val : IADR value for variable
        !          1066: ;
        !          1067: (defun e-shallowbind (name val)
        !          1068:   (let ((vloc (d-loclit name t)))
        !          1069:        (e-write3 'movl (e-cvt vloc) '(+ #.bNp-reg))    ; store old val
        !          1070:        (e-write3 'movl (e-cvt `(lbind ,@(cdr vloc)))
        !          1071:                       '(+ #.bNp-reg))          ; now name
        !          1072:        (d-move val vloc)))             
        !          1073: 
        !          1074: ;--- e-unshallowbind :: un shallow bind n variable from top of stack
        !          1075: ;
        !          1076: (defun e-unshallowbind (n)
        !          1077:   (e-setupbind)                ; set up binding register
        !          1078:   (do ((i 1 (1+ i)))
        !          1079:       ((greaterp i n))
        !          1080:       (e-write3 'movl `(,(* -8 i) ,bNp-reg) `(* ,(+ 4 (* -8 i)) ,bNp-reg)))
        !          1081:   (e-write4 'subl3 `($ ,(* 8 n)) bNp-reg Bnp-val))
        !          1082: 
        !          1083: ;----------- very low level routines
        !          1084: ; all output to the assembler file goes through these routines.
        !          1085: ; They filter out obviously extraneous instructions as well as 
        !          1086: ; combine sequential drops of np.
        !          1087: 
        !          1088: ;--- e-dropnp :: unstack n values from np.
        !          1089: ; rather than output the instruction now, we just remember that it
        !          1090: ; must be done before any other instructions are done.  This will
        !          1091: ; enable us to catch sequential e-dropnp's
        !          1092: ;
        !          1093: (defun e-dropnp (n)
        !          1094:   (If (not g-skipcode)
        !          1095:       then (setq g-dropnpcnt (+ n (If g-dropnpcnt thenret else 0)))))
        !          1096: 
        !          1097: ;--- em-checknpdrop :: check if we have a pending npdrop
        !          1098: ; and do it if so.
        !          1099: ;
        !          1100: (defmacro em-checknpdrop nil
        !          1101:   `(If g-dropnpcnt then (let ((dr g-dropnpcnt))
        !          1102:                             (setq g-dropnpcnt nil)
        !          1103:                             (e-write3 'subl2 `($ ,(* dr 4)) Np-reg))))
        !          1104: 
        !          1105: ;--- em-checkskip :: check if we are skipping this code due to jump
        !          1106: ;
        !          1107: (defmacro em-checkskip nil
        !          1108:   '(If g-skipcode then (sfilewrite "# ")))
        !          1109: 
        !          1110: 
        !          1111: ;--- e-jump :: jump to given label
        !          1112: ; and set g-skipcode so that all code following until the next label
        !          1113: ; will be skipped.
        !          1114: ;
        !          1115: (defun e-jump (l)
        !          1116:   (em-checknpdrop)
        !          1117:   (e-write2 'jbr l)
        !          1118:   (setq g-skipcode t))
        !          1119: 
        !          1120: ;--- e-return :: do return, and dont check for np drop
        !          1121: ;
        !          1122: (defun e-return nil
        !          1123:   (setq g-dropnpcnt nil)  ; we dont need to worry about nps
        !          1124:   (e-write1 'ret))
        !          1125: 
        !          1126: 
        !          1127: ;--- e-writel :: write out a label
        !          1128: ;
        !          1129: (defun e-writel (label)
        !          1130:   (setq g-skipcode nil)
        !          1131:   (em-checknpdrop)
        !          1132:   (sfilewrite label)
        !          1133:   (sfilewrite '":")
        !          1134:   (e-docomment))
        !          1135: 
        !          1136: ;--- e-write1 :: write out one litteral
        !          1137: ;
        !          1138: (defun e-write1 (lit)
        !          1139:   (em-checkskip)
        !          1140:   (em-checknpdrop)
        !          1141:   (sfilewrite lit)
        !          1142:   (e-docomment))
        !          1143: 
        !          1144: ;--- e-write2 :: write one one litteral, and one operand
        !          1145: ;
        !          1146: (defun e-write2 (lit frm)
        !          1147:   (em-checkskip)
        !          1148:   (em-checknpdrop)
        !          1149:   (sfilewrite lit)
        !          1150:   (sfilewrite '"       ")
        !          1151:   (e-cvtas frm)
        !          1152:   (e-docomment))
        !          1153: 
        !          1154: ;--- e-write3 :: write one one litteral, and two operands
        !          1155: ;
        !          1156: (defun e-write3 (lit frm1 frm2)
        !          1157:   (em-checkskip)
        !          1158:   (em-checknpdrop)
        !          1159:   (sfilewrite lit)
        !          1160:   (sfilewrite '"       ")
        !          1161:   (e-cvtas frm1)
        !          1162:   (sfilewrite '",")
        !          1163:   (e-cvtas frm2)
        !          1164:   (e-docomment))
        !          1165: 
        !          1166: ;--- e-write4 :: write one one litteral, and three operands
        !          1167: ;
        !          1168: (defun e-write4 (lit frm1 frm2 frm3)
        !          1169:   (em-checkskip)
        !          1170:   (em-checknpdrop)
        !          1171:   (sfilewrite lit)
        !          1172:   (sfilewrite '"       ")
        !          1173:   (e-cvtas frm1)
        !          1174:   (sfilewrite '",")
        !          1175:   (e-cvtas frm2)
        !          1176:   (sfilewrite '",")
        !          1177:   (e-cvtas frm3)
        !          1178:   (e-docomment))
        !          1179: 
        !          1180: 
        !          1181: ;--- e-write5 :: write one one litteral, and four operands
        !          1182: ;
        !          1183: (defun e-write5 (lit frm1 frm2 frm3 frm4)
        !          1184:   (em-checkskip)
        !          1185:   (em-checknpdrop)
        !          1186:   (sfilewrite lit)
        !          1187:   (sfilewrite '"       ")
        !          1188:   (e-cvtas frm1)
        !          1189:   (sfilewrite '",")
        !          1190:   (e-cvtas frm2)
        !          1191:   (sfilewrite '",")
        !          1192:   (e-cvtas frm3)
        !          1193:   (sfilewrite '",")
        !          1194:   (e-cvtas frm4)
        !          1195:   (e-docomment))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.