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/PPC.prim.asm
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 810 - (view) (download)

1 : monnier 249 /* PPC.prim.asm
2 :     *
3 :     * COPYRIGHT (c) 1997 Bell Labs, Lucent Technologies.
4 :     */
5 :    
6 :     #ifndef _ASM_
7 :     #define _ASM_
8 :     #endif
9 :    
10 :     #include "ml-base.h"
11 :     #include "asm-base.h"
12 :     #include "ml-values.h"
13 :     #include "tags.h"
14 :     #include "ml-request.h"
15 :     #include "ml-limits.h"
16 :     #include "mlstate-offsets.h" /** this file is generated **/
17 :    
18 : george 810 /* factor out variations in assembler synatax */
19 :     #if defined(OPSYS_DARWIN)
20 :     /* use the macOS X names by default */
21 :     # define HI(name) ha16(name)
22 :     # define LO(name) lo16(name)
23 :    
24 :    
25 :     #else
26 :     # define HI(name) name@ha
27 :     # define LO(name) name@l
28 :    
29 :     # define cr0 0
30 :     # define cr1 1
31 :     # define r0 0
32 :     # define r1 1
33 :     # define r2 2
34 :     # define r3 3
35 :     # define r4 4
36 :     # define r5 5
37 :     # define r6 6
38 :     # define r7 7
39 :     # define r8 8
40 :     # define r9 9
41 :     # define r10 10
42 :     # define r11 11
43 :     # define r12 12
44 :     # define r13 13
45 :     # define r14 14
46 :     # define r15 15
47 :     # define r16 16
48 :     # define r17 17
49 :     # define r18 18
50 :     # define r19 19
51 :     # define r20 20
52 :     # define r21 21
53 :     # define r22 22
54 :     # define r23 23
55 :     # define r24 24
56 :     # define r25 25
57 :     # define r26 26
58 :     # define r27 27
59 :     # define r28 28
60 :     # define r29 29
61 :     # define r30 30
62 :     # define r31 31
63 :    
64 :     # define f0 0
65 :     # define f1 1
66 :     # define f2 2
67 :     # define f3 3
68 :     # define f4 4
69 :     # define f5 5
70 :     # define f6 6
71 :     # define f7 7
72 :     # define f8 8
73 :     # define f9 9
74 :     # define f10 10
75 :     # define f11 11
76 :     # define f12 12
77 :     # define f13 13
78 :     # define f14 14
79 :     # define f15 15
80 :     # define f16 16
81 :     # define f17 17
82 :     # define f18 18
83 :     # define f19 19
84 :     # define f20 20
85 :     # define f21 21
86 :     # define f22 22
87 :     # define f23 23
88 :     # define f24 24
89 :     # define f25 25
90 :     # define f26 26
91 :     # define f27 27
92 :     # define f28 28
93 :     # define f29 29
94 :     # define f30 30
95 :     # define f31 31
96 :    
97 :     #endif
98 :    
99 :    
100 :    
101 : monnier 249 /** register usage **/
102 : george 810 #define sp r1
103 : monnier 249 #define stackptr sp
104 :    
105 : george 810 #define allocptr r14
106 :     #define limitptr r15
107 :     #define storeptr r16
108 :     #define stdlink r17
109 :     #define stdclos r18
110 :     #define stdarg r19
111 :     #define stdcont r20
112 :     #define exncont r21
113 :     #define varptr r22
114 :     #define miscreg0 r24
115 :     #define miscreg1 r25
116 :     #define miscreg2 r26
117 : monnier 249
118 : george 810 #define pc r28
119 : monnier 249
120 :    
121 : george 810 #define atmp1 r29
122 :     #define atmp2 r30
123 :     #define atmp3 r31
124 :     #define atmp4 r13
125 : monnier 249
126 :     /* stackframe layout:
127 :     * Note: 1. The offset of cvti2d tmp is used in rs6000.sml
128 :     * float load/store offset is hardwired in rs6000instr.sml
129 :     *
130 :     * +-------------------+
131 :     * sp--> 0(sp) | mlstate addr |
132 :     * +-------------------+
133 :     * 4(sp) | _startgc addr |
134 :     * +-------------------+
135 :     * 8(sp) | cvti2d const |
136 :     * +-------------------+
137 :     * 16(sp) | cvti2d tmp2 |
138 :     * +-------------------+
139 :     * 24(sp) | float load/store |
140 :     * +-------------------+
141 :     * 32(sp) | floor tmp |
142 :     * +-------------------+
143 :     * 40(sp) | unused |
144 :     * +-------------------+
145 :     * 44(sp) | unused |
146 :     * +-------------------+
147 :     * argblock(sp) | C calleesave regs |
148 :     * . .
149 :     * . .
150 :     * +-------------------+
151 :     * argblock+92(sp) | |
152 :     */
153 :    
154 :    
155 :     /** MLState offsets **/
156 :     #define argblock 48
157 :     #define savearea (23*4+4) /* lr,cr,1,2,13-31,padding */
158 :     #define framesize 4096
159 :     #define MLSTATE_OFFSET 0
160 :     #define STARTGC_OFFSET 4
161 :     #define CVTI2D_OFFSET 8
162 :     #define FLOOR_OFFSET 32
163 :    
164 :     /** offsets in condition register CR.0 **/
165 :    
166 :     #define CR0_LT 0
167 :     #define CR0_GT 1
168 :     #define CR0_EQ 2
169 :     #define CR0_SO 3
170 :    
171 : george 810 #define CR0 cr0
172 : monnier 249
173 :    
174 :     /** C parameter passing conventions **/
175 : george 810 #define CARG1 r3
176 :     #define CRESULT1 r3
177 : monnier 249
178 :    
179 :     #define CONTINUE \
180 : george 810 cmpl CR0,allocptr,limitptr __SC__ \
181 :     mtlr stdcont __SC__ \
182 : monnier 249 blr
183 :    
184 :     #define CHECKLIMIT(label) \
185 : george 810 bt CR0_LT, label __SC__ \
186 :     addi pc, stdlink,0 __SC__ \
187 :     b CSYM(saveregs) __SC__ \
188 : monnier 249 label:
189 :    
190 : george 810 #if defined (USE_TOC)
191 :     /* create table of contents entries for things we need the address of. */
192 : monnier 249 .extern CSYM(_PollFreq0)
193 :     .extern CSYM(_PollEvent0)
194 :     .extern CSYM(saveregs)
195 :    
196 :     .toc
197 :     T._PollFreq0:
198 :     .tc H._PollFreq0[TC],CSYM(_PollFreq0)
199 :     T._PollEvent0:
200 :     .tc H._PollEvent0[TC],CSYM(_PollEvent0)
201 :     T.saveregs:
202 :     .tc H.saveregs[TC],CSYM(saveregs)
203 :     T.cvti2d_CONST:
204 :     .tc H.cvti2d_CONST[TC],cvti2d_CONST
205 :     #endif
206 :     RO_DATA
207 :     ALIGN8
208 :     cvti2d_CONST:
209 :     DOUBLE(4503601774854144.0)
210 :    
211 :     TEXT
212 :     /* sig_return : ('a cont * 'a) -> 'b
213 :     */
214 :     ML_CODE_HDR(sigh_return_a)
215 :     li atmp4,REQ_SIG_RETURN
216 :     li stdlink, ML_unit
217 :     li stdclos, ML_unit
218 :     li pc, ML_unit
219 :     b set_request
220 :    
221 :     ENTRY(sigh_resume)
222 :     li atmp4, REQ_SIG_RESUME
223 : monnier 439 b set_request
224 : monnier 249
225 :     /* pollh_return_a:
226 :     * The return continuation for the ML poll handler.
227 :     */
228 :     ML_CODE_HDR(pollh_return_a)
229 :     li atmp4,REQ_POLL_RETURN
230 :     li stdlink, ML_unit
231 :     li stdclos, ML_unit
232 :     li pc, ML_unit
233 :     b set_request
234 :    
235 :     /* pollh_resume:
236 :     * Resume execution at the point at which a poll event occurred.
237 :     */
238 :     ENTRY(pollh_resume)
239 :     li atmp4,REQ_POLL_RESUME
240 :     b set_request
241 :    
242 :     /* exception handler for ML functions called from C */
243 :     ML_CODE_HDR(handle_a)
244 :     li atmp4,REQ_EXN
245 :     addi pc, stdlink, 0
246 :     b set_request
247 :    
248 :    
249 :     /* continuation for ML functions called from C */
250 :     ML_CODE_HDR(return_a)
251 :     li atmp4,REQ_RETURN
252 :     li stdlink, ML_unit
253 :     li stdclos, ML_unit
254 :     li pc, ML_unit
255 :     b set_request
256 :    
257 :    
258 :     ENTRY(request_fault)
259 :     li atmp4,REQ_FAULT
260 :     addi pc, stdlink, 0
261 :     b set_request
262 :    
263 :    
264 :     /* bind_cfun : (string * string) -> c_function
265 :     */
266 :     ML_CODE_HDR(bind_cfun_a)
267 :     CHECKLIMIT(bind_cfun_v_limit)
268 :     li atmp4,REQ_BIND_CFUN
269 :     b set_request
270 :    
271 :     ML_CODE_HDR(build_literals_a)
272 :     CHECKLIMIT(build_literals_v_limit)
273 :     li atmp4,REQ_BUILD_LITERALS
274 :     b set_request
275 :    
276 :     ML_CODE_HDR(callc_a)
277 :     CHECKLIMIT(callc_v_limit)
278 :     li atmp4,REQ_CALLC
279 :     b set_request
280 :    
281 :    
282 :     ENTRY(saveregs)
283 :     li atmp4, REQ_GC
284 :     mflr pc
285 :     /* fall through */
286 :    
287 :     set_request:
288 :     lwz atmp3,MLSTATE_OFFSET(sp) /* save the minimal ML state */
289 :     lwz atmp2,VProcOffMSP(atmp3) /* atmp2 := VProc State ptr */
290 : george 810 li r0,0
291 :     stw r0,InMLOffVSP(atmp2) /* note that we have left ML */
292 : monnier 249 stw allocptr,AllocPtrOffMSP(atmp3)
293 :     stw limitptr,LimitPtrOffMSP(atmp3)
294 :     stw storeptr,StorePtrOffMSP(atmp3)
295 :     stw stdlink,LinkRegOffMSP(atmp3)
296 :     stw pc,PCOffMSP(atmp3)
297 :     stw stdarg,StdArgOffMSP(atmp3)
298 :     stw stdcont,StdContOffMSP(atmp3)
299 :     stw stdclos,StdClosOffMSP(atmp3)
300 :     stw varptr,VarPtrOffMSP(atmp3)
301 :     stw exncont,ExnPtrOffMSP(atmp3)
302 :     stw miscreg0,Misc0OffMSP(atmp3)
303 :     stw miscreg1,Misc1OffMSP(atmp3)
304 :     stw miscreg2,Misc2OffMSP(atmp3)
305 :    
306 : george 810 addi r3,atmp4,0 /* request as argument */
307 : monnier 249
308 :     restore_c_regs:
309 : george 810 lwz r2, (argblock+4)(sp)
310 :     lwz r13, (argblock+8)(sp)
311 :     lwz r14, (argblock+12)(sp)
312 :     lwz r15, (argblock+16)(sp)
313 :     lwz r16, (argblock+20)(sp)
314 :     lwz r17, (argblock+24)(sp)
315 :     lwz r18, (argblock+28)(sp)
316 :     lwz r19, (argblock+32)(sp)
317 :     lwz r20, (argblock+36)(sp)
318 :     lwz r21, (argblock+40)(sp)
319 :     lwz r22, (argblock+44)(sp)
320 :     lwz r23, (argblock+48)(sp)
321 :     lwz r24, (argblock+52)(sp)
322 :     lwz r25, (argblock+56)(sp)
323 :     lwz r26, (argblock+60)(sp)
324 :     lwz r27, (argblock+64)(sp)
325 :     lwz r28, (argblock+68)(sp)
326 :     lwz r29, (argblock+72)(sp)
327 :     lwz r30, (argblock+76)(sp)
328 :     lwz r31, (argblock+80)(sp)
329 :     lwz r0, (argblock+84)(sp)
330 :     mtlr r0
331 :     lwz r0, (argblock+88)(sp)
332 :     mtcrf 0x80, r0
333 : monnier 249 addi sp,sp,framesize
334 :     blr
335 :    
336 :    
337 :    
338 :     CENTRY(restoreregs)
339 :     addi sp,sp,-framesize
340 :     #if defined(USE_TOC)
341 : george 810 lwz r0,T.saveregs(2)
342 : monnier 249 #else
343 : george 810 lis r28, HI(CSYM(saveregs)) /* GPR0 <- addrof(saveregs) */
344 :     addi r28, r28, LO(CSYM(saveregs))
345 :     li r0, 0
346 :     add r0, r28, r0
347 : monnier 249 #endif
348 : george 810 stw r3, MLSTATE_OFFSET(sp)
349 :     stw r0, STARTGC_OFFSET(sp)
350 : monnier 249 #if defined(USE_TOC)
351 : george 810 lwz r4, T.cvti2d_CONST(r2) /* GPR2 is RTOC */
352 :     lfd f0, 0(r4)
353 : monnier 249 #else
354 : george 810 lis r4, HI(cvti2d_CONST)
355 :     lfd f0, LO(cvti2d_CONST)(r4)
356 : monnier 249 #endif
357 : george 810 stfd f0, CVTI2D_OFFSET(sp)
358 : monnier 249
359 : george 810 stw r2, argblock+4(sp)
360 :     stw r13, argblock+8(sp)
361 :     stw r14, argblock+12(sp)
362 :     stw r15, argblock+16(sp)
363 :     stw r16, argblock+20(sp)
364 :     stw r17, argblock+24(sp)
365 :     stw r18, argblock+28(sp)
366 :     stw r19, argblock+32(sp)
367 :     stw r20, argblock+36(sp)
368 :     stw r21, argblock+40(sp)
369 :     stw r22, argblock+44(sp)
370 :     stw r23, argblock+48(sp)
371 :     stw r24, argblock+52(sp)
372 :     stw r25, argblock+56(sp)
373 :     stw r26, argblock+60(sp)
374 :     stw r27, argblock+64(sp)
375 :     stw r28, argblock+68(sp)
376 :     stw r29, argblock+72(sp)
377 :     stw r30, argblock+76(sp)
378 :     stw r31, argblock+80(sp)
379 :     mflr r0
380 :     stw r0, argblock+84(sp)
381 :     mfcr r0
382 :     stw r0, argblock+88(sp)
383 : monnier 249
384 : george 810 and atmp1,r3,r3 /* atmp1 := MLState pointer */
385 : monnier 249
386 :     lwz allocptr,AllocPtrOffMSP(atmp1)
387 :     lwz limitptr,LimitPtrOffMSP(atmp1)
388 :     lwz storeptr,StorePtrOffMSP(atmp1)
389 :     lwz atmp2,VProcOffMSP(atmp1) /* atmp2 := VProc State ptr */
390 :     li atmp3,1
391 :     stw atmp3,InMLOffVSP(atmp2) /* we are entering ML code */
392 :     lwz stdarg,StdArgOffMSP(atmp1)
393 :     lwz stdcont,StdContOffMSP(atmp1)
394 :     lwz stdclos,StdClosOffMSP(atmp1)
395 :     lwz exncont,ExnPtrOffMSP(atmp1)
396 :     lwz miscreg0,Misc0OffMSP(atmp1)
397 :     lwz miscreg1,Misc1OffMSP(atmp1)
398 :     lwz miscreg2,Misc2OffMSP(atmp1)
399 :     lwz stdlink,LinkRegOffMSP(atmp1)
400 :     lwz varptr,VarPtrOffMSP(atmp1)
401 :     lwz atmp3,PCOffMSP(atmp1)
402 :     mtlr atmp3
403 :     /* check for pending signals */
404 :     lwz atmp1,NPendingSysOffVSP(atmp2)
405 :     lwz atmp3,NPendingOffVSP(atmp2)
406 :     add atmp1,atmp1,atmp3
407 :     cmpi CR0,atmp1,0
408 :     bf CR0_EQ,pending_sigs
409 :    
410 :    
411 :     ENTRY(ml_go)
412 :     cmpl CR0,allocptr,limitptr
413 :     mtfsfi 3,0 /* Ensure that no exceptions are set */
414 :     mtfsfi 2,0
415 :     mtfsfi 1,0
416 :     mtfsfi 0,0
417 : george 810 li r0,0
418 :     mtxer r0
419 : monnier 249 blr /* jump to ML code */
420 :    
421 :     pending_sigs: /* there are pending signals */
422 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
423 :     cmpi CR0,atmp1,0
424 :     bf CR0_EQ,CSYM(ml_go)
425 :     /* check if currently handling a signal */
426 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
427 :     cmpi CR0,atmp1,0
428 :     bf CR0_EQ,CSYM(ml_go)
429 :    
430 : george 810 li r0,1
431 :     stw r0,HandlerPendingOffVSP(atmp2)
432 : monnier 249 addi limitptr,allocptr,0
433 :     b CSYM(ml_go)
434 :    
435 :     /* array : (int * 'a) -> 'a array
436 :     * Allocate and initialize a new array. This can cause GC.
437 :     */
438 :     ML_CODE_HDR(array_a)
439 :     CHECKLIMIT(array_a_limit)
440 :    
441 :     lwz atmp1,0(stdarg) /* atmp1 := length in words */
442 :     srawi atmp2, atmp1, 1 /* atmp2 := length (untagged) */
443 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
444 :     bf CR0_LT, array_a_large
445 :    
446 :     lwz stdarg,4(stdarg) /* initial value */
447 :     slwi atmp3,atmp2,TAG_SHIFTW /* build descriptor in tmp3 */
448 :     ori atmp3,atmp3,MAKE_TAG(DTAG_arr_data)
449 :     stw atmp3,0(allocptr) /* store descriptor */
450 :     addi allocptr,allocptr,4 /* points to new object */
451 :     addi atmp3,allocptr,0 /* array data ptr in atmp3 */
452 :    
453 :     array_a_1:
454 :     stw stdarg,0(allocptr) /* initialize array */
455 :     addi atmp2,atmp2,-1
456 :     addi allocptr,allocptr,4
457 :     cmpi CR0,atmp2,0
458 :     bf CR0_EQ,array_a_1
459 :    
460 :     /* allocate array header */
461 :     li atmp2,DESC_polyarr /* descriptor in tmp2 */
462 :     stw atmp2,0(allocptr) /* store descriptor */
463 :     addi allocptr, allocptr, 4 /* allocptr++ */
464 :     addi stdarg, allocptr, 0 /* result = header addr */
465 :     stw atmp3,0(allocptr) /* store pointer to data */
466 :     stw atmp1,4(allocptr)
467 :     addi allocptr,allocptr,8
468 :     CONTINUE
469 :     array_a_large: /* off-line allocation */
470 :     li atmp4,REQ_ALLOC_ARRAY
471 :     addi pc, stdlink,0
472 :     b set_request
473 :    
474 :     /* create_b : int -> bytearray
475 :     * Create a bytearray of the given length.
476 :     */
477 :     ML_CODE_HDR(create_b_a)
478 :     CHECKLIMIT(create_b_a_limit)
479 :    
480 :     srawi atmp2,stdarg,1 /* atmp2 = length (untagged int) */
481 :     addi atmp2,atmp2,3 /* atmp2 = length in words */
482 :     srawi atmp2,atmp2,2
483 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
484 :     bf CR0_LT,create_b_a_large
485 :    
486 :     /* allocate the data object */
487 :     slwi atmp1,atmp2,TAG_SHIFTW /* build descriptor in atmp1 */
488 :     ori atmp1,atmp1,MAKE_TAG(DTAG_raw32)
489 :     stw atmp1,0(allocptr) /* store the data descriptor */
490 :     addi allocptr,allocptr,4 /* allocptr++ */
491 :     addi atmp3, allocptr, 0 /* atmp3 = data object */
492 :     slwi atmp2, atmp2, 2 /* atmp2 = length in bytes */
493 :     add allocptr,allocptr,atmp2 /* allocptr += total length */
494 :    
495 :     /* allocate the header object */
496 :     li atmp1, DESC_word8arr /* header descriptor */
497 :     stw atmp1,0(allocptr)
498 :     addi allocptr, allocptr, 4 /* allocptr++ */
499 :     stw atmp3,0(allocptr) /* header data field */
500 :     stw stdarg,4(allocptr) /* header length field */
501 :     addi stdarg, allocptr, 0 /* stdarg = header object */
502 :     addi allocptr,allocptr,8 /* allocptr += 2 */
503 :     CONTINUE
504 :    
505 :     create_b_a_large: /* off-line allocation */
506 :     li atmp4,REQ_ALLOC_BYTEARRAY
507 :     addi pc, stdlink,0
508 :     b set_request
509 :    
510 :    
511 :     /*
512 :     ** create_s_a: int -> string
513 :     */
514 :     ML_CODE_HDR(create_s_a)
515 :     CHECKLIMIT(create_s_a_limit)
516 :    
517 :     srawi atmp2,stdarg,1 /* atmp2 = length(untagged int) */
518 :     addi atmp2,atmp2,4
519 :     srawi atmp2,atmp2,2 /* length in words (including desc) */
520 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
521 :     bf CR0_LT,create_s_a_large
522 :    
523 :     slwi atmp1,atmp2,TAG_SHIFTW /* build descriptor in atmp3 */
524 :     ori atmp1,atmp1,MAKE_TAG(DTAG_raw32)
525 :     stw atmp1,0(allocptr) /* store descriptor */
526 :     addi allocptr,allocptr,4 /* allocptr++ */
527 :     addi atmp3,allocptr,0 /* atmp3 = data object */
528 :     slwi atmp2,atmp2,2 /* atmp2 = length in bytes */
529 :     add allocptr,atmp2,allocptr /* allocptr += total length */
530 : george 810 stw r0,-4(allocptr) /* store zero in last word */
531 : monnier 249
532 :     /* Allocate the header object */
533 :     li atmp1, DESC_string /* header descriptor */
534 :     stw atmp1, 0(allocptr)
535 :     addi allocptr,allocptr,4 /* allocptr++ */
536 :     stw atmp3,0(allocptr) /* header data field */
537 :     stw stdarg,4(allocptr) /* header length field */
538 :     addi stdarg,allocptr,0 /* stdarg = header object */
539 :     addi allocptr,allocptr,8 /* allocptr += 2 */
540 :     CONTINUE
541 :    
542 :     create_s_a_large: /* off-line allocation */
543 :     li atmp4,REQ_ALLOC_STRING
544 :     addi pc, stdlink,0
545 :     b set_request
546 :    
547 :    
548 :    
549 :     ML_CODE_HDR(create_r_a)
550 :     CHECKLIMIT(create_r_a_limit)
551 :    
552 :     srawi atmp2,stdarg,1 /* atmp2 = length (untagged int) */
553 :     slwi atmp2,atmp2,1 /* length in words */
554 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
555 :     bf CR0_LT,create_r_a_large
556 :    
557 :     /* allocate the data object */
558 :     slwi atmp1, atmp2, TAG_SHIFTW /* descriptor in atmp1 */
559 :     ori atmp1, atmp1, MAKE_TAG(DTAG_raw64)
560 :     #ifdef ALIGN_REALDS
561 :     ori allocptr,allocptr,4
562 :     #endif
563 :     stw atmp1,0(allocptr) /* store the descriptor */
564 :     addi allocptr, allocptr, 4 /* allocptr++ */
565 :     addi atmp3, allocptr, 0 /* atmp3 = data object */
566 :     slwi atmp2, atmp2, 2 /* tmp2 = length in bytes */
567 :     add allocptr,allocptr,atmp2 /* allocptr += length */
568 :    
569 :     /* allocate the header object */
570 :     li atmp1, DESC_real64arr
571 :     stw atmp1, 0(allocptr) /* header descriptor */
572 :     addi allocptr,allocptr,4 /* allocptr++ */
573 :     stw atmp3,0(allocptr) /* header data field */
574 :     stw stdarg,4(allocptr) /* header length field */
575 :     addi stdarg,allocptr,0 /* stdarg = header object */
576 :     addi allocptr,allocptr,8 /* allocptr += 2 */
577 :     CONTINUE
578 :     create_r_a_large: /* offline allocation */
579 :     li atmp4,REQ_ALLOC_REALDARRAY
580 :     addi pc, stdlink,0
581 :     b set_request
582 :    
583 :    
584 :     /* create_v_a : (int * 'a list) -> 'a vector
585 :     * Create a vector with elements taken from a list.
586 :     * NOTE: the front-end ensures that list cannot be nil.
587 :     */
588 :     ML_CODE_HDR(create_v_a)
589 :     CHECKLIMIT(create_v_a_limit)
590 :    
591 :     lwz atmp1,0(stdarg) /* atmp1 = tagged length */
592 :     srawi atmp2,atmp1,1 /* atmp2 = untagged length */
593 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
594 :     bf CR0_LT,create_v_a_large
595 :    
596 :     slwi atmp2,atmp2,TAG_SHIFTW /* build descriptor in atmp2 */
597 :     ori atmp2,atmp2,MAKE_TAG(DTAG_vec_data)
598 :     stw atmp2,0(allocptr) /* store descriptor */
599 :     addi allocptr,allocptr,4 /* allocptr++ */
600 :     lwz atmp2,4(stdarg) /* atmp2 := list */
601 :     addi stdarg,allocptr,0 /* stdarg := vector */
602 :    
603 :     create_v_a_1:
604 :     lwz atmp3,0(atmp2) /* atmp3:=hd(atmp2) */
605 :     lwz atmp2,4(atmp2) /* atmp2:=tl(atmp2) */
606 :     stw atmp3,0(allocptr) /* store word */
607 :     addi allocptr,allocptr,4 /* allocptr++ */
608 :     cmpi CR0,atmp2,ML_nil
609 :     bf CR0_EQ,create_v_a_1
610 :    
611 :     /* allocate header object */
612 :     li atmp3, DESC_polyvec /* descriptor in tmp3 */
613 :     stw atmp3,0(allocptr) /* store descriptor */
614 :     addi allocptr,allocptr,4 /* allocptr++ */
615 :     stw stdarg,0(allocptr) /* header data field */
616 :     stw atmp1,4(allocptr) /* header length */
617 :     addi stdarg, allocptr, 0 /* result = header object */
618 :     addi allocptr,allocptr,8 /* allocptr += 2 */
619 :     CONTINUE
620 :    
621 :     create_v_a_large:
622 :     li atmp4,REQ_ALLOC_VECTOR
623 :     addi pc, stdlink,0
624 :     b set_request
625 :    
626 :    
627 :     #if defined(USE_TOC)
628 :     .toc
629 :     T.floor_CONST:
630 :     .tc H.floor_CONST[TC],floor_CONST
631 :     #endif
632 :     RO_DATA
633 :     ALIGN8
634 :     floor_CONST:
635 :     DOUBLE(4512395720392704.0)
636 :    
637 :     TEXT
638 :     /*
639 :     ** floor_a : real -> int
640 :     ** Do not test for overflow, it's the caller's
641 :     ** responsibility to be in range.
642 :     **
643 :     ** This code essentially loads 1.0*2^52 into
644 :     ** register f3. A floating add will internally
645 :     ** perform an exponent alignment, which will
646 :     ** bring the required bits into the mantissa.
647 :     */
648 :     ML_CODE_HDR(floor_a)
649 : george 810 lfd f1, 0(stdarg)
650 : monnier 249 /*
651 :     ** Neat thing here is that this code works for
652 :     ** both +ve and -ve floating point numbers.
653 :     */
654 : george 810 mffs f0
655 :     stfd f0,0(allocptr) /* steal the allocptr for a second */
656 :     lwz r0, 4(allocptr)
657 : monnier 249 mtfsb1 30
658 :     mtfsb1 31
659 :     #ifdef USE_TOC
660 : george 810 lwz atmp1, T.floor_CONST(r2)
661 :     lfd f3, 0(atmp1)
662 : monnier 249 #else
663 : george 810 lis atmp1, HI(floor_CONST)
664 :     lfd f3, LO(floor_CONST)(atmp1)
665 : monnier 249 #endif
666 : george 810 fadd f6,f1,f3
667 :     stfd f6,FLOOR_OFFSET(sp)
668 : monnier 249 lwz stdarg,FLOOR_OFFSET+4(sp)
669 :     add stdarg,stdarg,stdarg
670 :     addi stdarg,stdarg,1
671 :    
672 : george 810 andi. r0,r0, 0xf
673 :     mtfsf 0xff,f0
674 : monnier 249 CONTINUE
675 :    
676 :    
677 :     ML_CODE_HDR(logb_a)
678 :     lwz stdarg,0(stdarg) /* most significant part */
679 :     srawi stdarg,stdarg,20 /* throw out 20 low bits */
680 :     andi. stdarg,stdarg,0x07ff /* clear all but 11 low bits */
681 :     addi stdarg,stdarg,-1023 /* subtract 1023 */
682 :     slwi stdarg,stdarg,1 /* make room for tag bit */
683 :     addi stdarg,stdarg,1 /* add the tag bit */
684 :     CONTINUE
685 :    
686 :    
687 :     /*
688 :     ** scalb : real * int -> real
689 :     ** scalb(x,y) = x * 2^y
690 :     */
691 :     ML_CODE_HDR(scalb_a)
692 :     CHECKLIMIT(scalb_v_limit)
693 :     lwz atmp1,4(stdarg) /* atmp1 := y */
694 :     srawi atmp1,atmp1,1 /* atmp1 := machine int y */
695 :     lwz stdarg,0(stdarg) /* stdarg := x */
696 :     lwz atmp2,0(stdarg) /* atmp2 := MSW(x) */
697 : george 810 lis r0,0x7ff0 /* r0 := 0x7ff0,0000 */
698 :     and. atmp3,atmp2,r0 /* atmp3 := atmp2 & 0x7ff00000 */
699 : monnier 249 bt CR0_EQ,scalb_all_done
700 :    
701 :     srawi atmp3,atmp3,20 /* atmp3 := ieee(exp) */
702 :     add. atmp1,atmp1,atmp3 /* scale exponent */
703 :     bt CR0_LT,scalb_underflow
704 :    
705 :     cmpi CR0,atmp1,2047 /* max. ieee(exp) */
706 :     bf CR0_LT,scalb_overflow
707 :    
708 : george 810 not r0,r0 /* r0 := not(r0) */
709 :     and atmp2,atmp2,r0 /* atmp2 := high mantessa bits + sign */
710 : monnier 249 slwi atmp1,atmp1,20 /* atmp1 := new exponent */
711 :     or atmp1,atmp1,atmp2 /* atmp1 := new MSB(x) */
712 :     lwz atmp2, 4(stdarg)
713 :    
714 :     scalb_write_out:
715 :     stw atmp1, 4(allocptr)
716 :     stw atmp2, 8(allocptr)
717 :     li atmp3, DESC_reald
718 :     stw atmp3, 0(allocptr)
719 :     addi stdarg,allocptr,4
720 :     addi allocptr,allocptr,12
721 :    
722 :     scalb_all_done:
723 :     CONTINUE
724 :    
725 :     scalb_underflow:
726 :     li atmp1,0
727 :     li atmp2,0
728 :     b scalb_write_out
729 :    
730 :     LABEL(scalb_overflow)
731 :     mtfsb1 3
732 :    
733 :    
734 :    
735 :     ML_CODE_HDR(try_lock_a)
736 :     lwz atmp1,0(stdarg)
737 :     li atmp2,1 /* ML_false */
738 :     stw atmp2,0(stdarg)
739 :     addi stdarg,atmp1,0
740 :     CONTINUE
741 :    
742 :    
743 :     ML_CODE_HDR(unlock_a)
744 :     li atmp1,3 /* ML_true */
745 :     stw atmp1,0(stdarg)
746 :     li stdarg,1 /* just return unit */
747 :     CONTINUE
748 :    
749 :    
750 :    
751 :     CENTRY(set_fsr)
752 :     mtfsb0 24 /* disable invalid exception */
753 :     mtfsb0 25 /* disable overflow exception */
754 :     mtfsb0 26 /* disable underflow exception */
755 :     mtfsb0 28 /* disable inexact exception */
756 :     mtfsb0 30 /* round to nearest */
757 :     mtfsb0 31
758 :     blr /* return */
759 :    
760 :     /* saveFPRegs and restoreFPRegs are called from C only. */
761 :     #define ctmp1 12
762 :     #define ctmp2 11
763 :     #define ctmp3 10
764 :    
765 :    
766 :     CENTRY(SaveFPRegs)
767 : george 810 stfd f14, 4(r3)
768 :     stfd f15, 12(r3)
769 :     stfd f16, 20(r3)
770 :     stfd f17, 28(r3)
771 :     stfd f18, 36(r3)
772 :     stfd f19, 44(r3)
773 :     stfd f20, 52(r3)
774 :     stfd f21, 60(r3)
775 :     stfd f22, 68(r3)
776 :     stfd f23, 76(r3)
777 :     stfd f24, 84(r3)
778 :     stfd f25, 92(r3)
779 :     stfd f26, 100(r3)
780 :     stfd f27, 108(r3)
781 :     stfd f28, 116(r3)
782 :     stfd f29, 124(r3)
783 :     stfd f30, 132(r3)
784 :     stfd f31, 140(r3)
785 : monnier 249
786 :     blr
787 :    
788 :     CENTRY(RestoreFPRegs)
789 : george 810 lfd f14, 0(r3)
790 :     lfd f15, 8(r3)
791 :     lfd f16, 16(r3)
792 :     lfd f17, 24(r3)
793 :     lfd f18, 32(r3)
794 :     lfd f19, 40(r3)
795 :     lfd f20, 48(r3)
796 :     lfd f21, 56(r3)
797 :     lfd f22, 64(r3)
798 :     lfd f23, 72(r3)
799 :     lfd f24, 80(r3)
800 :     lfd f25, 88(r3)
801 :     lfd f26, 96(r3)
802 :     lfd f27, 104(r3)
803 :     lfd f28, 112(r3)
804 :     lfd f29, 120(r3)
805 :     lfd f30, 128(r3)
806 :     lfd f31, 136(r3)
807 : monnier 249 blr
808 :    
809 : george 810 #if (defined(TARGET_PPC) && (defined(OPSYS_LINUX) || defined(OPSYS_DARWIN) ))
810 : monnier 249
811 :     #define CACHE_LINE_SZB 32
812 :     #define CACHE_LINE_MASK (CACHE_LINE_SZB-1)
813 :     #define CACHE_LINE_BITS 26
814 :    
815 :     /* FlushICache:
816 :     *
817 :     * void FlushICache (Addr_t addr, Addr_t nbytes)
818 :     */
819 :     CENTRY(FlushICache)
820 : george 810 add r4,r3,r4 /* stop := addr+nbytes */
821 :     addic r4,r4,CACHE_LINE_MASK /* stop := stop + CACHE_LINE_MASK */
822 :     rlwinm r4,r4,0,0,CACHE_LINE_BITS /* stop := stop & ~CACHE_LINE_MASK */
823 : monnier 249 L_FlushICache_1:
824 : george 810 cmplw cr1,r3,r4 /* while (addr < stop) */
825 : monnier 249 bc 4,4,L_FlushICache_2
826 : george 810 dcbf 0,r3 /* flush addr */
827 :     icbi 0,r3 /* invalidate addr */
828 :     addi r3,r3,CACHE_LINE_SZB /* addr := addr + CACHE_LINE_SZB */
829 : monnier 249 b L_FlushICache_1 /* end while */
830 :     L_FlushICache_2:
831 :     blr
832 :    
833 :     #endif
834 :    

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