|
|
1.1 root 1: /*
2: *$Header: qfuncl.c,v 1.7 83/09/06 21:49:27 layer Exp $
3: *$Locker: $
4: *
5: * Copyright (c) 1982, by the Regents, University of California
6: *
7: * -[Tue Mar 22 15:42:27 1983 by layer]-
8: *
9: * "quick" functions file.
10: *
11: * This is written in assembler but must be passed through the C preprocessor
12: * before being assembled.
13: *
14: */
15:
16: #include "ltypes.h"
17: #include "config.h"
18:
19: /* important offsets within data types for atoms */
20: #define Atomfnbnd 8
21:
22: /* for arrays */
23: #define Arrayaccfun 0
24:
25: /* register defines */
26: #define FIXREG d2
27:
28: #ifdef NPINREG
29: #define _np a2
30: #define _lbot d3
31: #endif
32:
33:
34: #ifdef PROF
35: .set indx,0
36: #define Profile \
37: lea prbuf+indx,a0 \
38: .set indx,indx+4 \
39: jsr mcount
40: #define Profile2 \
41: movl a0,sp@-
42: lea prbuf+indx,a0 \
43: .set indx,indx+4 \
44: jsr mcount
45: movl sp@+,a0
46: #else
47: #define Profile
48: #define Profile2
49: #endif
50:
51: #ifdef PORTABLE
52: #define NILtest(p) cmpl #/**/OFFSET,p
53: #define NILsub(p) subl #/**/OFFSET,p
54: #else
55: #define NILtest(p)
56: #define NILsub(p)
57: #endif
58:
59:
60: .text
61:
62: /* transfer table linkage routine */
63: .globl _qlinker
64: _qlinker:
65: Profile
66: link a6,#-28
67: tstb sp@(-132)
68: moveml #036000,a6@(-28) |a(2,3,4,5)
69:
70: tstl _exception |any pending exceptions
71: jeq noexc
72: tstl _sigintcnt |is it because of SIGINT
73: jeq noexc |if not, just leave
74: movl #2,sp@- |else push SIGINT
75: jsr _sigcall
76: noexc:
77: movl a6@(4),a4 |get return pc
78: movl a4@(-6),a4 |get pointer to table
79: movl a4@(4),a5 |get atom pointer
80: retry: |come here after undeffunc err
81: movl a5@(8),a0 |get function binding
82: cmpl a0,d7 |if nil,
83: jeq nonex |then leave
84: tstl 2*4+_stattab |see if linkin posble (Strans)
85: jeq nolink |no, it isn't
86: movl a0,d0 |check type of function
87: NILsub(d0)
88: moveq #9,d1
89: asrl d1,d0
90: lea _typetable+1,a3
91: movb a3@(0,d0:L),d1
92: cmpb #/**/BCD,d1
93: jeq linkin |bcd, link it in!
94: cmpb #/**/ARRAY,d1 |how about array?
95: jeq doarray |yep
96:
97: nolink:
98: movl a5,sp@- |non, bcd, call interpreter
99: jsr _Ifuncal
100: moveml a6@(-28),#036000
101: unlk a6
102: rts
103:
104: /*
105: * handle arrays by pushing the array descriptor on the table and checking
106: * for a bcd array handler
107: */
108: doarray:
109: movl a0@(Arrayaccfun),d0 |get access func addr shifted
110: NILsub(d0)
111: movl #9,d1
112: asrl d1,d0
113: lea _typetable+1,a3
114: cmpb #/**/BCD,a3@(0,d0:L) |bcd??
115: jne nolink |no, let funcal handle it
116: movl a0,a2@+ |store array header on stack
117: movl a2,_np
118: movl a0@,a0 |movl *(a0),a0 on VAX
119: movl a0@,a0
120: jsr a0@
121: subql #4,_np
122: moveml a6@(-28),#036000
123: unlk a6
124: rts
125:
126:
127: linkin:
128: movl a0@(4),d0 |check type of function discipline
129: NILsub(d0)
130: movl #9,d1
131: asrl d1,d0
132: lea _typetable+1,a3
133: cmpb #/**/STRNG,a3@(0,d0:L) |is it string?
134: jeq nolink |yes, it is a c call,
135: |so dont link in
136: movl a0@,a0 |get function addr
137: movl a0,a4@ |put fcn addr in table
138: jbsr a0@
139: moveml a6@(-28),#036000
140: unlk a6
141: rts
142:
143:
144: nonex: movl a4,sp@- |preserve table address
145: movl a5,sp@- |non existant fcn
146: jsr _Undeff |call processor
147: movl d0,a5 |back in r1
148: addql #4,sp
149: movl sp@+,a4 |restore table address
150: jra retry |for the retry.
151:
152:
153: .data
154: .globl __erthrow
155: __erthrow:
156: .asciz "Uncaught throw from compiled code"
157: .text
158:
159: .globl _tynames
160: _tynames:
161: .long _nilatom |nothing here
162: .long 20*4+_lispsys |str_name
163: .long 21*4+_lispsys |atom_name
164: .long 19*4+_lispsys |int_name
165: .long 23*4+_lispsys |dtpr_name
166: .long 22*4+_lispsys |doub_name
167: .long 58*4+_lispsys |funct_name
168: .long 103*4+_lispsys |port_name
169: .long 47*4+_lispsys |array_name
170: .long _nilatom |nothing here
171: .long 50*4+_lispsys |sdot_name
172: .long 53*4+_lispsys |val_nam
173:
174: .long _nilatom | hunk2_nam
175: .long _nilatom | hunk4_nam
176: .long _nilatom | hunk8_nam
177: .long _nilatom | hunk16_nam
178: .long _nilatom | hunk32_nam
179: .long _nilatom | hunk64_nam
180: .long _nilatom | hunk128_nam
181: .long 124*4+_lispsys |vector_nam
182: .long 125*4+_lispsys |vectori_nam
183:
184: /* Quickly allocate small fixnums */
185:
186: .globl _qnewint
187: _qnewint:
188: Profile
189: cmpl #1024,FIXREG
190: bge alloc
191: cmpl #-1024,FIXREG
192: bmi alloc
193: movl FIXREG,d0
194: asll #2,d0
195: addl #_Fixzero,d0
196: rts
197: alloc:
198: movl _int_str,a0 |move next cell addr to r0
199: NILtest(a0)
200: jmi callnewi |if no space, allocate
201: movl 4*24+_lispsys,a1
202: addql #1,a1@ |inc count of ints
203: movl a0@,_int_str |advance free list
204: movl FIXREG,a0@ |put baby to bed.
205: movl a0,d0
206: rts
207: callnewi:
208: movl FIXREG,sp@-
209: movl a2,_np |gc could occur
210: movl a2,_lbot
211: jsr _newint
212: movl d0,a0
213: movl sp@+,a0@
214: rts
215:
216: /* _qoneplus adds one to the boxed fixnum in r0
217: * and returns a boxed fixnum.
218: */
219:
220: .globl _qoneplus
221: _qoneplus:
222: Profile
223: movl a0@,FIXREG
224: addql #1,FIXREG
225: bra _qnewint
226:
227: /* _qoneminus subtracts one from the boxes fixnum in r0 and returns a
228: * boxed fixnum
229: */
230: .globl _qoneminus
231: _qoneminus:
232: Profile
233: movl a0@,FIXREG
234: subql #1,FIXREG
235: bra _qnewint
236:
237: /*
238: * _qnewdoub quick allocation of a initialized double (float) cell.
239: * This entry point is required by the compiler for symmetry reasons.
240: * Passed to _qnewdoub in d0,d1 is a double precision floating point
241: * number. This routine allocates a new cell, initializes it with
242: * the given value and then returns the cell.
243: */
244:
245: .globl _qnewdoub
246:
247: _qnewdoub:
248: Profile
249: movl _doub_str,a0 |move next cell addr to r0
250: NILtest(a0)
251: jmi callnewd |if no space, allocate
252: |incl *_lispsys+30*4 |inc count of doubs
253: lea 30*4+_lispsys,a1
254: addl #1,a1@
255: movl a0@,_doub_str |advance free list
256: strdb:
257: movl d0,a0@ |put baby to bed.
258: movl d1,a0@(4) |put baby to bed.
259: rts
260:
261: callnewd:
262: movl d0,sp@- |stack initial value
263: movl d1,sp@- |stack initial value
264: movl a2,_np |gc could occur
265: movl a2,_lbot
266: jsr _newdoub
267: movl d0,a0
268: movl sp@+,d1 |restore initial value
269: movl sp@+,d0 |restore initial value
270: bra strdb
271:
272:
273:
274: /*
275: * quick cons call, the car and cdr are stacked on the namestack
276: * and this function is jsb'ed to.
277: */
278: .globl _qcons
279: _qcons:
280: Profile
281: movl _dtpr_str,a0 |move next cell addr to a0
282: NILtest(a0)
283: jmi getnew |if ran out of space jump
284: movl 28*4+_lispsys,a1 |inc count of dtprs
285: addql #1,a1@
286: movl a0@,_dtpr_str |advance free list
287: storit: movl a2@-,a0@ |store in cdr
288: movl a2@-,a0@(4) |store in car
289: movl a0,d0
290: rts
291:
292: getnew: movl a2,_np
293: jsr _newdot |must gc to get one
294: jra storit |now initialize it.
295:
296: /*
297: * Fast equivalent of newdot, entered by jsb
298: */
299:
300: .globl _qnewdot
301: _qnewdot:
302: Profile
303: movl _dtpr_str,a0 |mov next cell addr t0 r0
304: NILtest(a0)
305: jmi mustallo |if ran out of space
306:
307: movl a0,sp@-
308: movl 28*4+_lispsys,a0 |inc count of dtprs
309: addql #1,a0@
310: movl sp@+,a0
311:
312: movl a0@,_dtpr_str |advance free list
313: clrl a0@ |clrq (r0)
314: clrl a0@(4)
315: rts
316: mustallo:
317: movl a2,_np |gc could occur
318: jsr _newdot
319: rts
320:
321:
322: /*
323: * this is called exactly like popnames would be from C
324: * but has been carefully improved so that it doesn't
325: * have to alter the stack.
326: */
327: .globl _qpopnames
328: _qpopnames:
329: movl _bnp,a1
330: movl sp,a0
331: movl a0@(4),d0
332: jra .L130
333: .L20001:
334: movl a1@(4),a0
335: movl a1@,a0@
336: .L130:
337: subql #8,a1
338: cmpl a1,d0
339: jls .L20001
340: movl a1,_bnp
341: rts
342:
343: /*
344: * _qget : fast get subroutine
345: * (get 'atom 'ind)
346: * called with a2@(-8) equal to the atom
347: * a2@(-4) equal to the indicator
348: * no assumption is made about _lbot
349: * unfortunately, the atom may not in fact be an atom, it may
350: * be a list or nil, which are special cases.
351: * For nil, we grab the nil property list (stored in a special place)
352: * and for lists we punt and call the C routine since it is most likely
353: * and error and we havent put in error checks yet.
354: */
355:
356: .globl _qget
357: _qget:
358: Profile
359: movl a2@(-4),a1 |put indicator in a1
360: movl a2@(-8),a0 |and atom into a0
361: cmpl a0,d7
362: jeq nilpli |jump if atom is nil
363: movl a0,d0 |check type
364: NILsub(d0)
365: movl #9,d1
366: asrl d1,d0
367: lea _typetable+1,a5
368: cmpb #/**/ATOM,a5@(0,d0:L) |is it a symbol??
369: jne notsymb |nope
370: movl a0@(4),a0 |yes, put prop list in
371: | a0 to begin scan
372: cmpl a0,d7
373: jeq fail |if no prop list,
374: | we lose right away
375: lp: cmpl a0@(4),a1 |is car of list = to indicator?
376: jeq good |jump if so
377: movl a0@,a0 |else cddr
378: movl a0@,a0 | down list
379: cmpl a0,d7
380: jne lp |and jump if more list to go.
381:
382: fail: movl a0,d0
383: subql #8,a2
384: rts |return with a0 eq to nil
385:
386: good: movl a0@,a0 |return cadr of list
387: movl a0@(4),d0
388: subql #8,a2
389: rts
390:
391: nilpli: movl 64*4+_lispsys,a0 |want nil prop list,
392: | get it specially
393: cmpl a0,d7
394: jne lp |and process if anything there
395: movl a0,d0
396: subql #8,a2
397: rts |else fail
398:
399: notsymb:
400: lea a2@(-8),a0 |set up lbot before callin
401: movl a0,_lbot
402: movl a2,_np
403: jsr _Lget |not a symbol, call C routine
404: | to error check
405: subql #8,a2
406: rts |and return what it returned.
407:
408:
409: /*
410: * prunel - return a list of dtpr cells to the free list
411: * this is called by the pruneb after it has discarded the top bignum
412: * the dtpr cells are linked through their cars not their cdrs.
413: * this returns with an rsb
414: *
415: * method of operation: the dtpr list we get is linked by car's so we
416: * go through the list and link it by cdr's, then have the last dtpr
417: * point to the free list and then make the free list begin at the
418: * first dtpr.
419: */
420: qprunel:
421: movl a0,d0 |remember first dtpr location
422: movl 28*4+_lispsys,a1 |dec count of dtprs
423: rep:
424: subql #1,a2@
425: movl a0@(4),a0@ |make cdr (forward lnk) == car
426: jeq endoflist |if nil, then end of list
427: movl a0@,a0 |advance to next dtpr
428: jra rep |and loop around
429: endoflist:
430: movl _dtpr_str,a0@ |make last 1 pnt to free list
431: movl d0,_dtpr_str |& free list begin at 1st one
432: rts
433:
434: /*
435: * qpruneb - called by the arithmetic routines to free an sdot and the dtprs
436: * which hang on it.
437: * called by
438: * pushl sdotaddr
439: * jsb _qpruneb
440: */
441: .globl _qpruneb
442: _qpruneb:
443: Profile
444: movl 48*4+_lispsys,a0 |decr count of used sdots
445: subql #1,a0@
446: movl sp@(4),a0 |get address
447: movl _sdot_str,a0@ |have new sdot pnt to free lst
448: movl a0,_sdot_str |strt free list at new sdot
449: movl a0@(4),a0 |get address of first dtpr
450: jne qprunel |if exists, prune it
451: rts |else return.
452:
453:
454: /*
455: * _qprunei
456: * called by the arithmetic routines to free a fixnum cell
457: * calling sequence
458: * pushl fixnumaddr
459: * jsb _qprunei
460: */
461:
462: .globl _qprunei
463: _qprunei:
464: Profile
465: movl a1,sp@-
466: movl sp@(4),a0 |get address of fixnum
467: cmpl #4*1023+_Fixzero,a0 |is it a small fixnum
468: jmi skipit |if so, leave
469: movl 24*4+_lispsys,a1 |decr count of used ints
470: subql #1,a1@
471: movl _int_str,a0@ |link the fixnum into the
472: | free list
473: movl a0,_int_str
474: skipit:
475: movl sp@+,a1
476: rts
477: Iclear:
478: clrl d0
479: rts
480: .text
481: .globl _Itstbt
482: _Itstbt:
483: movl a5,d1
484: NILsub(d1)
485: lsrl #2,d1
486: movl d1,d0
487: andl #7,d0
488: lsrl #3,d1
489: lea _bitmapi,a0
490: bset d0,a0@(0,d1:L)
491: beq .L14
492: moveq #1,d0
493: bra .L12
494: .L14:
495: clrl d0
496: .L12: rts
497:
498: /*
499: * this routine returns an assembly language entry pt.
500: * it is put here to match the vax verison.
501: */
502: .globl _gstart
503: .globl _proflush
504: _gstart:
505: movl #start,d0
506: _proflush:
507: rts
508: /*
509: * The definition of mcount must be present even when the C code
510: * isn't being profiled, since lisp code may reference it.
511: */
512: .globl _mcount
513: #ifdef SunGotItsActTogetherAboutTakingMcountOutOfCrt0
514: .globl mcount
515: #endif
516:
517: _mcount:
518: mcount:
519: #ifdef PROF
520: movl a0@,a1
521: jne incr
522: movl _countbase,a1
523: jeq return
524: addql #8,_countbase
525: movl sp@,a1@+
526: movl a1,a0@
527: incr:
528: addql #1,a1@
529: return:
530: #endif
531: rts
532:
533: /*
534: * pushframe : stack a frame
535: * When this is called, the optional arguments and class have already been
536: * pushed on the stack as well as the return address (by virtue of the jsb)
537: * , we push on the rest of the stuff (see h/frame.h)
538: * for a picture of the save frame
539: */
540: .globl _pushframe
541: .globl _qpushframe
542: .globl _Pushframe
543: _pushframe:
544: _qpushframe:
545: _Pushframe:
546: movl sp@,a0
547: movl _errp,sp@-
548: movl _bnp,sp@-
549: movl _np,sp@-
550: movl _lbot,sp@-
551: movl sp,d0 | return addr of lbot on stack
552: subl #56,sp
553: moveml #0x7cfc,sp@(12) | save fp,a5-a2,d7-d2
554: clrl _retval | set retval to C_INITIAL
555: jmp a0@ | return through return address
556:
557: /*
558: * qretfromfr
559: * called with frame to ret to in a5. The popnames has already been done.
560: * we must restore all registers, and jump to the ret addr. the popping
561: * must be done without reducing the stack pointer since an interrupt
562: * could come in at any time and this frame must remain on the stack.
563: * thus we can't use popr.
564: */
565:
566: .globl _qretfromfr
567:
568: _qretfromfr:
569: movl a5,d0 | return error frame location
570: movl a5,a0 | prepare to pop off
571: moveml a0@(-44),#0x7cfc | restore registers
572: lea a0@(-56),sp
573: movl a0@+,_lbot
574: movl a0@+,_np
575: movl a0@(8),a0 | return address
576: jmp a0@
577:
578: /* This must be at the end of the file. If we are profiling, allocate
579: * space for the profile buffer
580: */
581: #ifdef PROF
582: .data
583: .comm _countbase,4
584: .lcomm prbuf,indx+4
585: .text
586: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.