Annotation of 43BSDReno/pgrm/lisp/liszt/util.l, revision 1.1

1.1     ! root        1: (include-if (null (get 'chead 'version)) "../chead.l")
        !             2: (Liszt-file util
        !             3:    "$Header: util.l,v 1.15 87/12/15 17:09:21 sklower Exp $")
        !             4: 
        !             5: ;;; ----       u t i l                 general utility functions
        !             6: ;;;
        !             7: ;;;                            -[Tue Aug 16 17:17:32 1983 by layer]-
        !             8: 
        !             9: 
        !            10: ;--- d-handlecc :: handle g-cc
        !            11: ; at this point the Z condition code has been set up and if g-cc is
        !            12: ; non nil, we must jump on condition to the label given in g-cc
        !            13: ;
        !            14: (defun d-handlecc nil
        !            15:    (if (car g-cc)
        !            16:        then (e-gotot (car g-cc))
        !            17:     elseif (cdr g-cc)
        !            18:        then (e-gotonil (cdr g-cc))))
        !            19: 
        !            20: ;--- d-invert :: handle inverted condition codes
        !            21: ; this routine is called if a result has just be computed which alters
        !            22: ; the condition codes such that Z=1 if the result is t, and Z=0 if the
        !            23: ; result is nil (this is the reverse of the usual sense).  The purpose
        !            24: ; of this routine is to handle g-cc and g-loc.  That is if g-loc is 
        !            25: ; specified, we must convert the value of the Z bit of the condition 
        !            26: ; code to t or nil and store that in g-loc.  After handling g-loc we
        !            27: ; must handle g-cc, that is if the part of g-cc is non nil which matches
        !            28: ; the inverse of the current condition code, we must jump to that.
        !            29: ;
        !            30: (defun d-invert nil
        !            31:   (if (null g-loc) 
        !            32:       then (if (car g-cc) then (e-gotonil (car g-cc))
        !            33:            elseif (cdr g-cc) then  (e-gotot (cdr g-cc)))
        !            34:       else (let ((lab1 (d-genlab))
        !            35:                 (lab2 (if (cdr g-cc) thenret else (d-genlab))))
        !            36:                (e-gotonil lab1)
        !            37:                ; Z=1, but remember that this implies nil due to inversion
        !            38:                (d-move 'Nil g-loc)
        !            39:                (e-goto lab2)
        !            40:                (e-label lab1)
        !            41:                ; Z=0, which means t
        !            42:                (d-move 'T g-loc)
        !            43:                (if (car g-cc) then (e-goto (car g-cc)))
        !            44:                (if (null (cdr g-cc)) then (e-label lab2)))))
        !            45:                        
        !            46: ;--- d-noninvert :: handle g-cc and g-loc assuming cc non inverted
        !            47: ; 
        !            48: ; like d-invert except Z=0 implies nil, and Z=1 implies t
        !            49: ;
        !            50: (defun d-noninvert nil
        !            51:   (if (null g-loc) 
        !            52:       then (if (car g-cc) then (e-gotot (car g-cc))
        !            53:            elseif (cdr g-cc) then  (e-gotonil (cdr g-cc)))
        !            54:       else (let ((lab1 (d-genlab))
        !            55:                 (lab2 (if (cdr g-cc) thenret else (d-genlab))))
        !            56:                (e-gotot lab1)
        !            57:                ; Z=0, this implies nil
        !            58:                (d-move 'Nil g-loc)
        !            59:                (e-goto lab2)
        !            60:                (e-label lab1)
        !            61:                ; Z=1, which means t
        !            62:                (d-move 'T g-loc)
        !            63:                (if (car g-cc) then (e-goto (car g-cc)))
        !            64:                (if (null (cdr g-cc)) then (e-label lab2)))))
        !            65: 
        !            66: ;--- d-macroexpand :: macro expand a form as much as possible
        !            67: ;
        !            68: ; only macro expands the top level though.
        !            69: (defun d-macroexpand (i)
        !            70:    (prog (first type)
        !            71:       loop
        !            72:       (if (and (dtpr i) (symbolp (setq first (car i))))
        !            73:         then (if (eq 'macro (setq type (d-functyp first 'macro-ok)))
        !            74:                 then (setq i (apply first i))
        !            75:                      (go loop)
        !            76:               elseif (eq 'cmacro type)
        !            77:                 then (setq i (apply (get first 'cmacro) i))
        !            78:                      (go loop)))
        !            79:       (return i)))
        !            80: 
        !            81: ;--- d-fullmacroexpand :: macro expand down all levels
        !            82: ; this is not always possible to due since it is not always clear
        !            83: ; if a function is a lambda or nlambda, and there are lots of special
        !            84: ; forms.  This is just a first shot at such a function, this should
        !            85: ; be improved upon.
        !            86: ;
        !            87: (defun d-fullmacroexpand (form)
        !            88:    (if (not (dtpr form))
        !            89:        then form
        !            90:        else (setq form (d-macroexpand form))   ; do one level
        !            91:             (if (and (dtpr form) (symbolp (car form)))
        !            92:                then (let ((func (getd (car form))))
        !            93:                          (if (or (and (bcdp func)
        !            94:                                       (eq 'lambda (getdisc func)))
        !            95:                                  (and (dtpr func)
        !            96:                                       (memq (car func) '(lambda lexpr)))
        !            97:                                  (memq (car form) '(or and)))
        !            98:                              then `(,(car form)
        !            99:                                      ,@(mapcar 'd-fullmacroexpand
        !           100:                                                (cdr form)))
        !           101:                            elseif (eq (car form) 'setq)
        !           102:                              then (d-setqexpand form)
        !           103:                            else form))
        !           104:                else form)))
        !           105: 
        !           106: ;--- d-setqexpand :: macro expand a setq statemant
        !           107: ; a setq is unusual in that alternate values are macroexpanded.
        !           108: ;
        !           109: (defun d-setqexpand (form)
        !           110:    (if (oddp (length (cdr form)))
        !           111:        then (comp-err "wrong number of args to setq " form)
        !           112:        else (do ((xx (reverse (cdr form)) (cddr xx))
        !           113:                 (res))
        !           114:                ((null xx) (cons 'setq res))
        !           115:                (setq res `(,(cadr xx)
        !           116:                             ,(d-fullmacroexpand (car xx))
        !           117:                             ,@res)))))
        !           118:    
        !           119: ;--- d-typesimp ::  determine the type of the argument 
        !           120: ;
        !           121: #+(or for-vax for-tahoe)
        !           122: (defun d-typesimp (arg val)
        !           123:   (let ((argloc (d-simple arg)))
        !           124:        (if (null argloc)
        !           125:            then (let ((g-loc 'reg)
        !           126:                       g-cc g-ret)
        !           127:                     (d-exp arg))
        !           128:                 (setq argloc 'reg))
        !           129:        #+for-vax (e-write4 'ashl '$-9 (e-cvt argloc) 'r0)
        !           130:        #+for-tahoe (e-write4 'shar '$9 (e-cvt argloc) 'r0)
        !           131:        (e-write3 'cmpb '"_typetable+1[r0]" val)
        !           132:        (d-invert)))
        !           133: 
        !           134: #+for-68k
        !           135: (defun d-typesimp (arg val)
        !           136:    (let ((argloc (d-simple arg)))
        !           137:        (if (null argloc)
        !           138:           then (let ((g-loc 'reg)
        !           139:                      g-cc g-ret)
        !           140:                    (d-exp arg))
        !           141:                (setq argloc 'reg)
        !           142:           else (e-move (e-cvt argloc) 'd0))
        !           143:        (e-sub '#.nil-reg 'd0)
        !           144:        (e-write3 'moveq '($ 9) 'd1)
        !           145:        (e-write3 'asrl 'd1 'd0)
        !           146:        (e-write3 'lea '"_typetable+1" 'a5)
        !           147:        (e-write3 'cmpb val '(% 0 a5 d0))
        !           148:        (d-invert)))
        !           149: 
        !           150: ;--- d-typecmplx  :: determine if arg has one of many types
        !           151: ;      - arg : lcode argument to be evaluated and checked
        !           152: ;      - vals : fixnum with a bit in position n if we are to check type n
        !           153: ;
        !           154: #+(or for-vax for-tahoe)
        !           155: (defun d-typecmplx (arg vals)
        !           156:   (let ((argloc (d-simple arg))
        !           157:        (reg))
        !           158:        (if (null argloc) then (let ((g-loc 'reg)
        !           159:                                    g-cc g-ret)
        !           160:                                   (d-exp arg))
        !           161:                              (setq argloc 'reg))
        !           162:        (setq reg 'r0)
        !           163:        #+for-vax (e-write4 'ashl '$-9 (e-cvt argloc) reg)
        !           164:        #+for-tahoe (e-write4 'shar '$9 (e-cvt argloc) reg)
        !           165:        (e-write3 'cvtbl (concat "_typetable+1[" reg "]") reg)
        !           166:        (e-write4 #+for-vax 'ashl #+for-tahoe 'shal reg '$1 reg)
        !           167:        (e-write3 'bitw vals reg)
        !           168:        (d-noninvert)))
        !           169: 
        !           170: #+for-68k
        !           171: (defun d-typecmplx (arg vals)
        !           172:    (let ((argloc (d-simple arg))
        !           173:         (l1 (d-genlab))
        !           174:         (l2 (d-genlab)))
        !           175:        (makecomment '(d-typecmplx: type check))
        !           176:        (if (null argloc)
        !           177:           then (let ((g-loc 'reg)
        !           178:                      g-cc g-ret)
        !           179:                    (d-exp arg))
        !           180:                (setq argloc 'reg)
        !           181:           else (e-move (e-cvt argloc) 'd0))
        !           182:        (e-sub '#.nil-reg 'd0)
        !           183:        (e-write3 'moveq '($ 9) 'd1)
        !           184:        (e-write3 'asrl 'd1 'd0)
        !           185:        (e-write3 'lea '"_typetable+1" 'a5)
        !           186:        (e-add 'd0 'a5)
        !           187:        (e-write3 'movb '(0 a5) 'd0)
        !           188:        (e-write2 'extw 'd0)
        !           189:        (e-write2 'extl 'd0)
        !           190:        (e-write3 'moveq '($ 1) 'd1)
        !           191:        (e-write3 'asll 'd0 'd1)
        !           192:        (e-move 'd1 'd0)
        !           193:        (e-write3 'andw vals 'd0)
        !           194:        (d-noninvert)
        !           195:        (makecomment '(d-typecmplx: end))))
        !           196: 
        !           197: ;---- register handling routines.
        !           198: 
        !           199: ;--- d-allocreg :: allocate a register 
        !           200: ;  name - the name of the register to allocate or nil if we should
        !           201: ;        allocate the least recently used.
        !           202: ;
        !           203: (defun d-allocreg (name)
        !           204:   (if name 
        !           205:       then (let ((av (assoc name g-reguse)))
        !           206:                (if av then (rplaca (cdr av) (1+ (cadr av)))) ; inc used count
        !           207:                name)
        !           208:       else ; find smallest used count
        !           209:           (do ((small (car g-reguse))
        !           210:                (smc (cadar g-reguse))
        !           211:                (lis (cdr g-reguse) (cdr lis)))
        !           212:               ((null lis)
        !           213:                (rplaca (cdr small) (1+ smc))
        !           214:                (car small))
        !           215:               (if (< (cadar lis) smc)
        !           216:                   then (setq small (car lis)
        !           217:                              smc   (cadr small))))))
        !           218: 
        !           219: 
        !           220: ;--- d-bestreg :: determine the register which is closest to what we have
        !           221: ;  name - name of variable whose subcontents we want
        !           222: ;  pat  - list of d's and a's which tell which part we want
        !           223: ;
        !           224: (defun d-bestreg (name pat)
        !           225:   (do ((ll g-reguse (cdr ll))
        !           226:        (val)
        !           227:        (best)
        !           228:        (tmp)
        !           229:        (bestv -1))
        !           230:       ((null ll)
        !           231:        (if best
        !           232:           then (rplaca (cdr best) (1+ (cadr best)))
        !           233:                (list (car best)
        !           234:                      (if (> bestv 0) 
        !           235:                          then (rplacd (nthcdr (1- bestv)
        !           236:                                               (setq tmp
        !           237:                                                     (copy pat)))
        !           238:                                       nil)
        !           239:                               tmp
        !           240:                          else nil)
        !           241:                      (nthcdr bestv pat))))
        !           242:       (if (and (setq val (cddar ll))
        !           243:               (eq name (car val)))
        !           244:          then (if (> (setq tmp (d-matchcnt pat (cdr val)))
        !           245:                      bestv)
        !           246:                   then (setq bestv tmp
        !           247:                              best  (car ll))))))
        !           248: 
        !           249: ;--- d-matchcnt :: determine how many parts of a pattern match
        !           250: ; want - pattern we want to achieve
        !           251: ; have - pattern whose value exists in a register
        !           252: ; 
        !           253: ; we return a count of the number of parts of the pattern match.
        !           254: ; If this pattern will be any help at all, we return a value from 
        !           255: ; 0 to the length of the pattern.
        !           256: ; If this pattern will not work at all, we return a number smaller
        !           257: ; than -1.  
        !           258: ; For `have' to be useful for `want', `have' must be a substring of 
        !           259: ; `want'.  If it is a substring, we return the length of `have'.
        !           260: ; 
        !           261: (defun d-matchcnt (want have)
        !           262:   (let ((length 0))
        !           263:        (if (do ((hh have (cdr hh))
        !           264:                (ww want (cdr ww)))
        !           265:               ((null hh) t)
        !           266:               (if (or (null ww) (not (eq (car ww) (car hh))))
        !           267:                   then (return nil)
        !           268:                   else (incr length)))
        !           269:           then  length
        !           270:           else  -2)))
        !           271: 
        !           272: ;--- d-clearreg :: clear all values in registers or just one
        !           273: ; if no args are given, clear all registers.
        !           274: ; if an arg is given, clear that register
        !           275: ;
        !           276: (defun d-clearreg n
        !           277:   (cond ((zerop n) 
        !           278:         (mapc '(lambda (x) (rplaca (cdr x) 0)
        !           279:                     (rplacd (cdr x) nil))
        !           280:               g-reguse))
        !           281:        (t (let ((av (assoc (arg 1) g-reguse)))
        !           282:                (if av
        !           283:                   then
        !           284:                        #+for-68k (d-regused (car av))
        !           285:                        (rplaca (cdr av) 0)
        !           286:                        (rplacd (cdr av) nil)
        !           287:                   else nil)))))
        !           288: 
        !           289: ;--- d-clearuse :: clear all register which reference a given variable
        !           290: ;
        !           291: (defun d-clearuse (varib)
        !           292:   (mapc '(lambda (x)
        !           293:                 (if (eq (caddr x) varib) then (rplacd (cdr x) nil)))
        !           294:        g-reguse))
        !           295: 
        !           296: ;--- d-inreg :: declare that a value is in a register
        !           297: ; name - register name
        !           298: ; value - value in a register
        !           299: ;
        !           300: (defun d-inreg (name value)
        !           301:   (let ((av (assoc name g-reguse)))
        !           302:        (if av then (rplacd (cdr av) value))
        !           303:        name))
        !           304: 
        !           305: (defun e-setup-np-lbot nil
        !           306:    (e-move '#.np-reg '#.np-sym)
        !           307:    (e-move '#.lbot-reg '#.lbot-sym))
        !           308: 
        !           309: ;---------------MC68000 only routines
        !           310: #+for-68k
        !           311: (progn 'compile
        !           312: 
        !           313: ;--- d-regtype :: find out what type of register the operand goes
        !           314: ;                in.
        !           315: ; eiadr - an EIADR
        !           316: ;
        !           317: (defun d-regtype (eiadr)
        !           318:    (if (symbolp eiadr)
        !           319:        then (if (memq eiadr '(d0 d1 d2 d3 d4 d5 d6 d7 reg)) then 'd
        !           320:             elseif (memq eiadr '(a0 a1 a2 a3 a4 a5 a6 a7 sp areg)) then 'a)
        !           321:     elseif (or (eq '\# (car eiadr))
        !           322:               (eq '$ (car eiadr))
        !           323:               (and (eq '* (car eiadr))
        !           324:                    (eq '\# (cadr eiadr))))
        !           325:        then 'd
        !           326:        else 'a))
        !           327: 
        !           328: ;--- d-regused :: declare that a reg is used in a function
        !           329: ;      regname - name of the register that is going to be used
        !           330: ;                (ie, 'd0 'a2...)
        !           331: ;
        !           332: (defun d-regused (regname)
        !           333:    (let ((regnum (diff (cadr (exploden regname)) 48))
        !           334:         (regtype (car (explode regname))))
        !           335:        (if (memq regname '(a0 a1 d0 d1))
        !           336:           thenret
        !           337:        elseif (equal 'd regtype)
        !           338:           then (rplacx regnum g-regmaskvec t) regname
        !           339:           else (rplacx (plus regnum 8) g-regmaskvec t) regname)))
        !           340: 
        !           341: ;--- d-makemask :: make register mask for moveml instr
        !           342: ;
        !           343: (defun d-makemask ()
        !           344:    (do ((ii 0 (1+ ii))
        !           345:        (mask 0))
        !           346:        ((greaterp ii 15) mask)
        !           347:        (if (cxr ii g-regmaskvec)
        !           348:           then (setq mask (plus mask (expt 2 ii))))))
        !           349: 
        !           350: ;--- init-regmaskvec :: initalize hunk structure to all default
        !           351: ;                      save mask.
        !           352: ;
        !           353: ; nil means don't save it, and t means save the register upon function entry.
        !           354: ; order in vector: d0 .. d7, a0 .. a7.
        !           355: ; d3 : lbot (if $global-reg$ is t then save)
        !           356: ; d7 : _nilatom
        !           357: ; a2 : _np
        !           358: ; a3 : literal table ptr
        !           359: ; a4 : old _lbot (if $global-reg$ is t don't save)
        !           360: ; a5 : intermediate address calc
        !           361: ;
        !           362: (defun init-regmaskvec ()
        !           363:    (setq g-regmaskvec
        !           364:         (makhunk
        !           365:             (if $global-reg$
        !           366:                 then (quote (nil nil nil t   nil nil nil t
        !           367:                              nil nil t   t   t   t   nil nil))
        !           368:                 else (quote (nil nil nil nil nil nil nil t
        !           369:                              nil nil t   t   t   t   nil nil))))))
        !           370: 
        !           371: ;--- Cstackspace :: calc local space on C stack
        !           372: ; space = 4 * (no. of register variables saved on stack)
        !           373: ;
        !           374: (defun Cstackspace ()
        !           375:    (do ((ii 0 (1+ ii))
        !           376:        (retval 0))
        !           377:        ((greaterp ii 15) (* 4 retval))
        !           378:        (if (cxr ii g-regmaskvec) then (setq retval (1+ retval)))))
        !           379: 
        !           380: ;--- d-alloc-register :: allocate a register
        !           381: ;  type - type of register (a or d)
        !           382: ;  name - the name of the register to allocate or nil if we should
        !           383: ;        allocate the least recently used.
        !           384: ;
        !           385: (defun d-alloc-register (type name)
        !           386:    (if name 
        !           387:        then (let ((av (assoc name g-reguse)))
        !           388:                (d-regused name)
        !           389:                (if av then (rplaca (cdr av) (1+ (cadr av)))) ; inc used count
        !           390:                name)
        !           391:        else ; find smallest used count
        !           392:            (let ((reguse))
        !           393:                (do ((cur g-reguse (cdr cur)))
        !           394:                    ((null cur))
        !           395:                    (if (eq type (car (explode (caar cur))))
        !           396:                        then (setq reguse (cons (car cur) reguse))))
        !           397:                (do ((small (car reguse))
        !           398:                     (smc (cadar reguse))
        !           399:                     (lis (cdr reguse) (cdr lis)))
        !           400:                    ((null lis)
        !           401:                     (rplaca (cdr small) (1+ smc))
        !           402:                     (d-regused (car small))
        !           403:                     (car small))
        !           404:                    (if (< (cadar lis) smc)
        !           405:                        then (setq small (car lis)
        !           406:                                   smc   (cadr small)))))))
        !           407: 
        !           408: ); end 68000 only routines

unix.superglobalmegacorp.com

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