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 439 - (view) (download)
Original Path: sml/branches/SMLNJ/src/runtime/mach-dep/PPC.prim.asm

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 :     lis 0, CSYM(saveregs)@ha /* GPR0 <- addrof(saveregs) */
265 :     addi 0, 0, CSYM(saveregs)@l
266 :     #endif
267 :     stw 3, MLSTATE_OFFSET(sp)
268 :     stw 0, STARTGC_OFFSET(sp)
269 :     #if defined(USE_TOC)
270 :     lwz 4, T.cvti2d_CONST(2) /* GPR2 is RTOC */
271 :     lfd 0, 0(4)
272 :     #else
273 :     lis 4, cvti2d_CONST@ha
274 :     lfd 0, cvti2d_CONST@l(4)
275 :     #endif
276 :     stfd 0, CVTI2D_OFFSET(sp)
277 :    
278 :     stw 2, argblock+4(sp)
279 :     stw 13, argblock+8(sp)
280 :     stw 14, argblock+12(sp)
281 :     stw 15, argblock+16(sp)
282 :     stw 16, argblock+20(sp)
283 :     stw 17, argblock+24(sp)
284 :     stw 18, argblock+28(sp)
285 :     stw 19, argblock+32(sp)
286 :     stw 20, argblock+36(sp)
287 :     stw 21, argblock+40(sp)
288 :     stw 22, argblock+44(sp)
289 :     stw 23, argblock+48(sp)
290 :     stw 24, argblock+52(sp)
291 :     stw 25, argblock+56(sp)
292 :     stw 26, argblock+60(sp)
293 :     stw 27, argblock+64(sp)
294 :     stw 28, argblock+68(sp)
295 :     stw 29, argblock+72(sp)
296 :     stw 30, argblock+76(sp)
297 :     stw 31, argblock+80(sp)
298 :     mflr 0
299 :     stw 0, argblock+84(sp)
300 :     mfcr 0
301 :     stw 0, argblock+88(sp)
302 :    
303 :     and atmp1,3,3 /* atmp1 := MLState pointer */
304 :    
305 :     lwz allocptr,AllocPtrOffMSP(atmp1)
306 :     lwz limitptr,LimitPtrOffMSP(atmp1)
307 :     lwz storeptr,StorePtrOffMSP(atmp1)
308 :     lwz atmp2,VProcOffMSP(atmp1) /* atmp2 := VProc State ptr */
309 :     li atmp3,1
310 :     stw atmp3,InMLOffVSP(atmp2) /* we are entering ML code */
311 :     lwz stdarg,StdArgOffMSP(atmp1)
312 :     lwz stdcont,StdContOffMSP(atmp1)
313 :     lwz stdclos,StdClosOffMSP(atmp1)
314 :     lwz exncont,ExnPtrOffMSP(atmp1)
315 :     lwz miscreg0,Misc0OffMSP(atmp1)
316 :     lwz miscreg1,Misc1OffMSP(atmp1)
317 :     lwz miscreg2,Misc2OffMSP(atmp1)
318 :     lwz stdlink,LinkRegOffMSP(atmp1)
319 :     lwz varptr,VarPtrOffMSP(atmp1)
320 :     lwz atmp3,PCOffMSP(atmp1)
321 :     mtlr atmp3
322 :     /* check for pending signals */
323 :     lwz atmp1,NPendingSysOffVSP(atmp2)
324 :     lwz atmp3,NPendingOffVSP(atmp2)
325 :     add atmp1,atmp1,atmp3
326 :     cmpi CR0,atmp1,0
327 :     bf CR0_EQ,pending_sigs
328 :    
329 :    
330 :     ENTRY(ml_go)
331 :     cmpl CR0,allocptr,limitptr
332 :     mtfsfi 3,0 /* Ensure that no exceptions are set */
333 :     mtfsfi 2,0
334 :     mtfsfi 1,0
335 :     mtfsfi 0,0
336 :     li 0,0
337 :     mtxer 0
338 :     blr /* jump to ML code */
339 :    
340 :     pending_sigs: /* there are pending signals */
341 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
342 :     cmpi CR0,atmp1,0
343 :     bf CR0_EQ,CSYM(ml_go)
344 :     /* check if currently handling a signal */
345 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
346 :     cmpi CR0,atmp1,0
347 :     bf CR0_EQ,CSYM(ml_go)
348 :    
349 :     li 0,1
350 :     stw 0,HandlerPendingOffVSP(atmp2)
351 :     addi limitptr,allocptr,0
352 :     b CSYM(ml_go)
353 :    
354 :     /* array : (int * 'a) -> 'a array
355 :     * Allocate and initialize a new array. This can cause GC.
356 :     */
357 :     ML_CODE_HDR(array_a)
358 :     CHECKLIMIT(array_a_limit)
359 :    
360 :     lwz atmp1,0(stdarg) /* atmp1 := length in words */
361 :     srawi atmp2, atmp1, 1 /* atmp2 := length (untagged) */
362 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
363 :     bf CR0_LT, array_a_large
364 :    
365 :     lwz stdarg,4(stdarg) /* initial value */
366 :     slwi atmp3,atmp2,TAG_SHIFTW /* build descriptor in tmp3 */
367 :     ori atmp3,atmp3,MAKE_TAG(DTAG_arr_data)
368 :     stw atmp3,0(allocptr) /* store descriptor */
369 :     addi allocptr,allocptr,4 /* points to new object */
370 :     addi atmp3,allocptr,0 /* array data ptr in atmp3 */
371 :    
372 :     array_a_1:
373 :     stw stdarg,0(allocptr) /* initialize array */
374 :     addi atmp2,atmp2,-1
375 :     addi allocptr,allocptr,4
376 :     cmpi CR0,atmp2,0
377 :     bf CR0_EQ,array_a_1
378 :    
379 :     /* allocate array header */
380 :     li atmp2,DESC_polyarr /* descriptor in tmp2 */
381 :     stw atmp2,0(allocptr) /* store descriptor */
382 :     addi allocptr, allocptr, 4 /* allocptr++ */
383 :     addi stdarg, allocptr, 0 /* result = header addr */
384 :     stw atmp3,0(allocptr) /* store pointer to data */
385 :     stw atmp1,4(allocptr)
386 :     addi allocptr,allocptr,8
387 :     CONTINUE
388 :     array_a_large: /* off-line allocation */
389 :     li atmp4,REQ_ALLOC_ARRAY
390 :     addi pc, stdlink,0
391 :     b set_request
392 :    
393 :     /* create_b : int -> bytearray
394 :     * Create a bytearray of the given length.
395 :     */
396 :     ML_CODE_HDR(create_b_a)
397 :     CHECKLIMIT(create_b_a_limit)
398 :    
399 :     srawi atmp2,stdarg,1 /* atmp2 = length (untagged int) */
400 :     addi atmp2,atmp2,3 /* atmp2 = length in words */
401 :     srawi atmp2,atmp2,2
402 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
403 :     bf CR0_LT,create_b_a_large
404 :    
405 :     /* allocate the data object */
406 :     slwi atmp1,atmp2,TAG_SHIFTW /* build descriptor in atmp1 */
407 :     ori atmp1,atmp1,MAKE_TAG(DTAG_raw32)
408 :     stw atmp1,0(allocptr) /* store the data descriptor */
409 :     addi allocptr,allocptr,4 /* allocptr++ */
410 :     addi atmp3, allocptr, 0 /* atmp3 = data object */
411 :     slwi atmp2, atmp2, 2 /* atmp2 = length in bytes */
412 :     add allocptr,allocptr,atmp2 /* allocptr += total length */
413 :    
414 :     /* allocate the header object */
415 :     li atmp1, DESC_word8arr /* header descriptor */
416 :     stw atmp1,0(allocptr)
417 :     addi allocptr, allocptr, 4 /* allocptr++ */
418 :     stw atmp3,0(allocptr) /* header data field */
419 :     stw stdarg,4(allocptr) /* header length field */
420 :     addi stdarg, allocptr, 0 /* stdarg = header object */
421 :     addi allocptr,allocptr,8 /* allocptr += 2 */
422 :     CONTINUE
423 :    
424 :     create_b_a_large: /* off-line allocation */
425 :     li atmp4,REQ_ALLOC_BYTEARRAY
426 :     addi pc, stdlink,0
427 :     b set_request
428 :    
429 :    
430 :     /*
431 :     ** create_s_a: int -> string
432 :     */
433 :     ML_CODE_HDR(create_s_a)
434 :     CHECKLIMIT(create_s_a_limit)
435 :    
436 :     srawi atmp2,stdarg,1 /* atmp2 = length(untagged int) */
437 :     addi atmp2,atmp2,4
438 :     srawi atmp2,atmp2,2 /* length in words (including desc) */
439 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
440 :     bf CR0_LT,create_s_a_large
441 :    
442 :     slwi atmp1,atmp2,TAG_SHIFTW /* build descriptor in atmp3 */
443 :     ori atmp1,atmp1,MAKE_TAG(DTAG_raw32)
444 :     stw atmp1,0(allocptr) /* store descriptor */
445 :     addi allocptr,allocptr,4 /* allocptr++ */
446 :     addi atmp3,allocptr,0 /* atmp3 = data object */
447 :     slwi atmp2,atmp2,2 /* atmp2 = length in bytes */
448 :     add allocptr,atmp2,allocptr /* allocptr += total length */
449 :     stw 0,-4(allocptr) /* store zero in last word */
450 :    
451 :     /* Allocate the header object */
452 :     li atmp1, DESC_string /* header descriptor */
453 :     stw atmp1, 0(allocptr)
454 :     addi allocptr,allocptr,4 /* allocptr++ */
455 :     stw atmp3,0(allocptr) /* header data field */
456 :     stw stdarg,4(allocptr) /* header length field */
457 :     addi stdarg,allocptr,0 /* stdarg = header object */
458 :     addi allocptr,allocptr,8 /* allocptr += 2 */
459 :     CONTINUE
460 :    
461 :     create_s_a_large: /* off-line allocation */
462 :     li atmp4,REQ_ALLOC_STRING
463 :     addi pc, stdlink,0
464 :     b set_request
465 :    
466 :    
467 :    
468 :     ML_CODE_HDR(create_r_a)
469 :     CHECKLIMIT(create_r_a_limit)
470 :    
471 :     srawi atmp2,stdarg,1 /* atmp2 = length (untagged int) */
472 :     slwi atmp2,atmp2,1 /* length in words */
473 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
474 :     bf CR0_LT,create_r_a_large
475 :    
476 :     /* allocate the data object */
477 :     slwi atmp1, atmp2, TAG_SHIFTW /* descriptor in atmp1 */
478 :     ori atmp1, atmp1, MAKE_TAG(DTAG_raw64)
479 :     #ifdef ALIGN_REALDS
480 :     ori allocptr,allocptr,4
481 :     #endif
482 :     stw atmp1,0(allocptr) /* store the descriptor */
483 :     addi allocptr, allocptr, 4 /* allocptr++ */
484 :     addi atmp3, allocptr, 0 /* atmp3 = data object */
485 :     slwi atmp2, atmp2, 2 /* tmp2 = length in bytes */
486 :     add allocptr,allocptr,atmp2 /* allocptr += length */
487 :    
488 :     /* allocate the header object */
489 :     li atmp1, DESC_real64arr
490 :     stw atmp1, 0(allocptr) /* header descriptor */
491 :     addi allocptr,allocptr,4 /* allocptr++ */
492 :     stw atmp3,0(allocptr) /* header data field */
493 :     stw stdarg,4(allocptr) /* header length field */
494 :     addi stdarg,allocptr,0 /* stdarg = header object */
495 :     addi allocptr,allocptr,8 /* allocptr += 2 */
496 :     CONTINUE
497 :     create_r_a_large: /* offline allocation */
498 :     li atmp4,REQ_ALLOC_REALDARRAY
499 :     addi pc, stdlink,0
500 :     b set_request
501 :    
502 :    
503 :     /* create_v_a : (int * 'a list) -> 'a vector
504 :     * Create a vector with elements taken from a list.
505 :     * NOTE: the front-end ensures that list cannot be nil.
506 :     */
507 :     ML_CODE_HDR(create_v_a)
508 :     CHECKLIMIT(create_v_a_limit)
509 :    
510 :     lwz atmp1,0(stdarg) /* atmp1 = tagged length */
511 :     srawi atmp2,atmp1,1 /* atmp2 = untagged length */
512 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
513 :     bf CR0_LT,create_v_a_large
514 :    
515 :     slwi atmp2,atmp2,TAG_SHIFTW /* build descriptor in atmp2 */
516 :     ori atmp2,atmp2,MAKE_TAG(DTAG_vec_data)
517 :     stw atmp2,0(allocptr) /* store descriptor */
518 :     addi allocptr,allocptr,4 /* allocptr++ */
519 :     lwz atmp2,4(stdarg) /* atmp2 := list */
520 :     addi stdarg,allocptr,0 /* stdarg := vector */
521 :    
522 :     create_v_a_1:
523 :     lwz atmp3,0(atmp2) /* atmp3:=hd(atmp2) */
524 :     lwz atmp2,4(atmp2) /* atmp2:=tl(atmp2) */
525 :     stw atmp3,0(allocptr) /* store word */
526 :     addi allocptr,allocptr,4 /* allocptr++ */
527 :     cmpi CR0,atmp2,ML_nil
528 :     bf CR0_EQ,create_v_a_1
529 :    
530 :     /* allocate header object */
531 :     li atmp3, DESC_polyvec /* descriptor in tmp3 */
532 :     stw atmp3,0(allocptr) /* store descriptor */
533 :     addi allocptr,allocptr,4 /* allocptr++ */
534 :     stw stdarg,0(allocptr) /* header data field */
535 :     stw atmp1,4(allocptr) /* header length */
536 :     addi stdarg, allocptr, 0 /* result = header object */
537 :     addi allocptr,allocptr,8 /* allocptr += 2 */
538 :     CONTINUE
539 :    
540 :     create_v_a_large:
541 :     li atmp4,REQ_ALLOC_VECTOR
542 :     addi pc, stdlink,0
543 :     b set_request
544 :    
545 :    
546 :     #if defined(USE_TOC)
547 :     .toc
548 :     T.floor_CONST:
549 :     .tc H.floor_CONST[TC],floor_CONST
550 :     #endif
551 :     RO_DATA
552 :     ALIGN8
553 :     floor_CONST:
554 :     DOUBLE(4512395720392704.0)
555 :    
556 :     TEXT
557 :     /*
558 :     ** floor_a : real -> int
559 :     ** Do not test for overflow, it's the caller's
560 :     ** responsibility to be in range.
561 :     **
562 :     ** This code essentially loads 1.0*2^52 into
563 :     ** register f3. A floating add will internally
564 :     ** perform an exponent alignment, which will
565 :     ** bring the required bits into the mantissa.
566 :     */
567 :     ML_CODE_HDR(floor_a)
568 :     lfd 1, 0(stdarg)
569 :     /*
570 :     ** Neat thing here is that this code works for
571 :     ** both +ve and -ve floating point numbers.
572 :     */
573 :     mffs 0
574 :     stfd 0,0(allocptr) /* steal the allocptr for a second */
575 :     lwz 0, 4(allocptr)
576 :     mtfsb1 30
577 :     mtfsb1 31
578 :     #ifdef USE_TOC
579 :     lwz atmp1, T.floor_CONST(2)
580 :     lfd 3, 0(atmp1)
581 :     #else
582 :     lis atmp1, floor_CONST@ha
583 :     lfd 3, floor_CONST@l(atmp1)
584 :     #endif
585 :     fadd 6,1,3
586 :     stfd 6,FLOOR_OFFSET(sp)
587 :     lwz stdarg,FLOOR_OFFSET+4(sp)
588 :     add stdarg,stdarg,stdarg
589 :     addi stdarg,stdarg,1
590 :    
591 :     andi. 0,0, 0xf
592 :     mtfsf 0xff,0
593 :     CONTINUE
594 :    
595 :    
596 :     ML_CODE_HDR(logb_a)
597 :     lwz stdarg,0(stdarg) /* most significant part */
598 :     srawi stdarg,stdarg,20 /* throw out 20 low bits */
599 :     andi. stdarg,stdarg,0x07ff /* clear all but 11 low bits */
600 :     addi stdarg,stdarg,-1023 /* subtract 1023 */
601 :     slwi stdarg,stdarg,1 /* make room for tag bit */
602 :     addi stdarg,stdarg,1 /* add the tag bit */
603 :     CONTINUE
604 :    
605 :    
606 :     /*
607 :     ** scalb : real * int -> real
608 :     ** scalb(x,y) = x * 2^y
609 :     */
610 :     ML_CODE_HDR(scalb_a)
611 :     CHECKLIMIT(scalb_v_limit)
612 :     lwz atmp1,4(stdarg) /* atmp1 := y */
613 :     srawi atmp1,atmp1,1 /* atmp1 := machine int y */
614 :     lwz stdarg,0(stdarg) /* stdarg := x */
615 :     lwz atmp2,0(stdarg) /* atmp2 := MSW(x) */
616 :     lis 0,0x7ff0 /* r0 := 0x7ff0,0000 */
617 :     and. atmp3,atmp2,0 /* atmp3 := atmp2 & 0x7ff00000 */
618 :     bt CR0_EQ,scalb_all_done
619 :    
620 :     srawi atmp3,atmp3,20 /* atmp3 := ieee(exp) */
621 :     add. atmp1,atmp1,atmp3 /* scale exponent */
622 :     bt CR0_LT,scalb_underflow
623 :    
624 :     cmpi CR0,atmp1,2047 /* max. ieee(exp) */
625 :     bf CR0_LT,scalb_overflow
626 :    
627 :     not 0,0 /* r0 := not(r0) */
628 :     and atmp2,atmp2,0 /* atmp2 := high mantessa bits + sign */
629 :     slwi atmp1,atmp1,20 /* atmp1 := new exponent */
630 :     or atmp1,atmp1,atmp2 /* atmp1 := new MSB(x) */
631 :     lwz atmp2, 4(stdarg)
632 :    
633 :     scalb_write_out:
634 :     stw atmp1, 4(allocptr)
635 :     stw atmp2, 8(allocptr)
636 :     li atmp3, DESC_reald
637 :     stw atmp3, 0(allocptr)
638 :     addi stdarg,allocptr,4
639 :     addi allocptr,allocptr,12
640 :    
641 :     scalb_all_done:
642 :     CONTINUE
643 :    
644 :     scalb_underflow:
645 :     li atmp1,0
646 :     li atmp2,0
647 :     b scalb_write_out
648 :    
649 :     LABEL(scalb_overflow)
650 :     mtfsb1 3
651 :    
652 :    
653 :    
654 :     ML_CODE_HDR(try_lock_a)
655 :     lwz atmp1,0(stdarg)
656 :     li atmp2,1 /* ML_false */
657 :     stw atmp2,0(stdarg)
658 :     addi stdarg,atmp1,0
659 :     CONTINUE
660 :    
661 :    
662 :     ML_CODE_HDR(unlock_a)
663 :     li atmp1,3 /* ML_true */
664 :     stw atmp1,0(stdarg)
665 :     li stdarg,1 /* just return unit */
666 :     CONTINUE
667 :    
668 :    
669 :    
670 :     CENTRY(set_fsr)
671 :     mtfsb0 24 /* disable invalid exception */
672 :     mtfsb0 25 /* disable overflow exception */
673 :     mtfsb0 26 /* disable underflow exception */
674 :     mtfsb0 28 /* disable inexact exception */
675 :     mtfsb0 30 /* round to nearest */
676 :     mtfsb0 31
677 :     blr /* return */
678 :    
679 :     /* saveFPRegs and restoreFPRegs are called from C only. */
680 :     #define ctmp1 12
681 :     #define ctmp2 11
682 :     #define ctmp3 10
683 :    
684 :    
685 :     CENTRY(SaveFPRegs)
686 :     stfd 14, 4(3)
687 :     stfd 15, 12(3)
688 :     stfd 16, 20(3)
689 :     stfd 17, 28(3)
690 :     stfd 18, 36(3)
691 :     stfd 19, 44(3)
692 :     stfd 20, 52(3)
693 :     stfd 21, 60(3)
694 :     stfd 22, 68(3)
695 :     stfd 23, 76(3)
696 :     stfd 24, 84(3)
697 :     stfd 25, 92(3)
698 :     stfd 26, 100(3)
699 :     stfd 27, 108(3)
700 :     stfd 28, 116(3)
701 :     stfd 29, 124(3)
702 :     stfd 30, 132(3)
703 :     stfd 31, 140(3)
704 :    
705 :     blr
706 :    
707 :     CENTRY(RestoreFPRegs)
708 :     lfd 14, 0(3)
709 :     lfd 15, 8(3)
710 :     lfd 16, 16(3)
711 :     lfd 17, 24(3)
712 :     lfd 18, 32(3)
713 :     lfd 19, 40(3)
714 :     lfd 20, 48(3)
715 :     lfd 21, 56(3)
716 :     lfd 22, 64(3)
717 :     lfd 23, 72(3)
718 :     lfd 24, 80(3)
719 :     lfd 25, 88(3)
720 :     lfd 26, 96(3)
721 :     lfd 27, 104(3)
722 :     lfd 28, 112(3)
723 :     lfd 29, 120(3)
724 :     lfd 30, 128(3)
725 :     lfd 31, 136(3)
726 :     blr
727 :    
728 :     #if defined(OPSYS_MKLINUX)
729 :    
730 :     #define CACHE_LINE_SZB 32
731 :     #define CACHE_LINE_MASK (CACHE_LINE_SZB-1)
732 :     #define CACHE_LINE_BITS 26
733 :    
734 :     /* FlushICache:
735 :     *
736 :     * void FlushICache (Addr_t addr, Addr_t nbytes)
737 :     */
738 :     CENTRY(FlushICache)
739 :     add 4,3,4 /* stop := addr+nbytes */
740 :     addic 4,4,CACHE_LINE_MASK /* stop := stop + CACHE_LINE_MASK */
741 :     rlwinm 4,4,0,0,CACHE_LINE_BITS /* stop := stop & ~CACHE_LINE_MASK */
742 :     L_FlushICache_1:
743 :     cmplw 1,3,4 /* while (addr < stop) */
744 :     bc 4,4,L_FlushICache_2
745 :     dcbf 0,3 /* flush addr */
746 :     icbi 0,3 /* invalidate addr */
747 :     addi 3,3,CACHE_LINE_SZB /* addr := addr + CACHE_LINE_SZB */
748 :     b L_FlushICache_1 /* end while */
749 :     L_FlushICache_2:
750 :     blr
751 :    
752 :     #endif
753 :    

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