Annotation of 42BSD/ucb/lisp/liszt/vector.l, revision 1.1

1.1     ! root        1: (include-if (null (get 'chead 'version)) "../chead.l")
        !             2: (Liszt-file vector
        !             3:    "$Header: vector.l,v 1.9 83/09/01 12:06:02 sklower Exp $")
        !             4: 
        !             5: ;;; ----       v e c t o r                     vector referencing
        !             6: ;;;
        !             7: ;;;                            -[Thu Aug 11 18:29:32 1983 by layer]-
        !             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 #+for-vax 'r0 #+for-68k 'a0)
        !            53:         (val-reg #+for-vax 'r1 #+for-68k 'd1)
        !            54:         (index-reg '#.fixnum-reg)
        !            55:         (temp-reg #+for-vax 'r4 #+for-68k 'd0)
        !            56:         (temp-areg #+for-vax '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:                         #+for-vax
        !           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 #+for-vax '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-68k
        !           148:                (progn
        !           149:                    (e-move `(-8 ,vect-addr) temp-reg)
        !           150:                    (e-write3 'asrl `($ ,size) temp-reg))
        !           151:                (e-cmp index-addr temp-reg)
        !           152:                (d-clearreg temp-reg))
        !           153:        ;; size is the number of objects, the index is 0 based so
        !           154:        ;; it must be less than the vector size
        !           155:        (e-write2 #+for-vax 'jlss #+for-68k 'jmi oklab)
        !           156:        (e-write2 'jmp 'vecindexerr)
        !           157:        (e-label oklab)
        !           158: 
        !           159:        (if fetchval
        !           160:           then ; unstack the value to store...
        !           161:                (e-move (e-cvt 'unstack) val-reg)
        !           162:                (setq vect-val val-reg))
        !           163: 
        !           164:        ;; if we get here then the access is in bounds
        !           165:        (if (eq type 'lisp)
        !           166:           then #+for-vax
        !           167:                (e-move vect-val `(0 ,vect-addr ,index-addr))
        !           168:                #+for-68k
        !           169:                (progn
        !           170:                    (e-move index-addr temp-reg)
        !           171:                    (e-write3 'asll '($ 2) temp-reg)
        !           172:                    (e-add vect-addr temp-reg)
        !           173:                    (e-move temp-reg temp-areg)
        !           174:                    (e-move vect-val `(0 ,temp-areg)))
        !           175:                (if g-loc (e-move vect-val (e-cvt g-loc)))
        !           176:                (if g-cc then (d-handlecc))
        !           177:           else (setq temp (cadr (assq type '((byte movb)
        !           178:                                              (word movw)
        !           179:                                              (long movl)))))
        !           180:                #+for-vax
        !           181:                (e-write3 temp vect-val `(0 ,vect-addr ,index-addr))
        !           182:                #+for-68k
        !           183:                (progn
        !           184:                    (e-move index-addr temp-reg)
        !           185:                    (caseq type
        !           186:                        (word (e-write3 'asll '($ 1) temp-reg))
        !           187:                        (long (e-write3 'asll '($ 2) temp-reg)))
        !           188:                    (e-write3 'lea `(% 0 ,vec-reg ,temp-reg) temp-areg)
        !           189:                    (if (eq type 'long)
        !           190:                        then (e-write3 temp vect-val `(0 ,temp-areg))
        !           191:                        else (e-move vect-val 'd1)
        !           192:                             (e-write3 temp 'd1 `(0 ,temp-areg))))
        !           193:                (if g-loc
        !           194:                    then (if (eq type 'byte)
        !           195:                             then ; all bytes values are within the fixnum
        !           196:                                  ; range, we convert them to immediate
        !           197:                                  ; fixum with ease.
        !           198:                                  #+for-vax
        !           199:                                  (progn
        !           200:                                      (e-write4 'ashl '($ 2)
        !           201:                                                index-reg index-reg)
        !           202:                                      (e-write3 'movab
        !           203:                                                `(5120 ,index-reg)
        !           204:                                                (e-cvt g-loc)))
        !           205:                                  #+for-68k
        !           206:                                  (progn
        !           207:                                      (e-move index-reg temp-reg)
        !           208:                                      (e-write3 'asll '($ 2) temp-reg)
        !           209:                                      (e-move temp-reg temp-areg)
        !           210:                                      (e-move
        !           211:                                                (e-cvt '(fixnum 0))
        !           212:                                                temp-reg)
        !           213:                                      (e-write3 'lea
        !           214:                                                `(% 0 ,temp-areg ,temp-reg)
        !           215:                                                temp-areg)
        !           216:                                      (e-move
        !           217:                                                temp-areg
        !           218:                                                (e-cvt g-loc)))
        !           219:                             else ; must convert the hard way
        !           220:                                  (e-call-qnewint)
        !           221:                                  (d-clearreg)
        !           222:                                  (if (not (eq g-loc 'reg))
        !           223:                                      then (d-move 'reg g-loc)))
        !           224:                         ; result is always non nil
        !           225:                         (if (car g-cc) then (e-goto (car g-cc)))
        !           226:                 elseif (car g-cc) then (e-goto (car g-cc))))
        !           227:        (d-vectorindexcode)))
        !           228: 
        !           229: ;--- d-vref :: handle all types of vref's
        !           230: (defun d-vref (type)
        !           231:    ;;  Generic vector reference.  Type is either 'lisp', 'byte', 'word',
        !           232:    ;; or 'long'.
        !           233:    (let ((vect (cadr v-form))
        !           234:         (index (caddr v-form))
        !           235:         (vect-addr) (index-addr) (temp) (size)
        !           236:         (vec-reg #+for-vax 'r0 #+for-68k 'a0)
        !           237:         (index-reg '#.fixnum-reg)
        !           238:         (temp-reg #+for-vax 'r4 #+for-68k 'd0)
        !           239:         (temp-areg #+for-vax 'rX #+for-68k 'a1)
        !           240:         (oklab (d-genlab))
        !           241:         (needlowcheck t))  ; t if must check lower index bounds
        !           242: 
        !           243:        #+for-68k (d-regused '#.fixnum-reg)
        !           244:        (makecomment `(doing vec ref type ,type))
        !           245:        (if (fixp index)
        !           246:           then (if (<& index 0)
        !           247:                    then (comp-err "vector index less than 0 " v-form))
        !           248:                (setq needlowcheck nil))
        !           249: 
        !           250:        (if (setq index-addr (d-simple index))
        !           251:           then (let ((g-loc vec-reg) g-cc g-ret)
        !           252:                    (d-exp vect))
        !           253:                (setq vect-addr vec-reg)        ; the vector op is in vec-reg
        !           254:                ; we really want the cdr of index (the actual number).
        !           255:                ; if we can do that simply, great.  otherwise we
        !           256:                ; bring the index into index-reg and then do the cdr ourselves
        !           257:                (if (setq temp (d-simple `(cdr ,index)))
        !           258:                    then (d-move temp index-reg)
        !           259:                    else (d-move index-addr index-reg)
        !           260:                         #+for-vax
        !           261:                         (e-move `(0 ,index-reg) index-reg)
        !           262:                         #+for-68k
        !           263:                         (progn
        !           264:                             (e-move index-reg 'a5)
        !           265:                             (e-move '(0 a5) index-reg)))
        !           266:                (setq index-addr index-reg)
        !           267:           else ; the index isn't computable simply, so we must
        !           268:                ; stack the vector location to keep it safe
        !           269:                (let ((g-loc 'stack) g-cc g-ret)
        !           270:                    (d-exp vect))
        !           271:                (push nil g-locs)
        !           272:                (incr g-loccnt)
        !           273:                ; compute index's value into index-reg
        !           274:                (d-fixnumexp index)
        !           275:                ; now put vector address into vec-reg
        !           276:                (d-move 'unstack vec-reg)
        !           277:                (decr g-loccnt)
        !           278:                (pop g-locs)
        !           279:                (setq vect-addr vec-reg
        !           280:                      index-addr index-reg)
        !           281:                ; must be sure that the cc's reflect the value of index-reg
        !           282:                (e-tst index-reg))
        !           283:        
        !           284:        ; at this point, vect-addr (always vec-reg) contains the location of
        !           285:        ; the start of the vector,  index-addr (always index-reg) contains
        !           286:        ; the index value.  the condition codes reflect the value of
        !           287:        ; the index
        !           288:        ; First we insure that the index is non negative
        !           289:        ; test must use a jmp in case the object file is large
        !           290:        (if needlowcheck
        !           291:           then (e-write2 #+for-vax 'jgeq #+for-68k 'jpl oklab)
        !           292:                (e-write2 'jmp 'vecindexerr)
        !           293:                (e-label oklab)
        !           294:                (setq oklab (d-genlab)))
        !           295: 
        !           296:        ; now, we compare against the size of the vector
        !           297:        ; the size of the vector is in bytes, we may want to shift this
        !           298:        ; to reflect the size in words or longwords, depending on the
        !           299:        ; type of reference
        !           300:        (if (eq type 'byte)
        !           301:           then ; can compare right away
        !           302:                (e-cmp index-addr `(-8 ,vect-addr))
        !           303:           else ; shift size into temp-reg
        !           304:                (setq size (if (eq type 'word) then 1 else 2))
        !           305:                #+for-vax
        !           306:                (e-write4 'ashl (concat '$- size) `(-8 ,vect-addr) temp-reg)
        !           307:                #+for-68k
        !           308:                (progn
        !           309:                    (e-move `(-8 ,vect-addr) temp-reg)
        !           310:                    (e-write3 'asrl `($ ,size) temp-reg))
        !           311:                (e-cmp index-addr temp-reg)
        !           312:                (d-clearreg temp-reg))
        !           313:        ; size is the number of objects, the index is 0 based so
        !           314:        ; it must be less than the vector size
        !           315:        (e-write2 #+for-vax 'jlss #+for-68k 'jmi oklab)
        !           316:        (e-write2 'jmp 'vecindexerr)
        !           317:        (e-label oklab)
        !           318: 
        !           319:        ;; if we get here then the access is in bounds
        !           320:        (if g-loc
        !           321:           then ; we care about the value.
        !           322:                ; if the value is one of the fixnum types, then we
        !           323:                ; move the value to index-reg so it can be fixnum converted
        !           324:                (if (eq type 'lisp)
        !           325:                    then #+for-vax
        !           326:                         (e-move `(0 ,vect-addr ,index-addr)
        !           327:                                   (e-cvt g-loc))
        !           328:                         #+for-68k
        !           329:                         (progn
        !           330:                             (e-move index-addr temp-reg)
        !           331:                             (e-write3 'asll '($ 2) temp-reg)
        !           332:                             (e-add vect-addr temp-reg)
        !           333:                             (e-move temp-reg temp-areg)
        !           334:                             (e-move `(0 ,temp-areg) (e-cvt g-loc)))
        !           335:                         (if g-cc then (d-handlecc))
        !           336:                    else #+for-vax
        !           337:                         (progn
        !           338:                             (setq temp (cadr (assq type '((byte cvtbl)
        !           339:                                                           (word cvtwl)
        !           340:                                                           (long movl)))))
        !           341:                             (e-write3 temp
        !           342:                                       `(0 ,vect-addr ,index-addr)
        !           343:                                       index-reg))
        !           344:                         #+for-68k
        !           345:                         (progn
        !           346:                             (setq temp
        !           347:                                   (cadr (assq type '((byte movb)
        !           348:                                                      (word movw)
        !           349:                                                      (long movl)))))
        !           350:                             (caseq type
        !           351:                                    (word (e-write3 'asll '($ 1) index-reg))
        !           352:                                    (long (e-write3 'asll '($ 2) index-reg)))
        !           353:                             (e-write3 'lea `(% 0 ,vec-reg ,index-reg)
        !           354:                                       temp-areg)
        !           355:                             (if (memq type '(byte word))
        !           356:                                 then (e-write2 'clrl index-reg))
        !           357:                             (e-write3 temp `(0 ,temp-areg) index-reg))
        !           358:                         (if (eq type 'byte)
        !           359:                             then ; all bytes values are within the fixnum
        !           360:                                  ; range, we convert them to immediate
        !           361:                                  ; fixum with ease.
        !           362:                                  #+for-vax
        !           363:                                  (progn
        !           364:                                      (e-write4 'ashl '($ 2)
        !           365:                                                index-reg index-reg)
        !           366:                                      (e-write3 'movab
        !           367:                                                `(5120 ,index-reg)
        !           368:                                                (e-cvt g-loc)))
        !           369:                                  #+for-68k
        !           370:                                  (progn
        !           371:                                      (e-write3 'asll '($ 2) index-reg)
        !           372:                                      (e-move index-reg temp-areg)
        !           373:                                      (e-move
        !           374:                                                '($ _nilatom+0x1400)
        !           375:                                                temp-reg)
        !           376:                                      (e-write3 'lea
        !           377:                                                `(% 0 ,temp-areg ,temp-reg)
        !           378:                                                temp-areg)
        !           379:                                      (e-move
        !           380:                                                temp-areg
        !           381:                                                (e-cvt g-loc)))
        !           382:                             else ; must convert the hard way
        !           383:                                  (e-call-qnewint)
        !           384:                                  (d-clearreg)
        !           385:                                  (if (not (eq g-loc 'reg))
        !           386:                                      then (d-move 'reg g-loc)))
        !           387:                         ; result is always non nil
        !           388:                         (if (car g-cc) then (e-goto (car g-cc))))
        !           389:        elseif g-cc
        !           390:             ; we dont care about the value, just whether it nil
        !           391:           then (if (eq type 'lisp)
        !           392:                    then #+for-vax
        !           393:                         (e-tst `(0 ,vect-addr ,index-addr))
        !           394:                         #+for-68k
        !           395:                         (progn
        !           396:                             (e-move index-addr temp-reg)
        !           397:                             (e-write3 'asll '($ 2) temp-reg)
        !           398:                             (e-add vect-addr temp-reg)
        !           399:                             (e-move temp-reg temp-areg)
        !           400:                             (e-tst `(0 ,temp-areg)))
        !           401:                         (d-handlecc)
        !           402:                    else ; if fixnum, then it is always true
        !           403:                         (if (car g-cc) then (e-goto (car g-cc)))))
        !           404:        (d-vectorindexcode)))
        !           405: 
        !           406: ;--- d-vectorindexcode :: put out code to call the vector range error.
        !           407: ; At this point the vector is in r0, the index an immediate fixnum in r5
        !           408: ; we call the function int:vector-range-error with two arguments, the
        !           409: ; vector and the index.
        !           410: ;
        !           411: (defun d-vectorindexcode ()
        !           412:    (if (null g-didvectorcode)
        !           413:       then (let ((afterlab (d-genlab)))
        !           414:              (e-goto afterlab)
        !           415:              (e-label 'vecindexerr)
        !           416:              (d-move #+for-vax 'r0 #+for-68k 'a0 'stack)
        !           417:              (e-call-qnewint)
        !           418:              (d-move 'reg 'stack)
        !           419:              (d-calltran 'int:vector-range-error 2)
        !           420:              ; never returns
        !           421:              (e-label afterlab))
        !           422:           (setq g-didvectorcode t)))
        !           423: 
        !           424: 
        !           425: ;------------------------ vector access functions
        !           426: 
        !           427: ;--- cc-vectorp :: check for vectorness
        !           428: ;
        !           429: (defun cc-vectorp nil
        !           430:   (d-typesimp (cadr v-form) #.(immed-const 18)))
        !           431: 
        !           432: ;--- cc-vectorip :: check for vectoriness
        !           433: ;
        !           434: (defun cc-vectorip nil
        !           435:   (d-typesimp (cadr v-form) #.(immed-const 19)))
        !           436: 
        !           437: ;--- c-vsize :: extract vsize
        !           438: ;
        !           439: (defun c-vsize nil
        !           440:    (d-vectorsize (cadr v-form) '2))
        !           441: 
        !           442: (defun c-vsize-byte nil
        !           443:    (d-vectorsize (cadr v-form) '0))
        !           444: 
        !           445: (defun c-vsize-word nil
        !           446:    (d-vectorsize (cadr v-form) '1))
        !           447: 
        !           448: (defun d-vectorsize (form shift)
        !           449:    (let ((g-loc 'reg)
        !           450:         g-cc
        !           451:         g-ret)
        !           452:        (d-exp form))
        !           453:    ; get size into `fixnum-reg' for fixnum boxing
        !           454:    (if (zerop shift)
        !           455:        then (e-move '(-8 #+for-vax r0 #+for-68k a0) '#.fixnum-reg)
        !           456:        else #+for-vax
        !           457:            (e-write4 'ashl (concat '$- shift) '(-8 r0) '#.fixnum-reg)
        !           458:            #+for-68k
        !           459:            (progn
        !           460:                (e-move '(-8 a0) '#.fixnum-reg)
        !           461:                (e-write3 'asrl `($ ,shift) '#.fixnum-reg)))
        !           462:    (e-call-qnewint))

unix.superglobalmegacorp.com

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