|
|
1.1 ! root 1: (include-if (null (get 'chead 'version)) "../chead.l") ! 2: (Liszt-file vector ! 3: "$Header: vector.l,v 1.12 87/12/15 17:10:04 sklower Exp $") ! 4: ! 5: ;;; ---- v e c t o r vector referencing ! 6: ;;; ! 7: ;;; -[Fri Nov 11 22:35:50 1983 by jkf]- ! 8: ! 9: ! 10: (defun cc-vset () ! 11: ;; Set a vector created via 'vector'. ! 12: (d-vset 'lisp)) ! 13: ! 14: (defun cc-vref () ! 15: ;; Reference a vector created via 'vector'. ! 16: (d-vref 'lisp)) ! 17: ! 18: (defun cc-vseti-byte () ! 19: ;; Set a vector created via 'vectori-byte'. ! 20: (d-vset 'byte)) ! 21: ! 22: (defun cc-vrefi-byte () ! 23: ;; Reference a vector created via 'vectori-byte'. ! 24: (d-vref 'byte)) ! 25: ! 26: (defun cc-vseti-word () ! 27: ;; Set a vector created via 'vectori-word'. ! 28: (d-vset 'word)) ! 29: ! 30: (defun cc-vrefi-word () ! 31: ;; Reference a vector created via 'vectori-word'. ! 32: (d-vref 'word)) ! 33: ! 34: (defun cc-vseti-long () ! 35: ;; Set a vector created via 'vectori-long'. ! 36: (d-vset 'long)) ! 37: ! 38: (defun cc-vrefi-long () ! 39: ;; Reference a vector created via 'vectori-long'. ! 40: (d-vref 'long)) ! 41: ! 42: ;--- d-vset :: handle all types of vset's ! 43: (defun d-vset (type) ! 44: ;; Generic vector store. Type is either 'lisp', 'byte', 'word', ! 45: ;; or 'long'. ! 46: (let ((vect (cadr v-form)) ! 47: (index (caddr v-form)) ! 48: (val (cadddr v-form)) ! 49: (vect-addr) (index-addr) ! 50: (vect-val) (fetchval) ! 51: (temp) (size) ! 52: (vec-reg #+(or for-vax for-tahoe) 'r0 #+for-68k 'a0) ! 53: (val-reg #+(or for-vax for-tahoe) 'r1 #+for-68k 'd1) ! 54: (index-reg '#.fixnum-reg) ! 55: (temp-reg #+(or for-vax for-tahoe) 'r4 #+for-68k 'd0) ! 56: (temp-areg #+(or for-vax for-tahoe) 'bogus! #+for-68k 'a1) ! 57: (oklab (d-genlab)) ! 58: (needlowcheck t)) ; t if must check lower index bounds ! 59: ! 60: #+for-68k (d-regused '#.fixnum-reg) ! 61: (makecomment `(doing vec set type ,type)) ! 62: (if (fixp index) ! 63: then (if (<& index 0) ! 64: then (comp-err "vector index less than 0 " v-form)) ! 65: (setq needlowcheck nil)) ! 66: ! 67: ; Compute the value to be stored... ! 68: ; ! 69: ; If we are doing an immediate vector, then get the value ! 70: ; instead of the boxed fixnum (in the case of byte), or ! 71: ; word/long. ! 72: (if (null (eq 'lisp type)) then (setq val `(cdr ,val))) ! 73: ! 74: (if (null (setq vect-val (d-simple val))) ! 75: then (let ((g-loc val-reg) g-cc g-ret) ! 76: (d-exp val)) ! 77: (setq vect-val val-reg) ! 78: else (setq vect-val (e-cvt vect-val))) ! 79: ! 80: ; make sure that we are not going to clobber val-reg... ! 81: (if (not (and (d-simple vect) (d-simple index))) ! 82: then ; val-reg could be clobbered when we do the ! 83: ; fetching of the vector or index values ! 84: (setq fetchval t) ! 85: (e-move vect-val (e-cvt 'stack))) ! 86: ! 87: ; Compute the index... ! 88: ; ! 89: (if (setq index-addr (d-simple index)) ! 90: then (let ((g-loc vec-reg) g-cc g-ret) ! 91: (d-exp vect)) ! 92: (setq vect-addr vec-reg) ; the vector op is in vec-reg ! 93: ; we really want the cdr of index (the actual number). ! 94: ; if we can do that simply, great. otherwise we ! 95: ; bring the index into index-reg and then do the cdr ourselves ! 96: (if (setq temp (d-simple `(cdr ,index))) ! 97: then (d-move temp index-reg) ! 98: else (d-move index-addr index-reg) ! 99: #+(or for-vax for-tahoe) ! 100: (e-move `(0 ,index-reg) index-reg) ! 101: #+for-68k ! 102: (progn ! 103: (e-move index-reg 'a5) ! 104: (e-move '(0 a5) index-reg))) ! 105: (setq index-addr index-reg) ! 106: else ; the index isn't computable simply, so we must ! 107: ; stack the vector location to keep it safe ! 108: (let ((g-loc 'stack) g-cc g-ret) ! 109: (d-exp vect)) ! 110: (push nil g-locs) ! 111: (incr g-loccnt) ! 112: ; compute index's value into index-reg ! 113: (d-fixnumexp index) ! 114: ; now put vector address into vec-reg ! 115: (d-move 'unstack vec-reg) ! 116: (decr g-loccnt) ! 117: (pop g-locs) ! 118: (setq vect-addr vec-reg ! 119: index-addr index-reg) ! 120: ; must be sure that the cc's reflect the value of index-reg ! 121: (e-tst index-reg)) ! 122: ! 123: ; At this point, vect-addr (always vec-reg) contains the location of ! 124: ; the start of the vector, index-addr (always index-reg) contains ! 125: ; the index value. ! 126: ; The condition codes reflect the value of the index. ! 127: ; First we insure that the index is non negative ! 128: ; test must use a jmp in case the object file is large ! 129: ; ! 130: (if needlowcheck ! 131: then (e-write2 #+(or for-vax for-tahoe) 'jgeq #+for-68k 'jpl oklab) ! 132: (e-write2 'jmp 'vecindexerr) ! 133: (e-label oklab) ! 134: (setq oklab (d-genlab))) ! 135: ;; now, we compare against the size of the vector ! 136: ;; the size of the vector is in bytes, we may want to shift this ! 137: ;; to reflect the size in words or longwords, depending on the ! 138: ;; type of reference ! 139: (if (eq type 'byte) ! 140: then ; can compare right away ! 141: (e-cmp index-addr `(-8 ,vect-addr)) ! 142: else ; shift size into temp-reg ! 143: (setq size (if (eq type 'word) then 1 else 2)) ! 144: #+for-vax ! 145: (e-write4 'ashl (concat '$- size) ! 146: `(-8 ,vect-addr) temp-reg) ! 147: #+for-tahoe ! 148: (e-write4 'shar (concat '$ size) ! 149: `(-8 ,vect-addr) temp-reg) ! 150: #+for-68k ! 151: (progn ! 152: (e-move `(-8 ,vect-addr) temp-reg) ! 153: (e-write3 'asrl `($ ,size) temp-reg)) ! 154: (e-cmp index-addr temp-reg) ! 155: (d-clearreg temp-reg)) ! 156: ;; size is the number of objects, the index is 0 based so ! 157: ;; it must be less than the vector size ! 158: (e-write2 #+(or for-vax for-tahoe) 'jlss #+for-68k 'jmi oklab) ! 159: (e-write2 'jmp 'vecindexerr) ! 160: (e-label oklab) ! 161: ! 162: (if fetchval ! 163: then ; unstack the value to store... ! 164: (e-move (e-cvt 'unstack) val-reg) ! 165: (setq vect-val val-reg)) ! 166: ! 167: ;; if we get here then the access is in bounds ! 168: (if (eq type 'lisp) ! 169: then #+(or for-vax for-tahoe) ! 170: (e-move vect-val `(0 ,vect-addr ,index-addr)) ! 171: #+for-68k ! 172: (progn ! 173: (e-move index-addr temp-reg) ! 174: (e-write3 'asll '($ 2) temp-reg) ! 175: (e-add vect-addr temp-reg) ! 176: (e-move temp-reg temp-areg) ! 177: (e-move vect-val `(0 ,temp-areg))) ! 178: (if g-loc (e-move vect-val (e-cvt g-loc))) ! 179: (if g-cc then (d-handlecc)) ! 180: else (setq temp (cadr (assq type '((byte movb) ! 181: (word movw) ! 182: (long movl))))) ! 183: #+(or for-vax for-tahoe) ! 184: (e-write3 temp vect-val `(0 ,vect-addr ,index-addr)) ! 185: #+for-68k ! 186: (progn ! 187: (e-move index-addr temp-reg) ! 188: (caseq type ! 189: (word (e-write3 'asll '($ 1) temp-reg)) ! 190: (long (e-write3 'asll '($ 2) temp-reg))) ! 191: (e-write3 'lea `(% 0 ,vec-reg ,temp-reg) temp-areg) ! 192: (if (eq type 'long) ! 193: then (e-write3 temp vect-val `(0 ,temp-areg)) ! 194: else (e-move vect-val 'd1) ! 195: (e-write3 temp 'd1 `(0 ,temp-areg)))) ! 196: (if g-loc ! 197: then (if (eq type 'byte) ! 198: then ; all bytes values are within the fixnum ! 199: ; range, we convert them to immediate ! 200: ; fixum with ease. ! 201: #+for-vax ! 202: (progn ! 203: (e-write4 'ashl '($ 2) ! 204: index-reg index-reg) ! 205: (e-write3 'movab ! 206: `(5120 ,index-reg) ! 207: (e-cvt g-loc))) ! 208: #+for-tahoe ! 209: (progn ! 210: (e-write4 'shal '($ 2) ! 211: index-reg index-reg) ! 212: (e-write3 'movab ! 213: `(5120 ,index-reg) ! 214: (e-cvt g-loc))) ! 215: #+for-68k ! 216: (progn ! 217: (e-move index-reg temp-reg) ! 218: (e-write3 'asll '($ 2) temp-reg) ! 219: (e-move temp-reg temp-areg) ! 220: (e-move ! 221: (e-cvt '(fixnum 0)) ! 222: temp-reg) ! 223: (e-write3 'lea ! 224: `(% 0 ,temp-areg ,temp-reg) ! 225: temp-areg) ! 226: (e-move ! 227: temp-areg ! 228: (e-cvt g-loc))) ! 229: else ; must convert the hard way ! 230: (e-call-qnewint) ! 231: (d-clearreg) ! 232: (if (not (eq g-loc 'reg)) ! 233: then (d-move 'reg g-loc))) ! 234: ; result is always non nil ! 235: (if (car g-cc) then (e-goto (car g-cc))) ! 236: elseif (car g-cc) then (e-goto (car g-cc)))) ! 237: (d-vectorindexcode))) ! 238: ! 239: ;--- d-vref :: handle all types of vref's ! 240: (defun d-vref (type) ! 241: ;; Generic vector reference. Type is either 'lisp', 'byte', 'word', ! 242: ;; or 'long'. ! 243: (let ((vect (cadr v-form)) ! 244: (index (caddr v-form)) ! 245: (vect-addr) (index-addr) (temp) (size) ! 246: (vec-reg #+(or for-vax for-tahoe) 'r0 #+for-68k 'a0) ! 247: (index-reg '#.fixnum-reg) ! 248: (temp-reg #+(or for-vax for-tahoe) 'r4 #+for-68k 'd0) ! 249: (temp-areg #+(or for-vax for-tahoe) 'rX #+for-68k 'a1) ! 250: (oklab (d-genlab)) ! 251: (needlowcheck t)) ; t if must check lower index bounds ! 252: ! 253: #+for-68k (d-regused '#.fixnum-reg) ! 254: (makecomment `(doing vec ref type ,type)) ! 255: (if (fixp index) ! 256: then (if (<& index 0) ! 257: then (comp-err "vector index less than 0 " v-form)) ! 258: (setq needlowcheck nil)) ! 259: ! 260: (if (setq index-addr (d-simple index)) ! 261: then (let ((g-loc vec-reg) g-cc g-ret) ! 262: (d-exp vect)) ! 263: (setq vect-addr vec-reg) ; the vector op is in vec-reg ! 264: ; we really want the cdr of index (the actual number). ! 265: ; if we can do that simply, great. otherwise we ! 266: ; bring the index into index-reg and then do the cdr ourselves ! 267: (if (setq temp (d-simple `(cdr ,index))) ! 268: then (d-move temp index-reg) ! 269: else (d-move index-addr index-reg) ! 270: #+(or for-vax for-tahoe) ! 271: (e-move `(0 ,index-reg) index-reg) ! 272: #+for-68k ! 273: (progn ! 274: (e-move index-reg 'a5) ! 275: (e-move '(0 a5) index-reg))) ! 276: (setq index-addr index-reg) ! 277: else ; the index isn't computable simply, so we must ! 278: ; stack the vector location to keep it safe ! 279: (let ((g-loc 'stack) g-cc g-ret) ! 280: (d-exp vect)) ! 281: (push nil g-locs) ! 282: (incr g-loccnt) ! 283: ; compute index's value into index-reg ! 284: (d-fixnumexp index) ! 285: ; now put vector address into vec-reg ! 286: (d-move 'unstack vec-reg) ! 287: (decr g-loccnt) ! 288: (pop g-locs) ! 289: (setq vect-addr vec-reg ! 290: index-addr index-reg) ! 291: ; must be sure that the cc's reflect the value of index-reg ! 292: (e-tst index-reg)) ! 293: ! 294: ; at this point, vect-addr (always vec-reg) contains the location of ! 295: ; the start of the vector, index-addr (always index-reg) contains ! 296: ; the index value. the condition codes reflect the value of ! 297: ; the index ! 298: ; First we insure that the index is non negative ! 299: ; test must use a jmp in case the object file is large ! 300: (if needlowcheck ! 301: then (e-write2 #+(or for-vax for-tahoe) 'jgeq #+for-68k 'jpl oklab) ! 302: (e-write2 'jmp 'vecindexerr) ! 303: (e-label oklab) ! 304: (setq oklab (d-genlab))) ! 305: ! 306: ; now, we compare against the size of the vector ! 307: ; the size of the vector is in bytes, we may want to shift this ! 308: ; to reflect the size in words or longwords, depending on the ! 309: ; type of reference ! 310: (if (eq type 'byte) ! 311: then ; can compare right away ! 312: (e-cmp index-addr `(-8 ,vect-addr)) ! 313: else ; shift size into temp-reg ! 314: (setq size (if (eq type 'word) then 1 else 2)) ! 315: #+for-vax ! 316: (e-write4 'ashl (concat '$- size) `(-8 ,vect-addr) temp-reg) ! 317: #+for-tahoe ! 318: (e-write4 'shar (concat '$ size) `(-8 ,vect-addr) temp-reg) ! 319: #+for-68k ! 320: (progn ! 321: (e-move `(-8 ,vect-addr) temp-reg) ! 322: (e-write3 'asrl `($ ,size) temp-reg)) ! 323: (e-cmp index-addr temp-reg) ! 324: (d-clearreg temp-reg)) ! 325: ; size is the number of objects, the index is 0 based so ! 326: ; it must be less than the vector size ! 327: (e-write2 #+(or for-vax for-tahoe) 'jlss #+for-68k 'jmi oklab) ! 328: (e-write2 'jmp 'vecindexerr) ! 329: (e-label oklab) ! 330: ! 331: ;; if we get here then the access is in bounds ! 332: (if g-loc ! 333: then ; we care about the value. ! 334: ; if the value is one of the fixnum types, then we ! 335: ; move the value to index-reg so it can be fixnum converted ! 336: (if (eq type 'lisp) ! 337: then #+(or for-vax for-tahoe) ! 338: (e-move `(0 ,vect-addr ,index-addr) ! 339: (e-cvt g-loc)) ! 340: #+for-68k ! 341: (progn ! 342: (e-move index-addr temp-reg) ! 343: (e-write3 'asll '($ 2) temp-reg) ! 344: (e-add vect-addr temp-reg) ! 345: (e-move temp-reg temp-areg) ! 346: (e-move `(0 ,temp-areg) (e-cvt g-loc))) ! 347: (if g-cc then (d-handlecc)) ! 348: else #+(or for-vax for-tahoe) ! 349: (progn ! 350: (setq temp (cadr (assq type '((byte cvtbl) ! 351: (word cvtwl) ! 352: (long movl))))) ! 353: (e-write3 temp ! 354: `(0 ,vect-addr ,index-addr) ! 355: index-reg)) ! 356: #+for-68k ! 357: (progn ! 358: (setq temp ! 359: (cadr (assq type '((byte movb) ! 360: (word movw) ! 361: (long movl))))) ! 362: (caseq type ! 363: (word (e-write3 'asll '($ 1) index-reg)) ! 364: (long (e-write3 'asll '($ 2) index-reg))) ! 365: (e-write3 'lea `(% 0 ,vec-reg ,index-reg) ! 366: temp-areg) ! 367: (if (memq type '(byte word)) ! 368: then (e-write2 'clrl index-reg)) ! 369: (e-write3 temp `(0 ,temp-areg) index-reg)) ! 370: (if (eq type 'byte) ! 371: then ; all bytes values are within the fixnum ! 372: ; range, we convert them to immediate ! 373: ; fixum with ease. ! 374: #+for-vax ! 375: (progn ! 376: (e-write4 'ashl '($ 2) ! 377: index-reg index-reg) ! 378: (e-write3 'movab ! 379: `(5120 ,index-reg) ! 380: (e-cvt g-loc))) ! 381: #+for-tahoe ! 382: (progn ! 383: (e-write4 'shal '($ 2) ! 384: index-reg index-reg) ! 385: (e-write3 'movab ! 386: `(5120 ,index-reg) ! 387: (e-cvt g-loc))) ! 388: #+for-68k ! 389: (progn ! 390: (e-write3 'asll '($ 2) index-reg) ! 391: (e-move index-reg temp-areg) ! 392: (e-move ! 393: '($ _nilatom+0x1400) ! 394: temp-reg) ! 395: (e-write3 'lea ! 396: `(% 0 ,temp-areg ,temp-reg) ! 397: temp-areg) ! 398: (e-move ! 399: temp-areg ! 400: (e-cvt g-loc))) ! 401: else ; must convert the hard way ! 402: (e-call-qnewint) ! 403: (d-clearreg) ! 404: (if (not (eq g-loc 'reg)) ! 405: then (d-move 'reg g-loc))) ! 406: ; result is always non nil ! 407: (if (car g-cc) then (e-goto (car g-cc)))) ! 408: elseif g-cc ! 409: ; we dont care about the value, just whether it nil ! 410: then (if (eq type 'lisp) ! 411: then #+(or for-vax for-tahoe) ! 412: (e-tst `(0 ,vect-addr ,index-addr)) ! 413: #+for-68k ! 414: (progn ! 415: (e-move index-addr temp-reg) ! 416: (e-write3 'asll '($ 2) temp-reg) ! 417: (e-add vect-addr temp-reg) ! 418: (e-move temp-reg temp-areg) ! 419: (e-cmpnil `(0 ,temp-areg))) ! 420: (d-handlecc) ! 421: else ; if fixnum, then it is always true ! 422: (if (car g-cc) then (e-goto (car g-cc))))) ! 423: (d-vectorindexcode))) ! 424: ! 425: ;--- d-vectorindexcode :: put out code to call the vector range error. ! 426: ; At this point the vector is in r0, the index an immediate fixnum in r5 ! 427: ; we call the function int:vector-range-error with two arguments, the ! 428: ; vector and the index. ! 429: ; ! 430: (defun d-vectorindexcode () ! 431: (if (null g-didvectorcode) ! 432: then (let ((afterlab (d-genlab))) ! 433: (e-goto afterlab) ! 434: (e-label 'vecindexerr) ! 435: (d-move #+(or for-vax for-tahoe) 'r0 #+for-68k 'a0 'stack) ! 436: (e-call-qnewint) ! 437: (d-move 'reg 'stack) ! 438: (d-calltran 'int:vector-range-error 2) ! 439: ; never returns ! 440: (e-label afterlab)) ! 441: (setq g-didvectorcode t))) ! 442: ! 443: ! 444: ;------------------------ vector access functions ! 445: ! 446: ;--- cc-vectorp :: check for vectorness ! 447: ; ! 448: (defun cc-vectorp nil ! 449: (d-typesimp (cadr v-form) #.(immed-const 18))) ! 450: ! 451: ;--- cc-vectorip :: check for vectoriness ! 452: ; ! 453: (defun cc-vectorip nil ! 454: (d-typesimp (cadr v-form) #.(immed-const 19))) ! 455: ! 456: ;--- c-vsize :: extract vsize ! 457: ; ! 458: (defun c-vsize nil ! 459: (d-vectorsize (cadr v-form) '2)) ! 460: ! 461: (defun c-vsize-byte nil ! 462: (d-vectorsize (cadr v-form) '0)) ! 463: ! 464: (defun c-vsize-word nil ! 465: (d-vectorsize (cadr v-form) '1)) ! 466: ! 467: (defun d-vectorsize (form shift) ! 468: (let ((g-loc #+(or for-vax for-tahoe) 'reg #+for-68k 'a0) ! 469: g-cc ! 470: g-ret) ! 471: (d-exp form)) ! 472: ; get size into `fixnum-reg' for fixnum boxing ! 473: (if (zerop shift) ! 474: then (e-move '(-8 #+(or for-vax for-tahoe) r0 #+for-68k a0) '#.fixnum-reg) ! 475: else #+for-vax ! 476: (e-write4 'ashl (concat '$- shift) '(-8 r0) '#.fixnum-reg) ! 477: #+for-tahoe ! 478: (e-write4 'shar (concat '$ shift) '(-8 r0) '#.fixnum-reg) ! 479: #+for-68k ! 480: (progn ! 481: (e-move '(-8 a0) '#.fixnum-reg) ! 482: (e-write3 'asrl `($ ,shift) '#.fixnum-reg))) ! 483: (e-call-qnewint))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.