Annotation of 42BSD/ucb/lisp/liszt/util.l, revision 1.1.1.1

1.1       root        1: (include-if (null (get 'chead 'version)) "../chead.l")
                      2: (Liszt-file util
                      3:    "$Header: util.l,v 1.14 83/08/28 17:13:11 layer 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: #+for-vax
                    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:        (e-write4 'ashl '$-9 (e-cvt argloc) 'r0)
                    130:        (e-write3 'cmpb '"_typetable+1[r0]" val)
                    131:        (d-invert)))
                    132: 
                    133: #+for-68k
                    134: (defun d-typesimp (arg val)
                    135:    (let ((argloc (d-simple arg)))
                    136:        (if (null argloc)
                    137:           then (let ((g-loc 'reg)
                    138:                      g-cc g-ret)
                    139:                    (d-exp arg))
                    140:                (setq argloc 'reg)
                    141:           else (e-move (e-cvt argloc) 'd0))
                    142:        (e-sub '#.nil-reg 'd0)
                    143:        (e-write3 'moveq '($ 9) 'd1)
                    144:        (e-write3 'asrl 'd1 'd0)
                    145:        (e-write3 'lea '"_typetable+1" 'a5)
                    146:        (e-write3 'cmpb val '(% 0 a5 d0))
                    147:        (d-invert)))
                    148: 
                    149: ;--- d-typecmplx  :: determine if arg has one of many types
                    150: ;      - arg : lcode argument to be evaluated and checked
                    151: ;      - vals : fixnum with a bit in position n if we are to check type n
                    152: ;
                    153: #+for-vax
                    154: (defun d-typecmplx (arg vals)
                    155:   (let ((argloc (d-simple arg))
                    156:        (reg))
                    157:        (if (null argloc) then (let ((g-loc 'reg)
                    158:                                    g-cc g-ret)
                    159:                                   (d-exp arg))
                    160:                              (setq argloc 'reg))
                    161:        (setq reg 'r0)
                    162:        (e-write4 'ashl '$-9 (e-cvt argloc) reg)
                    163:        (e-write3 'cvtbl (concat "_typetable+1[" reg "]") reg)
                    164:        (e-write4 'ashl reg '$1 reg)
                    165:        (e-write3 'bitw vals reg)
                    166:        (d-noninvert)))
                    167: 
                    168: #+for-68k
                    169: (defun d-typecmplx (arg vals)
                    170:    (let ((argloc (d-simple arg))
                    171:         (l1 (d-genlab))
                    172:         (l2 (d-genlab)))
                    173:        (makecomment '(d-typecmplx: type check))
                    174:        (if (null argloc)
                    175:           then (let ((g-loc 'reg)
                    176:                      g-cc g-ret)
                    177:                    (d-exp arg))
                    178:                (setq argloc 'reg)
                    179:           else (e-move (e-cvt argloc) 'd0))
                    180:        (e-sub '#.nil-reg 'd0)
                    181:        (e-write3 'moveq '($ 9) 'd1)
                    182:        (e-write3 'asrl 'd1 'd0)
                    183:        (e-write3 'lea '"_typetable+1" 'a5)
                    184:        (e-add 'd0 'a5)
                    185:        (e-write3 'movb '(0 a5) 'd0)
                    186:        (e-write2 'extw 'd0)
                    187:        (e-write2 'extl 'd0)
                    188:        (e-write3 'moveq '($ 1) 'd1)
                    189:        (e-write3 'asll 'd0 'd1)
                    190:        (e-move 'd1 'd0)
                    191:        (e-write3 'andw vals 'd0)
                    192:        (d-noninvert)
                    193:        (makecomment '(d-typecmplx: end))))
                    194: 
                    195: ;---- register handling routines.
                    196: 
                    197: ;--- d-allocreg :: allocate a register 
                    198: ;  name - the name of the register to allocate or nil if we should
                    199: ;        allocate the least recently used.
                    200: ;
                    201: (defun d-allocreg (name)
                    202:   (if name 
                    203:       then (let ((av (assoc name g-reguse)))
                    204:                (if av then (rplaca (cdr av) (1+ (cadr av)))) ; inc used count
                    205:                name)
                    206:       else ; find smallest used count
                    207:           (do ((small (car g-reguse))
                    208:                (smc (cadar g-reguse))
                    209:                (lis (cdr g-reguse) (cdr lis)))
                    210:               ((null lis)
                    211:                (rplaca (cdr small) (1+ smc))
                    212:                (car small))
                    213:               (if (< (cadar lis) smc)
                    214:                   then (setq small (car lis)
                    215:                              smc   (cadr small))))))
                    216: 
                    217: 
                    218: ;--- d-bestreg :: determine the register which is closest to what we have
                    219: ;  name - name of variable whose subcontents we want
                    220: ;  pat  - list of d's and a's which tell which part we want
                    221: ;
                    222: (defun d-bestreg (name pat)
                    223:   (do ((ll g-reguse (cdr ll))
                    224:        (val)
                    225:        (best)
                    226:        (tmp)
                    227:        (bestv -1))
                    228:       ((null ll)
                    229:        (if best
                    230:           then (rplaca (cdr best) (1+ (cadr best)))
                    231:                (list (car best)
                    232:                      (if (> bestv 0) 
                    233:                          then (rplacd (nthcdr (1- bestv)
                    234:                                               (setq tmp
                    235:                                                     (copy pat)))
                    236:                                       nil)
                    237:                               tmp
                    238:                          else nil)
                    239:                      (nthcdr bestv pat))))
                    240:       (if (and (setq val (cddar ll))
                    241:               (eq name (car val)))
                    242:          then (if (> (setq tmp (d-matchcnt pat (cdr val)))
                    243:                      bestv)
                    244:                   then (setq bestv tmp
                    245:                              best  (car ll))))))
                    246: 
                    247: ;--- d-matchcnt :: determine how many parts of a pattern match
                    248: ; want - pattern we want to achieve
                    249: ; have - pattern whose value exists in a register
                    250: ; 
                    251: ; we return a count of the number of parts of the pattern match.
                    252: ; If this pattern will be any help at all, we return a value from 
                    253: ; 0 to the length of the pattern.
                    254: ; If this pattern will not work at all, we return a number smaller
                    255: ; than -1.  
                    256: ; For `have' to be useful for `want', `have' must be a substring of 
                    257: ; `want'.  If it is a substring, we return the length of `have'.
                    258: ; 
                    259: (defun d-matchcnt (want have)
                    260:   (let ((length 0))
                    261:        (if (do ((hh have (cdr hh))
                    262:                (ww want (cdr ww)))
                    263:               ((null hh) t)
                    264:               (if (or (null ww) (not (eq (car ww) (car hh))))
                    265:                   then (return nil)
                    266:                   else (incr length)))
                    267:           then  length
                    268:           else  -2)))
                    269: 
                    270: ;--- d-clearreg :: clear all values in registers or just one
                    271: ; if no args are given, clear all registers.
                    272: ; if an arg is given, clear that register
                    273: ;
                    274: (defun d-clearreg n
                    275:   (cond ((zerop n) 
                    276:         (mapc '(lambda (x) (rplaca (cdr x) 0)
                    277:                     (rplacd (cdr x) nil))
                    278:               g-reguse))
                    279:        (t (let ((av (assoc (arg 1) g-reguse)))
                    280:                (if av
                    281:                   then
                    282:                        #+for-68k (d-regused (car av))
                    283:                        (rplaca (cdr av) 0)
                    284:                        (rplacd (cdr av) nil)
                    285:                   else nil)))))
                    286: 
                    287: ;--- d-clearuse :: clear all register which reference a given variable
                    288: ;
                    289: (defun d-clearuse (varib)
                    290:   (mapc '(lambda (x)
                    291:                 (if (eq (caddr x) varib) then (rplacd (cdr x) nil)))
                    292:        g-reguse))
                    293: 
                    294: ;--- d-inreg :: declare that a value is in a register
                    295: ; name - register name
                    296: ; value - value in a register
                    297: ;
                    298: (defun d-inreg (name value)
                    299:   (let ((av (assoc name g-reguse)))
                    300:        (if av then (rplacd (cdr av) value))
                    301:        name))
                    302: 
                    303: (defun e-setup-np-lbot nil
                    304:    (e-move '#.np-reg '#.np-sym)
                    305:    (e-move '#.lbot-reg '#.lbot-sym))
                    306: 
                    307: ;---------------MC68000 only routines
                    308: #+for-68k
                    309: (progn 'compile
                    310: 
                    311: ;--- d-regtype :: find out what type of register the operand goes
                    312: ;                in.
                    313: ; eiadr - an EIADR
                    314: ;
                    315: (defun d-regtype (eiadr)
                    316:    (if (symbolp eiadr)
                    317:        then (if (memq eiadr '(d0 d1 d2 d3 d4 d5 d6 d7 reg)) then 'd
                    318:             elseif (memq eiadr '(a0 a1 a2 a3 a4 a5 a6 a7 sp areg)) then 'a)
                    319:     elseif (or (eq '\# (car eiadr))
                    320:               (eq '$ (car eiadr))
                    321:               (and (eq '* (car eiadr))
                    322:                    (eq '\# (cadr eiadr))))
                    323:        then 'd
                    324:        else 'a))
                    325: 
                    326: ;--- d-regused :: declare that a reg is used in a function
                    327: ;      regname - name of the register that is going to be used
                    328: ;                (ie, 'd0 'a2...)
                    329: ;
                    330: (defun d-regused (regname)
                    331:    (let ((regnum (diff (cadr (exploden regname)) 48))
                    332:         (regtype (car (explode regname))))
                    333:        (if (memq regname '(a0 a1 d0 d1))
                    334:           thenret
                    335:        elseif (equal 'd regtype)
                    336:           then (rplacx regnum g-regmaskvec t) regname
                    337:           else (rplacx (plus regnum 8) g-regmaskvec t) regname)))
                    338: 
                    339: ;--- d-makemask :: make register mask for moveml instr
                    340: ;
                    341: (defun d-makemask ()
                    342:    (do ((ii 0 (1+ ii))
                    343:        (mask 0))
                    344:        ((greaterp ii 15) mask)
                    345:        (if (cxr ii g-regmaskvec)
                    346:           then (setq mask (plus mask (expt 2 ii))))))
                    347: 
                    348: ;--- init-regmaskvec :: initalize hunk structure to all default
                    349: ;                      save mask.
                    350: ;
                    351: ; nil means don't save it, and t means save the register upon function entry.
                    352: ; order in vector: d0 .. d7, a0 .. a7.
                    353: ; d3 : lbot (if $global-reg$ is t then save)
                    354: ; d7 : _nilatom
                    355: ; a2 : _np
                    356: ; a3 : literal table ptr
                    357: ; a4 : old _lbot (if $global-reg$ is t don't save)
                    358: ; a5 : intermediate address calc
                    359: ;
                    360: (defun init-regmaskvec ()
                    361:    (setq g-regmaskvec
                    362:         (makhunk
                    363:             (if $global-reg$
                    364:                 then (quote (nil nil nil t   nil nil nil t
                    365:                              nil nil t   t   t   t   nil nil))
                    366:                 else (quote (nil nil nil nil nil nil nil t
                    367:                              nil nil t   t   t   t   nil nil))))))
                    368: 
                    369: ;--- Cstackspace :: calc local space on C stack
                    370: ; space = 4 * (no. of register variables saved on stack)
                    371: ;
                    372: (defun Cstackspace ()
                    373:    (do ((ii 0 (1+ ii))
                    374:        (retval 0))
                    375:        ((greaterp ii 15) (* 4 retval))
                    376:        (if (cxr ii g-regmaskvec) then (setq retval (1+ retval)))))
                    377: 
                    378: ;--- d-alloc-register :: allocate a register
                    379: ;  type - type of register (a or d)
                    380: ;  name - the name of the register to allocate or nil if we should
                    381: ;        allocate the least recently used.
                    382: ;
                    383: (defun d-alloc-register (type name)
                    384:    (if name 
                    385:        then (let ((av (assoc name g-reguse)))
                    386:                (d-regused name)
                    387:                (if av then (rplaca (cdr av) (1+ (cadr av)))) ; inc used count
                    388:                name)
                    389:        else ; find smallest used count
                    390:            (let ((reguse))
                    391:                (do ((cur g-reguse (cdr cur)))
                    392:                    ((null cur))
                    393:                    (if (eq type (car (explode (caar cur))))
                    394:                        then (setq reguse (cons (car cur) reguse))))
                    395:                (do ((small (car reguse))
                    396:                     (smc (cadar reguse))
                    397:                     (lis (cdr reguse) (cdr lis)))
                    398:                    ((null lis)
                    399:                     (rplaca (cdr small) (1+ smc))
                    400:                     (d-regused (car small))
                    401:                     (car small))
                    402:                    (if (< (cadar lis) smc)
                    403:                        then (setq small (car lis)
                    404:                                   smc   (cadr small)))))))
                    405: 
                    406: ); 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.