source: branches/lispworks/disk-cache-accessors.lisp@ 18

Last change on this file since 18 was 7, checked in by Gail Zacharias, 17 years ago

Credit for Anvita

  • Property svn:eol-style set to native
File size: 69.5 KB
Line 
1;;;-*- Mode: Lisp; Package: ccl -*-
2
3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4;;
5;; disk-cache-accessors.lisp
6;; low-level accessors for disk-cache's
7;;
8;; Portions Copyright © 2006 Clozure Associates and Anvita eReference (www.Anvita.info).
9;; Copyright © 1996 Digitool, Inc.
10;; Copyright © 1992-1995 Apple Computer, Inc.
11;; All rights reserved.
12;; Permission is given to use, copy, and modify this software provided
13;; that Digitool is given credit in all derivative works.
14;; This software is provided "as is". Digitool makes no warranty or
15;; representation, either express or implied, with respect to this software,
16;; its quality, accuracy, merchantability, or fitness for a particular
17;; purpose.
18;;
19
20(eval-when (:execute)
21 ;; We lie a lot about the types of arrays. The compiler is willing
22 ;; to trust us, the evaluator might not.
23 (warn "This file must be compiled, it probably won't work evaluated."))
24
25;;;;;;;;;;;;;;;;;;;;;;;;;;
26;;
27;; Modification History
28;;
29;; 02/01/06 gz LispWorks port
30;; ------------- 0.961
31;; 09/19/96 bill The PPC version of %%load-pointer handles short floats now via %%load-short-float
32;; 09/18/96 bill Fix brain-damage in PPC versions of read-double-float and (setf read-double-float)
33;; ------------- 0.96
34;; 06/14/96 bill AlanR's fix to read-double-float
35;; ------------- 0.95
36;; 03/20/96 bill Make work in MCL-PPC
37;; ------------- 0.93
38;; 05/25/95 bill more da -> da.l changes.
39;; ------------- 0.9
40;; 03/13/95 bill byte-array-p & ensure-byte-array-p move to "block-io-mcl.lisp"
41;; 10/28/94 Moon Change without-interrupts to with-databases-locked.
42;; 10/03/94 bill (setf wood::read-8-bits) no longer fails when writing
43;; less than 4 bytes from the end of the buffer.
44;; 09/21/94 bill without-interrupts as necessary for interlocking
45;; ------------- 0.8
46;; 08/10/93 bill eval-when around requires of lapmacros & lispequ.
47;; ------------- 0.6
48;; 12/09/92 bill fill-long, fill-word, & fill-byte return right away if (<= count 0).
49;; ------------- 0.5
50;; 07/23/92 bill array-data-and-offset -> lenient-array-data-and-offset
51;; length -> uvector-bytes
52;; These make the code that saves and restores non-array
53;; ivectors (e.g. bignums, ratios, complex numbers)
54;; work correctly.
55;; 07/20/92 bill da -> da.l where necessary.
56;; ------------ 0.1
57;; 05/30/92 bill read-string & fill-xxx now skip $block-overhead
58;; 03/16/92 bill New file.
59;;
60
61(in-package :wood)
62
63(export '(read-long read-unsigned-long
64 read-string read-pointer
65 read-low-24-bits read-8-bits
66 fill-long fill-word fill-byte))
67
68#+ccl
69(eval-when (:compile-toplevel :execute)
70 #-ppc-target
71 (require :lapmacros)
72 (require :lispequ))
73
74#+ppc-target
75(progn
76
77(declaim (inline %%load-long %%load-unsigned-long))
78
79(defun %%load-long (array address)
80 (declare (type (simple-array (unsigned-byte 16) (*)) array)
81 (fixnum address)
82 (optimize (speed 3) (safety 0)))
83 (let* ((index (ash address -1))
84 (high-word (aref array index))
85 (low-word (aref array (the fixnum (1+ index)))))
86 (declare (fixnum index high-word low-word))
87 (if (logbitp 15 high-word)
88 (progn
89 (setq high-word (- high-word (expt 2 16)))
90 (if (>= high-word (- (expt 2 (- 15 ppc::fixnum-shift))))
91 (the fixnum
92 (+ (the fixnum (ash high-word 16)) low-word))
93 (+ (ash high-word 16) low-word)))
94 (if (< high-word (expt 2 (- 15 ppc::fixnum-shift)))
95 (the fixnum
96 (+ (the fixnum (ash high-word 16)) low-word))
97 (+ (ash high-word 16) low-word)))))
98
99(defun %%load-unsigned-long (array address)
100 (declare (type (simple-array (unsigned-byte 16) (*)) array)
101 (fixnum address)
102 (optimize (speed 3) (safety 0)))
103 (let* ((index (ash address -1))
104 (high-word (aref array index))
105 (low-word (aref array (the fixnum (1+ index)))))
106 (declare (fixnum index high-word low-word))
107 (if (< high-word (expt 2 (- 15 ppc::fixnum-shift)))
108 (the fixnum
109 (+ (the fixnum (ash high-word 16)) low-word))
110 (+ (ash high-word 16) low-word))))
111
112) ; end of #+ppc-target progn
113
114#+LispWorks
115(progn
116
117(defun-inline %%load-long (byte-array address)
118 (declare (type (simple-array (unsigned-byte 8) (*)) byte-array)
119 (type fixnum address)
120 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
121 (sys:int32-to-integer
122 (sys:int32-logior
123 (sys:int32-logior (sys:int32<< (aref byte-array (the fixnum address)) 24)
124 (sys:int32<< (aref byte-array (the fixnum (+ address 1))) 16))
125 (sys:int32-logior (sys:int32<< (aref byte-array (the fixnum (+ address 2))) 8)
126 (aref byte-array (the fixnum (+ address 3)))))))
127
128(defun-inline %%load-unsigned-long (byte-array address)
129 (declare (type (simple-array (unsigned-byte 8) (*)) byte-array)
130 (type fixnum address)
131 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
132 (let* ((b0 (aref byte-array address))
133 (int (sys:int32-to-integer
134 (sys:int32-logior
135 (sys:int32-logior (sys:int32<< b0 24)
136 (sys:int32<< (aref byte-array (the fixnum (+ address 1))) 16))
137 (sys:int32-logior (sys:int32<< (aref byte-array (the fixnum (+ address 2))) 8)
138 (aref byte-array (the fixnum (+ address 3))))))))
139 (declare (type (unsigned-byte 8) b0))
140 (if (logbitp 7 b0)
141 (logand #xFFFFFFFF int)
142 int)))
143)
144
145(defun read-long (disk-cache address)
146 (with-databases-locked
147 (multiple-value-bind (array index count)
148 (get-disk-page disk-cache address)
149 (declare (fixnum index count))
150 (unless (and (>= count 4) (eql 0 (the fixnum (logand 1 index))))
151 (error "Address odd or past eof: ~s" address))
152 #+ccl-68k-target
153 (ccl::lap-inline ()
154 (:variable array index)
155 (ccl::move.l (ccl::varg array) ccl::atemp0)
156 (ccl::move.l (ccl::varg index) ccl::da)
157 (ccl::getint ccl::da)
158 (ccl::move.l (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::arg_z)
159 (ccl::jsr_subprim ccl::$sp-mklong))
160 #-ccl-68k-target
161 (%%load-long array index))))
162
163(defmacro check-byte-array-address (address size array)
164 (let ((addr (gensym)))
165 `(let ((,addr ,address))
166 (unless (and (<= 0 ,addr)
167 ,(if (eql size 1)
168 `(< ,addr (length ,array))
169 `(<= (the fixnum (+ ,addr ,size)) (length ,array))))
170 (error "Attempt to access outside of buffer bounds")))))
171
172(defun %load-long (array address)
173 (ensure-byte-array array)
174 (unless (fixnump address)
175 (setq address (require-type address 'fixnum)))
176 (locally (declare (fixnum address))
177 (check-byte-array-address address 4 array)
178 (unless (eql 0 (the fixnum (logand 1 address)))
179 (error "Odd address: ~s" address))
180 #+ccl-68k-target
181 (ccl::lap-inline ()
182 (:variable array address immediate?)
183 (ccl::move.l (ccl::varg array) ccl::atemp0)
184 (ccl::move.l (ccl::varg address) ccl::da)
185 (ccl::getint ccl::da)
186 (ccl::move.l (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::arg_z)
187 (ccl::jsr_subprim ccl::$sp-mklong))
188 #-ccl-68k-target
189 (%%load-long array address)))
190
191(defun read-unsigned-long (disk-cache address)
192 (with-databases-locked
193 (multiple-value-bind (array index count)
194 (get-disk-page disk-cache address)
195 (declare (fixnum index count))
196 (unless (and (>= count 4) (eql 0 (the fixnum (logand 1 index))))
197 (error "Address odd or past eof: ~s" address))
198 #+ccl-68k-target
199 (ccl::lap-inline ()
200 (:variable array index)
201 (ccl::move.l (ccl::varg array) ccl::atemp0)
202 (ccl::move.l (ccl::varg index) ccl::da)
203 (ccl::getint ccl::da)
204 (ccl::move.l (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::arg_z)
205 (ccl::jsr_subprim ccl::$sp-mkulong))
206 #-ccl-68k-target
207 (%%load-unsigned-long array index))))
208
209(defun %load-unsigned-long (array address)
210 (ensure-byte-array array)
211 (setq address (require-type address 'fixnum))
212 (locally (declare (fixnum address))
213 (check-byte-array-address address 4 array)
214 (unless (eql 0 (the fixnum (logand 1 address)))
215 (error "Odd address: ~s" address))
216 #+ccl-68k-target
217 (ccl::lap-inline ()
218 (:variable array address)
219 (ccl::move.l (ccl::varg array) ccl::atemp0)
220 (ccl::move.l (ccl::varg address) ccl::da)
221 (ccl::getint ccl::da)
222 (ccl::move.l (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::arg_z)
223 (ccl::jsr_subprim ccl::$sp-mkulong))
224 #-ccl-68k-target
225 (%%load-unsigned-long array address)))
226
227#+ppc-target
228(defun-inline %%store-long (value array address)
229 (declare (type (simple-array (unsigned-byte 16) (*)) array)
230 (fixnum address)
231 (optimize (speed 3) (safety 0)))
232 (let ((index (ash address -1))
233 (low-word 0)
234 (high-word 0))
235 (if (fixnump value)
236 (locally (declare (fixnum low-word high-word address))
237 (setq low-word (logand value #xffff)
238 high-word (ash value -16)))
239 (setq low-word (logand value #xffff)
240 high-word (ash value -16)))
241 (setf (aref array index) high-word
242 (aref array (the fixnum (1+ index))) low-word))
243 value)
244
245#+LispWorks
246(defun %%store-long (value array address)
247 (declare (type (simple-array (unsigned-byte 8) (*)) array)
248 (type fixnum address)
249 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
250 (let ((int (sys:integer-to-int32 value)))
251 (declare (type sys:int32 int))
252 (setf (aref array (the fixnum address)) (the fixnum (sys:int32-to-integer (sys:int32>> int 24))))
253 (setf (aref array (the fixnum (+ address 1))) (the fixnum (sys:int32-to-integer (sys:int32>> int 16))))
254 (setf (aref array (the fixnum (+ address 2))) (the fixnum (sys:int32-to-integer (sys:int32>> int 8))))
255 (setf (aref array (the fixnum (+ address 3))) (the fixnum (sys:int32-to-integer int)))))
256
257(defun (setf read-long) (value disk-cache address)
258 (unless (>= (disk-cache-size disk-cache)
259 (+ address 4))
260 (extend-disk-cache disk-cache (+ address 4)))
261 (with-databases-locked
262 (multiple-value-bind (array index count)
263 (get-disk-page disk-cache address t)
264 (declare (fixnum index count))
265 (unless (and (>= count 4) (eql 0 (the fixnum (logand 1 index))))
266 (error "Address odd or past eof: ~s" address))
267 #+ccl-68k-target
268 (ccl::lap-inline ()
269 (:variable array index value)
270 (ccl::move.l (ccl::varg value) ccl::arg_z)
271 (ccl::jsr_subprim ccl::$sp-getxlong)
272 (ccl::move.l (ccl::varg array) ccl::atemp0)
273 (ccl::move.l (ccl::varg index) ccl::da)
274 (ccl::getint ccl::da)
275 (ccl::move.l ccl::acc (ccl::atemp0 ccl::da.l ccl::$v_data)))
276 #-ccl-68k-target
277 (%%store-long value array index)))
278 value)
279
280(defsetf read-unsigned-long (disk-cache address) (value)
281 `(setf (read-long ,disk-cache ,address) ,value))
282
283(defun %store-long (value array address)
284 (ensure-byte-array array)
285 (setq address (require-type address 'fixnum))
286 (locally (declare (fixnum address))
287 (check-byte-array-address address 4 array)
288 (unless (eql 0 (the fixnum (logand 1 address)))
289 (error "Odd address: ~s" address))
290 #+ccl-68k-target
291 (ccl::lap-inline ()
292 (:variable array address value)
293 (ccl::move.l (ccl::varg value) ccl::arg_z)
294 (ccl::jsr_subprim ccl::$sp-getxlong)
295 (ccl::move.l (ccl::varg array) ccl::atemp0)
296 (ccl::move.l (ccl::varg address) ccl::da)
297 (ccl::getint ccl::da)
298 (ccl::move.l ccl::acc (ccl::atemp0 ccl::da.l ccl::$v_data)))
299 #-ccl-68k-target
300 (%%store-long value array address))
301 value)
302
303#+ppc-target
304(progn
305
306(defun-inline %%load-word (array index)
307 (locally (declare (type (simple-array (signed-byte 16) (*)) array)
308 (optimize (speed 3) (safety 0)))
309 (setq index (ash index -1))
310 (aref array index)))
311
312(defun-inline %%load-unsigned-word (array index)
313 (declare (type (simple-array (unsigned-byte 16) (*)) array)
314 (optimize (speed 3) (safety 0)))
315 (aref array (the fixnum (ash index -1))))
316
317(defun-inline %%store-word (value array index)
318 (locally (declare (type (simple-array (unsigned-byte 16) (*)) array)
319 (type fixnum index)
320 (optimize (speed 3) (safety 0)))
321 (setq index (ash index -1))
322 (setf (aref array index) value)))
323
324)
325
326
327#+LispWorks
328(progn
329(defun-inline %%load-word (array address)
330 (declare (type (simple-array (unsigned-byte 8) (*)) array)
331 (type fixnum address)
332 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
333 (let ((b0 (aref array address)))
334 (declare (type (unsigned-byte 8) b0))
335 (the fixnum
336 (sys:int32-to-integer
337 (sys:int32-logior (sys:int32>> (sys:int32<< b0 24) 16) ;; sign-extend
338 (aref array (the fixnum (1+ address))))))))
339
340(defun-inline %%load-unsigned-word (array address)
341 (declare (type (simple-array (unsigned-byte 8) (*)) array)
342 (type fixnum address)
343 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
344 (the fixnum
345 (sys:int32-to-integer
346 (sys:int32-logior (sys:int32<< (aref array address) 8) (aref array (the fixnum (1+ address)))))))
347
348(defun-inline %%store-word (value array address)
349 (declare (type (simple-array (unsigned-byte 8) (*)) array)
350 (type fixnum address)
351 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
352 (let ((int (sys:integer-to-int32 value)))
353 (declare (type sys:int32 int))
354 (setf (aref array (the fixnum address)) (the fixnum (sys:int32-to-integer (sys:int32>> int 8))))
355 (setf (aref array (the fixnum (+ address 1))) (the fixnum (sys:int32-to-integer int)))))
356)
357
358(defun read-word (disk-cache address)
359 (with-databases-locked
360 (multiple-value-bind (array index count)
361 (get-disk-page disk-cache address)
362 (declare (fixnum index count))
363 (unless (and (>= count 2) (eql 0 (the fixnum (logand 1 index))))
364 (error "Address odd or past eof: ~s" address))
365 #+ccl-68k-target
366 (ccl::lap-inline ()
367 (:variable array index)
368 (ccl::move.l (ccl::varg array) ccl::atemp0)
369 (ccl::move.l (ccl::varg index) ccl::da)
370 (ccl::getint ccl::da)
371 (ccl::move.w (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::acc)
372 (ccl::ext.l ccl::acc)
373 (ccl::mkint ccl::acc))
374 #-ccl-68k-target
375 (%%load-word array index))))
376
377(defun %load-word (array address)
378 (ensure-byte-array array)
379 (setq address (require-type address 'fixnum))
380 (locally (declare (fixnum address))
381 (check-byte-array-address address 2 array)
382 (unless (eql 0 (the fixnum (logand 1 address)))
383 (error "Odd address: ~s" address))
384 #+ccl-68k-target
385 (ccl::lap-inline ()
386 (:variable array address)
387 (ccl::move.l (ccl::varg array) ccl::atemp0)
388 (ccl::move.l (ccl::varg address) ccl::da)
389 (ccl::getint ccl::da)
390 (ccl::move.w (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::acc)
391 (ccl::ext.l ccl::acc)
392 (ccl::mkint ccl::acc))
393 #-ccl-68k-target
394 (%%load-word array address)))
395
396(defun read-unsigned-word (disk-cache address)
397 (with-databases-locked
398 (multiple-value-bind (array index count)
399 (get-disk-page disk-cache address)
400 (declare (fixnum index count))
401 (unless (and (>= count 2) (eql 0 (the fixnum (logand 1 index))))
402 (error "Address odd or past eof: ~s" address))
403 #+ccl-68k-target
404 (ccl::lap-inline ()
405 (:variable array index)
406 (ccl::move.l (ccl::varg array) ccl::atemp0)
407 (ccl::move.l (ccl::varg index) ccl::da)
408 (ccl::getint ccl::da)
409 (ccl::move.l (ccl::$ 0) ccl::acc)
410 (ccl::move.w (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::acc)
411 (ccl::mkint ccl::acc))
412 #-ccl-68k-target
413 (%%load-unsigned-word array index))))
414
415(defun %load-unsigned-word (array address)
416 (ensure-byte-array array)
417 (setq address (require-type address 'fixnum))
418 (locally (declare (fixnum address))
419 (check-byte-array-address address 2 array)
420 (unless (eql 0 (the fixnum (logand 1 address)))
421 (error "Odd address: ~s" address))
422 #+ccl-68k-target
423 (ccl::lap-inline ()
424 (:variable array address)
425 (ccl::move.l (ccl::varg array) ccl::atemp0)
426 (ccl::move.l (ccl::varg address) ccl::da)
427 (ccl::getint ccl::da)
428 (ccl::move.l (ccl::$ 0) ccl::acc)
429 (ccl::move.w (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::acc)
430 (ccl::mkint ccl::acc))
431 #-ccl-68k-target
432 (%%load-unsigned-word array address)))
433
434(defun (setf read-word) (value disk-cache address)
435 (setq value (require-type value 'fixnum))
436 (unless (>= (disk-cache-size disk-cache)
437 (+ address 4))
438 (extend-disk-cache disk-cache (+ address 4)))
439 (with-databases-locked
440 (multiple-value-bind (array index count)
441 (get-disk-page disk-cache address t)
442 (declare (fixnum index count))
443 (unless (and (>= count 2) (eql 0 (the fixnum (logand 1 index))))
444 (error "Odd address: ~s" address))
445 #+ccl-68k-target
446 (ccl::lap-inline ()
447 (:variable array index value)
448 (ccl::move.l (ccl::varg value) ccl::acc)
449 (ccl::getint ccl::acc)
450 (ccl::move.l (ccl::varg array) ccl::atemp0)
451 (ccl::move.l (ccl::varg index) ccl::da)
452 (ccl::getint ccl::da)
453 (ccl::move.w ccl::acc (ccl::atemp0 ccl::da.l ccl::$v_data))
454 (ccl::mkint ccl::acc))
455 #-ccl-68k-target
456 (%%store-word value array index))))
457
458(defsetf read-unsigned-word (disk-cache address) (value)
459 `(setf (read-word ,disk-cache ,address) ,value))
460
461(defun %store-word (value array address)
462 (ensure-byte-array array)
463 (setq address (require-type address 'fixnum))
464 (locally (declare (fixnum address))
465 (check-byte-array-address address 2 array)
466 (unless (eql 0 (the fixnum (logand 1 address)))
467 (error "Address not word aligned: ~s" address))
468 #+ccl-68k-target
469 (ccl::lap-inline ()
470 (:variable value array address)
471 (ccl::move.l (ccl::varg array) ccl::atemp0)
472 (ccl::move.l (ccl::varg address) ccl::da)
473 (ccl::getint ccl::da)
474 (ccl::move.l (ccl::varg value) ccl::acc)
475 (ccl::getint ccl::acc)
476 (ccl::move.w ccl::acc (ccl::atemp0 ccl::da.l ccl::$v_data))
477 (ccl::mkint ccl::acc))
478 #-ccl-68k-target
479 (%%store-word value array address)))
480
481;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
482
483; same as %load-pointer, but does no type checking
484#+ccl-68k-target
485(progn
486
487(defun-inline %%load-pointer (array address)
488 (let (immediate?)
489 (values
490 (ccl::lap-inline ()
491 (:variable array address immediate?)
492 (ccl::move.l (ccl::varg array) ccl::atemp0)
493 (ccl::move.l (ccl::varg address) ccl::da)
494 (ccl::getint ccl::da)
495 (ccl::move.l (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::arg_z)
496 (ccl::if# (ccl::ne (ccl::dtagp ccl::arg_z ccl::$t_fixnum ccl::$t_imm ccl::$t_sfloat))
497 (ccl::movereg ccl::arg_z ccl::acc)
498 (ccl::move.l '1 (ccl::varg immediate?))
499 ccl::else#
500 (ccl::jsr_subprim ccl::$sp-mkulong)))
501 immediate?)))
502
503; Same as %store-pointer, but doesn't type check
504(defun-inline %%store-pointer (value array address &optional immediate?)
505 (ccl::lap-inline ()
506 (:variable array address value immediate?)
507 (ccl::move.l (ccl::varg value) ccl::arg_z)
508 (ccl::if# (ccl::eq (ccl::cmp.l (ccl::varg immediate?) ccl::nilreg))
509 (ccl::jsr_subprim ccl::$sp-getxlong))
510 (ccl::move.l (ccl::varg array) ccl::atemp0)
511 (ccl::move.l (ccl::varg address) ccl::da)
512 (ccl::getint ccl::da)
513 (ccl::move.l ccl::acc (ccl::atemp0 ccl::da.l ccl::$v_data))))
514)
515
516#+ppc-target
517(progn
518
519; Load a Wood fixnum returning a lisp fixnum
520(ccl::defppclapfunction %%load-fixnum ((array ccl::arg_y) (address ccl::arg_z))
521 (ccl::unbox-fixnum ccl::imm0 address)
522 (ccl::la ccl::imm0 ppc::misc-data-offset ccl::imm0)
523 (ccl::lwzx ccl::imm0 ccl::imm0 array)
524 (ccl::srawi ccl::imm0 ccl::imm0 3)
525 (ccl::box-fixnum ccl::arg_z ccl::imm0)
526 (ccl::blr))
527
528(ccl::defppclapfunction %%store-fixnum ((value ccl::arg_x) (array ccl::arg_y) (address ccl::arg_z))
529 (ccl::unbox-fixnum ccl::imm0 address)
530 (ccl::la ccl::imm0 ppc::misc-data-offset ccl::imm0)
531 (ccl::slwi ccl::imm1 value (- 3 ppc::fixnum-shift))
532 (ccl::stwx ccl::imm1 ccl::imm0 array)
533 (ccl::mr ccl::arg_z ccl::arg_x)
534 (ccl::blr))
535
536; Load a Wood character returning a lisp character
537(ccl::defppclapfunction %%load-character ((array ccl::arg_y) (address ccl::arg_z))
538 (ccl::unbox-fixnum ccl::imm0 address)
539 (ccl::la ccl::imm0 ppc::misc-data-offset ccl::imm0)
540 (ccl::lwzx ccl::imm0 ccl::imm0 array)
541 (ccl::li ccl::arg_z ppc::subtag-character)
542 (ccl::rlwimi ccl::arg_z ccl::imm0 0 0 15)
543 (ccl::blr))
544
545(ccl::defppclapfunction %%store-character ((value ccl::arg_x) (array ccl::arg_y) (address ccl::arg_z))
546 (ccl::unbox-fixnum ccl::imm0 address)
547 (ccl::la imm0 ppc::misc-data-offset ccl::imm0)
548 (ccl::li ccl::imm1 ccl::$t_imm_char)
549 (ccl::rlwimi ccl::imm1 value 0 0 15)
550 (ccl::stwx ccl::imm1 ccl::imm0 array)
551 (ccl::mr ccl::arg_z ccl::arg_x)
552 (ccl::blr))
553
554(defun-inline %%load-pointer (array address)
555 (declare (optimize (speed 3) (safety 0))
556 (fixnum address))
557 (let* ((tag-byte
558 (locally (declare (type (simple-array (unsigned-byte 8) (*)) array)
559 (optimize (speed 3) (safety 0)))
560 (aref array (the fixnum (+ address 3)))))
561 (tag (logand tag-byte 7)))
562 (declare (fixnum tag-byte tag))
563 (case tag
564 (#.$t_fixnum
565 (values (%%load-fixnum array address) t))
566 (#.$t_imm
567 (values
568 (ecase tag-byte
569 (#.ccl::$undefined (%unbound-marker))
570 (#.ccl::$illegal (ccl::%illegal-marker))
571 (#.ccl::$t_imm_char (%%load-character array address)))
572 t))
573 (#.$t_sfloat
574 (values (%%load-short-float array address) t))
575 (t (%%load-unsigned-long array address)))))
576
577(defun %%load-short-float (array address)
578 (declare (fixnum address)
579 (type (simple-array (unsigned-byte 8) (*)) array)
580 (optimize (speed 3) (safety 0)))
581 (let* ((tag-byte (aref array (the fixnum (+ address 3))))
582 (expt-byte (aref array address))
583 (expt-bits (ash expt-byte -3)) ; 5 bits of exponent
584 (expt (+ expt-bits
585 (the fixnum
586 (if (logbitp 4 expt-bits)
587 (- (ash 3 5) #x7f)
588 (- (ash 4 5) #x7f)))))
589 (normalized-expt (+ expt #x3ff))
590 (byte-1 (aref array (the fixnum (+ address 1))))
591 (byte-2 (aref array (the fixnum (+ address 2))))
592 (mantissa (+ (the fixnum (ash tag-byte -4))
593 (the fixnum (ash byte-2 4))
594 (the fixnum (ash byte-1 12))
595 (the fixnum (ash (the fixnum (logand expt-byte 7)) 20))))
596 (negative (logbitp 3 tag-byte))
597 (word-0 (+ (the fixnum (ash normalized-expt 4))
598 (the fixnum (ash mantissa -19))))
599 (word-1 (logand (the fixnum (ash mantissa -3)) #xffff))
600 (word-2 (ash (logand mantissa 7) 13))
601 (res (%copy-float 0.0)))
602 (declare (type fixnum tag-byte expt-byte expt-bits expt normalized-expt byte-1 byte-2 mantissa
603 word-0 word-1 word-2)
604 (type (simple-array (unsigned-byte 16) (*)) res) ; lie
605 )
606 (when negative
607 (incf word-0 #x8000))
608 ;(print-db word-0 word-1 word-2)
609 (setf (aref res 2) word-0
610 (aref res 3) word-1
611 (aref res 4) word-2
612 (aref res 5) 0)
613 res))
614
615(defun-inline %%store-pointer (value array address &optional imm?)
616 (cond ((not imm?)
617 (%%store-long value array address))
618 ((fixnump value) (%%store-fixnum value array address))
619 ((characterp value) (%%store-character value array address))
620 ((eq value (%unbound-marker))
621 (%%store-long ccl::$undefined array address))
622 ((eq value (ccl::%illegal-marker))
623 (%%store-long ccl::$illegal array address))
624 (t (error "~s is not a valid immediate" value)))
625 value)
626
627) ; end of #+ppc-target progn
628
629#+LispWorks
630(progn
631
632(defun-inline %%store-tagged (value tag array address)
633 (declare (type (simple-array (unsigned-byte 8) (*)) array)
634 (type fixnum value address tag)
635 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
636 (let ((int (sys:integer-to-int32 value)))
637 (declare (type sys:int32 int))
638 (setf (aref array (the fixnum address)) (the fixnum (sys:int32-to-integer (sys:int32>> int 21))))
639 (setf (aref array (the fixnum (+ address 1))) (the fixnum (sys:int32-to-integer (sys:int32>> int 13))))
640 (setf (aref array (the fixnum (+ address 2))) (the fixnum (sys:int32-to-integer (sys:int32>> int 5))))
641 (setf (aref array (the fixnum (+ address 3))) (the fixnum (sys:int32-to-integer
642 (sys:int32-logior (sys:integer-to-int32 tag)
643 (sys:int32<< int 3)))))))
644(defun-inline %%load-tagged (array address)
645 (declare (type (simple-array (unsigned-byte 8) (*)) array)
646 (type fixnum address)
647 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
648 (let ((b3 (aref array (the fixnum (+ address 3)))))
649 (declare (type (unsigned-byte 8) b3))
650 (values
651 (the fixnum
652 (sys:int32-to-integer
653 (sys:int32-logior
654 (sys:int32-logior (sys:int32<< (aref array (the fixnum address)) 21)
655 (sys:int32<< (aref array (the fixnum (+ address 1))) 13))
656 (sys:int32-logior (sys:int32<< (aref array (the fixnum (+ address 2))) 5)
657 (sys:int32>> b3 3)))))
658 (pointer-tag b3))))
659
660(defun-inline %%load-pointer (array address)
661 (declare (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
662 (multiple-value-bind (value tag) (%%load-tagged array address)
663 (declare (type fixnum value tag))
664 (case tag
665 (#.$t_pos_fixnum (values value t))
666 (#.$t_neg_fixnum (values (the fixnum (+ most-negative-fixnum value)) t))
667 (#.$t_char (values (code-char value) t))
668 (#.$t_imm (values (ecase value
669 (#.$undefined-imm (%unbound-marker))) t))
670 (t (%%load-unsigned-long array address)))))
671
672(defun-inline %%store-pointer (value array address &optional imm?)
673 (cond ((not imm?) (%%store-long value array address))
674 ((fixnump value) (if (>= (the fixnum value) 0)
675 (%%store-tagged value $t_pos_fixnum array address)
676 (%%store-tagged value $t_neg_fixnum array address)))
677 ((characterp value) (%%store-tagged (char-code value) $t_char array address))
678 ;; Do we even need tnis?
679 ((eq value (%unbound-marker)) (%%store-tagged $undefined-imm $t_imm array address))
680 (t (error "~s is an unknown immediate type" value))))
681
682) ; end of #+LispWorks progn
683
684; Avoid consing bignums by not boxing immediate data from the file.
685; Second value is true if the result was immediate.
686(defun read-pointer (disk-cache address #+LispWorks &optional #+LispWorks ignore)
687 #+LispWorks (declare (ignore ignore)) ;; see def-accessor for explanation.
688 (declare (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
689 (with-databases-locked
690 (multiple-value-bind (array index count)
691 (get-disk-page disk-cache address)
692 (declare (fixnum index count))
693 (unless (and (>= count 4) (eql 0 (the fixnum (logand 1 index))))
694 (error "Address odd or past eof: ~s" address))
695 (%%load-pointer array index))))
696
697; load directly from a byte array.
698(defun %load-pointer (array address)
699 (ensure-byte-array array)
700 (setq address (require-type address 'fixnum))
701 (locally (declare (fixnum address))
702 (check-byte-array-address address 4 array)
703 (unless (eql 0 (the fixnum (logand 1 address)))
704 (error "Odd address: ~s" address))
705 (%%load-pointer array address)))
706
707(defun (setf read-pointer) (value disk-cache address &optional immediate?)
708 (unless (>= (disk-cache-size disk-cache)
709 (+ address 4))
710 (extend-disk-cache disk-cache (+ address 4)))
711 (with-databases-locked
712 (multiple-value-bind (array index count)
713 (get-disk-page disk-cache address t)
714 (declare (fixnum index count))
715 (unless (and (>= count 4) (eql 0 (the fixnum (logand 1 index))))
716 (error "Address odd or past eof: ~s" address))
717 (%%store-pointer value array index immediate?)))
718 value)
719
720(defun %store-pointer (value array address &optional immediate?)
721 (ensure-byte-array array)
722 (setq address (require-type address 'fixnum))
723 (locally (declare (fixnum address))
724 (check-byte-array-address address 4 array)
725 (unless (eql 0 (the fixnum (logand 1 address)))
726 (error "Odd address: ~s" address))
727 (%%store-pointer value array address immediate?))
728 value)
729
730#+ccl (progn
731(declaim (inline %%load-low-24-bits %%store-low-24-bits))
732
733(defun %%load-low-24-bits (array index)
734 (declare (optimize (speed 3) (safety 0))
735 (fixnum index))
736 (let* ((word-index (ash index -1))
737 (low-word
738 (locally (declare (type (simple-array (unsigned-byte 16) (*)) array))
739 (aref array (the fixnum (1+ word-index)))))
740 (high-word
741 (locally (declare (type (simple-array (unsigned-byte 8) (*)) array))
742 (aref array (the fixnum (1+ index))))))
743 (declare (fixnum word-index low-word high-word))
744 (the fixnum
745 (+ (the fixnum (ash high-word 16)) low-word))))
746
747(defun %%store-low-24-bits (value array index)
748 (declare (optimize (speed 3) (safety 0))
749 (fixnum value index))
750 (let* ((word-index (ash index -1))
751 (low-word (logand value #xffff))
752 (high-word (ash value -16)))
753 (declare (fixnum word-index low-word high-word))
754 (locally (declare (type (simple-array (unsigned-byte 16) (*)) array))
755 (setf (aref array (the fixnum (1+ word-index))) low-word))
756 (locally (declare (type (simple-array (unsigned-byte 8) (*)) array))
757 (setf (aref array (the fixnum (1+ index))) high-word)))
758 value)
759) ;#+ccl
760
761#+LispWorks (progn
762(defun-inline %%load-low-24-bits (array address)
763 (declare (type (simple-array (unsigned-byte 8) (*)) array)
764 (type fixnum address)
765 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
766 (sys:int32-to-integer
767 (sys:int32-logior
768 (sys:int32<< (aref array (the fixnum (+ address 1))) 16)
769 (sys:int32-logior (sys:int32<< (aref array (the fixnum (+ address 2))) 8)
770 (aref array (the fixnum (+ address 3)))))))
771
772(defun-inline %%store-low-24-bits (value array address)
773 (declare (type (simple-array (unsigned-byte 8) (*)) array)
774 (type fixnum address)
775 (optimize (speed 3) (safety 0) #+LispWorks (float 0)))
776 (let ((int (sys:integer-to-int32 value)))
777 (declare (type sys:int32 int))
778 (setf (aref array (the fixnum (+ address 1))) (the fixnum (sys:int32-to-integer (sys:int32>> int 16))))
779 (setf (aref array (the fixnum (+ address 2))) (the fixnum (sys:int32-to-integer (sys:int32>> int 8))))
780 (setf (aref array (the fixnum (+ address 3))) (the fixnum (sys:int32-to-integer int)))))
781) ;#+LispWorks
782
783(defun read-low-24-bits (disk-cache address)
784 (with-databases-locked
785 (multiple-value-bind (array index count)
786 (get-disk-page disk-cache address)
787 (declare (fixnum index count))
788 (unless (>= count 4)
789 (error "Address past eof or not longword aligned: ~s" address))
790 (%%load-low-24-bits array index))))
791
792(defun (setf read-low-24-bits) (value disk-cache address)
793 (unless (fixnump value)
794 (setq value (require-type value 'fixnum)))
795 (unless (>= (disk-cache-size disk-cache)
796 (+ address 4))
797 (extend-disk-cache disk-cache (+ address 4)))
798 (with-databases-locked
799 (multiple-value-bind (array index count)
800 (get-disk-page disk-cache address t)
801 (declare (fixnum index count))
802 (unless (>= count 4)
803 (error "Address not longword aligned: ~s" address))
804 (%%store-low-24-bits value array index)))
805 value)
806
807; Read an unsigned byte. Can't call it read-byte as Common Lisp
808; already exports that symbol
809(defun read-8-bits (disk-cache address)
810 (with-databases-locked
811 (multiple-value-bind (array index count)
812 (get-disk-page disk-cache address)
813 (declare (fixnum index count)
814 (type (simple-array (unsigned-byte 8) (*)) array)
815 (optimize (speed 3) (safety 0)))
816 (unless (>= count 1)
817 (error "Address past eof"))
818 (aref array index))))
819
820(defun read-8-bits-signed (disk-cache address)
821 (with-databases-locked
822 (multiple-value-bind (array index count)
823 (get-disk-page disk-cache address)
824 (declare (fixnum index count)
825 (type (simple-array (signed-byte 8) (*)) array) ;lie
826 (optimize (speed 3) (safety 0)))
827 (unless (>= count 1)
828 (error "Address past eof"))
829 (aref array index))))
830
831(defun %load-8-bits (array address)
832 (ensure-byte-array array)
833 (setq address (require-type address 'fixnum))
834 (locally (declare (fixnum address)
835 (type (simple-array (unsigned-byte 8) (*)) array)
836 (optimize (speed 3) (safety 0)))
837 (check-byte-array-address address 1 array)
838 (aref array address)))
839
840(defun (setf read-8-bits) (value disk-cache address)
841 (unless (>= (disk-cache-size disk-cache)
842 (+ address 4))
843 (extend-disk-cache disk-cache (+ address 4)))
844 (with-databases-locked
845 (multiple-value-bind (array index count)
846 (get-disk-page disk-cache address t)
847 (declare (fixnum index count)
848 (type (simple-array (unsigned-byte 8) (*)) array)
849 (optimize (speed 3) (safety 0)))
850 (unless (>= count 1)
851 (error "Address past eof"))
852 (setf (aref array index) value))))
853
854(defsetf read-8-bits-signed (disk-cache address) (value)
855 `(setf (read-8-bits ,disk-cache ,address) ,value))
856
857(defun %store-8-bits (value array address)
858 (ensure-byte-array array)
859 (setq address (require-type address 'fixnum))
860 (locally (declare (fixnum address)
861 (type (simple-array (unsigned-byte 8) (*)) array)
862 (optimize (speed 3) (safety 0)))
863 (check-byte-array-address address 1 array)
864 (setf (aref array address) value)))
865
866; These will get less ugly when we can stack cons float vectors
867#+ccl-68k-target (progn
868(defun read-double-float (disk-cache address)
869 (let ((vector (make-array 2 :element-type '(signed-byte 32))))
870 (declare (dynamic-extent vector))
871 (load-bytes-to-ivector disk-cache address 8 vector)
872 (ccl::%typed-uvref ccl::$v_floatv vector 0)))
873
874(defun (setf read-double-float) (value disk-cache address)
875 (let ((vector (make-array 2 :element-type '(signed-byte 32))))
876 (declare (dynamic-extent vector))
877 (ccl::%typed-uvset ccl::$v_floatv vector 0 value)
878 (store-bytes-as-byte-vector vector disk-cache address 8 0))
879 value)
880) ; #+ccl-68k-target
881
882#+ppc-target (progn
883(defun (setf read-double-float) (value disk-cache address)
884 (unless (typep value 'double-float)
885 (setq value (require-type value 'double-float)))
886 (store-bytes-as-byte-vector value disk-cache address 8 4)
887 value)
888
889(defun read-double-float (disk-cache address)
890 (let ((float (ccl::%copy-float 0.0)))
891 (load-bytes-as-byte-vector disk-cache address 8 float 4) ;; lie
892 float))
893) ; #+ppc-target
894
895#+LispWorks
896(progn
897
898(defparameter *unknown-float* (make-array 1 :element-type 'double-float :initial-element 7.7d70))
899
900(defun make-a-float ()
901 (declare (optimize (safety 0) (speed 3) #+LispWorks (float 0)))
902 ;; This has to box the float, so we get a new float object.
903 (aref (the (simple-array double-float (*)) *unknown-float*) 0))
904
905(defun read-double-float (disk-cache address)
906 (declare (optimize (speed 3) (safety 0) (debug 0)))
907 (let ((float (make-a-float)))
908 (load-bytes-as-byte-vector disk-cache address 8 float $float-read-offset)
909 float))
910
911(defun (setf read-double-float) (value disk-cache address)
912 (declare (optimize (speed 3) (safety 0) (debug 0)))
913 (store-bytes-as-byte-vector value disk-cache address 8 $float-read-offset)
914 value)
915) ; #+LispWorks
916
917(defun read-string (disk-cache address length &optional string)
918 (setq length (require-type length 'fixnum))
919 (locally (declare (fixnum length))
920 (when (> (+ address length) (disk-cache-size disk-cache))
921 (error "Attempt to read past EOF"))
922 (let ((offset 0)
923 inner-string)
924 (declare (fixnum offset))
925 (cond ((and string
926 (progn
927 (setq string (require-type string 'string))
928 (array-has-fill-pointer-p string)))
929 (if (> length (array-total-size string))
930 (setq string (adjust-array string length))
931 (setf (fill-pointer string) length))
932 (multiple-value-setq (inner-string offset)
933 (array-data-and-offset string)))
934 (string
935 (unless (>= (length string) length)
936 (error "~s is < ~s characters long" string length))
937 (multiple-value-setq (inner-string offset)
938 (array-data-and-offset string)))
939 (t (setq inner-string
940 (setq string (make-string length :element-type 'base-character)))))
941 (loop
942 (with-databases-locked
943 (multiple-value-bind (array index count)
944 (get-disk-page disk-cache address)
945 (declare (fixnum count index))
946 #+ccl-68k-target
947 (ccl::lap-inline ()
948 (:variable array index count length inner-string offset)
949 (ccl::move.l (ccl::varg array) ccl::atemp0)
950 (ccl::move.l (ccl::varg index) ccl::da)
951 (ccl::getint ccl::da)
952 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
953 (ccl::move.l (ccl::varg inner-string) ccl::atemp1)
954 (ccl::move.l (ccl::varg offset) ccl::da)
955 (ccl::getint ccl::da)
956 (ccl::lea (ccl::atemp1 ccl::da.l ccl::$v_data) ccl::atemp1)
957 (ccl::move.l (ccl::varg length) ccl::da)
958 (ccl::if# (ccl::gt (ccl::cmp.l (ccl::varg count) ccl::da))
959 (ccl::move.l (ccl::varg count) ccl::da))
960 (ccl::getint ccl::da)
961 (ccl::dbfloop.l ccl::da
962 (ccl::move.b ccl::atemp0@+ ccl::atemp1@+)))
963 #-ccl-68k-target
964 (copy-as-byte-vector
965 array index inner-string offset
966 (if (< count length) count length))
967 (when (<= (decf length count) 0)
968 (return))
969 (incf address (the fixnum (+ count $block-overhead)))
970 (incf offset count))))))
971 string)
972
973; Same as array-data-and-offset but works for
974; non-array uvectors.
975(defun lenient-array-data-and-offset (array)
976 (if #+ccl-68k-target (eql $v_arrayh (%vect-subtype array))
977 #+ppc-target (let ((typecode (ppc-typecode array)))
978 (declare (fixnum typecode))
979 (or (eql typecode ppc::subtag-arrayh)
980 (eql typecode ppc::subtag-vectorh)))
981 #-ccl (arrayp array)
982 (array-data-and-offset array)
983 (values array 0)))
984
985#+ccl-68k-target
986(defun uvector-bytes (uvector)
987 (ccl::lap-inline (uvector)
988 (ccl::if# (ccl::eq (ccl::dtagp ccl::arg_z ccl::$t_vector))
989 (ccl::wtaerr ccl::arg_z 'ccl::uvector))
990 (ccl::move.l ccl::arg_z ccl::atemp0)
991 (ccl::vsize ccl::atemp0 ccl::arg_z)
992 (ccl::mkint ccl::arg_z)))
993
994#+ppc-target
995(defun uvector-bytes (uvector)
996 (let* ((typecode (ppc-typecode uvector))
997 (typecode-tag (logand typecode ppc::fulltagmask))
998 (length (uvsize uvector)))
999 (declare (fixnum typecode t typecode-tag))
1000 (if (eql typecode-tag ppc::fulltag-immheader)
1001 (ppc-subtag-bytes typecode length)
1002 (ash length 2))))
1003
1004(defun-inline load-bytes-to-string (disk-cache address length string)
1005 (ensure-byte-array string)
1006 (if (> length (byte-vector-length string))
1007 (error "(~s ~s) < ~s" 'byte-vector-length string length))
1008 (load-bytes-to-ivector disk-cache address length string))
1009
1010(defun-inline load-bytes-to-bit-vector (disk-cache address num-bytes bitvector)
1011 (assert (typep bitvector '(simple-array (unsigned-byte 1) (*))))
1012 (load-bytes-to-ivector disk-cache address num-bytes bitvector))
1013
1014(defun load-bytes-to-ivector (disk-cache address length ivector)
1015 (declare (special *subtype->bytes-per-element* *subtype->array-byte-offset*))
1016 (multiple-value-bind (inner-array offset) (lenient-array-data-and-offset ivector)
1017 (let* ((subtype (uvector-subtype ivector))
1018 (byte-offset (+ (* offset (svref *subtype->bytes-per-element* subtype))
1019 #+LispWorks (svref *subtype->array-byte-offset* subtype))))
1020 (load-bytes-as-byte-vector disk-cache address length inner-array byte-offset)))
1021 ivector)
1022
1023#+LispWorks
1024(defun load-bytes-to-iarray (disk-cache address num-bytes array)
1025 ;; Array is a non-displaced array of immediate data. I won't even begin to guess at the
1026 ;; internal format.
1027 (let* ((num-elts (array-total-size array))
1028 (ivector (make-array num-elts :element-type (array-element-type array))))
1029 (load-bytes-to-ivector disk-cache address num-bytes ivector)
1030 (loop for i from 0 below num-elts
1031 do (setf (row-major-aref array i) (aref ivector i)))
1032 array))
1033
1034(defun load-bytes-as-byte-vector (disk-cache address length ivector byte-offset)
1035 (setq length (require-type length 'fixnum))
1036 (setq byte-offset (require-type byte-offset 'fixnum))
1037 (setq ivector (require-type ivector 'simple-array))
1038 (locally (declare (fixnum length byte-offset))
1039 (when (> (+ address length) (disk-cache-size disk-cache))
1040 (error "Attempt to read past EOF"))
1041 (loop
1042 (with-databases-locked
1043 (multiple-value-bind (array index count)
1044 (get-disk-page disk-cache address)
1045 (declare (fixnum count index))
1046 #+ccl-68k-target
1047 (ccl::lap-inline ()
1048 (:variable array index count length ivector byte-offset)
1049 (ccl::move.l (ccl::varg array) ccl::atemp0)
1050 (ccl::move.l (ccl::varg index) ccl::da)
1051 (ccl::getint ccl::da)
1052 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1053 (ccl::move.l (ccl::varg ivector) ccl::atemp1)
1054 (ccl::move.l (ccl::varg byte-offset) ccl::da)
1055 (ccl::getint ccl::da)
1056 (ccl::lea (ccl::atemp1 ccl::da.l ccl::$v_data) ccl::atemp1)
1057 (ccl::move.l (ccl::varg length) ccl::da)
1058 (ccl::if# (ccl::gt (ccl::cmp.l (ccl::varg count) ccl::da))
1059 (ccl::move.l (ccl::varg count) ccl::da))
1060 (ccl::getint ccl::da)
1061 (ccl::dbfloop.l ccl::da
1062 (ccl::move.b ccl::atemp0@+ ccl::atemp1@+)))
1063 #-ccl-68k-target
1064 (copy-as-byte-vector array index ivector byte-offset
1065 (if (< count length) count length))
1066 (when (<= (decf length count) 0)
1067 (return))
1068 (incf address (the fixnum (+ count $block-overhead)))
1069 (incf byte-offset count))))))
1070
1071
1072; Copy length bytes from from at from-index to to at to-index.
1073; from-index, length, and to-index must be fixnums
1074; if (eq from to), the copying will be done in the correct order.
1075; If either array is not a byte array or string, you will likely crash
1076; sometime in the future.
1077(defun %copy-byte-array-portion (from from-index length to to-index &optional to-page)
1078 (declare (ignore to-page)) ; for logging/recovery
1079 (setq from-index (require-type from-index 'fixnum))
1080 (setq length (require-type length 'fixnum))
1081 (setq to-index (require-type to-index 'fixnum))
1082 (locally (declare (fixnum from-index length to-index))
1083 (when (> length 0)
1084 (unless (and (>= from-index 0)
1085 (<= (the fixnum (+ from-index length)) (byte-vector-length from))
1086 (>= to-index 0)
1087 (<= (the fixnum (+ to-index length)) (byte-vector-length to)))
1088 (error "Attempt to index off end of one of the arrays"))
1089 (multiple-value-bind (from off) (lenient-array-data-and-offset from)
1090 (incf from-index off)
1091 (multiple-value-bind (to off) (lenient-array-data-and-offset to)
1092 (incf to-index off)
1093 (ensure-byte-array from)
1094 (ensure-byte-array to)
1095 #+ccl-68k-target
1096 (ccl::lap-inline ()
1097 (:variable from from-index length to to-index)
1098 (ccl::move.l (ccl::varg from) ccl::atemp0)
1099 (ccl::move.l ccl::atemp0 ccl::arg_x) ; arg_x = from
1100 (ccl::move.l (ccl::varg from-index) ccl::da)
1101 (ccl::getint ccl::da)
1102 (ccl::move.l ccl::da ccl::arg_y) ; arg_y = from-index
1103 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1104 (ccl::move.l (ccl::varg to) ccl::atemp1)
1105 (ccl::move.l ccl::atemp1 ccl::arg_z) ; arg_z = to
1106 (ccl::move.l (ccl::varg to-index) ccl::da)
1107 (ccl::getint ccl::da)
1108 (ccl::move.l ccl::da ccl::db) ; db = to-index
1109 (ccl::lea (ccl::atemp1 ccl::da.l ccl::$v_data) ccl::atemp1)
1110 (ccl::move.l (ccl::varg length) ccl::da)
1111 (ccl::getint ccl::da)
1112 ; _BlockMove is slower for small moves
1113 (ccl::if# (ccl::gt (ccl::cmp.l (ccl::$ 128) ccl::da))
1114 (ccl::move.l ccl::da ccl::acc)
1115 (ccl::dc.w #_BlockMove)
1116 ccl::else#
1117 (ccl::if# (and (ccl::eq (ccl::cmp.l ccl::arg_x ccl::arg_z))
1118 (ccl::gt (ccl::cmp.l ccl::arg_y ccl::db)))
1119 (ccl::add.l ccl::da ccl::atemp0)
1120 (ccl::add.l da ccl::atemp1)
1121 (ccl::dbfloop.l ccl::da
1122 (ccl::move.b ccl::-@atemp0 ccl::-@atemp1))
1123 ccl::else#
1124 (ccl::dbfloop.l ccl::da
1125 (ccl::move.b ccl::atemp0@+ ccl::atemp1@+)))))
1126 #-ccl-68k-target
1127 (copy-as-byte-vector
1128 from from-index to to-index length)))))
1129 to)
1130
1131(defun %load-string (array index length &optional string)
1132 (unless string
1133 (setq string (make-string length :element-type 'base-character)))
1134 (%copy-byte-array-portion array index length string 0))
1135
1136(defun %store-string (string array index &optional (length (length string)))
1137 (%copy-byte-array-portion string 0 length array index)
1138 string)
1139
1140(defun (setf read-string) (string disk-cache address &optional length)
1141 (if length
1142 (when (> (setq length (require-type length 'fixnum)) (length string))
1143 (error "~s > the length of the string." 'length))
1144 (setq length (length string)))
1145 (unless (>= (disk-cache-size disk-cache)
1146 (+ address length))
1147 (extend-disk-cache disk-cache (+ address length)))
1148 (multiple-value-bind (string offset) (array-data-and-offset string)
1149 (declare (fixnum offset))
1150 (loop
1151 (with-databases-locked
1152 (multiple-value-bind (array index count)
1153 (get-disk-page disk-cache address t)
1154 (declare (fixnum count index))
1155 #+ccl-68k-target
1156 (ccl::lap-inline ()
1157 (:variable array index count length string offset)
1158 (ccl::move.l (ccl::varg array) ccl::atemp0)
1159 (ccl::move.l (ccl::varg index) ccl::da)
1160 (ccl::getint ccl::da)
1161 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1162 (ccl::move.l (ccl::varg string) ccl::atemp1)
1163 (ccl::move.l (ccl::varg offset) ccl::da)
1164 (ccl::getint ccl::da)
1165 (ccl::lea (ccl::atemp1 ccl::da.l ccl::$v_data) ccl::atemp1)
1166 (ccl::move.l (ccl::varg length) ccl::da)
1167 (ccl::if# (ccl::gt (ccl::cmp.l (ccl::varg count) ccl::da))
1168 (ccl::move.l (ccl::varg count) ccl::da))
1169 (ccl::getint ccl::da)
1170 (ccl::dbfloop.l ccl::da
1171 (ccl::move.b ccl::atemp1@+ ccl::atemp0@+)))
1172 #-ccl-68k-target
1173 (copy-as-byte-vector
1174 string offset array index
1175 (if (< count length) count length))
1176 (when (<= (decf length count) 0)
1177 (return))
1178 (incf address (the fixnum (+ count wood::$block-overhead)))
1179 (incf offset count)))))
1180 string)
1181
1182
1183(defun-inline store-bytes-from-string (byte-array disk-cache address length)
1184 (ensure-byte-array byte-array)
1185 (store-bytes-from-ivector byte-array disk-cache address length))
1186
1187(defun-inline store-bytes-from-bit-vector (bitvector disk-cache address length)
1188 (assert (typep bitvector '(simple-array (unsigned-byte 1) (*))))
1189 (store-bytes-from-ivector bitvector disk-cache address length))
1190
1191(defun store-bytes-from-ivector (ivector disk-cache address length)
1192 (declare (special *subtype->bytes-per-element* *subtype->array-byte-offset*))
1193 (multiple-value-bind (inner-array offset) (lenient-array-data-and-offset ivector)
1194 (let* ((subtype (uvector-subtype ivector))
1195 (byte-offset (+ (* offset (svref *subtype->bytes-per-element* subtype))
1196 #+LispWorks (svref *subtype->array-byte-offset* subtype))))
1197 (store-bytes-as-byte-vector inner-array disk-cache address length byte-offset))))
1198
1199#+LispWorks
1200(defun store-bytes-from-iarray (array disk-cache address num-bytes)
1201 ;; Array is a non-displaced array of immediate data. I won't even begin to guess at the
1202 ;; internal format.
1203 (let* ((num-elts (array-total-size array))
1204 (ivector (make-array num-elts :element-type (array-element-type array))))
1205 (loop for i from 0 below num-elts
1206 do (setf (aref ivector i) (row-major-aref array i)))
1207 (store-bytes-from-ivector ivector disk-cache address num-bytes)
1208 array))
1209
1210
1211(defun store-bytes-as-byte-vector (byte-array disk-cache address length start)
1212 (setq length (require-type length 'fixnum))
1213 (setq start (require-type start 'fixnum))
1214 (locally (declare (fixnum length))
1215 (when (> (+ address length) (disk-cache-size disk-cache))
1216 (error "Attempt to read past EOF"))
1217 (multiple-value-bind (inner-array offset) (lenient-array-data-and-offset byte-array)
1218 (incf offset start)
1219 (loop
1220 (with-databases-locked
1221 (multiple-value-bind (array index count)
1222 (get-disk-page disk-cache address t)
1223 (declare (fixnum count index))
1224 #+ccl-68k-target
1225 (ccl::lap-inline ()
1226 (:variable array index count length inner-array offset)
1227 (ccl::move.l (ccl::varg array) ccl::atemp0)
1228 (ccl::move.l (ccl::varg index) ccl::da)
1229 (ccl::getint ccl::da)
1230 (lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1231 (ccl::move.l (ccl::varg inner-array) ccl::atemp1)
1232 (ccl::move.l (ccl::varg offset) ccl::da)
1233 (ccl::getint ccl::da)
1234 (ccl::lea (ccl::atemp1 ccl::da.l ccl::$v_data) ccl::atemp1)
1235 (ccl::move.l (ccl::varg length) ccl::da)
1236 (ccl::if# (ccl::gt (ccl::cmp.l (ccl::varg count) ccl::da))
1237 (ccl::move.l (ccl::varg count) ccl::da))
1238 (ccl::getint ccl::da)
1239 (ccl::dbfloop.l ccl::da
1240 (ccl::move.b ccl::atemp1@+ ccl::atemp0@+)))
1241 #-ccl-68k-target
1242 (copy-as-byte-vector
1243 inner-array offset array index
1244 (if (< count length) count length))
1245 (when (<= (decf length count) 0)
1246 (return))
1247 (incf address (the fixnum (+ count $block-overhead)))
1248 (incf offset count))))))
1249 byte-array)
1250
1251
1252(defun fill-long (disk-cache address value count &optional immediate?)
1253 (let ((count (require-type count 'fixnum)))
1254 (declare (fixnum count))
1255 (unless (eql 0 (logand 1 address))
1256 (error "Odd address: ~s" address))
1257 (when (<= count 0) (return-from fill-long) nil)
1258 (let ((min-size (+ address (ash count 2))))
1259 (when (< (disk-cache-size disk-cache) min-size)
1260 (extend-disk-cache disk-cache min-size)))
1261 (loop
1262 (with-databases-locked
1263 (multiple-value-bind (vector offset size)
1264 (get-disk-page disk-cache address t)
1265 (declare (fixnum offset size))
1266 (when (<= size 0)
1267 (error "attempt to write past end of ~s" disk-cache))
1268 (let ((words (ash size -2)))
1269 (declare (fixnum words))
1270 (if (< count words) (setq words count))
1271 #+ccl-68k-target
1272 (ccl::lap-inline ()
1273 (:variable vector offset words value immediate?)
1274 (ccl::move.l (ccl::varg value) ccl::arg_z)
1275 (ccl::if# (ccl::eq (ccl::cmp.l (ccl::varg immediate?) ccl::nilreg))
1276 (ccl::jsr_subprim ccl::$sp-getxlong)
1277 ccl::else#
1278 (ccl::movereg ccl::arg_z ccl::acc))
1279 (ccl::move.l (ccl::varg vector) ccl::atemp0)
1280 (ccl::move.l (ccl::varg offset) ccl::da)
1281 (ccl::getint ccl::da)
1282 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1283 (ccl::move.l (ccl::varg words) ccl::da)
1284 (ccl::getint ccl::da)
1285 (ccl::dbfloop.l ccl::da (ccl::move.l ccl::acc ccl::atemp0@+)))
1286 #-ccl-68k-target
1287 (if immediate?
1288 (dotimes (i words)
1289 (%%store-pointer value vector offset t)
1290 (incf offset 4))
1291 (dotimes (i words)
1292 (%%store-long value vector offset)
1293 (incf offset 4)))
1294 (if (<= (decf count words) 0) (return)))
1295 (incf address (the fixnum (+ size $block-overhead))))))))
1296
1297(defun fill-word (disk-cache address value count &optional immediate?)
1298 (declare (ignore immediate?))
1299 (let ((count (require-type count 'fixnum))
1300 (address address)
1301 (value (require-type value 'fixnum)))
1302 (declare (fixnum count))
1303 (unless (eql 0 (logand 1 address))
1304 (error "Odd address: ~s" address))
1305 (when (<= count 0) (return-from fill-word) nil)
1306 (let ((min-size (+ address (ash count 1))))
1307 (when (< (disk-cache-size disk-cache) min-size)
1308 (extend-disk-cache disk-cache min-size)))
1309 (loop
1310 (with-databases-locked
1311 (multiple-value-bind (vector offset size)
1312 (get-disk-page disk-cache address t)
1313 (declare (fixnum offset size))
1314 (when (<= size 0)
1315 (error "attempt to write past end of ~s" disk-cache))
1316 (let ((words (ash size -1)))
1317 (declare (fixnum words))
1318 (if (< count words) (setq words count))
1319 #+ccl-68k-target
1320 (ccl::lap-inline ()
1321 (:variable vector offset words value)
1322 (ccl::move.l (ccl::varg vector) ccl::atemp0)
1323 (ccl::move.l (ccl::varg offset) ccl::da)
1324 (ccl::getint ccl::da)
1325 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1326 (ccl::move.l (ccl::varg words) ccl::da)
1327 (ccl::getint ccl::da)
1328 (ccl::move.l (ccl::varg value) ccl::acc)
1329 (ccl::getint ccl::acc)
1330 (ccl::dbfloop.l ccl::da (ccl:move.w ccl::acc ccl::atemp0@+)))
1331 #+ppc-target
1332 (locally (declare (type (simple-array (unsigned-byte 16) (*)) vector)
1333 (optimize (speed 3) (safety 0)))
1334 (let ((word-offset (ash offset -1)))
1335 (declare (fixnum word-offset))
1336 (dotimes (i words)
1337 (setf (aref vector word-offset) value)
1338 (incf word-offset))))
1339 #-ccl
1340 (dotimes (i words)
1341 (%%store-word value vector offset)
1342 (incf offset 2))
1343 (if (<= (decf count words) 0) (return)))
1344 (incf address (the fixnum (+ size $block-overhead))))))))
1345
1346(defun fill-byte (disk-cache address value count &optional immediate?)
1347 (declare (ignore immediate?))
1348 (let ((count (require-type count 'fixnum))
1349 (address address)
1350 (value (require-type value 'fixnum)))
1351 (declare (fixnum count))
1352 (when (<= count 0) (return-from fill-byte) nil)
1353 (let ((min-size (+ address count)))
1354 (when (< (disk-cache-size disk-cache) min-size)
1355 (extend-disk-cache disk-cache min-size)))
1356 (loop
1357 (with-databases-locked
1358 (multiple-value-bind (vector offset size)
1359 (get-disk-page disk-cache address t)
1360 (declare (fixnum offset size))
1361 (when (<= size 0)
1362 (error "attempt to write past end of ~s" disk-cache))
1363 (if (< count size) (setq size count))
1364 #+ccl-68k-target
1365 (ccl::lap-inline ()
1366 (:variable vector offset size value)
1367 (ccl::move.l (ccl::varg vector) ccl::atemp0)
1368 (ccl::move.l (ccl::varg offset) ccl::da)
1369 (ccl::getint ccl::da)
1370 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1371 (ccl::move.l (ccl::varg size) ccl::da)
1372 (ccl::getint ccl::da)
1373 (ccl::move.l (ccl::varg value) ccl::acc)
1374 (ccl::getint ccl::acc)
1375 (ccl::dbfloop.l ccl::da (ccl::move.b ccl::acc ccl::atemp0@+)))
1376 #-ccl-68k-target
1377 (locally (declare (type (simple-array (unsigned-byte 8) (*)) vector)
1378 (optimize (speed 3) (safety 0)))
1379 (dotimes (i size)
1380 (setf (aref vector offset) value)
1381 (incf offset)))
1382 (if (<= (decf count size) 0) (return))
1383 (incf address (the fixnum (+ size $block-overhead))))))))
1384
1385(defun array-fill-long (array address value count &optional immediate?)
1386 (ensure-byte-array array)
1387 (let ((count (require-type count 'fixnum))
1388 (address (require-type address 'fixnum))
1389 (value (require-type value 'fixnum)))
1390 (declare (fixnum count address))
1391 (check-byte-array-address address (* 4 count) array)
1392 (unless (eql 0 (the fixnum (logand 1 address)))
1393 (error "Odd address: ~s" address))
1394 #+ccl-68k-target
1395 (ccl::lap-inline ()
1396 (:variable array address value count immediate?)
1397 (ccl::move.l (ccl::varg array) ccl::atemp0)
1398 (ccl::move.l (ccl::varg value) ccl::acc)
1399 (ccl::if# (ccl::eq (ccl::cmp.l (ccl::varg immediate?) ccl::nilreg))
1400 (ccl::movereg ccl::acc ccl::arg_z)
1401 (ccl::jsr_subprim ccl::$sp-getxlong))
1402 (ccl::move.l (ccl::varg address) ccl::da)
1403 (ccl::getint ccl::da)
1404 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1405 (ccl::move.l (ccl::varg count) ccl::da)
1406 (ccl::dbfloop.l ccl::da (ccl::move.l ccl::acc ccl::atemp0@+)))
1407 #-ccl-68k-target
1408 (let ((offset address))
1409 (declare (fixnum offset))
1410 (if immediate?
1411 (dotimes (i count)
1412 (%%store-pointer value array offset t)
1413 (incf offset 4))
1414 (dotimes (i count)
1415 (%%store-long value array offset)
1416 (incf offset 4)))))
1417 nil)
1418
1419(defun array-fill-word (array address value count)
1420 (ensure-byte-array array)
1421 (let ((count (require-type count 'fixnum))
1422 (address (require-type address 'fixnum))
1423 (value (require-type value 'fixnum)))
1424 (declare (fixnum count address))
1425 (check-byte-array-address address (* 2 count) array)
1426 (unless (eql 0 (the fixnum (logand 1 address)))
1427 (error "Odd address: ~s" address))
1428 #+ccl-68k-target
1429 (ccl::lap-inline ()
1430 (:variable array address value count)
1431 (ccl::move.l (ccl::varg array) ccl::atemp0)
1432 (ccl::move.l (ccl::varg value) ccl::acc)
1433 (ccl::getint ccl::acc)
1434 (ccl::move.l (ccl::varg address) ccl::da)
1435 (ccl::getint ccl::da)
1436 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1437 (ccl::move.l (ccl::varg count) ccl::da)
1438 (ccl::dbfloop.l ccl::da (ccl::move.w ccl::acc ccl::atemp0@+)))
1439 #+ppc-target
1440 (let ((index (ash address -1)))
1441 (declare (fixnum offset)
1442 (type (simple-array (unsigned-byte 16) (*)) array)
1443 (optimize (speed 3) (safety 0)))
1444 (dotimes (i count)
1445 (setf (aref array index) value)
1446 (incf index)))
1447 #-ccl
1448 (dotimes (i count)
1449 (declare (fixnum i))
1450 (%%store-word value array address)
1451 (incf address 2)))
1452 nil)
1453
1454(defun array-fill-byte (array address value count)
1455 (ensure-byte-array array)
1456 (let ((count (require-type count 'fixnum))
1457 (address (require-type address 'fixnum))
1458 (value (require-type value 'fixnum)))
1459 (declare (fixnum count address))
1460 (check-byte-array-address address count array)
1461 #+ccl-68k-target
1462 (ccl::lap-inline ()
1463 (:variable array address value count)
1464 (ccl::move.l (ccl::varg array) ccl::atemp0)
1465 (ccl::move.l (ccl::varg value) ccl::acc)
1466 (ccl::getint ccl::acc)
1467 (ccl::move.l (ccl::varg address) ccl::da)
1468 (ccl::getint ccl::da)
1469 (ccl::lea (ccl::atemp0 ccl::da.l ccl::$v_data) ccl::atemp0)
1470 (ccl::move.l (ccl::varg count) ccl::da)
1471 (ccl::getint ccl::da)
1472 (ccl::dbfloop.l ccl::da (ccl::move.b ccl::acc ccl::atemp0@+)))
1473 #-ccl-68k-target
1474 (let ((offset address))
1475 (declare (fixnum offset)
1476 (type (simple-array (unsigned-byte 8) (*)) array)
1477 (optimize (speed 3) (safety 0)))
1478 (dotimes (i count)
1479 (setf (aref array offset) value)
1480 (incf offset))))
1481 nil)
1482
1483
1484; some macros to make using this take less typing.
1485(export '(accessing-disk-cache))
1486
1487(defmacro accessing-disk-cache ((disk-cache &optional base) &body body)
1488 (let* ((b (gensym)))
1489 `(let ((-*dc*- ,disk-cache)
1490 ,@(when base
1491 `((,b ,base))))
1492 (macrolet ((-*addr*- (address)
1493 (if ',base
1494 `(+ ,',b ,address)
1495 address))
1496 (-*select*- (operation disk-cache-code array-code)
1497 (declare (ignore array-code))
1498 (if (eq disk-cache-code :error)
1499 (error "~s not supported for disk-cache's" operation))
1500 disk-cache-code))
1501 ,@body))))
1502
1503(defmacro accessing-byte-array ((byte-array &optional base disk-page) &body body)
1504 (let* ((b (gensym)))
1505 `(let ((-*dc*- ,byte-array)
1506 ,@(when base
1507 `((,b ,base))))
1508 (macrolet ((-*addr*- (address)
1509 (if ',base
1510 `(+ ,',b ,address)
1511 address))
1512 (-*select*- (operation disk-cache-code array-code)
1513 (declare (ignore disk-cache-code))
1514 (if (eq array-code :error)
1515 (error "~s not supported for arrays" operation))
1516 array-code))
1517 ,disk-page
1518 ,@body))))
1519
1520(defun ensure-accessing-disk-cache (accessor env)
1521 (unless (and (eq :lexical (variable-information '-*dc*- env))
1522 #-LispWorks (eq :macro (function-information '-*addr*- env))
1523 #-LispWorks (eq :macro (function-information '-*select*- env)))
1524 (error "~s called ouside of ~s environment" accessor 'accessing-disk-cache)))
1525
1526(defmacro load.l (address &environment env)
1527 (ensure-accessing-disk-cache 'load.l env)
1528 `(-*select*-
1529 load.l
1530 (read-long -*dc*- (-*addr*- ,address))
1531 (%load-long -*dc*- (-*addr*- ,address))))
1532
1533(defmacro load.ul (address &environment env)
1534 (ensure-accessing-disk-cache 'load.ul env)
1535 `(-*select*-
1536 load.ul
1537 (read-unsigned-long -*dc*- (-*addr*- ,address))
1538 (%load-unsigned-long -*dc*- (-*addr*- ,address))))
1539
1540(defmacro load.p (address &environment env)
1541 (ensure-accessing-disk-cache 'load.ul env)
1542 `(-*select*-
1543 load.p
1544 (read-pointer -*dc*- (-*addr*- ,address))
1545 (%load-pointer -*dc*- (-*addr*- ,address))))
1546
1547(defmacro load.w (address &environment env)
1548 (ensure-accessing-disk-cache 'load.w env)
1549 `(the fixnum
1550 (-*select*-
1551 load.w
1552 (read-word -*dc*- (-*addr*- ,address))
1553 (%load-word -*dc*- (-*addr*- ,address)))))
1554
1555(defmacro load.uw (address &environment env)
1556 (ensure-accessing-disk-cache 'load.uw env)
1557 `(the fixnum
1558 (-*select*-
1559 load.uw
1560 (read-unsigned-word -*dc*- (-*addr*- ,address))
1561 (%load-unsigned-word -*dc*- (-*addr*- ,address)))))
1562
1563(defmacro load.b (address &environment env)
1564 (ensure-accessing-disk-cache 'load.b env)
1565 `(the fixnum
1566 (-*select*-
1567 load.b
1568 (read-8-bits -*dc*- (-*addr*- ,address))
1569 (%load-8-bits -*dc*- (-*addr*- ,address)))))
1570
1571(defmacro load.string (address length &optional string &environment env)
1572 (ensure-accessing-disk-cache 'load.string env)
1573 `(-*select*-
1574 load.string
1575 (read-string -*dc*- (-*addr*- ,address) ,length
1576 ,@(if string `(,string)))
1577 (%load-string -*dc*- (-*addr*- ,address) ,length
1578 ,@(if string `(,string)))))
1579
1580(defmacro store.l (value address &environment env)
1581 (ensure-accessing-disk-cache 'store.l env)
1582 `(-*select*-
1583 store.l
1584 (let ((-*temp*- ,value))
1585 (setf (read-long -*dc*- (-*addr*- ,address)) -*temp*-))
1586 (%store-long ,value -*dc*- (-*addr*- ,address))))
1587
1588(defmacro store.p (value address &optional value-imm? &environment env)
1589 (ensure-accessing-disk-cache 'store.p env)
1590 `(-*select*-
1591 store.p
1592 (let ((-*temp*- ,value))
1593 (setf (read-pointer -*dc*- (-*addr*- ,address)
1594 ,@(if value-imm? `(,value-imm?)))
1595 -*temp*-))
1596 (%store-pointer ,value -*dc*- (-*addr*- ,address)
1597 ,@(if value-imm? `(,value-imm?)))))
1598
1599(defmacro store.w (value address &environment env)
1600 (ensure-accessing-disk-cache 'store.w env)
1601 `(-*select*-
1602 store.w
1603 (let ((-*temp*- ,value))
1604 (setf (read-word -*dc*- (-*addr*- ,address)) -*temp*-))
1605 (%store-word ,value -*dc*- (-*addr*- ,address))))
1606
1607(defmacro store.b (value address &environment env)
1608 (ensure-accessing-disk-cache 'store.b env)
1609 `(-*select*-
1610 store.b
1611 (let ((-*temp*- ,value))
1612 (setf (read-8-bits -*dc*- (-*addr*- ,address)) -*temp*-))
1613 (%store-8-bits ,value -*dc*- (-*addr*- ,address))))
1614
1615(defmacro store.string (string address &optional length &environment env)
1616 (ensure-accessing-disk-cache 'store.string env)
1617 `(-*select*-
1618 store.string
1619 (funcall #'(setf read-string)
1620 ,string -*dc*- (-*addr*- ,address)
1621 ,@(if length `(,length)))
1622 (%store-string ,string -*dc*- (-*addr*- ,address)
1623 ,@(if length `(,length)))))
1624
1625(defmacro fill.l (address value count &optional imm? &environment env)
1626 (ensure-accessing-disk-cache 'fill.l env)
1627 `(-*select*-
1628 fill.l
1629 (fill-long -*dc*- (-*addr*- ,address) ,value ,count ,imm?)
1630 (array-fill-long -*dc*- (-*addr*- ,address) ,value ,count ,imm?)))
1631
1632(defmacro fill.w (address value count &environment env)
1633 (ensure-accessing-disk-cache 'fill.w env)
1634 `(-*select*-
1635 fill.w
1636 (fill-word -*dc*- (-*addr*- ,address) ,value ,count)
1637 (array-fill-word -*dc*- (-*addr*- ,address) ,value ,count)))
1638
1639(defmacro fill.b (address value count &environment env)
1640 (ensure-accessing-disk-cache 'fill.b env)
1641 `(-*select*-
1642 fill.b
1643 (fill-byte -*dc*- (-*addr*- ,address) ,value ,count)
1644 (array-fill-byte -*dc*- (-*addr*- ,address) ,value ,count)))
1645
1646(defmacro svref.p (vector index &environment env)
1647 (ensure-accessing-disk-cache 'svref.p env)
1648 `(-*select*-
1649 svref.p
1650 (dc-%svref -*dc*- ,vector ,index)
1651 :error))
1652
1653(defmacro svset.p (vector index value &optional immediate? &environment env)
1654 (ensure-accessing-disk-cache 'svset.p env)
1655 `(-*select*-
1656 svset.p
1657 (setf (dc-%svref -*dc*- ,vector ,index ,@(if immediate? `(,immediate?)))
1658 ,value)
1659 :error))
1660
1661(defmacro %vector-size.p (vector &environment env)
1662 (ensure-accessing-disk-cache '%vector-size.p env)
1663 `(-*select*-
1664 %vector-size.p
1665 (dc-%vector-size -*dc*- ,vector)
1666 :error))
1667
1668
1669#|
1670(close-disk-cache dc)
1671(setq wood::dc (wood::open-disk-cache "temp.dc"
1672 :if-exists :overwrite
1673 :if-does-not-exist :create))
1674
1675(defun wood::wi (&optional (count 100000))
1676 (declare (special wood::dc))
1677 (let ((index 0))
1678 (declare (fixnum index))
1679 (dotimes (i count)
1680 (setf (wood::read-long wood::dc index) i)
1681 (incf index 4))))
1682
1683(defun wood::ri (&optional (count 100000))
1684 (declare (special wood::dc))
1685 (let ((index 0))
1686 (declare (fixnum index))
1687 (dotimes (i count)
1688 (let ((was (wood::read-long wood::dc index)))
1689 (incf index 4)
1690 (unless (eql i was)
1691 (cerror "continue" "SB: ~d, Was: ~d" i was))))))
1692
1693#-ppc-target
1694(progn
1695
1696(require :lapmacros)
1697
1698(defun time-moves (&optional (count 100))
1699 (setq count (require-type count 'fixnum))
1700 (macrolet ((moves (count)
1701 `(ccl::lap-inline (,count)
1702 (ccl::getint ccl::arg_z)
1703 (ccl::move.l (ccl::$ 0) ccl::atemp0)
1704 (ccl::dbfloop ccl::arg_z
1705 ,@(make-list 1000
1706 :initial-element
1707 '(ccl::move.l ccl::atemp0@+ ccl::da))))))
1708 (moves count)
1709 (* count 1000)))
1710
1711)
1712
1713
1714; Timing on a mac IIfx running System 7.0.
1715;
1716; (wi) first time: 2080 usec/long (file allocation)
1717; (wi) second time: 372 usec/long (read every block. write half of them)
1718; (ri) first time: 200 usec/long (read every block. write half of them)
1719; (ri) second time: 144 usec/long (read every block)
1720; (ri 20000) 2nd time: 66 usec/long (no disk I/O)
1721; (time-moves): 270 nanoseconds/long
1722
1723(defun wood::ws (&optional (count most-positive-fixnum) (package :ccl))
1724 (declare (special wood::dc))
1725 (let ((address 0))
1726 (do-symbols (sym package)
1727 (let* ((name (symbol-name sym))
1728 (length (length name))
1729 (rounded-length (logand -4 (+ length 3))))
1730 (setf (wood::read-long wood::dc address) (length name))
1731 (incf address 4)
1732 (setf (wood::read-string wood::dc address) name)
1733 (incf address rounded-length)
1734 (if (<= (decf count) 0) (return))))
1735 (setf (wood::read-long wood::dc address) 0)
1736 address))
1737
1738(defun wood::rs ()
1739 (declare (special wood::dc))
1740 (let ((address 0)
1741 (string (make-array 50 :fill-pointer t :adjustable t
1742 :element-type 'base-character)))
1743 (loop
1744 (let ((length (wood::read-long wood::dc address)))
1745 (if (eql length 0) (return))
1746 (incf address 4)
1747 (print (wood::read-string wood::dc address length string))
1748 (incf address (logand -4 (+ length 3)))))))
1749
1750
1751|#
1752;;; 1 3/10/94 bill 1.8d247
1753;;; 2 10/04/94 bill 1.9d071
1754;;; 3 11/01/94 Derek 1.9d085 Bill's Saving Library Task
1755;;; 4 11/03/94 Moon 1.9d086
1756;;; 2 3/23/95 bill 1.11d010
1757;;; 3 6/02/95 bill 1.11d040
Note: See TracBrowser for help on using the repository browser.