Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/mach-dep/M68.prim.asm
ViewVC logotype

Annotation of /sml/trunk/src/runtime/mach-dep/M68.prim.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (view) (download)

1 : monnier 2 /* M68.prim.asm
2 :     *
3 :     * COPYRIGHT (c) 1990 by AT&T Bell Laboratories.
4 :     *
5 :     * M68 primitive runtime code for SML/NJ.
6 :     *
7 :     * The m680x0 registers are used as follows; the names in parentheses are the
8 :     * MLState field names (see ml_state.h):
9 :     *
10 :     * a6 = freespace pointer (ml_allocptr)
11 :     * d5 = data limit (ml_limitptr)
12 :     * d6 = store ptr (ml_storeptr)
13 :     * d3 = var ptr (ml_varptr)
14 :     *
15 :     * a0 = standard arg (ml_arg)
16 :     * a1 = standard continuation (ml_cont)
17 :     * a2 = standard closure (ml_closure)
18 :     * a3 = standard link
19 :     * d7 = exception handler continuation (ml_exncont)
20 :     *
21 :     * a4 = general purpose pointers (ml_roots[4] and ml_roots[5])
22 :     * a5 = pointer temps
23 :     * d0,d1 = arithtemps used by generic.sml
24 :     * d2,d4 = arithtemps used by m68.sml
25 :     *
26 :     * a7 = stack ptr (not used by ML)
27 :     *
28 :     *
29 :     * The ML state structure has the following layout for the mc680x0 (see "ml_state.h"):
30 :     *
31 :     * +-------------------+
32 :     * MLState --> | ml_allocptr (a6) |
33 :     * +-------------------+
34 :     * +4: | ml_limitptr (d5) |
35 :     * +-------------------+
36 :     * +8: | ml_storeptr (d6) |
37 :     * +-------------------+
38 :     * +12: | ml_exncont (d7) |
39 :     * +-------------------+
40 :     * +16: | ml_arg (a0) |
41 :     * +-------------------+
42 :     * +20: | ml_cont (a1) |
43 :     * +-------------------+
44 :     * +24: | ml_closure (a2) |
45 :     * +-------------------+
46 :     * +28: | (a3, a4) |
47 :     * +-------------------+
48 :     * +36: | ml_varptr (d3) |
49 :     * +-------------------+
50 :     * +40: | ml_pc |
51 :     * +-------------------+
52 :     * +44: | inML |
53 :     * +-------------------+
54 :     * +48: | request |
55 :     * +-------------------+
56 :     * +52: | handlerPending |
57 :     * +-------------------+
58 :     * +56: | inSigHandler |
59 :     * +-------------------+
60 :     * +60: | maskSignals |
61 :     * +-------------------+
62 :     * +64: | NumPendingSigs |
63 :     * +-------------------+
64 :     * +68: | ioWaitFlag |
65 :     * +-------------------+
66 :     * +72: | GCpending |
67 :     * +-------------------+
68 :     * +76: | saved_pc |
69 :     * +-------------------+
70 :     * | ... |
71 :     */
72 :    
73 :     #include "mask.h"
74 :     #include "tags.h"
75 :     #include "request.h"
76 :     #include "fpregs.h"
77 :    
78 :     #ifdef AUX
79 :     #define CSYM(sym) sym
80 :     #define d0 %D0
81 :     #define d1 %D1
82 :     #define d2 %D2
83 :     #define d3 %D3
84 :     #define d4 %D4
85 :     #define d5 %D5
86 :     #define d6 %D6
87 :     #define d7 %D7
88 :     #define a0 %A0
89 :     #define a1 %A1
90 :     #define a2 %A2
91 :     #define a3 %A3
92 :     #define a4 %A4
93 :     #define a5 %A5
94 :     #define a6 %A6
95 :     #define sp %SP
96 :     #define cc %CC
97 :     #define fp0 %FP0
98 :     #define fp1 %FP1
99 :     #define fp2 %FP2
100 :     #define fp3 %FP3
101 :     #define fp4 %FP4
102 :     #define fp5 %FP5
103 :     #define fp6 %FP6
104 :     #define fp7 %FP7
105 :     #define fpcr %FPCR
106 :     #else
107 :     #ifdef __STDC__
108 :     #define CSYM(sym) _##sym
109 :     #else
110 :     #define CSYM(sym) _/**/sym
111 :     #endif
112 :     #endif
113 :    
114 :     #define allocptr a6
115 :     #define limit d5
116 :     #define storeptr d6
117 :     #define exncont d7
118 :     #define stdarg a0
119 :     #define stdcont a1
120 :     #define stdclos a2
121 :     #define stdlink a3
122 :    
123 :     #define ptrtmp a5
124 :    
125 :     #define ml_allocptr_offset 0
126 :    
127 :     #define inML 44
128 :     #define request 48
129 :     #define handlerPending 52
130 :     #define inSigHandler 56
131 :     #define maskSignals 60
132 :     #define NumPendingSigs 64
133 :     #define ioWaitFlag 68
134 :     #define GCpending 72
135 :     #define saved_pc_ 76
136 :     #define mask_ 96
137 :    
138 :     /* the save mask for saving C registers on callee save systems */
139 :     #define CREGMASK d2-d7/a2-a6
140 :     /* the MLState pointer is passed to restoreregs on the stack. Once we
141 :     * push the C-registers (11 of them) onto the stack, the MLState pointer
142 :     * can be found at the following offset:
143 :     */
144 :     /* #define MLSTATE_OFFSET ((11+1)*4) Avoid HPUX problem */
145 :     #define MLSTATE_OFFSET 48
146 :    
147 :     #define ML_CODE_HDR(name) \
148 :     .globl CSYM(name); \
149 :     .align 2; \
150 :     .word TAG_backptr; \
151 :     CSYM(name):
152 :    
153 :     #define CHECKLIMIT(mask) \
154 :     1: jgt 2f; \
155 :     lea 1b,a5; \
156 :     movl mask,d4; \
157 :     rts; \
158 :     2:
159 :    
160 :     #define CONTINUE \
161 :     movl a1@,stdlink; \
162 :     cmpl a6,d5; \
163 :     jmp stdlink@
164 :    
165 :    
166 :     #define RAISE \
167 :     movl d7,a1; CONTINUE
168 :    
169 :     .text
170 :     .globl CSYM(sigh_resume), CSYM(saveregs), CSYM(restoreregs)
171 :    
172 :     /* sigh_return_c:
173 :     * The return continuation for the ML signal handler.
174 :     */
175 :     ML_CODE_HDR(sigh_return_a)
176 :     movl sp@+,a5 /* flush startgc from stack */
177 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
178 :     movl #REQ_SIG_RETURN,a5@(request)
179 :     jra CSYM(quicksave)
180 :    
181 :     /* sigh_resume:
182 :     * Resume execution at the point at which a handler trap occurred. This is a
183 :     * standard two-argument function, thus the closure is in ml_cont (a1).
184 :     */
185 :     CSYM(sigh_resume):
186 :     movl sp@+,a5 /* flush startgc from stack */
187 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
188 :     movl #REQ_SIG_RESUME,a5@(request)
189 :     jra CSYM(quicksave)
190 :    
191 :     ML_CODE_HDR(handle_a)
192 :     movl sp@+,a5 /* flush startgc from stack */
193 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
194 :     movl #REQ_EXN,a5@(request)
195 :     jra CSYM(quicksave)
196 :    
197 :     ML_CODE_HDR(return_a)
198 :     movl sp@+,a5 /* flush startgc from stack */
199 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
200 :     movl #REQ_RETURN,a5@(request)
201 :     jra CSYM(quicksave)
202 :    
203 :     .globl CSYM(request_fault)
204 :     CSYM(request_fault):
205 :     movl sp@+,a5 /* flush startgc from stack */
206 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
207 :     movl #REQ_FAULT,a5@(request)
208 :     jra CSYM(quicksave)
209 :    
210 :     ML_CODE_HDR(callc_a)
211 :     CHECKLIMIT(#closmask)
212 :     movl sp@+,a5 /* flush startgc from stack */
213 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
214 :     movl #REQ_CALLC,a5@(request)
215 :     /* fall into quicksave */
216 :    
217 :     CSYM(quicksave):
218 :     clrl a5@(inML) /* note that we have left ML code */
219 :     movl a6,a5@
220 :     moveml d6-d7/a0-a2,a5@(8) /* save storeptr, exncont, arg, cont, closure */
221 :     movl d3,a5@(36) /* save varptr */
222 :     moveml sp@+,CREGMASK /* restore the C registers */
223 :     rts /* return to run_ml() */
224 :    
225 :     CSYM(saveregs):
226 :     pea a5@
227 :     movl sp@(MLSTATE_OFFSET+4),a5 /* get MLState ptr off the stack */
228 :     movl sp@+,a5@(40) /* save resume pc */
229 :     clrl a5@(inML) /* note that we have left ML code */
230 :     tstl d5 /* see if it was a signal */
231 :     bne 1f
232 :     movl #REQ_SIGNAL,a5@(request)
233 :     1:
234 :     movl d4,a5@(mask_)
235 :     movl a6,a5@
236 :     moveml d6-d7/a0-a4,a5@(8)
237 :     movl d3,a5@(36) /* save varptr */
238 :     moveml sp@+,CREGMASK /* restore the C registers */
239 :     rts /* return to run_ml() */
240 :    
241 :     CSYM(restoreregs):
242 :     moveml CREGMASK,sp@- /* save the C registers */
243 :     movl sp@(MLSTATE_OFFSET),a5 /* get the MLState ptr off the stack */
244 :     movl a5@,a6
245 :     moveml a5@(4),d5-d7/a0-a4
246 :     movl a5@(36),d3
247 :     addql #1,a5@(inML) /* note that we are executing ML code */
248 :     tstl a5@(GCpending)
249 :     jne 3f
250 :    
251 :     tstl a5@(NumPendingSigs) /* check for pending signals */
252 :     jne 2f
253 :     1:
254 :     pea CSYM(saveregs)
255 :     movl a5@(40),a5 /* fetch the saved pc */
256 :     cmpl a6,d5
257 :     jmp a5@
258 :     2: /* there are pending signals */
259 :     tstl a5@(maskSignals) /* are signals masked? */
260 :     jne 1b
261 :     tstl a5@(inSigHandler) /* are currently handling a signal? */
262 :     jne 1b
263 :     addql #1,a5@(handlerPending) /* note that a trap is pending */
264 :     3: clrl d5 /* trap on the next limit check */
265 :     jra 1b
266 :    
267 :    
268 :     .globl CSYM(savefpregs)
269 :     CSYM(savefpregs):
270 :     link a6, #-4 /* temp. space */
271 :     movl a0, a6@(-4) /* save a0 */
272 :     #if (MAX_PROCS > 1)
273 :     ???
274 :     #else /* (MAX_PROCS == 1) */
275 :     movl CSYM(MLproc), a0 /* ml state vector */
276 :     #endif
277 :     movl a0@(ml_allocptr_offset), a0 /* next available heap addr */
278 :     movl #MAKE_DESC(NSAVED_FPREGS*8,TAG_string), a0@+
279 :     fmoved fp2, a0@+
280 :     fmoved fp3, a0@+
281 :     fmoved fp4, a0@+
282 :     fmoved fp5, a0@+
283 :     fmoved fp6, a0@+
284 :     fmoved fp7, a0@+
285 :     movl a6@(-4), a0 /* restore a0 */
286 :     unlk a6
287 :     rts
288 :    
289 :     .globl CSYM(restorefpregs)
290 :     CSYM(restorefpregs):
291 :     link a6, #-4 /* temp. space */
292 :     movl a0, a6@(-4) /* save a0 */
293 :     movl a6@(8), a0 /* pointer to string of floats */
294 :     fmoved a0@+, fp2
295 :     fmoved a0@+, fp3
296 :     fmoved a0@+, fp4
297 :     fmoved a0@+, fp5
298 :     fmoved a0@+, fp6
299 :     fmoved a0@+, fp7
300 :     movl a6@(-4), a0 /* restore a0 */
301 :     unlk a6
302 :     rts
303 :    
304 :    
305 :     /* adjust_limit:
306 :     * Adjust the heap limit pointer so that a trap will be generated on the next limit
307 :     * check and then continue executing ML code.
308 :     * NOTE: this code cannot trash any registers (other than d5) or the condition
309 :     * codes. Also, we need to come up with a solution for the case when
310 :     * MAX_PROCS > 1 for getting at the saved_pc and condition codes.
311 :     */
312 :     .globl CSYM(adjust_limit), CSYM(saved_pc)
313 :     CSYM(adjust_limit):
314 :     #if (MAX_PROCS > 1)
315 :     ???
316 :     #else /* (MAX_PROCS == 1) */
317 :     movw cc,d5 /* save condition codes */
318 :     movl CSYM(saved_pc),sp@-
319 :     movw d5,sp@- /* push the saved condition codes */
320 :     clrl d5 /* generate a trap on the next limit check */
321 :     rtr /* return, restoring condition codes */
322 :     #endif
323 :    
324 :     /* array : (int * 'a) -> 'a array
325 :     * Allocate and initialize a new array. This can cause GC.
326 :     */
327 :     ML_CODE_HDR(array_a)
328 :     1: /* jump back here after GC trap */
329 :     movl a0@,d1 /* get tagged length */
330 :     asrl #1,d1 /* d1 = length (untagged) */
331 :     movl d1,d2
332 :     asll #width_tags,d2
333 :     orl #TAG_array,d2 /* d2 = new tag */
334 :     asll #2,d1
335 :     movl a6,d4
336 :     addl d1,d4
337 :     cmpl d4,d5 /* check the heap limit */
338 :     jpl 4f
339 :     lea 1b,a5
340 :     movl #closmask,d4
341 :     rts
342 :     4:
343 :     movl a0@(4),d0 /* d0 = initial value */
344 :     movl d2,a6@+ /* write the tag */
345 :     movl a6,a0
346 :     jra 3f
347 :     2: movl d0,a6@+ /* store default */
348 :     3: subql #4,d1
349 :     jge 2b
350 :     CONTINUE
351 :    
352 :     /* create_b : int -> bytearray
353 :     * create_r : int -> realarray
354 :     * create_s : int -> string
355 :     * Create bytearray or string of given length. This can cause GC.
356 :     */
357 :     ML_CODE_HDR(create_r_a)
358 :     1: movl a0,d1
359 :     asrl #1,d1 /* d1 = # of elements */
360 :     movl d1,d2
361 :     asll #width_tags,d2
362 :     asll #3,d1 /* d1 = byte length, not including desc. */
363 :     addl #TAG_realdarray,d2 /* d2 = new tag */
364 :     movl a6,d4
365 :     addl d1,d4
366 :     cmpl d4,d5 /* check the heap limit */
367 :     jpl 4f
368 :     lea 1b,a5
369 :     movl #closmask,d4
370 :     rts
371 :     4:
372 :     movl d2,a6@+ /* write the descriptor */
373 :     movl a6,a0
374 :     addl d1,a6
375 :     CONTINUE
376 :    
377 :     ML_CODE_HDR(create_b_a)
378 :     1: /* jump back to here after a GC trap */
379 :     movl a0,d1
380 :     asrl #1,d1 /* d1 = # of elements */
381 :     movl d1,d2
382 :     asll #width_tags,d2
383 :     addl #3,d1
384 :     addl #TAG_bytearray,d2 /* d2 = new tag */
385 :     andl #~3,d1 /* d1+4 = bytes in string, not including tag */
386 :     movl a6,d4
387 :     addl d1,d4
388 :     cmpl d4,d5 /* check the heap limit */
389 :     jpl 4f
390 :     lea 1b,a5
391 :     movl #closmask,d4
392 :     rts
393 :     4:
394 :     movl d2,a6@+ /* write the descriptor */
395 :     movl a6,a0
396 :     addl d1,a6
397 :     CONTINUE
398 :    
399 :     ML_CODE_HDR(create_s_a)
400 :     1: /* jump back to here after a GC trap */
401 :     movl a0,d1
402 :     asrl #1,d1 /* d1 = # of elements */
403 :     movl d1,d2
404 :     asll #width_tags,d2
405 :     addl #4,d1
406 :     addl #TAG_string,d2 /* d2 = new tag */
407 :     andl #~3,d1 /* d1+4 = bytes in string, not including tag */
408 :     movl a6,d4
409 :     addl d1,d4
410 :     cmpl d4,d5 /* check the heap limit */
411 :     jpl 4f
412 :     lea 1b,a5
413 :     movl #closmask,d4
414 :     rts
415 :     4:
416 :     movl d2,a6@+ /* write the descriptor */
417 :     movl a6,a0
418 :     movl #0,a6@(-4) /* clear the last word to zero */
419 :     addl d1,a6
420 :     CONTINUE
421 :    
422 :     /* create_v_a : int * 'a list -> 'a vector
423 :     * creates a vector with elements taken from a list.
424 :     * n.b. The front end ensure that list cannot be nil.
425 :     */
426 :     ML_CODE_HDR(create_v_a)
427 :     #define ML_NIL 1
428 :     #define ML_LIST_HD(p) p@
429 :     #define ML_LIST_TL(p) p@(4)
430 :     1: /* jump back here after GC */
431 :     movl stdarg@,d1 /* d1 := tagged length */
432 :     asrl #1,d1 /* untagged length */
433 :     movl d1,d2 /* build descriptor in d2 */
434 :     asll #width_tags,d2 /* length field */
435 :     orl #TAG_record,d2 /* tag field */
436 :     asll #2,d1 /* d1 := length in bytes */
437 :     movl allocptr,d4
438 :     addl d1,d4 /* d4 := new allocptr */
439 :     cmpl d4,limit /* check heap limit */
440 :     jpl 4f
441 :     lea 1b,a5
442 :     movl #closmask,d4
443 :     rts
444 :     4:
445 :     movl d2,allocptr@+ /* store the descriptor */
446 :     movl stdarg@(4),ptrtmp /* ptrtmp := list */
447 :     movl allocptr,stdarg /* return value */
448 :     movl #ML_NIL,d1 /* d1 := NIL */
449 :     3: /* loop */
450 :     movl ML_LIST_HD(ptrtmp),allocptr@+ /* update vector */
451 :     movl ML_LIST_TL(ptrtmp),ptrtmp /* cdr list */
452 :     cmpl ptrtmp,d1 /* continue ? */
453 :     bne 3b
454 :     CONTINUE
455 :    
456 :     /* try_lock: spin_lock -> bool.
457 :     * low-level test-and-set style primitive for mutual-exclusion among
458 :     * processors. For now, we only provide a uni-processor trivial version.
459 :     */
460 :     ML_CODE_HDR(try_lock_a)
461 :     #if (MAX_PROCS > 1)
462 :     ???
463 :     #else /* (MAX_PROCS == 1) */
464 :     movl a0@,d0 /* get old value of lock */
465 :     movl #1,a0@ /* set the lock to ML_false */
466 :     movl d0,a0 /* return old value of lock */
467 :     CONTINUE
468 :     #endif
469 :    
470 :     /* unlock : releases a spin lock
471 :     */
472 :     ML_CODE_HDR(unlock_a)
473 :     #if (MAX_PROCS > 1)
474 :     ???
475 :     #else /* (MAX_PROCS == 1) */
476 :     movl #3,a0@ /* store ML_true into lock */
477 :     movl #1,a0 /* and return unit */
478 :     CONTINUE
479 :     #endif
480 :    
481 :    
482 :     /* Floating point primitives
483 :     *
484 :     * All the m68code for ML reals assumes that NaN's and INF's are never
485 :     * generated and therefore do not need to be handled.
486 :     * This code does not produce NaN's or INF's as long as none are passed to it
487 :     * and overflow, underflow, and operr are handled.
488 :     *
489 :     * Floating exceptions raised (assuming NaN's and INF's are never passed to
490 :     * functions):
491 :     * OPERR - (div) for 0.0/0.0 (does NOT also cause DZ)
492 :     * DZ - (div) for (in range) / 0.0
493 :     * OVERFLOW/UNDERFLOW - (add,div,sub,mul) as appropriate */
494 :    
495 :     ML_CODE_HDR(floor_a)
496 :     fmoved a0@,fp0
497 :     ftstx fp0 /* handle positive and negative cases separately*/
498 :     fblt 1f
499 :     /* positive numbers */
500 :     fintrzx fp0,fp0 /* round towards zero (down) */
501 :     fmovel fp0,d0
502 :     asll #1,d0
503 :     trapv
504 :     addql #1,d0
505 :     movl d0,a0
506 :     CONTINUE
507 :     /* negative numbers */
508 :     1: fintrzx fp0,fp1 /* round towards zero (up) */
509 :     fmovel fp1,d0
510 :     asll #1,d0
511 :     trapv
512 :     fcmpx fp0,fp1
513 :     fjeq 1f
514 :     subql #1,d0
515 :     trapv
516 :     movl d0,a0
517 :     CONTINUE
518 :     1: addql #1,d0
519 :     movl d0,a0
520 :     CONTINUE
521 :    
522 :     /* returns 0 on 0. */
523 :     ML_CODE_HDR(logb_a)
524 :     fgetexpd a0@,fp0
525 :     fmovel fp0,d0
526 :     asll #1,d0
527 :     addql #1,d0
528 :     movl d0,a0
529 :     CONTINUE
530 :    
531 :     ML_CODE_HDR(scalb_a)
532 :     lea CSYM(overflow_e0)+4,a0
533 :     RAISE
534 :    
535 :     #ifdef sun3
536 :     .globl CSYM(minitfp_) /* checks for 68881 and sets flags */
537 :     .globl CSYM(fp_state_mc68881) /* a flag that gets set */
538 :     #define fp_enabled 2 /* from /usr/src/lib/libc/sun/crt/fpcrttypes.h */
539 :     #endif
540 :     .align 2
541 :     /* Enable/disable float operand error, overflow, and div. If no 68881
542 :     is present, nothing happens. */
543 :     .globl CSYM(FPEnable)
544 :     .globl CSYM(FPDisable)
545 :     CSYM(FPEnable):
546 :     #ifdef sun3
547 :     jsr CSYM(minitfp_) /* checks for 68881 and sets flags.
548 :     normally executed on startup,
549 :     but won't be if compiled without
550 :     -f68881 (for possible sun/50
551 :     compatibility). This is just
552 :     to make sure. */
553 :     cmpl #fp_enabled,CSYM(fp_state_mc68881)
554 :     jne 1f
555 :     #endif
556 :     /* Sorry, but A/UX doesn't seem to handle fpu exceptions correctly. */
557 :     #ifndef AUX
558 :     fmovel #0x3400,fpcr
559 :     #endif
560 :     1: rts
561 :     CSYM(FPDisable):
562 :     #ifdef sun3
563 :     cmpl #fp_enabled,CSYM(fp_state_mc68881)
564 :     jne 1f
565 :     #endif sun3
566 :     #ifndef AUX
567 :     fmovel #0,fpcr
568 :     #endif
569 :     1: rts
570 :    
571 :     /* Mathematical routines */
572 :    
573 :     ML_CODE_HDR(arctan_a)
574 :     CHECKLIMIT(#closmask)
575 :     fatand a0@,fp0
576 :     jra finishfloat
577 :     ML_CODE_HDR(cos_a)
578 :     CHECKLIMIT(#closmask)
579 :     fcosd a0@,fp0
580 :     jra finishfloat
581 :     ML_CODE_HDR(exp_a)
582 :     CHECKLIMIT(#closmask)
583 :     fetoxd a0@,fp0
584 :     jra finishfloat
585 :     ML_CODE_HDR(ln_a)
586 :     CHECKLIMIT(#closmask)
587 :     fmoved a0@,fp0
588 :     ftstx fp0
589 :     fble 1f
590 :     flognx fp0,fp0
591 :     jra finishfloat
592 :     1: lea CSYM(ln_e0)+4,a0
593 :     RAISE
594 :     ML_CODE_HDR(sin_a)
595 :     CHECKLIMIT(#closmask)
596 :     fsind a0@,fp0
597 :     jra finishfloat
598 :     ML_CODE_HDR(sqrt_a)
599 :     CHECKLIMIT(#closmask)
600 :     fmoved a0@,fp0
601 :     ftstx fp0
602 :     fblt 1f
603 :     fsqrtx fp0,fp0
604 :     jra finishfloat
605 :     1: lea CSYM(sqrt_e0)+4,a0
606 :     RAISE
607 :    
608 :     finishfloat: /* allocate a heap object for the result */
609 :     movl #DESC_reald,a6@+
610 :     movl a6,a0
611 :     fmoved fp0,a6@+
612 :     CONTINUE
613 :    
614 :    
615 :     #ifdef NeXT
616 :     /* this is needed to avoid a bug in the NeXT's implementation of syscall */
617 :     .globl CSYM(syscall)
618 :     CSYM(syscall):
619 :     movl sp@(4),d0 /* get the syscall code */
620 :     movl sp@,sp@(4)
621 :     movl d0,sp@ /* the stack now is: syscall#, return-pc, args ... */
622 :     trap #0 /* do the syscall */
623 :     /* the stack now is: return-pc, args ... */
624 :     bcs 2f /* check for errors */
625 :     1: /* return */
626 :     movl sp@,a0
627 :     jmp a0@
628 :     2: /* an error, save the errno and return -1 */
629 :     movl d0,CSYM(errno)
630 :     moveq #-1,d0
631 :     jra 1b
632 :    
633 :     #endif
634 :    
635 :     /* this bogosity is for export.c */
636 :     .globl CSYM(startptr)
637 :     CSYM(startptr):
638 :     #ifdef AUX
639 :     .long _start
640 :     #else
641 :     .long start
642 :     #endif
643 :     #ifdef HPUX
644 :     /* pseudo-op to set floating
645 :     point version no in a.out
646 :     header. Guessing...
647 :     */
648 :     version 3
649 :     #endif

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0