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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (view) (download)
Original Path: sml/branches/SMLNJ/src/runtime/mach-dep/RS6000.prim.asm

1 : monnier 2 /* RS6000.prim.asm
2 :     *
3 :     * COPYRIGHT (c) 1994 by AT&T Bell Laboratories.
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 "reg-mask.h"
16 :     #include "ml-limits.h"
17 :     #include "mlstate-offsets.h" /** this file is generated **/
18 :    
19 :     /* The root registers in the ML state vector have the following layout,
20 :     * where roots is guaranteed to be 8-byte aligned relative to the start
21 :     * of the ML state vector (see "ml-state.h" and "mlstate-offsets.h"):
22 :     *
23 :     * +----------------------+
24 :     * root --> | ml_stdlink (17) |
25 :     * +----------------------+
26 :     * +4: | ml_closure (18) |
27 :     * +----------------------+
28 :     * +8: | ml_arg (19) |
29 :     * +----------------------+
30 :     * +12: | ml_cont (20) |
31 :     * +----------------------+
32 :     * +16: | ml_exn (21) |
33 :     * +----------------------+
34 :     * +20: | ml_varptr (22) |
35 :     * +----------------------+
36 :     * +24: | ml_basereg (23) |
37 :     * +----------------------+
38 :     * +28: | unused |
39 :     * +----------------------+
40 :     * +32: | ml_pc |
41 :     * +----------------------+
42 :     * +36: | misc 24-27,3-13 |
43 :     * . .
44 :     * . .
45 :     * +----------------------+
46 :     */
47 :    
48 :     /** register usage **/
49 :    
50 :     #define sp 1
51 :     #define stackptr sp
52 :     #define allocptr 14
53 :     #define limitptr 15
54 :     #define storeptr 16
55 :     #define stdlink 17
56 :     #define stdclos 18
57 :     #define stdarg 19
58 :     #define stdcont 20
59 :     #define exncont 21
60 :     #define varptr 22
61 :     #define basereg 23
62 :     #define miscreg0 24
63 :     #define miscreg1 25
64 :     #define miscreg2 26
65 :     #define miscreg3 27
66 :     #define miscreg4 3
67 :     #define miscreg5 4
68 :     #define miscreg6 5
69 :     #define miscreg7 6
70 :     #define miscreg8 7
71 :     #define miscreg9 8
72 :     #define miscreg10 9
73 :     #define miscreg11 10
74 :     #define miscreg12 11
75 :     #define miscreg13 12
76 :     #define miscreg14 13
77 :     #define gclink 28
78 :    
79 :     #define atmp1 29
80 :     #define atmp2 30
81 :     #define atmp3 31
82 :     #define atmp4 miscreg13
83 :    
84 :     /* stackframe layout:
85 :     * Note: 1. The offset of cvti2d tmp is used in rs6000.sml
86 :     * float load/store offset is hardwired in rs6000instr.sml
87 :     * 2. The offset of pseudo regs is used in rs6000/rs6000.sml
88 :     * to support loadpseudo and storepseudo.
89 :     *
90 :     * +-------------------+
91 :     * sp--> 0(sp) | mlstate addr |
92 :     * +-------------------+
93 :     * 4(sp) | _startgc addr |
94 :     * +-------------------+
95 :     * 8(sp) | cvti2d const |
96 :     * +-------------------+
97 :     * 16(sp) | cvti2d tmp2 |
98 :     * +-------------------+
99 :     * 24(sp) | float load/store |
100 :     * +-------------------+
101 :     * 32(sp) | floor tmp |
102 :     * +-------------------+
103 :     * 40(sp) | pseudo regs 1 |
104 :     * +-------------------+
105 :     * 44(sp) | pseudo regs 2 |
106 :     * +-------------------+
107 :     * argblock(sp) | C calleesave regs |
108 :     * . .
109 :     * . .
110 :     * +-------------------+
111 :     * argblock+92(sp) | |
112 :     */
113 :    
114 :    
115 :     /** MLState offsets **/
116 :     #define NROOTS 24 /* from ml_state.h */
117 :    
118 :     #define argblock 48
119 :     #define savearea (23*4+4) /* lr,cr,1,2,13-31,padding */
120 :     #define framesize (argblock+savearea)
121 :     #define MLSTATE_OFFSET 0
122 :     #define STARTGC_OFFSET 4
123 :     #define CVTI2D_OFFSET 8
124 :     #define FLOOR_OFFSET 32
125 :     #define PSEUDOREG_OFFSET 40
126 :    
127 :     /** offsets in condition register CR.0 **/
128 :    
129 :     #define CR0_LT 0
130 :     #define CR0_GT 1
131 :     #define CR0_EQ 2
132 :     #define CR0_SO 3
133 :    
134 :     #define CR0 0
135 :    
136 :     /** special registers **/
137 :    
138 :     #define SPR_LR 8
139 :    
140 :     /** C parameter passing conventions **/
141 :     #define CARG1 3
142 :     #define CRESULT1 3
143 :    
144 :    
145 :     #if (CALLEESAVE > 0)
146 :     #define CONTINUE \
147 :     cmpl CR0,limitptr,allocptr; \
148 :     mtlr stdcont; \
149 :     blr
150 :     #endif
151 :    
152 :     #define CHECKLIMIT(mask,label) \
153 :     bt CR0_GT, label; \
154 :     lwz atmp2,STARTGC_OFFSET(stackptr); \
155 :     li atmp1,mask; \
156 :     mtspr SPR_LR, atmp2; \
157 :     addi gclink,stdlink,0; \
158 :     blr ; \
159 :     label:
160 :    
161 :     .extern CSYM(_PollFreq0)
162 :     .extern CSYM(_PollEvent0)
163 :     .extern CSYM(saveregs)
164 :    
165 :     #if defined (USE_TOC)
166 :     /* create table of contents entries for things we need the address of. */
167 :     .toc
168 :     T._PollFreq0:
169 :     .tc H._PollFreq0[TC],CSYM(_PollFreq0)
170 :     T._PollEvent0:
171 :     .tc H._PollEvent0[TC],CSYM(_PollEvent0)
172 :     T.saveregs:
173 :     .tc H.saveregs[TC],CSYM(saveregs)
174 :     T.cvti2d_CONST:
175 :     .tc H.cvti2d_CONST[TC],cvti2d_CONST
176 :     #endif
177 :     RO_DATA
178 :     ALIGN8
179 :     cvti2d_CONST:
180 :     DOUBLE(4503601774854144.0)
181 :    
182 :     TEXT
183 :     /* sig_return : ('a cont * 'a) -> 'b
184 :     */
185 :     ML_CODE_HDR(sigh_return_a)
186 :     li atmp1,RET_MASK
187 :     li atmp4,REQ_SIG_RETURN
188 :     b set_request
189 :    
190 :     ENTRY(sigh_resume)
191 :     li atmp1,FUN_MASK
192 :     li atmp4, REQ_SIG_RESUME
193 :     b set_request
194 :    
195 :     /* pollh_return_a:
196 :     * The return continuation for the ML poll handler.
197 :     */
198 :     ML_CODE_HDR(pollh_return_a)
199 :     li atmp1,RET_MASK
200 :     li atmp4,REQ_POLL_RETURN
201 :     b set_request
202 :    
203 :     /* pollh_resume:
204 :     * Resume execution at the point at which a poll event occurred.
205 :     */
206 :     ENTRY(pollh_resume)
207 :     li atmp1,FUN_MASK
208 :     li atmp4,REQ_POLL_RESUME
209 :     b set_request
210 :    
211 :     /* exception handler for ML functions called from C */
212 :     ML_CODE_HDR(handle_a)
213 :     li atmp1,EXN_MASK
214 :     li atmp4,REQ_EXN
215 :     b set_request
216 :    
217 :    
218 :     /* continuation for ML functions called from C */
219 :     ML_CODE_HDR(return_a)
220 :     li atmp1,RET_MASK
221 :     li atmp4,REQ_RETURN
222 :     b set_request
223 :    
224 :    
225 :     ENTRY(request_fault)
226 :     li atmp1,EXN_MASK
227 :     li atmp4,REQ_FAULT
228 :     b set_request
229 :    
230 :    
231 :     /* bind_cfun : (string * string) -> c_function
232 :     */
233 :     ML_CODE_HDR(bind_cfun_a)
234 :     CHECKLIMIT(FUN_MASK,bind_cfun_v_limit)
235 :     li atmp1,FUN_MASK
236 :     li atmp4,REQ_BIND_CFUN
237 :     b set_request
238 :    
239 :     ML_CODE_HDR(build_literals_a)
240 :     CHECKLIMIT(FUN_MASK,build_literals_v_limit)
241 :     li atmp1,FUN_MASK
242 :     li atmp4,REQ_BUILD_LITERALS
243 :     b set_request
244 :    
245 :     ML_CODE_HDR(callc_a)
246 :     CHECKLIMIT(FUN_MASK,callc_v_limit)
247 :     li atmp1,FUN_MASK
248 :     li atmp4,REQ_CALLC
249 :     /* fall through */
250 :    
251 :     set_request:
252 :     lwz atmp3,MLSTATE_OFFSET(sp) /* save the minimal ML state */
253 :     stw atmp1,MaskOffMSP(atmp3) /* mask */
254 :     lwz atmp2,VProcOffMSP(atmp3) /* atmp2 := VProc State ptr */
255 :     li 0,0
256 :     stw 0,InMLOffVSP(atmp2) /* note that we have left ML */
257 :     stw allocptr,AllocPtrOffMSP(atmp3)
258 :     stw limitptr,LimitPtrOffMSP(atmp3)
259 :     stw storeptr,StorePtrOffMSP(atmp3)
260 :     stw stdlink,LinkRegOffMSP(atmp3)
261 :     stw stdlink,PCOffMSP(atmp3)
262 :     stw stdarg,StdArgOffMSP(atmp3)
263 :     stw stdcont,StdContOffMSP(atmp3)
264 :     stw stdclos,StdClosOffMSP(atmp3)
265 :     stw varptr,VarPtrOffMSP(atmp3)
266 :     stw exncont,ExnPtrOffMSP(atmp3)
267 :     #if CALLEESAVE > 0
268 :     stw miscreg0,MiscRegOffMSP(0)(atmp3)
269 :     #if CALLEESAVE > 1
270 :     stw miscreg1,MiscRegOffMSP(1)(atmp3)
271 :     #if CALLEESAVE > 2
272 :     stw miscreg2,MiscRegOffMSP(2)(atmp3)
273 :     #if CALLEESAVE > 3
274 :     ??
275 :     #endif
276 :     #endif
277 :     #endif
278 :     #endif
279 :     addi 3,atmp4,0 /* request as argument */
280 :    
281 :     restore_c_regs:
282 :     lwz atmp1,PSEUDOREG_OFFSET(sp) /* restore pseudo registers */
283 :     stw atmp1,PseudoReg1OffMSP(atmp3)
284 :     lwz atmp1,PSEUDOREG_OFFSET+4(sp)
285 :     stw atmp1,PseudoReg2OffMSP(atmp3)
286 :     lwz 2, (argblock+4)(sp)
287 :     lwz 13, (argblock+8)(sp)
288 :     lwz 14, (argblock+12)(sp)
289 :     lwz 15, (argblock+16)(sp)
290 :     lwz 16, (argblock+20)(sp)
291 :     lwz 17, (argblock+24)(sp)
292 :     lwz 18, (argblock+28)(sp)
293 :     lwz 19, (argblock+32)(sp)
294 :     lwz 20, (argblock+36)(sp)
295 :     lwz 21, (argblock+40)(sp)
296 :     lwz 22, (argblock+44)(sp)
297 :     lwz 23, (argblock+48)(sp)
298 :     lwz 24, (argblock+52)(sp)
299 :     lwz 25, (argblock+56)(sp)
300 :     lwz 26, (argblock+60)(sp)
301 :     lwz 27, (argblock+64)(sp)
302 :     lwz 28, (argblock+68)(sp)
303 :     lwz 29, (argblock+72)(sp)
304 :     lwz 30, (argblock+76)(sp)
305 :     lwz 31, (argblock+80)(sp)
306 :     lwz 0, (argblock+84)(sp)
307 :     mtlr 0
308 :     lwz 0, (argblock+88)(sp)
309 :     mtcrf 0x80, 0
310 :     addi sp,sp,framesize
311 :     blr
312 :    
313 :     TEXT
314 :     ENTRY(saveregs)
315 :     lwz atmp3,MLSTATE_OFFSET(sp)
316 :     stw atmp1,MaskOffMSP(atmp3)
317 :    
318 :     #ifdef SOFT_POLL
319 :     /* free some regs */
320 :     stw miscreg0,MiscRegOffMSP(0)(atmp3) /* use as tmp */
321 :     stw miscreg1,MiscRegOffMSP(1)(atmp3) /* use as tmp */
322 :     #define pfreq atmp1
323 :     #define pevent miscreg0
324 :     #define ptmp miscreg1
325 :    
326 :     /* check if polling enabled (PollFreq > 0) */
327 :     lwz pfreq,T._PollFreq0(2) /* address of PollFreq */
328 :     lwz pfreq,4(pfreq) /* contents of PollFreq */
329 :     sri pfreq,pfreq,1 /* strip integer tag */
330 :     cmpi CR0,pfreq,0
331 :     bt CR0_EQ,check_for_gc /* go check for real gc */
332 :     lwz ptmp,InPollHandlerOffMSP(atmp3) /* if we're in the handler */
333 :     cmpi CR0,ptmp,0
334 :     bt CR0_GT,reset_limit /* ignore poll events */
335 :     lwz ptmp,T._PollEvent0(2) /* address of PollEvent */
336 :     lwz pevent,4(ptmp) /* contents of PollEvent */
337 :     sri pevent,pevent,1
338 :     cmpi CR0,pevent,0
339 :     bt CR0_EQ,reset_limit
340 :     /* event occurred, so set ml_pollHandlerPending */
341 :     li ptmp,1
342 :     stw ptmp,PollPendingOffMSP(atmp3)
343 :     b do_gc /* and handle event in the C runtime */
344 :    
345 :     reset_limit: /* reset limit ptr */
346 :     slwi pfreq,pfreq,POLL_GRAIN_BITS /* mult by POLL_GRAIN_CPSI */
347 :     add limitptr,pfreq,allocptr
348 :    
349 :     check_for_gc:
350 :     #define ptmp2 pfreq
351 :     #define vsp pevent
352 :     /* ensure real limit is >= limit */
353 :     lwz ptmp,RealLimitOffMSP(atmp3)
354 :     cmpl CR0,ptmp,limitptr
355 :     bt CR0_GT,ok_limit
356 :     addi limitptr,ptmp,0 /* move ptmp into limit */
357 :     ok_limit:
358 :     addi ptmp,limitptr,-4096
359 :     cmpl CR0,ptmp,allocptr
360 :     bf CR0_GT,do_gc /* gc *//* should be a common case */
361 :     /* since a signal also sets limitptr == allocptr to force a trap, */
362 :     /* we need to disambiguate poll-events/signals here */
363 :     lwz vsp,VProcOffMSP(atmp3) /* get the vsp */
364 :     lwz ptmp,PollPendingOffMSP(atmp3)
365 :     lwz ptmp2,NPendingOffVSP(vsp)
366 :     add ptmp,ptmp,ptmp2
367 :     lwz ptmp2,NPendingSysOffVSP(vsp)
368 :     add ptmp,ptmp,ptmp2
369 :     cmpi CR0,ptmp,0
370 :     bt CR0_GT,do_gc
371 :     #undef vsp
372 :     #undef ptmp2
373 :    
374 :     no_gc: /* an uneventful poll check, back to ML */
375 :     lwz miscreg0,MiscRegOffMSP(0)(atmp3) /* reload miscregs */
376 :     lwz miscreg1,MiscRegOffMSP(1)(atmp3)
377 :     b CSYM(ml_go)
378 :    
379 :     do_gc:
380 :     stw limitptr,LimitPtrOffMSP(atmp3)
381 :    
382 :     #undef pfreq
383 :     #undef pevent
384 :     #undef ptmp
385 :     #endif /* SOFT_POLL */
386 :    
387 :     lwz atmp2,VProcOffMSP(atmp3) /* atmp2 := VProc State ptr */
388 :     li 0,0
389 :     stw 0,InMLOffVSP(atmp2) /* note that we have left ML */
390 :     addi basereg, basereg, -32764
391 :     stw allocptr,AllocPtrOffMSP(atmp3)
392 :     stw storeptr,StorePtrOffMSP(atmp3)
393 :     stw stdarg,StdArgOffMSP(atmp3)
394 :     stw stdcont,StdContOffMSP(atmp3)
395 :     stw stdclos,StdClosOffMSP(atmp3)
396 :     stw gclink,PCOffMSP(atmp3)
397 :     stw exncont,ExnPtrOffMSP(atmp3)
398 :     /* save misc. roots */
399 :     #ifndef SOFT_POLL /* miscreg0 & miscreg1 saved above for SOFT_POLL */
400 :     stw miscreg0,MiscRegOffMSP(0)(atmp3)
401 :     stw miscreg1,MiscRegOffMSP(1)(atmp3)
402 :     #endif
403 :     stw miscreg2,MiscRegOffMSP(2)(atmp3)
404 :     stw miscreg3,MiscRegOffMSP(3)(atmp3)
405 :     stw miscreg4,MiscRegOffMSP(4)(atmp3)
406 :     stw miscreg5,MiscRegOffMSP(5)(atmp3)
407 :     stw miscreg6,MiscRegOffMSP(6)(atmp3)
408 :     stw miscreg7,MiscRegOffMSP(7)(atmp3)
409 :     stw miscreg8,MiscRegOffMSP(8)(atmp3)
410 :     stw miscreg9,MiscRegOffMSP(9)(atmp3)
411 :     stw miscreg10,MiscRegOffMSP(10)(atmp3)
412 :     stw miscreg11,MiscRegOffMSP(11)(atmp3)
413 :     stw miscreg12,MiscRegOffMSP(12)(atmp3)
414 :     stw miscreg13,MiscRegOffMSP(13)(atmp3)
415 :     stw miscreg14,MiscRegOffMSP(14)(atmp3)
416 :     stw stdlink,LinkRegOffMSP(atmp3)
417 :     stw basereg,BasePtrOffMSP(atmp3) /* base reg */
418 :     stw varptr,VarPtrOffMSP(atmp3)
419 :     li CARG1,REQ_GC
420 :     b restore_c_regs
421 :    
422 :    
423 :     CENTRY(restoreregs)
424 :     addi sp,sp,-framesize
425 :     #if defined(USE_TOC)
426 :     lwz 0,T.saveregs(2)
427 :     #else
428 :     lis 0, CSYM(saveregs)@ha /* GPR0 <- addrof(saveregs) */
429 :     addi 0, 0, CSYM(saveregs)@l
430 :     #endif
431 :     stw 3, MLSTATE_OFFSET(sp)
432 :     stw 0, STARTGC_OFFSET(sp)
433 :     #if defined(USE_TOC)
434 :     lwz 4, T.cvti2d_CONST(2) /* GPR2 is RTOC */
435 :     lfd 0, 0(4)
436 :     #else
437 :     lis 4, cvti2d_CONST@ha
438 :     lfd 0, cvti2d_CONST@l(4)
439 :     #endif
440 :     stfd 0, CVTI2D_OFFSET(sp)
441 :    
442 :     stw 2, argblock+4(sp)
443 :     stw 13, argblock+8(sp)
444 :     stw 14, argblock+12(sp)
445 :     stw 15, argblock+16(sp)
446 :     stw 16, argblock+20(sp)
447 :     stw 17, argblock+24(sp)
448 :     stw 18, argblock+28(sp)
449 :     stw 19, argblock+32(sp)
450 :     stw 20, argblock+36(sp)
451 :     stw 21, argblock+40(sp)
452 :     stw 22, argblock+44(sp)
453 :     stw 23, argblock+48(sp)
454 :     stw 24, argblock+52(sp)
455 :     stw 25, argblock+56(sp)
456 :     stw 26, argblock+60(sp)
457 :     stw 27, argblock+64(sp)
458 :     stw 28, argblock+68(sp)
459 :     stw 29, argblock+72(sp)
460 :     stw 30, argblock+76(sp)
461 :     stw 31, argblock+80(sp)
462 :     mflr 0
463 :     stw 0, argblock+84(sp)
464 :     mfcr 0
465 :     stw 0, argblock+88(sp)
466 :    
467 :     and atmp1,3,3 /* atmp1 := MLState pointer */
468 :    
469 :     lwz allocptr,AllocPtrOffMSP(atmp1)
470 :     lwz limitptr,LimitPtrOffMSP(atmp1)
471 :     lwz storeptr,StorePtrOffMSP(atmp1)
472 :     lwz atmp2,PseudoReg1OffMSP(atmp1) /* restore pseudo registers */
473 :     lwz atmp3,PseudoReg2OffMSP(atmp1)
474 :     stw atmp2,PSEUDOREG_OFFSET(sp)
475 :     stw atmp3,PSEUDOREG_OFFSET+4(sp)
476 :     lwz atmp2,VProcOffMSP(atmp1) /* atmp2 := VProc State ptr */
477 :     li atmp3,1
478 :     stw atmp3,InMLOffVSP(atmp2) /* we are entering ML code */
479 :     lwz stdarg,StdArgOffMSP(atmp1)
480 :     lwz stdcont,StdContOffMSP(atmp1)
481 :     lwz stdclos,StdClosOffMSP(atmp1)
482 :     lwz exncont,ExnPtrOffMSP(atmp1)
483 :     lwz miscreg0,MiscRegOffMSP(0)(atmp1)
484 :     lwz miscreg1,MiscRegOffMSP(1)(atmp1)
485 :     lwz miscreg2,MiscRegOffMSP(2)(atmp1)
486 :     lwz miscreg3,MiscRegOffMSP(3)(atmp1)
487 :     lwz miscreg4,MiscRegOffMSP(4)(atmp1)
488 :     lwz miscreg5,MiscRegOffMSP(5)(atmp1)
489 :     lwz miscreg6,MiscRegOffMSP(6)(atmp1)
490 :     lwz miscreg7,MiscRegOffMSP(7)(atmp1)
491 :     lwz miscreg8,MiscRegOffMSP(8)(atmp1)
492 :     lwz miscreg9,MiscRegOffMSP(9)(atmp1)
493 :     lwz miscreg10,MiscRegOffMSP(10)(atmp1)
494 :     lwz miscreg11,MiscRegOffMSP(11)(atmp1)
495 :     lwz miscreg12,MiscRegOffMSP(12)(atmp1)
496 :     lwz miscreg13,MiscRegOffMSP(13)(atmp1)
497 :     lwz miscreg14,MiscRegOffMSP(14)(atmp1)
498 :     lwz stdlink,LinkRegOffMSP(atmp1)
499 :     lwz varptr,VarPtrOffMSP(atmp1)
500 :     lwz basereg,BasePtrOffMSP(atmp1)
501 :     lwz gclink,PCOffMSP(atmp1)
502 :     addi basereg,basereg,32764 /* adjust baseReg */
503 :     /* check for pending signals */
504 :     lwz atmp1,NPendingSysOffVSP(atmp2)
505 :     lwz atmp3,NPendingOffVSP(atmp2)
506 :     add atmp1,atmp1,atmp3
507 :     cmpi CR0,atmp1,0
508 :     bf CR0_EQ,pending_sigs
509 :    
510 :    
511 :     ENTRY(ml_go)
512 :     cmpl CR0,limitptr,allocptr
513 :     mtlr gclink
514 :    
515 :     mtfsfi 3,0 /* Ensure that no exceptions are set */
516 :     mtfsfi 2,0
517 :     mtfsfi 1,0
518 :     mtfsfi 0,0
519 :     li 0,0
520 :     mtxer 0
521 :     blr /* jump to ML code */
522 :    
523 :     pending_sigs: /* there are pending signals */
524 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
525 :     cmpi CR0,atmp1,0
526 :     bf CR0_EQ,CSYM(ml_go)
527 :     /* check if currently handling a signal */
528 :     lwz atmp1,InSigHandlerOffVSP(atmp2)
529 :     cmpi CR0,atmp1,0
530 :     bf CR0_EQ,CSYM(ml_go)
531 :    
532 :     li 0,1
533 :     stw 0,HandlerPendingOffVSP(atmp2)
534 :     addi limitptr,allocptr,0
535 :     b CSYM(ml_go)
536 :    
537 :    
538 :     ML_CODE_HDR(array_a)
539 :     CHECKLIMIT(FUN_MASK,array_a_limit)
540 :     lwz atmp2,0(stdarg) /* atmp2 := tagged length */
541 :     srawi atmp2,atmp2,1 /* atmp2 := untagged length */
542 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a large object */
543 :     bf CR0_LT,array_a_large
544 :     slwi atmp3,atmp2,TAG_SHIFTW /* atmp3 := build descriptor */
545 :     ori atmp3,atmp3,MAKE_TAG(DTAG_array)
546 :     stw atmp3,0(allocptr) /* store the descriptor */
547 :     addi allocptr,allocptr,4 /* points to new object */
548 :     lwz atmp4,4(stdarg) /* atmp4 := get initial value */
549 :     addi stdarg,allocptr,0 /* put ptr in return register */
550 :     slwi atmp2,atmp2,2 /* atmp2 := length in bytes */
551 :     add atmp1,atmp2,allocptr /* beyond last word of new array */
552 :     array_a_2: /* loop */
553 :     addi allocptr,allocptr,4 /* on to the next word */
554 :     cmp CR0,allocptr,atmp1
555 :     stw atmp4,-4(allocptr) /* store the value */
556 :     bf CR0_EQ, array_a_2 /* if not off the end, repeat */
557 :     /* end loop */
558 :     CONTINUE
559 :     array_a_large: /* off-line allocation */
560 :     li atmp1,FUN_MASK
561 :     li atmp4,REQ_ALLOC_ARRAY
562 :     b set_request
563 :    
564 :    
565 :     ML_CODE_HDR(create_b_a)
566 :     CHECKLIMIT(FUN_MASK,create_b_a_limit)
567 :     srawi atmp2,stdarg,1 /* atmp1 = length */
568 :     addi atmp2,atmp2,3
569 :     srawi atmp2,atmp2,2 /* length in words (including desc) */
570 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
571 :     bf CR0_LT,create_b_a_large
572 :    
573 :     srawi atmp3,stdarg,1 /* build descriptor in atmp3 */
574 :     slwi atmp3,atmp3,TAG_SHIFTW
575 :     ori atmp3,atmp3,MAKE_TAG(DTAG_bytearray)
576 :     stw atmp3,0(allocptr) /* store descriptor */
577 :     addi stdarg,allocptr,4 /* pointer to new string */
578 :     slwi atmp2,atmp2,2 /* length in bytes */
579 :     addi atmp2,atmp2,4 /* length + tag */
580 :     add allocptr,allocptr,atmp2 /* advance allocptr */
581 :     CONTINUE
582 :    
583 :     create_b_a_large:
584 :     li atmp1,FUN_MASK
585 :     li atmp4,REQ_ALLOC_BYTEARRAY
586 :     b set_request
587 :    
588 :    
589 :     /*
590 :     ** create_s_a: int -> string
591 :     */
592 :     ML_CODE_HDR(create_s_a)
593 :     CHECKLIMIT(FUN_MASK,create_s_a_limit)
594 :     srawi atmp2,stdarg,1 /* atmp1 = length */
595 :     addi atmp2,atmp2,4
596 :     srawi atmp2,atmp2,2 /* length in words (including desc) */
597 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
598 :     bf CR0_LT,create_s_a_large
599 :    
600 :     srawi atmp1,stdarg,1 /* build descriptor in atmp1 */
601 :     slwi atmp1,atmp1,TAG_SHIFTW
602 :     ori atmp1,atmp1,MAKE_TAG(DTAG_string)
603 :     stw atmp1,0(allocptr) /* store descriptor */
604 :     addi stdarg,allocptr,4 /* pointer to new string */
605 :     slwi atmp2,atmp2,2 /* length in bytes */
606 :     addi atmp2,atmp2,4 /* + tag */
607 :     add allocptr,allocptr,atmp2 /* advance allocptr */
608 :     li 0,0
609 :     stw 0,-4(allocptr) /* zero in last word */
610 :     CONTINUE
611 :    
612 :     create_s_a_large:
613 :     li atmp1,FUN_MASK
614 :     li atmp4,REQ_ALLOC_STRING
615 :     b set_request
616 :    
617 :    
618 :    
619 :     ML_CODE_HDR(create_r_a)
620 :     CHECKLIMIT(FUN_MASK,create_r_a_limit)
621 :     srawi atmp2,stdarg,1 /* atmp1 = length */
622 :     slwi atmp2,atmp2,1 /* length in words */
623 :     cmpi CR0,atmp2,SMALL_OBJ_SZW /* is this a small object */
624 :     bf CR0_LT,create_r_a_large
625 :    
626 :     srawi atmp3,stdarg,1 /* descriptor in atmp3 */
627 :     slwi atmp3,atmp3,TAG_SHIFTW
628 :     ori atmp3,atmp3,MAKE_TAG(DTAG_realdarray)
629 :     #ifdef ALIGN_REALDS
630 :     ori allocptr,allocptr,4
631 :     #endif
632 :     stw atmp3,0(allocptr)
633 :     addi stdarg,allocptr,4 /* pointer to new realarray */
634 :     slwi atmp2,atmp2,2 /* length in bytes */
635 :     addi atmp2,atmp2,4 /* plus tag */
636 :     add allocptr,allocptr,atmp2 /* new allocptr */
637 :     CONTINUE
638 :     create_r_a_large:
639 :     li atmp1,FUN_MASK
640 :     li atmp4,REQ_ALLOC_REALDARRAY
641 :     b set_request
642 :    
643 :    
644 :     ML_CODE_HDR(create_v_a)
645 :     CHECKLIMIT(FUN_MASK,create_v_a_limit)
646 :     lwz atmp1,0(stdarg) /* atmp1 := tagged length */
647 :     srawi atmp1,atmp1,1 /* untagged length */
648 :     cmpi CR0,atmp1,SMALL_OBJ_SZW /* is this a small object */
649 :     bf CR0_LT,create_v_a_large
650 :    
651 :     slwi atmp2,atmp1,TAG_SHIFTW /* build descriptor in atmp2 */
652 :     ori atmp2,atmp2,MAKE_TAG(DTAG_vector)
653 :     stw atmp2,0(allocptr)
654 :     addi allocptr,allocptr,4
655 :     lwz atmp2,4(stdarg) /* atmp2 := list */
656 :     addi stdarg,allocptr,0 /* stdarg := vector */
657 :     li atmp3,ML_nil
658 :    
659 :     create_v_a_1:
660 :     lwz atmp1,0(atmp2) /* atmp1:=hd(atmp2) */
661 :     lwz atmp2,4(atmp2) /* atmp2:=tl(atmp2) */
662 :     cmp CR0,atmp2,atmp3
663 :     stw atmp1,0(allocptr) /* store word */
664 :     addi allocptr,allocptr,4
665 :     bf CR0_EQ,create_v_a_1
666 :    
667 :     CONTINUE
668 :    
669 :     create_v_a_large:
670 :     li atmp1,FUN_MASK
671 :     li atmp4,REQ_ALLOC_VECTOR
672 :     b set_request
673 :    
674 :    
675 :     #if defined(USE_TOC)
676 :     .toc
677 :     T.floor_CONST:
678 :     .tc H.floor_CONST[TC],floor_CONST
679 :     T.floor_MAXINT:
680 :     .tc H.floor_MAXINT[TC],floor_MAXINT
681 :     #endif
682 :     RO_DATA
683 :     ALIGN8
684 :     floor_CONST:
685 :     DOUBLE(4512395720392704.0)
686 :     floor_MAXINT:
687 :     DOUBLE(1073741824.0)
688 :    
689 :     TEXT
690 :     /*
691 :     ** floor_a : real -> int
692 :     ** The overflow test here is not quite
693 :     ** accurate. MINIT = -MAXINT instead of
694 :     ** MININT = -(MAXINT + 1). Should fix this
695 :     ** eventually!!
696 :     **
697 :     ** This code essentially loads 1.0*2^52 into
698 :     ** register f3. A floating add will internally
699 :     ** perform an exponent alignment, which will
700 :     ** bring the required bits into the mantissa.
701 :     */
702 :     ML_CODE_HDR(floor_a)
703 :     lfd 1, 0(stdarg)
704 :     #ifdef USE_TOC
705 :     lwz atmp1, T.floor_MAXINT(2)
706 :     lfd 0, 0(atmp1)
707 :     #else
708 :     lis atmp1, floor_MAXINT@ha
709 :     lfd 0, floor_MAXINT@l(atmp1)
710 :     #endif
711 :     fabs 5, 1
712 :     fcmpo CR0,5,0
713 :     bt CR0_GT,floor_overflow
714 :    
715 :     /*
716 :     ** Neat thing here is that this code works for
717 :     ** both +ve and -ve floating point numbers.
718 :     */
719 :     mffs 0
720 :     stfd 0,0(allocptr) /* steal the allocptr for a second */
721 :     lwz 0, 4(allocptr)
722 :     mtfsb1 30
723 :     mtfsb1 31
724 :     #ifdef USE_TOC
725 :     lwz atmp1, T.floor_CONST(2)
726 :     lfd 3, 0(atmp1)
727 :     #else
728 :     lis atmp1, floor_CONST@ha
729 :     lfd 3, floor_CONST@l(atmp1)
730 :     #endif
731 :     fadd 6,1,3
732 :     stfd 6,FLOOR_OFFSET(sp)
733 :     lwz stdarg,FLOOR_OFFSET+4(sp)
734 :     add stdarg,stdarg,stdarg
735 :     addi stdarg,stdarg,1
736 :    
737 :     andi. 0,0, 0xf
738 :     mtfsf 0xff,0
739 :     CONTINUE
740 :    
741 :     floor_overflow:
742 :     tweq 0,0
743 :    
744 :    
745 :    
746 :     ML_CODE_HDR(logb_a)
747 :     lwz stdarg,0(stdarg) /* most significant part */
748 :     srawi stdarg,stdarg,20 /* throw out 20 low bits */
749 :     andi. stdarg,stdarg,0x07ff /* clear all but 11 low bits */
750 :     addi stdarg,stdarg,-1023 /* subtract 1023 */
751 :     slwi stdarg,stdarg,1 /* make room for tag bit */
752 :     addi stdarg,stdarg,1 /* add the tag bit */
753 :     CONTINUE
754 :    
755 :    
756 :     /*
757 :     ** scalb : real * int -> real
758 :     ** scalb(x,y) = x * 2^y
759 :     */
760 :     ML_CODE_HDR(scalb_a)
761 :     CHECKLIMIT(FUN_MASK,scalb_v_limit)
762 :     lwz atmp1,4(stdarg) /* atmp1 := y */
763 :     srawi atmp1,atmp1,1 /* atmp1 := machine int y */
764 :     lwz stdarg,0(stdarg) /* stdarg := x */
765 :     lwz atmp2,0(stdarg) /* atmp2 := MSW(x) */
766 :     lis 0,0x7ff0 /* r0 := 0x7ff0,0000 */
767 :     and. atmp3,atmp2,0 /* atmp3 := atmp2 & 0x7ff00000 */
768 :     bt CR0_EQ,scalb_all_done
769 :    
770 :     srawi atmp3,atmp3,20 /* atmp3 := ieee(exp) */
771 :     add. atmp1,atmp1,atmp3 /* scale exponent */
772 :     bt CR0_LT,scalb_underflow
773 :    
774 :     cmpi CR0,atmp1,2047 /* max. ieee(exp) */
775 :     bf CR0_LT,scalb_overflow
776 :    
777 :     not 0,0 /* r0 := not(r0) */
778 :     and atmp2,atmp2,0 /* atmp2 := high mantessa bits + sign */
779 :     slwi atmp1,atmp1,20 /* atmp1 := new exponent */
780 :     or atmp1,atmp1,atmp2 /* atmp1 := new MSB(x) */
781 :     lwz atmp2, 4(stdarg)
782 :    
783 :     scalb_write_out:
784 :     stw atmp1, 4(allocptr)
785 :     stw atmp2, 8(allocptr)
786 :     li atmp3, DESC_reald
787 :     stw atmp3, 0(allocptr)
788 :     addi stdarg,allocptr,4
789 :     addi allocptr,allocptr,12
790 :    
791 :     scalb_all_done:
792 :     CONTINUE
793 :    
794 :     scalb_underflow:
795 :     li atmp1,0
796 :     li atmp2,0
797 :     b scalb_write_out
798 :    
799 :     LABEL(scalb_overflow)
800 :     mtfsb1 3
801 :    
802 :    
803 :    
804 :     ML_CODE_HDR(try_lock_a)
805 :     lwz atmp1,0(stdarg)
806 :     li atmp2,1 /* ML_false */
807 :     stw atmp2,0(stdarg)
808 :     addi stdarg,atmp1,0
809 :     CONTINUE
810 :    
811 :    
812 :     ML_CODE_HDR(unlock_a)
813 :     li atmp1,3 /* ML_true */
814 :     stw atmp1,0(stdarg)
815 :     li stdarg,1 /* just return unit */
816 :     CONTINUE
817 :    
818 :    
819 :    
820 :     /* saveFPRegs and restoreFPRegs are called from C only. */
821 :     #define ctmp1 12
822 :     #define ctmp2 11
823 :     #define ctmp3 10
824 :    
825 :    
826 :     CENTRY(SaveFPRegs)
827 :     stfd 14, 4(3)
828 :     stfd 15, 12(3)
829 :     stfd 16, 20(3)
830 :     stfd 17, 28(3)
831 :     stfd 18, 36(3)
832 :     stfd 19, 44(3)
833 :     stfd 20, 52(3)
834 :     stfd 21, 60(3)
835 :     stfd 22, 68(3)
836 :     stfd 23, 76(3)
837 :     stfd 24, 84(3)
838 :     stfd 25, 92(3)
839 :     stfd 26, 100(3)
840 :     stfd 27, 108(3)
841 :     stfd 28, 116(3)
842 :     stfd 29, 124(3)
843 :     stfd 30, 132(3)
844 :     stfd 31, 140(3)
845 :    
846 :     blr
847 :    
848 :     CENTRY(RestoreFPRegs)
849 :     lfd 14, 0(3)
850 :     lfd 15, 8(3)
851 :     lfd 16, 16(3)
852 :     lfd 17, 24(3)
853 :     lfd 18, 32(3)
854 :     lfd 19, 40(3)
855 :     lfd 20, 48(3)
856 :     lfd 21, 56(3)
857 :     lfd 22, 64(3)
858 :     lfd 23, 72(3)
859 :     lfd 24, 80(3)
860 :     lfd 25, 88(3)
861 :     lfd 26, 96(3)
862 :     lfd 27, 104(3)
863 :     lfd 28, 112(3)
864 :     lfd 29, 120(3)
865 :     lfd 30, 128(3)
866 :     lfd 31, 136(3)
867 :     blr
868 :    
869 :     #if defined(OPSYS_MKLINUX)
870 :    
871 :     #define CACHE_LINE_SZB 32
872 :     #define CACHE_LINE_MASK (CACHE_LINE_SZB-1)
873 :     #define CACHE_LINE_BITS 26
874 :    
875 :     /* FlushICache:
876 :     *
877 :     * void FlushICache (Addr_t addr, Addr_t nbytes)
878 :     */
879 :     CENTRY(FlushICache)
880 :     add 4,3,4 /* stop := addr+nbytes */
881 :     addic 4,4,CACHE_LINE_MASK /* stop := stop + CACHE_LINE_MASK */
882 :     rlwinm 4,4,0,0,CACHE_LINE_BITS /* stop := stop & ~CACHE_LINE_MASK */
883 :     L_FlushICache_1:
884 :     cmplw 1,3,4 /* while (addr < stop) */
885 :     bc 4,4,L_FlushICache_2
886 :     dcbf 0,3 /* flush addr */
887 :     icbi 0,3 /* invalidate addr */
888 :     addi 3,3,CACHE_LINE_SZB /* addr := addr + CACHE_LINE_SZB */
889 :     b L_FlushICache_1 /* end while */
890 :     L_FlushICache_2:
891 :     blr
892 :    
893 :     #endif
894 :    

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