BSD 3 development
[unix-history] / usr / src / cmd / liszt / complrd.l
CommitLineData
c7103161
TL
1;--- file: complrd.l
2(include "compmacs.l")
3
4(def e-bind
5 (lambda (v-v v-n)
6 (setq k-bind (cons (cons v-v v-n) k-bind))))
7
8(def e-reg
9 (lambda (v-r v-t)
10 (prog (v-v)
11 (cond ((setq v-v (get v-r x-reg)) (return v-v)))
12 (setq v-v
13 (cond (v-t)
14 ((prog (v-e v-l)
15 (setq v-e '(4 5 2 3 1 0))
16 next
17 (setq v-l k-regs)
18 loop
19 (cond ((null v-l) (return (car v-e)))
20 ((not (equal (cdar v-l) (car v-e)))
21 (setq v-l (cdr v-l))
22 (go loop))
23 ((setq v-e (cdr v-e)) (go next)))))
24 (t (cdar (nth k-regs -1)))))
25 (f-make v-r v-v)
26 (return v-v))))
27;--- e-addr - v-v : s-exp
28; v-r : ?
29; v-t : ?
30; return the address in assembler format of the s-exp in v-v.
31; If the s-exp is a list or number then it must be on the
32; alist, else we look for it on the local variable stack.
33;
34(def e-addr
35 (lambda (v-v v-r v-t)
36 (cond ((not (atom v-v)) (cdr (e-alist (cadr v-v)))) ; (quote arg)
37 ((numberp v-v) (cdr (e-alist v-v))) ;number
38 ((prog (v-l)
39 (cond ((setq v-l (assoc v-v k-bind))
40 (return
41 (cond ((ifflag v-v x-spec)
42 (e-alist v-v))
43 (t `(,(times 4 (cdr v-l))
44 ,lpar
45 ,olbot-reg
46 ,rpar))))))))
47 ((symbolp v-v) (e-alist v-v))
48 ; how is this reachable ??
49 (t (emit3 'movl
50 (list '$ v-v)
51 (cond (v-t (list 'r r-xv))
52 ((equal v-r r-xv) (list 'r r-xv+1))
53 (t (emit3 'movl (list 'r v-r) 'r0)
54 (list 'r r-xv+1))))))))
55
56;--- e-alist - v-v : s-exp to look for on the alist
57; returns an assembler address of the s-exp as an offset off the
58; link register ln-reg. If the given s-exp is not on the alist yet,
59; it is added to it, thus this routine never fails
60;
61(def e-alist
62 (lambda (v-v)
63 (prog (v-x)
64 (setq v-x
65 (cond ((cadr (assoc v-v k-ptrs)))
66 (t (setq k-ptrs
67 (cons (list v-v (setq k-disp (add k-disp 4)))
68 k-ptrs))
69 k-disp)))
70 (return (cond ((zerop v-x) `(* (,ln-reg)))
71 (t `(* ,v-x (,ln-reg))))))))
72
73\f
74;--- e-have - v-e : name of value (how generated?)
75; returns the register which contains this value, else nil if
76; this value is not in a register
77;
78(def e-have
79 (lambda (v-e)
80 (cond ((setq v-e (assoc v-e k-regs)) (cdr v-e)))))
81
82;--- e-note - v-r : register name
83; v-e : name of value
84; returns v-r
85; This makes us remember that register v-r contains value v-e
86; by placing it in the k-regs assoc list
87;
88(def e-note
89 (lambda (v-r v-e)
90 (setq k-regs (cons (cons v-e v-r) k-regs))
91 v-r))
92
93;--- e-lose - v-r : register name
94; returns v-r
95; This says that register v-r is clobbered and no longer contains
96; any known value.
97;
98(def e-lose
99 (lambda (v-r)
100 (setq k-regs (e-drop k-regs v-r))
101 v-r))
102
103;--- e-drop - v-r : register name (in general, anything)
104; v-l : list of registers (in general, any assoc list)
105; returns v-l with all entries with v-r as cadr removed.
106;
107(def e-drop
108 (lambda (v-l v-r)
109 (cond ((null v-l) nil)
110 ((equal (cdar v-l) v-r) (e-drop (cdr v-l) v-r))
111 (t (rplacd v-l (e-drop (cdr v-l) v-r))))))
112
113
114;--- e-type - v-r : register containing a lispval
115; emits instructions which replace that register with the type
116; number of the lispval it contained.
117;
118(def e-type
119 (lambda (v-r)
120 (setq v-r (list 'r v-r))
121 (emit4 'ashl '$-9 v-r v-r)
122 (emit3 'cvtbl (list '"_typetable+1[r" (cadr v-r) '"]") v-r)))
123
124(putprop 'get 'e-get 'x-emit)
125
126(def e-get
127 (lambda (v-r v-v)
128 (prog (v-cou)
129 (setq v-cou (get v-r 'x-count))
130
131 (cond ((null v-cou)
132 (comp-warn " value lost " (or v-v) " from reg " (or v-r)
133 " plist " (plist v-r) N))
134 ((and (eq 'used v-cou) ; if only used once
135 (eq (cadar k-code) v-r)
136 (or (eq 'set (caar k-code))
137 (eq 'push (caar k-code))))
138 (cond ((eq 'set (caar k-code))
139 (e-setnoreg v-v))
140 (t (e-pushnoreg v-v))))
141 (t (setq v-cou (e-have v-v))
142
143 (cond ((equal v-cou (setq v-r (e-reg v-r v-cou)))
144 (return t))
145 ((null v-v) (emit2 'clrl (list 'r v-r)))
146 ((setq v-cou (e-addr v-v v-r t))
147 (emit3 'movl v-cou (list 'r v-r))))
148 (e-note (e-lose v-r) v-v))))))
149\f
150;--- e-setnoreg - v-fromv : value want to set
151; This is used to shorcut the setting of a value. We bypass teh
152; pseudo register. the set instruction is in the car of k-code.
153;
154(def e-setnoreg
155 (lambda (v-fromv)
156 (prog (v-tov v-toadr v-floc)
157 (setq v-tov (caddar k-code) ; get loc to set to
158 v-toadr (e-addr v-tov nil nil) ;loc of it
159 v-floc (e-have v-fromv) ; reg location if exists
160 k-code (cdr k-code))
161
162 (cond ((null v-fromv) (emit2 'clrl v-toadr))
163 (t (cond (v-floc (emit3 'movl `(r ,v-floc) v-toadr))
164 (t (emit3 'movl (e-addr v-fromv nil nil)
165 v-toadr)))))
166
167 loop ; remove alloc occuraces of v-v from the registers
168 (cond ((null (setq v-toadr (e-have v-tov)))
169 (return nil))
170 (t (e-lose v-toadr)))
171 (go loop))))
172(putprop 'set 'e-set 'x-emit)
173;--- e-set - v-r : (actrnum) register number with value in it
174; - v-v : (actvname) name whose value will be replaced
175; emits an instruction to replace the value of v-v with
176; the value in v-r. Then we remove all mention of v-v
177; in the registers since we have changed the value.
178; Finally we note that the value is stored in v-r since
179; that is where it came from
180;
181(def e-set
182 (lambda (v-r v-v)
183 (prog (v-t)
184 (setq v-t (e-addr v-v v-r nil))
185 (cond (v-t (emit3 'movl (list 'r v-r) v-t))
186 (t (return)))
187 loop
188 (cond ((setq v-t (e-have v-v))
189 (e-lose v-t)
190 (go loop)))
191 (e-note v-r v-v))))
192
193(putprop 'push 'e-push 'x-emit)
194
195
196;--- e-push - v-r : register number
197; emits an instruction to push the value in the given register
198; on the name stack
199(def e-push
200 (lambda (v-r)
201 (emit3 'movl
202 (list 'r v-r) push-np)
203 (setq k-stak (add1 k-stak))))
204
205
206;--- e-pushnoreg - v-fromv : value we wish to stack
207; we stack a value without going through a intermediate register.
208;
209(def e-pushnoreg
210 (lambda (v-fromv)
211 (prog (v-floc)
212 (setq v-floc (e-have v-fromv) ; see if from is in regis
213 k-code (cdr k-code))
214
215 (cond ((null v-fromv) (emit2 'clrl push-np))
216 (v-floc (emit3 'movl `(r ,v-floc) push-np))
217 (t (emit3 'movl (e-addr v-fromv nil nil)
218 push-np)))
219 (setq k-stak (add1 k-stak)))))
220
221
222(putprop 'fpush 'e-fpush 'x-emit)
223
224(def e-fpush
225 (lambda (v-r)
226 (emit3 'movl (list 8 '"(" v-r '")") push-np)))
227
228(putprop 'gpush 'e-gpush 'x-emit)
229
230(def e-gpush
231 (lambda (v-r v-v)
232 (prog (v-t)
233 (setq v-t (e-have v-v))
234 (cond ((null v-v) (emit2 i-clr push-np))
235 ((equal v-t (setq v-r (e-reg v-r v-t)))
236 (emit3 i-mov (list 'r v-r) push-np))
237 ((setq v-t (e-addr v-v v-r t))
238 (emit3 i-mov v-t push-np))
239 ((zerop v-r))
240 (t (emit3 i-mov 'r0 push-np)))
241 (setq k-nargs (add1 k-nargs))
242 (setq k-stak (add1 k-stak)))))
243
244(putprop 'gfpush 'e-gfpush 'x-emit)
245
246(def e-gfpush
247 (lambda (v-r v-v)
248 (prog (v-t)
249 (setq v-t (e-have v-v))
250 (cond ((null v-v) (emit2 i-clr push-np))
251 ((equal v-t (setq v-r (e-reg v-r v-t)))
252 (emit3 i-mov (list 'r v-r) push-np))
253 ((setq v-t (cdr (e-addr v-v v-r t)))
254 ; mod by jkf, new calling seq, push atom addr
255 ; on stack, let qfuncl look 8 beyond
256 (emit3 i-mov v-t push-np)
257 ;(emit3 'movl v-t (list 'r v-r))
258 ;(emit3 i-mov (list 8 '"(r" v-r '")") push-np)
259 )
260 ((zerop v-r))
261 (t (emit3 i-mov '"8(r0)" push-np)))
262 (setq k-nargs (add1 k-nargs))
263 (setq k-stak (add1 k-stak)))))
264
265\f
266(putprop 'mark 'e-mark 'x-emit)
267;--- e-mark -
268; emit instructions to begin to call a function. This involves
269; setting lbot in Opus30, and saving the old lbot in Opus 20.
270; Also, some global variables are set.
271; details: In opus 30, np points to the next free loc, we set
272; lbot to one beyond that since where np points we will place
273; the address of the function to call. If we adopt a xfer
274; table scheme for calling, this would be different since
275; we wouldn't stack the address of the function.
276;
277(def e-mark
278 (lambda nil
279 nil)) ; no-op
280
281(putprop 'call 'e-call 'x-emit)
282
283;--- e-call - v-r : register where result will go, this will always be 0
284; - v-a : nil if calling throught the oblist, non nil then
285; this is the address of a system function to call
286; Calls a routine, eithere system or through the oblist.
287; In the former case, we have only stacked the args, in the
288; latter case, lbot points to the function code to call.
289; If we are calling a non system function with 4 or less args
290; we do not set up lbot, instead we enter qfuncl at a special
291; entry point which does the set up.
292;
293(def e-call
294 (lambda (v-r v-a v-nargs)
295 (prog (v-temp)
296 (setq k-stak (difference k-stak v-nargs))
297 (setq k-regs nil)
298 (cond ((or v-a (null (setq v-temp (get 'qfs (sub1 v-nargs)))))
299 (emit3 'movab `(- ,(times 4 v-nargs) ,lpar ,np-reg ,rpar)
300 lbot-reg))) ; set up lbot
301 (cond (v-a (emit3 'calls '$0 v-a)) ; system fcn
302 (v-temp (emit2 'jsb v-temp))
303 (t (emit2 'jsb qfuncl))) ; else non sys fcn
304 (cond (v-a (emit3 'movl lbot-reg np-reg)))))) ; fix up lbot if sys
305
306(putprop 'minus 'e-minus 'x-emit)
307
308(def e-minus
309 (lambda (v-r v-v)
310 (cond ((eq (caar k-code) 'get)
311 (prog (v-i v-b)
312 (setq v-i (cdar k-code))
313 (setq v-b (e-reg (car v-i) nil))
314 (setq k-code (cdr k-code))
315 (e-lose v-b)
316 (cond ((equal v-r v-b)
317 (setq v-r (e-reg (Gensym nil) nil))
318 (cond ((equal v-r v-b)
319 (setq v-r (remainder (add1 v-r) 6) )))
320 (emit3 'movl
321 (list 'r v-b)
322 (list 'r (e-lose v-r)))
323 (e-note v-r (Gensym nil))))
324 (cond ((null (cadr v-i)) (emit2 'clrl (list 'r v-b)))
325 (t (emit3 'movl
326 (e-addr (cadr v-i) v-b t)
327 (list 'r v-b)))))))
328 (cond ((null v-v) (emit2 'tstl (list 'r v-r)))
329 (t (emit3 'cmpl (e-addr v-v v-r t) (list 'r v-r))))))
330\f
331(putprop 'true 'e-true 'x-emit)
332
333(def e-true
334 (lambda (v-l v-dv)
335 (emit2 'jneq v-l)))
336
337(putprop 'false 'e-false 'x-emit)
338
339(def e-false
340 (lambda (v-l v-dv)
341 (emit2 'jeql v-l)))
342
343(putprop 'go 'e-go 'x-emit)
344
345(def e-go
346 (lambda (v-l)
347 (emit2 'jbr v-l)))
348
349(putprop 'skip 'e-skip 'x-emit)
350
351(def e-skip
352 (lambda (v-r v-l)
353 (prog (v-x)
354 (e-lose v-r)
355 (setq v-x (Gensym nil))
356 (emit3 'movab v-x (list 'r v-r))
357 (emit2 'jbr v-l)
358 (emit1 (list v-x ':)))))
359
360(putprop 'return 'e-rtn 'x-emit)
361
362(putprop 'bind 'e-xbind 'x-emit)
363
364;--- e-xbind - v-v : act varname to bind
365; Emits instrutions to bind v-v to the current top of stack.
366; it is possible for v-v to be nil, this means we should ignore
367; this value on the stack (but we remember that it is still on
368; the stack).
369;
370(def e-xbind
371 (lambda (v-vrbl)
372 (prog (v-loc)
373 (cond ((null v-vrbl)) ; ignore if nil
374 ((ifflag v-vrbl x-spec)
375 ; if first bound, get val of bnp in bnp-reg
376 (cond ((zerop k-regf) (emit3 'movl bnp-val bnp-reg)))
377
378
379 (setq k-regf (add1 k-regf) ; count specials bound
380 v-loc (e-alist v-vrbl)) ; addr of vars value
381 (emit3 'movl v-loc '"(r11)+") ; stack value
382 (emit3 'movl (cdr v-loc) '"(r11)+") ; now addr
383 (emit3 'movl bnp-reg bnp-val) ; keep current
384 (emit3 'movl `(,(times 4 k-stak) ,lpar ,olbot-reg ,rpar)
385 v-loc))
386 (t (e-bind v-vrbl k-stak))) ; update k-bind
387 (setq k-stak (add1 k-stak)))))
388
389\f
390
391(putprop 'label 'e-label 'x-emit)
392
393(def e-label
394 (lambda (v-l)
395 (put v-l x-lab 1)
396 (emit1 (list v-l ':))
397 (setq k-regs nil)))
398
399(putprop 'entry 'e-entry 'x-emit)
400
401(def e-entry
402 (lambda (type)
403 (setq k-bind nil)
404 (setq k-stak 0)
405 (emit2 '".word" '"0xdc0") ; save 11,10,8,7,6
406 (emit3 'movab '"linker" ln-reg)
407 (cond ((eq type 'lexpr)
408 (emit4 'subl3 '$4 lbot-reg `"-(sp)") ; stack num of args
409 (emit3 'movl np-reg olbot-reg) ; np is top
410 (emit4 'subl3 lbot-reg np-reg 'r0) ; stack numb of args
411 (emit3 'movab '"0x400(r0)" `(,lpar ,np-reg ,rpar +))
412 (emit3 'movl `(,lpar ,olbot-reg ,rpar) '"-(sp)"))
413 (t
414 (emit3 'movl `( ,lbot-reg) `( ,olbot-reg))))
415 (setq k-name (Gensym nil))
416 (emit1 (list k-name ':))))
417
418(putprop 'repeat 'e-repeat 'x-emit)
419
420(def e-repeat
421 (lambda nil
422 (emit2 'jbr k-name)))
423
424(putprop 'begin 'e-begin 'x-emit)
425
426(def e-begin
427 (lambda (v-nargs)
428 (setq k-stak (difference k-stak v-nargs)) ; make up for stacked args
429 (e-save)
430 (setq k-prog (Gensym nil))
431 (setq k-regf 0))) ; counts specials bound
432
433(putprop 'end 'e-end 'x-emit)
434
435(def e-end
436 (lambda (v-lab)
437 (cond (v-lab (emit1 `(,v-lab :)))) ; if label, put out
438
439 (cond ((not (zerop k-regf)) ; see of special to unbind
440 (emit3 'movl bnp-val bnp-reg)
441 (do ((i k-regf (sub1 i)))
442 ((zerop i) (emit3 'movl bnp-reg bnp-val))
443 (emit3 'movl
444 `(-8 ,lpar ,bnp-reg ,rpar)
445 `(*-4 ,lpar ,bnp-reg ,rpar))
446 (emit3 'subl2 '$8 bnp-reg))))
447
448 ; fix up np-reg to reflect poping off of local variables if
449 ; we are not at the end of the function and there are some to
450 ; pop off
451 (cond ((and (not (eq (caar k-code) 'fini))
452 (not (zerop (difference k-stak (cadr k-save)))))
453 (emit3 'subl2 `($ ,(times 4 (difference k-stak (cadr k-save))))
454 np-reg)))
455 (e-unsave)))
456
457(putprop 'unbind 'e-unbind 'x-emit)
458
459;--- e-unbind - levnum : number of contexts to unbind through
460; this is used to unbind specials when you don't want to
461; go to then end of the current context to do so. this
462; is used, for example, to handle non-local returns
463;
464(def e-unbind
465 (lambda (v-n)
466 (do ((numb k-regf) ; number of specials to unbind
467 (ll k-save (car ll)) ; stack of info
468 (count v-n (sub1 count))) ; index vrbl
469 ((zerop count)
470 ; if any specials were bound in the contexts, emit
471 ; the proper instructions to unbind them
472 (cond ((greaterp numb 0)
473 (emit3 'movl bnp-val bnp-reg)
474 (do ((cnt numb (sub1 cnt)))
475 ((zerop cnt)
476 (emit3 'movl bnp-reg bnp-val))
477 (emit3 'movl
478 `(-8 ,lpar ,bnp-reg ,rpar)
479 `(*-4 ,lpar ,bnp-reg ,rpar))
480 (emit3 'subl2 '$8 bnp-reg))))
481 ; pop off the namestack
482 (cond ((not (zerop (setq ll (difference k-stak (cadr ll)))))
483 (emit3 'subl2 `($ ,(times 4 ll)) np-reg))))
484 (setq numb (plus numb (caddr ll)))))) ; total k-regf
485
486;--- e-unsave : restore the state variables. Occurs when we leave one
487; frame and pop off to the next one
488;
489(def e-unsave
490 (lambda nil
491 (prog (tem)
492 (setq tem k-save
493 k-save (car tem) tem (cdr tem)
494 k-stak (car tem) tem (cdr tem)
495 k-regf (car tem) tem (cdr tem)
496 k-bind (car tem)))))
497
498(def e-save
499 (lambda nil
500 (setq k-save `(,k-save ,k-stak ,k-regf ,k-bind))))
501
502
503(def e-eq
504 (lambda (v-r1 v-r2)
505 (cond ((eq (caar k-code) 'get)
506 (prog (v-i v-b)
507 (setq v-i (cdar k-code))
508 (setq v-b (e-reg (car v-i) nil))
509 (e-lose v-b)
510 (setq k-code (cdr k-code))
511 (cond ((null (cadr v-i)) (emit2 'clrl (list 'r v-b)))
512 (t (emit3 'movl (e-addr (cadr v-i) v-b t)
513 (list 'r v-b)))))))
514 (cond ((eq (caar k-code) 'false)
515 (rplaca (car k-code) 'true))
516 ((eq (caar k-code) 'true)
517 (rplaca (car k-code) 'false)))
518 (emit3 'cmpl v-r1 v-r2)))
519
520(putprop 'eqs 'e-eqs 'x-emit)
521
522;--- e-eqs
523; emits instructions to compare the top two items on the stack.
524; note that it updates np first before poping the items from
525; the stack so if an interrupt occured here the top two values
526; would be clobbered, this must be fixed.
527;
528(def e-eqs
529 (lambda nil
530 (setq k-stak (difference k-stak 2))
531 (emit3 'subl2 '"$8"
532 np-reg)
533 (e-eq `(,lpar ,np-reg ,rpar) ; compare top two times (above stack)
534 `(4 ,lpar ,np-reg ,rpar))))
535
536(putprop 'eqv 'e-eqv 'x-emit)
537
538(def e-eqv
539 (lambda (v-r1 v-r2)
540 (e-eq (e-addr v-r1 nil t) (e-addr v-r2 nil t))))
541
542(putprop 'fixup 'e-fixup 'x-emit)
543
544
545
546\f
547(putprop 'seta 'e-seta 'x-emit)
548
549;--- e-seta - v-r1 : dtpr lispval
550; v-r2 : lispval
551; emits an instruction to replace the car of v-r1 with v-r2
552;
553(def e-seta
554 (lambda (v-r1 v-r2)
555 (emit3 'movl
556 (list 'r (e-reg v-r2 nil))
557 (list 4 '"(r" (e-reg v-r1 nil) '")"))))
558
559(putprop 'setas 'e-setas 'x-emit)
560
561;--- e-setas - v-r : result register
562; top-of-stack: lispval
563; top-of-stack - 1 : dtpr lispval
564; emits instructions to replace the car of the top-of-stack -1 lispval
565; with the top-of-stack lispval, then pops the stack of those two
566; lispval as put the top-of-stack - 1 lispval in v-r.
567; note: here again we pop np too soon which could result in big
568; problem if an interrupt occured in the middle of the instruction
569; sequence.
570;
571(def e-setas
572 (lambda (v-r)
573 (setq v-r (e-reg v-r nil))
574 (setq k-stak (difference k-stak 2))
575 (emit3 'subl2 '"$8"
576 np-reg)
577 (emit3 'movl `(,lpar ,np-reg ,rpar) (list 'r v-r))
578 (emit3 'movl `( 4 ,lpar ,np-reg ,rpar)
579 (list 4 '"(r" v-r '")"))))
580
581(putprop 'setd 'e-setd 'x-emit)
582
583;--- e-setd - v-r1 : dtpr lispval
584; v-r2 : lispval
585; emits instructions to replace the car of v-r1 with v-r2
586;
587(def e-setd
588 (lambda (v-r1 v-r2)
589 (emit3 'movl
590 (list 'r (e-reg v-r2 nil))
591 (list '"(r" (e-reg v-r1 nil) '")"))))
592
593(putprop 'setds 'e-setds 'x-emit)
594
595;--- e-setds - v-r : result register
596; top-of-stack : lispval
597; top-of-stack - 1 : dtpr lisval
598; emits instructions to replace the cdr of the top-of-stack -1
599; lispval with the top of stack lispval. The result is placed
600; in v-r
601(def e-setds
602 (lambda (v-r)
603 (setq v-r (e-reg v-r nil))
604 (setq k-stak (difference k-stak 2))
605 (emit3 'subl2 '"$8" np-reg)
606 (emit3 'movl `(,lpar ,np-reg ,rpar) (list 'r v-r))
607 (emit3 'movl `( 4 ,lpar ,np-reg ,rpar)
608 (list '"(r" v-r '")"))))
609
610
611
612
613(putprop 'dopop 'e-dopop 'x-emit)
614
615(def e-dopop
616 (lambda (v-l)
617 (mapc '(lambda (v-x)
618 (emit3 'movl `( - ,lpar ,np-reg ,rpar)
619 (e-addr v-x nil t))
620 (setq k-stak (sub1 k-stak)))
621 (reverse v-l))))
622
623(putprop 'list 'e-list 'x-emit)
624
625(def e-list (lambda nil nil))
626\f
627(putprop 'chain 'e-chain 'x-emit)
628
629;--- e-chain - v-r : result lispval
630; v-e : dtpr lispval
631; v-b : an atom of the form cxxr where the x's are a's and d's
632; emits instructions to put the cxxr of v-e in v-r
633;
634(def e-chain
635 (lambda (v-r v-e v-b)
636 (setq v-r (e-reg v-r nil))
637 (setq v-e (e-reg v-e nil))
638 (cond ((setq v-b (cdr (reverse (cdr (explode v-b)))))
639 (e-lose v-e)
640 (e-note (e-lose v-r) (Gensym nil))
641 (setq v-r (concat 'r v-r))
642 (setq v-e (concat 'r v-e))
643 (prog (op)
644
645 loop
646 (cond ((null v-b) (return)))
647 (cond ((eq (car v-b) 'd)
648 (setq op (list '"(" v-e '")" )))
649 (t (setq op (list 4 '"(" v-e '")" ))))
650 (setq v-b (cdr v-b))
651 (cond ((and (not (null v-b)) (eq (car v-b) 'd))
652 (setq v-b (cdr v-b))
653 (setq op (cons '* op))))
654 (emit3 'movl op v-r)
655 (setq v-e v-r)
656 (go loop)))
657
658 ((equal v-r v-e))
659
660 (t (emit3 'movl (list 'r v-e) (list 'r v-r))))))
661
662
663(putprop 'getype 'e-getype 'x-emit)
664
665(def e-getype
666 (lambda (v-r v-n)
667 (prog (v-i v-b v-x v-x1)
668 (setq v-r (e-reg v-r nil))
669 (setq v-x1 (setq v-x (list 'r v-r)))
670 (cond ((eq (caar k-code) 'get)
671 (setq v-i (cdar k-code))
672 (setq k-code (cdr k-code))
673 (e-type v-r)
674 (cond ((equal (e-note (e-lose
675 (setq v-b
676 (e-reg (car v-i) nil)))
677 (setq v-i (cadr v-i)))
678 v-r)
679 (emit2 'pushl v-x)
680 (setq v-x '"(sp)")
681 (setq v-x1 '"(sp)+")))
682 (cond ((null v-i) (emit2 'clrl (list 'r v-b)))
683 (t (emit3 'movl (e-addr v-i v-b t)
684 (list 'r v-b)))))
685 (t (e-type v-r)))
686 (e-lose v-r)
687 (cond ((eq v-n 'name)
688 (emit3 'movl (list '"_tynames+4[r" v-r '"]")
689 (list 'r v-r))
690 (emit3 'movl (list '"(r" v-r '")") (list 'r v-r)))
691 ((atom v-n) (emit3 'cmpl (list '$ v-n) v-x1)
692 (cond ((eq (caar k-code) 'false)
693 (rplaca (car k-code) 'true))
694 ((eq (caar k-code) 'true)
695 (rplaca (car k-code) 'false))))
696 (t (prog nil
697 (emit4 'ashl v-x '$1 v-x)
698 (setq v-i 0)
699 loop
700 (cond ((null v-n) (go out)))
701 (setq v-i (mylogor v-i (leftshift 1 (car v-n))))
702 (setq v-n (cdr v-n))
703 (go loop)
704 out
705 (emit3 'bitw (list '$ v-i) v-x1)))))))
706
707
708\f
709(putprop 'catchent 'e-catchent 'x-emit)
710
711;--- e-catchent - v-l : label throw should go to
712; - v-t : tag to be caught
713; - v-f : if non nil reg which contains flag to store in frame
714; We create a catch frame, the form is this:
715; ---------------
716; | return addr |
717; ---------------
718; | reg r13 (fp) |
719; ---------------
720; | reg r10 |
721; ---------------
722; | reg r8 | ^
723; --------------- | high addresses, bottom of stack
724; | reg r6 |
725; ---------------
726; | Saved |
727; | (return) | (10 words) (kls CROCK fix)
728; | dope |
729; ---------------
730; | bnp |
731; ---------------
732; | tag |
733; ---------------
734; | flag |
735; ---------------
736; | link | <-- errp points here
737; ---------------
738;
739; due to bad operation of e-addr (which returns addr of list or number,
740; and value of atom), we must carefully check v-t
741;
742(def e-catchent
743 (lambda (v-l v-t v-f)
744 (emit2 'pushab v-l)
745 (emit2 'pushr '"$0x2540") ; register save mask
746; (emit2 'subl2 '"$40,sp")
747; (emit2 'movc3 '"$40,_setsav,(sp)") ; this won't work since lisp
748 ; may user register 0 - 5
749 ; the whole thing is a crock anyhow
750
751 (emit2 'jsb '_svkludg)
752 (emit2 'pushl bnp-val) ; push value of bnp
753 (cond ((or (numberp v-t) (not (atom v-t)))
754 (emit2 'pushl (e-addr v-t nil nil)))
755 (v-t (emit2 'pushl `(r ,(e-reg v-t nil))))
756 (t (emit2 'clrl '"-(sp)"))) ; tag is nil
757 (cond (v-f (setq v-f (e-reg v-f nil)) ; if flag, find loc
758 (emit2 'pushl `(r ,v-f)))
759 (t (emit2 'pushl '$1))) ; non flag, assume true
760 (emit2 'pushl '_errp) ; sav current errp value
761 (emit3 'movl 'sp '_errp)))
762
763(putprop 'catchexit 'e-catchexit 'x-emit)
764
765;--- e-catchexit - do catchexit stuff. This code is hit if we exit
766; a catch by just falling through, instead of via a throw.
767;
768(def e-catchexit
769 (lambda nil
770 (emit3 'movl '"(sp)" '_errp) ; unstack error frame
771 (emit3 'addl2 '$76 'sp))) ; pop off 9 entries
772 ; + 10 for (return) context
773
774
775(putprop '*throw 'e-*throw 'x-emit)
776
777;--- e-*throw - v-r : pseudo reg containing value to throw
778; - v-nr : pseudo reg containing tag to throw
779;
780(def e-*throw
781 (lambda (v-r v-nr)
782 (setq v-r (e-reg v-r nil) ; get real regis
783 v-nr (e-reg v-nr nil))
784 (emit2 'pushl `(r ,v-r))
785 (emit2 'pushl `(r ,v-nr))
786 (emit3 'calls '$0 '_Idothrow)
787 (emit2 'clrl '"-(sp)")
788 (emit2 'pushab '__erthrow)
789 (emit3 'calls '$2 '_error)))
790(putprop 'pushnil 'e-pushnil 'x-emit)
791;--- e-pushnil - v-num : number of nils to push
792; pushs nils on the np stack in the most efficient way possible
793;
794(def e-pushnil
795 (lambda (v-num)
796 (do ((i v-num (difference i 2)))
797 ((lessp i 2) (cond ((equal i 1) (emit2 'clrl push-np))))
798
799 (emit2 'clrq push-np))
800
801 (setq k-stak (plus k-stak v-num))))
802
803(putprop 'fini 'e-fini 'x-emit)
804
805;--- e-fini
806; called at the end of a function, just emits a ret
807;
808(def e-fini
809 (lambda nil
810 (emit1 'ret)))
811
812(putprop 'arg 'e-arg 'x-emit)
813
814;--- e-arg
815; form is (arg psreg)
816;
817(def e-arg
818 (lambda (v-r)
819 (prog (tmp tmp2)
820 (setq v-r (e-reg v-r nil))
821 (emit3 'movl `(,lpar r ,v-r ,rpar) `(r ,v-r))
822 (emit2 'jeql (setq tmp (Gensym nil)))
823 (emit3 'movl `("*-4(fp)[r" ,v-r "]") `(r ,v-r))
824 (emit2 'jmp (setq tmp2 (Gensym nil)))
825 (emit1 `(,tmp :))
826 (emit3 'movl '"-8(fp)" `(r ,v-r))
827 (emit1 `(,tmp2 :))
828 (e-lose v-r))))
829
830
831\f
832;; special system functions
833
834(defsysf 'minus '_Lminus)
835(defsysf 'add1 '_Ladd1)
836(defsysf 'sub1 '_Lsub1)
837(defsysf 'plist '_Lplist)
838(defsysf 'cons '_Lcons)
839(defsysf 'putprop '_Lputprop)
840(defsysf 'print '_Lprint)
841(defsysf 'patom '_Lpatom)
842(defsysf 'read '_Lread)
843(defsysf 'concat '_Lconcat)
844(defsysf 'get '_Lget)
845(defsysf 'mapc '_Lmapc)
846(defsysf 'mapcan '_Lmapcan)
847(defsysf 'list '_Llist)
848(defsysf 'add '_Ladd)
849(defsysf 'plus '_Ladd)
850(defsysf '> '_Lgreaterp)
851(defsysf '= '_Lequal)
852(defsysf 'times '_Ltimes)
853(defsysf 'difference '_Lsub)
854
855(flag 'set 'x-asg)
856(flag 'push 'x-asg)
857(flag 'minus 'x-asg)
858(flag 'skip 'x-asg)
859(flag 'set 'x-dont)
860(flag 'setq 'x-dont)
861(flag 'prog 'x-dont)
862(flag 'lambda 'x-dont)
863(flag 'go 'x-dont)
864(flag 'return 'x-dont)
865(put 'go 'x-leap 'go)
866(put 'return 'x-leap 'return)
867(put 'label 'x-leap 'go)
868(setq x-spf 'x-spf)
869(setq x-spfq 'x-spfq)
870(setq x-spfn 'x-spfn)
871(setq x-spfh 'x-spfh)
872(setq x-con 'x-con)
873(setq x-leap 'x-leap)
874(setq x-reg 'x-reg)
875(setq x-indx 'x-indx)
876(setq x-opt 'x-opt)
877(setq x-emit 'x-emit)
878(setq x-asg 'x-asg)
879(setq x-lab 'x-lab)
880(setq x-dont 'x-dont)
881(setq g-xv 'xv)
882(setq g-xv+1 'xv+1)
883(setq g-xv+2 'xv+2)
884(setq k-regf nil)
885(setq k-free 'nil)
886(setq k-nargs nil)
887(setq k-cnargs nil)
888(setq k-stak 'nil)
889(setq k-cstk 'nil)
890(setq k-prog 'nil)
891(setq k-undo 'nil)
892(setq k-bind 'nil)
893(setq k-back 'nil)
894(setq k-save 'nil)
895(setq k-code 'nil)
896(setq k-name 'nil)
897(setq k-args 'nil)
898(setq k-regs 'nil)
899(setq push-np '"(r6)+")
900(setq r-xv 0)
901(setq r-xv+1 'r1)
902(put 'xv 'x-reg 0)
903(putprop 'xv 'force 'x-count)
904(put 'xv+1 'x-reg 1)
905(put 'xv+2 'x-reg 2)
906
907(setq $gccount$ 0) ; incase auxfns0 is old
908; macros are not compiled by default
909(setq macros nil)