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