|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.