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

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