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

SCM Repository

[smlnj] Diff of /sml/branches/SMLNJ/src/runtime/mach-dep/X86.prim.asm
ViewVC logotype

Diff of /sml/branches/SMLNJ/src/runtime/mach-dep/X86.prim.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 438, Wed Sep 15 16:37:27 1999 UTC revision 439, Wed Sep 15 16:37:27 1999 UTC
# Line 4  Line 4 
4   *   *
5   * This was derived from I386.prim.s, by Mark Leone (mleone@cs.cmu.edu)   * This was derived from I386.prim.s, by Mark Leone (mleone@cs.cmu.edu)
6   *   *
7   * Heavily modified and changed to use assyntax.h, by Lal George.   * Completely rewritten and changed to use assyntax.h, by Lal George.
8   */   */
9    
10  #include "ml-base.h"  #include "ml-base.h"
# Line 13  Line 13 
13  #include "tags.h"  #include "tags.h"
14  #include "ml-request.h"  #include "ml-request.h"
15  #include "ml-limits.h"  #include "ml-limits.h"
16    #include "assyntax.h"
 /* enable/disable virtual (memory-based) registers.  
  * the number of vregs, etc. must concur with:  
  *      src/runtime/include/ml-state.h  
  *      src/runtime/kernel/ml-state.c  
  *      src/sml-nj/x86/x86.sml  
  */  
17    
18  /* XXX:  May no longer be needed */  /* XXX:  May no longer be needed */
19  #ifndef VREGS  #ifndef VREGS
# Line 42  Line 36 
36   */   */
37    
38  /* Registers (see x86/x86.sml): */  /* Registers (see x86/x86.sml): */
39  #define temp            %eax  #define temp            EAX
40  #define misc0           %ebx  #define misc0           EBX
41  #define misc1           %ecx  #define misc1           ECX
42  #define misc2           %edx  #define misc2           EDX
43  #define stdcont         %esi  #define stdcont         ESI
44  #define stdarg          %ebp  #define stdarg          EBP
45  #define allocptr        %edi  #define allocptr        EDI
46  #define stackptr        %esp  #define stackptr        ESP
47    
48  /* other reg uses */  /* other reg uses */
49  #define creturn         %eax  #define creturn         EAX
50    
51          /* Stack frame */          /* Stack frame */
52  #define tempmem         0(%esp)  #define tempmem         REGOFF(0,ESP)
53  #define baseptr         4(%esp)  #define baseptr         REGOFF(4,ESP)
54  #define exncont         8(%esp)  #define exncont         REGOFF(8,ESP)
55  #define limitptr        12(%esp)  #define limitptr        REGOFF(12,ESP)
56  #define pc              16(%esp)  #define pc              REGOFF(16,ESP)
57  #define unused_1        20(%esp)  #define unused_1        REGOFF(20,ESP)
58  #define storeptr        24(%esp)  #define storeptr        REGOFF(24,ESP)
59  #define varptr          28(%esp)  #define varptr          REGOFF(28,ESP)
60  #define start_gc        32(%esp)  #define start_gc        REGOFF(32,ESP)
61  #define unused_2        36(%esp)  #define unused_2        REGOFF(36,ESP)
62  #define eaxSpill        40(%esp) /* eax=0 */  #define eaxSpill        REGOFF(40,ESP) /* eax=0 */
63  #define ecxSpill        44(%esp) /* ecx=1 */  #define ecxSpill        REGOFF(44,ESP) /* ecx=1 */
64  #define edxSpill        48(%esp) /* edx=2 */  #define edxSpill        REGOFF(48,ESP) /* edx=2 */
65  #define ebxSpill        52(%esp) /* ebx=3 */  #define ebxSpill        REGOFF(52,ESP) /* ebx=3 */
66  #define espSpill        56(%esp) /* esp=4 */  #define espSpill        REGOFF(56,ESP) /* esp=4 */
67  #define ebpSpill        60(%esp) /* ebp=5 */  #define ebpSpill        REGOFF(60,ESP) /* ebp=5 */
68  #define esiSpill        64(%esp) /* esi=6 */  #define esiSpill        REGOFF(64,ESP) /* esi=6 */
69  #define ediSpill        68(%esp) /* edi=7 */  #define ediSpill        REGOFF(68,ESP) /* edi=7 */
70  #define stdlink         72(%esp)  #define stdlink         REGOFF(72,ESP)
71  #define stdclos         76(%esp)  #define stdclos         REGOFF(76,ESP)
72    
73  #define ML_STATE_OFFSET 176  #define ML_STATE_OFFSET 176
74  #define mlstate_ptr     ML_STATE_OFFSET(%esp)  #define mlstate_ptr     REGOFF(ML_STATE_OFFSET, ESP)
75  #define freg8           184          /* double word aligned */  #define freg8           184          /* double word aligned */
76  #define freg9           192  #define freg9           192
77  #define freg31          368          /* 152 + (31-8)*8 */  #define freg31          368          /* 152 + (31-8)*8 */
# Line 87  Line 81 
81    
82  #define via  #define via
83    
84          DATA          SEG_DATA
85          ALIGN4          ALIGNDATA4
86  request_w:              /* place to put the request code */  request_w:              /* place to put the request code */
87          .long 0          D_LONG 0
88          GLOBAL(ML_X86Frame)          GLOBL ML_X86Frame
89  LABEL(CSYM(ML_X86Frame)) /* ptr to the ml frame (gives C access to limitptr) */  LABEL(CSYM(ML_X86Frame)) /* ptr to the ml frame (gives C access to limitptr) */
90          .long 0          D_LONG 0
91    
92  SavedSP:  SavedSP:
93          .long 0         /* Value of stack pointer to restore */          D_LONG 0                /* Value of stack pointer to restore */
94    
95    
96  #include "mlstate-offsets.h"    /** this file is generated **/  #include "mlstate-offsets.h"    /** this file is generated **/
# Line 113  Line 107 
107   *      Word-sized result returned in %eax.   *      Word-sized result returned in %eax.
108   */   */
109    
110  #define cresult %eax  #define cresult EAX
111    
112  #define CALLEE_SAVE     \  #define CALLEE_SAVE     \
113          pushl   %ebx;   \          PUSH_L(EBX);    \
114          pushl   %esi;   \          PUSH_L(ESI);    \
115          pushl   %edi;   \          PUSH_L(EDI);    \
116          pushl   %ebp          PUSH_L(EBP)
117    
118  #define CALLEE_RESTORE  \  #define CALLEE_RESTORE  \
119          popl    %ebp;   \          POP_L(EBP);     \
120          popl    %edi;   \          POP_L(EDI);     \
121          popl    %esi;   \          POP_L(ESI);     \
122          popl    %ebx          POP_L(EBX)
123    
124  /* MOVE copies one memory location to another, using a specified temporary. */  /* MOVE copies one memory location to another, using a specified temporary. */
125    
126  #define MOVE(src,tmp,dest)      \  #define MOVE(src,tmp,dest)      \
127          movl    src, tmp;       \          MOV_L(src, tmp);        \
128          movl    tmp, dest          MOV_L(tmp, dest)
129    
130  #define CONTINUE                                \  #define CONTINUE                                \
131          jmp     via stdcont          JMP(stdcont)
132    
133  #define CHECKLIMIT                              \  #define CHECKLIMIT                              \
134   1:;                                            \   1:;                                            \
135          MOVE(stdlink, temp, pc) ;               \          MOVE(stdlink, temp, pc) ;               \
136          cmpl    limitptr, allocptr;             \          CMP_L(limitptr, allocptr);              \
137          jb      9f;                             \          JB(9f);                                 \
138          call    via CSYM(saveregs);             \          CALL(saveregs);                         \
139          jmp     via 1b;                         \          JMP(1b);                                \
140   9:   9:
141    
142  /**********************************************************************/  /**********************************************************************/
143          TEXT          SEG_TEXT
144          ALIGN4          ALIGNTEXT4
145    
146  ML_CODE_HDR(sigh_return_a)  ML_CODE_HDR(sigh_return_a)
147          movl    IMMED(ML_unit),stdlink          MOV_L(CONST(ML_unit),stdlink)
148          movl    IMMED(ML_unit),stdclos          MOV_L(CONST(ML_unit),stdclos)
149          movl    IMMED(ML_unit),pc          MOV_L(CONST(ML_unit),pc)
150          movl    IMMED(REQ_SIG_RETURN), request_w          MOV_L(CONST(REQ_SIG_RETURN), request_w)
151          jmp     CSYM(set_request)          JMP(CSYM(set_request))
152    
153  /* sigh_resume:  /* sigh_resume:
154   * Resume execution at the point at which a handler trap occurred.  This is a   * Resume execution at the point at which a handler trap occurred.  This is a
# Line 162  Line 156 
156   */   */
157    
158  ENTRY(sigh_resume)  ENTRY(sigh_resume)
159          movl    IMMED(REQ_SIG_RESUME), request_w          MOV_L(CONST(REQ_SIG_RESUME), request_w)
160          movl    IMMED(ML_unit),stdlink          JMP(CSYM(set_request))
         movl    IMMED(ML_unit),stdclos  
         movl    IMMED(ML_unit),pc  
         jmp     CSYM(set_request)  
161    
162  /* pollh_return_a:  /* pollh_return_a:
163   * The return continuation for the ML poll handler.   * The return continuation for the ML poll handler.
164   */   */
165  ML_CODE_HDR(pollh_return_a)  ML_CODE_HDR(pollh_return_a)
166          movl    IMMED(REQ_POLL_RETURN), request_w          MOV_L(CONST(REQ_POLL_RETURN), request_w)
167          movl    IMMED(ML_unit),stdlink          MOV_L(CONST(ML_unit),stdlink)
168          movl    IMMED(ML_unit),stdclos          MOV_L(CONST(ML_unit),stdclos)
169          movl    IMMED(ML_unit),pc          MOV_L(CONST(ML_unit),pc)
170          jmp     CSYM(set_request)          JMP(CSYM(set_request))
171    
172  /* pollh_resume:  /* pollh_resume:
173   * Resume execution at the point at which a poll event occurred.   * Resume execution at the point at which a poll event occurred.
174   */   */
175  ENTRY(pollh_resume)  ENTRY(pollh_resume)
176          movl    IMMED(REQ_POLL_RESUME), request_w          MOV_L(CONST(REQ_POLL_RESUME), request_w)
177          movl    IMMED(ML_unit),stdlink          JMP(CSYM(set_request))
         movl    IMMED(ML_unit),stdclos  
         movl    IMMED(ML_unit),pc  
         jmp     CSYM(set_request)  
178    
179  ML_CODE_HDR(handle_a)  ML_CODE_HDR(handle_a)
180          movl    IMMED(REQ_EXN), request_w          MOV_L(CONST(REQ_EXN), request_w)
181          MOVE    (stdlink,temp,pc)          MOVE    (stdlink,temp,pc)
182          jmp     CSYM(set_request)          JMP(CSYM(set_request))
183    
184  ML_CODE_HDR(return_a)  ML_CODE_HDR(return_a)
185          movl    IMMED(REQ_RETURN), request_w          MOV_L(CONST(REQ_RETURN), request_w)
186          movl    IMMED(ML_unit),stdlink          MOV_L(CONST(ML_unit),stdlink)
187          movl    IMMED(ML_unit),stdclos          MOV_L(CONST(ML_unit),stdclos)
188          movl    IMMED(ML_unit),pc          MOV_L(CONST(ML_unit),pc)
189          jmp     CSYM(set_request)          JMP(CSYM(set_request))
190    
191  /* Request a fault.  The floating point coprocessor must be reset  /* Request a fault.  The floating point coprocessor must be reset
192   * (thus trashing the FP registers) since we don't know whether a   * (thus trashing the FP registers) since we don't know whether a
# Line 207  Line 195 
195   * the exception handler.   * the exception handler.
196   */   */
197  ENTRY(request_fault)  ENTRY(request_fault)
198          call    CSYM(FPEEnable)          /* Doesn't trash any general regs. */          CALL(CSYM(FPEEnable))          /* Doesn't trash any general regs. */
199          movl    IMMED(REQ_FAULT), request_w          MOV_L(CONST(REQ_FAULT), request_w)
200          MOVE    (stdlink,temp,pc)          MOVE    (stdlink,temp,pc)
201          jmp     CSYM(set_request)          JMP(CSYM(set_request))
202    
203  /* bind_cfun : (string * string) -> c_function  /* bind_cfun : (string * string) -> c_function
204   */   */
205  ML_CODE_HDR(bind_cfun_a)  ML_CODE_HDR(bind_cfun_a)
206          CHECKLIMIT          CHECKLIMIT
207          movl    IMMED(REQ_BIND_CFUN), request_w          MOV_L(CONST(REQ_BIND_CFUN), request_w)
208          jmp     CSYM(set_request)          JMP(CSYM(set_request))
209    
210  ML_CODE_HDR(build_literals_a)  ML_CODE_HDR(build_literals_a)
211          CHECKLIMIT          CHECKLIMIT
212          movl    IMMED(REQ_BUILD_LITERALS), request_w          MOV_L(CONST(REQ_BUILD_LITERALS), request_w)
213          jmp     CSYM(set_request)          JMP(CSYM(set_request))
214    
215  ML_CODE_HDR(callc_a)  ML_CODE_HDR(callc_a)
216          CHECKLIMIT          CHECKLIMIT
217          movl    IMMED(REQ_CALLC), request_w          MOV_L(CONST(REQ_CALLC), request_w)
218          jmp     CSYM(set_request)          JMP(CSYM(set_request))
219    
220  ENTRY(saveregs)  ENTRY(saveregs)
221          popl    pc          POP_L(pc)
222          movl    IMMED(REQ_GC), request_w          MOV_L(CONST(REQ_GC), request_w)
223          /* fall into set_request */          /* fall into set_request */
224    
225  ENTRY(set_request)  ENTRY(set_request)
226          /* temp holds mlstate_ptr, valid request in request_w  */          /* temp holds mlstate_ptr, valid request in request_w  */
227          /* Save registers */          /* Save registers */
228          movl    mlstate_ptr, temp          MOV_L(mlstate_ptr, temp)
229          movl    allocptr,AllocPtrOffMSP(temp)          MOV_L(allocptr, REGOFF(AllocPtrOffMSP,temp))
230          movl    stdarg,StdArgOffMSP(temp)          MOV_L(stdarg, REGOFF(StdArgOffMSP,temp))
231          movl    stdcont,StdContOffMSP(temp)          MOV_L(stdcont, REGOFF(StdContOffMSP,temp))
232    
233  #define temp2 allocptr  #define temp2 allocptr
234          /* note that we have left ML code */          /* note that we have left ML code */
235          movl    VProcOffMSP(temp),temp2          MOV_L(REGOFF(VProcOffMSP,temp), temp2)
236          movl    IMMED(0), InMLOffVSP(temp2)          MOV_L(CONST(0), REGOFF(InMLOffVSP,temp2))
237    
238          movl    misc0, Misc0OffMSP(temp)          MOV_L(misc0, REGOFF(Misc0OffMSP,temp))
239          movl    misc1, Misc1OffMSP(temp)          MOV_L(misc1, REGOFF(Misc1OffMSP,temp))
240          movl    misc2, Misc2OffMSP(temp)          MOV_L(misc2, REGOFF(Misc2OffMSP,temp))
241    
242          /* Save vregs before the stack frame is popped. */          /* Save vregs before the stack frame is popped. */
243          MOVE(limitptr,temp2, LimitPtrOffMSP(temp))          MOVE(limitptr,temp2, REGOFF(LimitPtrOffMSP,temp))
244          MOVE(exncont, temp2, ExnPtrOffMSP(temp))          MOVE(exncont, temp2, REGOFF(ExnPtrOffMSP,temp))
245          MOVE(stdclos, temp2, StdClosOffMSP(temp))          MOVE(stdclos, temp2, REGOFF(StdClosOffMSP,temp))
246          MOVE(stdlink, temp2, LinkRegOffMSP(temp))          MOVE(stdlink, temp2, REGOFF(LinkRegOffMSP,temp))
247          MOVE(pc, temp2, PCOffMSP(temp))          MOVE(pc, temp2, REGOFF(PCOffMSP,temp))
248          MOVE(storeptr,temp2, StorePtrOffMSP(temp))          MOVE(storeptr,temp2, REGOFF(StorePtrOffMSP,temp))
249          MOVE(varptr,  temp2, VarPtrOffMSP(temp))          MOVE(varptr,  temp2, REGOFF(VarPtrOffMSP,temp))
250  #undef  temp2  #undef  temp2
251    
252          /* return val of function is request code */          /* return val of function is request code */
253          movl    request_w,creturn          MOV_L(request_w,creturn)
254    
255          /* Pop the stack frame and return to run_ml(). */          /* Pop the stack frame and return to run_ml(). */
256          movl    SavedSP, %esp          MOV_L(SavedSP, ESP)
257          CALLEE_RESTORE          CALLEE_RESTORE
258          ret          RET
259    
260          TEXT          SEG_TEXT
261          ALIGN4          ALIGNTEXT4
262  ENTRY(restoreregs)  ENTRY(restoreregs)
263          movl    4(%esp), temp           /* Get argument (MLState ptr). */          MOV_L(4(ESP), temp)             /* Get argument (MLState ptr). */
264          CALLEE_SAVE          CALLEE_SAVE
265    
266          movl    %esp, SavedSP           /* save stack pointer */          MOV_L(ESP, SavedSP)             /* save stack pointer */
267    
268          /* Align on 8 byte boundary. Assumes that the stack          /* Align on 8 byte boundary. Assumes that the stack
269           * starts out being at least word aligned. But who knows ...           * starts out being at least word aligned. But who knows ...
270           */           */
271          orl     IMMED(4), %esp          OR_L(CONST(4), ESP)
272          subl    IMMED(4), %esp          /* stack grows from high to low */          SUB_L(CONST(4), ESP)            /* stack grows from high to low */
273    
274  #define temp2   %ebx  #define temp2   EBX
275          /* Allocate and initialize the ML stack frame. */          /* Allocate and initialize the ML stack frame. */
276          subl    IMMED(ML_FRAME_SIZE), %esp          SUB_L(CONST(ML_FRAME_SIZE), ESP)
277          MOVE    (ExnPtrOffMSP(temp),  temp2, exncont)          MOVE(REGOFF(ExnPtrOffMSP, temp),  temp2, exncont)
278          MOVE    (LimitPtrOffMSP(temp), temp2, limitptr)          MOVE(REGOFF(LimitPtrOffMSP, temp), temp2, limitptr)
279          MOVE    (StorePtrOffMSP(temp), temp2, storeptr)          MOVE(REGOFF(StorePtrOffMSP, temp), temp2, storeptr)
280          MOVE    (VarPtrOffMSP(temp),   temp2, varptr)          MOVE(REGOFF(VarPtrOffMSP, temp),   temp2, varptr)
281          lea     CSYM(saveregs), temp2          LEA_L(CSYM(saveregs), temp2)
282          movl    temp2,start_gc          MOV_L(temp2,start_gc)
283          movl    temp, mlstate_ptr          MOV_L(temp, mlstate_ptr)
284    
285          /* vregs */          /* vregs */
286          MOVE    (LinkRegOffMSP(temp),  temp2, stdlink)          MOVE    (LinkRegOffMSP(temp),  temp2, stdlink)
# Line 300  Line 288 
288  #undef  temp2  #undef  temp2
289    
290          /* Load ML registers. */          /* Load ML registers. */
291          movl    AllocPtrOffMSP(temp), allocptr          MOV_L(REGOFF(AllocPtrOffMSP,temp), allocptr)
292          movl    StdContOffMSP(temp), stdcont          MOV_L(REGOFF(StdContOffMSP,temp), stdcont)
293          movl    StdArgOffMSP(temp), stdarg          MOV_L(REGOFF(StdArgOffMSP,temp), stdarg)
294          movl    Misc0OffMSP(temp), misc0          MOV_L(REGOFF(Misc0OffMSP,temp), misc0)
295          movl    Misc1OffMSP(temp), misc1          MOV_L(REGOFF(Misc1OffMSP,temp), misc1)
296          movl    Misc2OffMSP(temp), misc2          MOV_L(REGOFF(Misc2OffMSP,temp), misc2)
297    
298          movl    %esp,CSYM(ML_X86Frame)  /* frame ptr for signal handler. */          MOV_L(ESP,CSYM(ML_X86Frame))    /* frame ptr for signal handler. */
299    
300          pushl   misc2                   /* free up a register   */          PUSH_L(misc2)                   /* free up a register   */
301          pushl   temp                    /* save msp temporarily */          PUSH_L(temp)                    /* save msp temporarily */
302    
303  #define tmpreg  misc2  #define tmpreg  misc2
304    
305          /* note that we're entering ML */          /* note that we're entering ML */
306          movl    VProcOffMSP(temp),temp  /* temp is now vsp */          MOV_L(REGOFF(VProcOffMSP,temp),temp)  /* temp is now vsp */
307  #define vsp     temp  #define vsp     temp
308          movl    IMMED(1),InMLOffVSP(vsp)          MOV_L(CONST(1),REGOFF(InMLOffVSP,vsp))
309    
310          /* handle signals */          /* handle signals */
311          movl    NPendingSysOffVSP(vsp),tmpreg          MOV_L(REGOFF(NPendingSysOffVSP,vsp),tmpreg)
312          addl    NPendingOffVSP(vsp),tmpreg          ADD_L(REGOFF(NPendingOffVSP,vsp),tmpreg)
313          cmpl    IMMED(0),tmpreg          CMP_L(CONST(0),tmpreg)
314    
315  #undef  tmpreg  #undef  tmpreg
316          jne     pending          JNE(pending)
317    
318  restore_and_jmp_ml:  restore_and_jmp_ml:
319          popl    temp                    /* restore temp to msp */          POP_L(temp)                     /* restore temp to msp */
320          popl    misc2          POP_L(misc2)
321    
322  jmp_ml:  jmp_ml:
323          cmpl    limitptr, allocptr          CMP_L(limitptr, allocptr)
324          jmpl    PCOffMSP(temp)                /* Jump to ML code. */          JMP(REGOFF(PCOffMSP,temp))      /* Jump to ML code. */
325    
326    
327  pending:  pending:
328          cmpl    IMMED(0),InSigHandlerOffVSP(vsp)   /* Currently handling signal? */                                          /* Currently handling signal? */
329          jne     restore_and_jmp_ml          CMP_L(CONST(0), REGOFF(InSigHandlerOffVSP,vsp))
330          movl    IMMED(1),HandlerPendingOffVSP(vsp) /* handler trap is now pending */          JNE(restore_and_jmp_ml)
331                                            /* handler trap is now pending */
332            movl    IMMED(1),HandlerPendingOffVSP(vsp)
333    
334          /* must restore here because limitptr is on stack */ /* XXX */          /* must restore here because limitptr is on stack */ /* XXX */
335          popl    temp                    /* restore temp to msp */          POP_L(temp)                     /* restore temp to msp */
336          popl    misc2          POP_L(misc2)
337    
338          movl    allocptr,limitptr          MOV_L(allocptr,limitptr)
339          jmp     jmp_ml                  /* Jump to ML code. */          JMP(jmp_ml)                     /* Jump to ML code. */
340  #undef  vsp  #undef  vsp
341    
342  /* ----------------------------------------------------------------------  /* ----------------------------------------------------------------------
# Line 354  Line 345 
345   */   */
346  ML_CODE_HDR(array_a)  ML_CODE_HDR(array_a)
347          CHECKLIMIT          CHECKLIMIT
348          movl    0(stdarg),temp               /* temp := length in words */          MOV_L(REGIND(stdarg),temp)         /* temp := length in words */
349          sarl    IMMED(1),temp                /* temp := length untagged */          SAR_L(CONST(1),temp)                 /* temp := length untagged */
350          cmpl    IMMED(SMALL_OBJ_SZW),temp    /* is this a small object */          CMP_L(CONST(SMALL_OBJ_SZW),temp)     /* is this a small object */
351          jge     3f          JGE(3f)
352    
353  #define temp1 misc0  #define temp1 misc0
354  #define temp2 misc1  #define temp2 misc1
355          pushl   misc0                        /* save misc0 */          PUSH_L(misc0)                        /* save misc0 */
356          pushl   misc1                        /* save misc1 */          PUSH_L(misc1)                        /* save misc1 */
357    
358          movl    temp, temp1          MOV_L(temp, temp1)
359          sall    IMMED(TAG_SHIFTW),temp1      /* build descriptor in temp1 */          SAL_L(CONST(TAG_SHIFTW),temp1)      /* build descriptor in temp1 */
360          orl     IMMED(MAKE_TAG(DTAG_arr_data)),temp1          OR_L(CONST(MAKE_TAG(DTAG_arr_data)),temp1)
361          movl    temp1,0(allocptr)            /* store descriptor */          MOV_L(temp1,REGIND(allocptr))        /* store descriptor */
362          addl    IMMED(4),allocptr            /* allocptr++ */          ADD_L(CONST(4),allocptr)             /* allocptr++ */
363          movl    allocptr, temp1              /* temp1 := array data ptr */          MOV_L(allocptr, temp1)               /* temp1 := array data ptr */
364          movl    4(stdarg), temp2             /* temp2 := initial value */          MOV_L(REGOFF(4,stdarg), temp2)       /* temp2 := initial value */
365  2:  2:
366          movl    temp2,0(allocptr)            /* initialize array */          MOV_L(temp2, REGIND(allocptr))     /* initialize array */
367          addl    IMMED(4), allocptr          ADD_L(CONST(4), allocptr)
368          subl    IMMED(1), temp          SUB_L(CONST(1), temp)
369          jne     2b          JNE(2b)
370    
371          /* Allocate array header */          /* Allocate array header */
372          movl    IMMED(DESC_polyarr),0(allocptr) /* descriptor in temp */          MOV_L(CONST(DESC_polyarr),REGIND(allocptr)) /* descriptor in temp */
373          addl    IMMED(4), allocptr           /* allocptr++ */          ADD_L(CONST(4), allocptr)            /* allocptr++ */
374          movl    0(stdarg), temp              /* temp := length */          MOV_L(REGIND(stdarg), temp)          /* temp := length */
375          movl    allocptr, stdarg             /* result = header addr */          MOV_L(allocptr, stdarg)              /* result = header addr */
376          movl    temp1, 0(allocptr)           /* store pointer to data */          MOV_L(temp1, REGIND(allocptr))       /* store pointer to data */
377          movl    temp, 4(allocptr)            /* store length */          MOV_L(temp, REGOFF(4,allocptr))      /* store length */
378          addl    IMMED(8), allocptr          ADD_L(CONST(8), allocptr)
379    
380          popl    misc1          POP_L(misc1)
381          popl    misc0          POP_L(misc0)
382          CONTINUE          CONTINUE
383  #undef  temp1  #undef  temp1
384  #undef  temp2  #undef  temp2
385  3:  3:
386          movl    IMMED(REQ_ALLOC_ARRAY), request_w          MOV_L(CONST(REQ_ALLOC_ARRAY), request_w)
387          MOVE    (stdlink, temp, pc)          MOVE    (stdlink, temp, pc)
388          jmp     CSYM(set_request)          JMP(CSYM(set_request))
389    
390    
391  /* create_r : int -> realarray */  /* create_r : int -> realarray */
392  ML_CODE_HDR(create_r_a)  ML_CODE_HDR(create_r_a)
393          CHECKLIMIT          CHECKLIMIT
394  #define temp1 misc0  #define temp1 misc0
395          push    misc0                   /* free temp1 */          PUSH_L(misc0)                   /* free temp1 */
396          movl    stdarg,temp             /* temp := length */          MOV_L(stdarg,temp)              /* temp := length */
397          sarl    IMMED(1),temp           /* temp := untagged length */          SAR_L(CONST(1),temp)            /* temp := untagged length */
398          shll    IMMED(1),temp           /* temp := length in words */          SHL_L(CONST(1),temp)            /* temp := length in words */
399          cmpl    IMMED(SMALL_OBJ_SZW),temp          CMP_L(CONST(SMALL_OBJ_SZW),temp)
400          jge     2f          JGE(2f)
401    
402          orl     IMMED(4),allocptr       /* align allocptr */          OR_L(CONST(4),allocptr) /* align allocptr */
403    
404          /* allocate the data object */          /* allocate the data object */
405          movl    temp, temp1          MOV_L(temp, temp1)
406          shll    IMMED(TAG_SHIFTW),temp1 /* temp1 := descriptor */          SHL_L(CONST(TAG_SHIFTW),temp1)  /* temp1 := descriptor */
407          orl     IMMED(MAKE_TAG(DTAG_raw64)),temp1          OR_L(CONST(MAKE_TAG(DTAG_raw64)),temp1)
408          movl    temp1,0(allocptr)       /* store descriptor */          MOV_L(temp1,REGIND(allocptr))   /* store descriptor */
409          addl    IMMED(4), allocptr      /* allocptr++ */          ADD_L(CONST(4), allocptr)       /* allocptr++ */
410          movl    allocptr, temp1         /* temp1 := data object */          MOV_L(allocptr, temp1)          /* temp1 := data object */
411          shll    IMMED(2),temp           /* temp := length in bytes */          SHL_L(CONST(2),temp)            /* temp := length in bytes */
412          addl    temp, allocptr          /* allocptr += length */          ADD_L(temp, allocptr)           /* allocptr += length */
413    
414          /* allocate the header object */          /* allocate the header object */
415          movl    IMMED(DESC_real64arr),0(allocptr)/* header descriptor */          MOV_L(CONST(DESC_real64arr),REGIND(allocptr))/* header descriptor */
416          addl    IMMED(4), allocptr      /* allocptr++ */          ADD_L(CONST(4), allocptr)       /* allocptr++ */
417          movl    temp1, 0(allocptr)      /* header data field */          MOV_L(temp1, REGIND(allocptr))  /* header data field */
418          movl    stdarg, 4(allocptr)     /* header length field */          MOV_L(stdarg, REGOFF(4,allocptr))       /* header length field */
419          movl    allocptr, stdarg                /* stdarg := header object */          MOV_L(allocptr, stdarg)         /* stdarg := header object */
420          addl    IMMED(8), allocptr      /* allocptr += 2 */          ADD_L(CONST(8), allocptr)       /* allocptr += 2 */
421    
422          popl    misc0                   /* restore temp1 */          POP_L(misc0)                    /* restore temp1 */
423          CONTINUE          CONTINUE
   
424  2:  2:
425          popl    misc0                   /* restore temp1 */          POP_L(misc0)                    /* restore temp1 */
426          movl    IMMED(REQ_ALLOC_REALDARRAY), request_w          MOV_L(CONST(REQ_ALLOC_REALDARRAY), request_w)
427          MOVE    (stdlink, temp, pc)          MOVE    (stdlink, temp, pc)
428          jmp     CSYM(set_request)          JMP(CSYM(set_request))
429  #undef temp1  #undef temp1
430    
431    
432  /* create_b : int -> bytearray */  /* create_b : int -> bytearray */
433  ML_CODE_HDR(create_b_a)  ML_CODE_HDR(create_b_a)
434          CHECKLIMIT          CHECKLIMIT
435          movl    stdarg,temp             /* temp := length(tagged int) */          MOV_L(stdarg,temp)              /* temp := length(tagged int) */
436          sarl    IMMED(1),temp           /* temp := length(untagged) */          SAR_L(CONST(1),temp)            /* temp := length(untagged) */
437          addl    IMMED(3),temp          ADD_L(CONST(3),temp)
438          sarl    IMMED(2),temp           /* temp := length(words) */          SAR_L(CONST(2),temp)            /* temp := length(words) */
439          cmpl    IMMED(SMALL_OBJ_SZW),temp /* small object? */          CMP_L(CONST(SMALL_OBJ_SZW),temp) /* small object? */
440          jmp     2f          JMP(2f)
441          jge     2f          JGE(2f)                         /* XXXXX */
442    
443  #define temp1   misc0  #define temp1   misc0
444          pushl   misc0          PUSH_L(misc0)
445    
446          /* allocate teh data object */          /* allocate teh data object */
447          movl    temp, temp1             /* temp1 :=  descriptor */          MOV_L(temp, temp1)              /* temp1 :=  descriptor */
448          shll    IMMED(TAG_SHIFTW),temp1          SHL_L(CONST(TAG_SHIFTW),temp1)
449          orl     IMMED(MAKE_TAG(DTAG_raw32)),temp1          OR_L(CONST(MAKE_TAG(DTAG_raw32)),temp1)
450          movl    temp1, 0(allocptr)      /* store descriptor */          MOV_L(temp1, REGIND(allocptr))  /* store descriptor */
451          addl    IMMED(4), allocptr      /* allocptr++ */          ADD_L(CONST(4), allocptr)       /* allocptr++ */
452          movl    allocptr, temp1         /* temp1 := data object */          MOV_L(allocptr, temp1)          /* temp1 := data object */
453          shll    IMMED(2), temp          /* temp := length in bytes */          SHL_L(CONST(2), temp)           /* temp := length in bytes */
454          addl    temp, allocptr          /* allocptr += length */          ADD_L(temp, allocptr)           /* allocptr += length */
455    
456          /* allocate the header object */          /* allocate the header object */
457          movl    IMMED(DESC_word8arr), 0(allocptr)/* header descriptor */          MOV_L(CONST(DESC_word8arr), REGIND(allocptr))/* header descriptor */
458          addl    IMMED(4),allocptr       /* allocptr++ */          ADD_L(CONST(4),allocptr)        /* allocptr++ */
459          movl    temp1, 0(allocptr)      /* header data field */          MOV_L(temp1, REGIND(allocptr))  /* header data field */
460          movl    stdarg,4(allocptr)      /* header length field */          MOV_L(stdarg, REGOFF(4,allocptr))       /* header length field */
461          movl    allocptr, stdarg        /* stdarg := header object */          MOV_L(allocptr, stdarg)         /* stdarg := header object */
462          addl    IMMED(8),allocptr       /* allocptr := 2 */          ADD_L(CONST(8),allocptr)        /* allocptr := 2 */
463          popl    misc0          POP_L(misc0)
464          CONTINUE          CONTINUE
465  #undef  temp1  #undef  temp1
466  2:  2:
467          movl    IMMED(REQ_ALLOC_BYTEARRAY), request_w          MOV_L(CONST(REQ_ALLOC_BYTEARRAY), request_w)
468          MOVE    (stdlink, temp, pc)          MOVE    (stdlink, temp, pc)
469          jmp     CSYM(set_request)          JMP(CSYM(set_request))
470    
471    
472  /* create_s : int -> string */  /* create_s : int -> string */
473  ML_CODE_HDR(create_s_a)  ML_CODE_HDR(create_s_a)
474          CHECKLIMIT          CHECKLIMIT
475          movl    stdarg,temp          MOV_L(stdarg,temp)
476          sarl    IMMED(1),temp           /* temp := length(untagged) */          SAR_L(CONST(1),temp)            /* temp := length(untagged) */
477          addl    IMMED(4),temp          ADD_L(CONST(4),temp)
478          sarl    IMMED(2),temp           /* temp := length(words) */          SAR_L(CONST(2),temp)            /* temp := length(words) */
479          cmpl    IMMED(SMALL_OBJ_SZW),temp          CMP_L(CONST(SMALL_OBJ_SZW),temp)
480          jge     2f          JGE(2f)
481    
482          pushl   misc0                   /* free misc0 */          PUSH_L(misc0)                   /* free misc0 */
483  #define temp1   misc0  #define temp1   misc0
484    
485          movl    temp, temp1          MOV_L(temp, temp1)
486          shll    IMMED(TAG_SHIFTW),temp1 /* build descriptor in temp1 */          SHL_L(CONST(TAG_SHIFTW),temp1)  /* build descriptor in temp1 */
487          orl     IMMED(MAKE_TAG(DTAG_raw32)), temp1          OR_L(CONST(MAKE_TAG(DTAG_raw32)), temp1)
488          movl    temp1, 0(allocptr)      /* store the data pointer */          MOV_L(temp1, REGIND(allocptr))/* store the data pointer */
489          addl    IMMED(4),allocptr       /* allocptr++ */          ADD_L(CONST(4),allocptr)        /* allocptr++ */
490    
491          movl    allocptr, temp1         /* temp1 := data object */          MOV_L(allocptr, temp1)          /* temp1 := data object */
492          shll    IMMED(2),temp           /* temp := length in bytes */          SHL_L(CONST(2),temp)            /* temp := length in bytes */
493          addl    temp, allocptr          /* allocptr += length */          ADD_L(temp, allocptr)           /* allocptr += length */
494          movl    IMMED(0),-4(allocptr)   /* zero out the last word */          MOV_L(CONST(0),REGOFF(-4,allocptr))     /* zero out the last word */
495    
496          /* allocate the header object */          /* allocate the header object */
497          movl    IMMED(DESC_string), temp        /* header descriptor */          MOV_L(CONST(DESC_string), temp) /* header descriptor */
498          movl    temp, 0(allocptr)          MOV_L(temp, REGIND(allocptr))
499          addl    IMMED(4), allocptr      /* allocptr++ */          ADD_L(CONST(4), allocptr)       /* allocptr++ */
500          movl    temp1, 0(allocptr)      /* header data field */          MOV_L(temp1, REGIND(allocptr))/* header data field */
501          movl    stdarg, 4(allocptr)     /* header length field */          MOV_L(stdarg, REGOFF(4,allocptr))       /* header length field */
502          movl    allocptr, stdarg        /* stdarg := header object */          MOV_L(allocptr, stdarg)         /* stdarg := header object */
503          addl    IMMED(8), allocptr          ADD_L(CONST(8), allocptr)
504    
505          popl    misc0                   /* restore misc0 */          POP_L(misc0)                    /* restore misc0 */
506  #undef  temp1  #undef  temp1
507          CONTINUE          CONTINUE
508  2:  2:
509          movl    IMMED(REQ_ALLOC_STRING), request_w          MOV_L(CONST(REQ_ALLOC_STRING), request_w)
510          MOVE    (stdlink, temp, pc)          MOVE    (stdlink, temp, pc)
511          jmp     CSYM(set_request)          JMP(CSYM(set_request))
512    
513  /* create_v_a : int * 'a list -> 'a vector  /* create_v_a : int * 'a list -> 'a vector
514   *      creates a vector with elements taken from a list.   *      creates a vector with elements taken from a list.
# Line 526  Line 516 
516   */   */
517  ML_CODE_HDR(create_v_a)  ML_CODE_HDR(create_v_a)
518          CHECKLIMIT          CHECKLIMIT
519          pushl   misc0          PUSH_L(misc0)
520          pushl   misc1          PUSH_L(misc1)
521  #define temp1   misc0  #define temp1   misc0
522  #define temp2   misc1  #define temp2   misc1
523          movl    0(stdarg),temp          /* temp := length(tagged) */          MOV_L(REGIND(stdarg),temp)              /* temp := length(tagged) */
524          movl    temp, temp1          MOV_L(temp, temp1)
525          sarl    IMMED(1),temp1          /* temp1 := length(untagged) */          SAR_L(CONST(1),temp1)           /* temp1 := length(untagged) */
526          cmpl    IMMED(SMALL_OBJ_SZW),temp1          CMP_L(CONST(SMALL_OBJ_SZW),temp1)
527          jge     3f          JGE(3f)
528    
529    
530          shll    IMMED(TAG_SHIFTW),temp1 /* build descriptor in temp1 */          SHL_L(CONST(TAG_SHIFTW),temp1)  /* build descriptor in temp1 */
531          orl     IMMED(MAKE_TAG(DTAG_vec_data)),temp1          OR_L(CONST(MAKE_TAG(DTAG_vec_data)),temp1)
532          movl    temp1,0(allocptr)       /* store descriptor */          MOV_L(temp1,REGIND(allocptr))   /* store descriptor */
533          addl    IMMED(4),allocptr       /* allocptr++ */          ADD_L(CONST(4),allocptr)        /* allocptr++ */
534          movl    4(stdarg),temp1         /* temp1 := list */          MOV_L(REGOFF(4,stdarg),temp1)           /* temp1 := list */
535          movl    allocptr,stdarg         /* stdarg := vector */          MOV_L(allocptr,stdarg)          /* stdarg := vector */
536    
537  2:  2:
538          movl    0(temp1),temp2          /* temp2 := hd(temp1) */          MOV_L(REGIND(temp1),temp2)              /* temp2 := hd(temp1) */
539          movl    temp2, 0(allocptr)      /* store word in vector */          MOV_L(temp2, REGIND(allocptr))  /* store word in vector */
540          addl    IMMED(4), allocptr      /* allocptr++ */          ADD_L(CONST(4), allocptr)       /* allocptr++ */
541          movl    4(temp1),temp1          /* temp1 := tl(temp1) */          MOV_L(REGOFF(4,temp1),temp1)            /* temp1 := tl(temp1) */
542          cmpl    IMMED(ML_nil),temp1     /* temp1 = nil? */          CMP_L(CONST(ML_nil),temp1)      /* temp1 = nil? */
543          jne     2b          JNE(2b)
544    
545          /* allocate header object */          /* allocate header object */
546          movl    IMMED(DESC_polyvec),temp1/* descriptor in temp1 */          MOV_L(CONST(DESC_polyvec),temp1)/* descriptor in temp1 */
547          movl    temp1, 0(allocptr)      /* store descriptor */          MOV_L(temp1, REGIND(allocptr))  /* store descriptor */
548          addl    IMMED(4),allocptr       /* allocptr++ */          ADD_L(CONST(4),allocptr)        /* allocptr++ */
549          movl    stdarg, 0(allocptr)     /* header data field */          MOV_L(stdarg, REGIND(allocptr)) /* header data field */
550          movl    temp, 4(allocptr)       /* header length */          MOV_L(temp, REGOFF(4,allocptr)) /* header length */
551          movl    allocptr, stdarg        /* result = header object */          MOV_L(allocptr, stdarg)         /* result = header object */
552          addl    IMMED(8),allocptr       /* allocptr += 2 */          ADD_L(CONST(8),allocptr)        /* allocptr += 2 */
553    
554          popl    misc1          POP_L(misc1)
555          popl    misc0          POP_L(misc0)
556          CONTINUE          CONTINUE
557  3:  3:
558          popl    misc1          POP_L(misc1)
559          popl    misc0          POP_L(misc0)
560          movl    IMMED(REQ_ALLOC_VECTOR), request_w          MOV_L(CONST(REQ_ALLOC_VECTOR), request_w)
561          MOVE    (stdlink, temp, pc)          MOVE    (stdlink, temp, pc)
562          jmp     CSYM(set_request)          JMP(CSYM(set_request))
563  #undef  temp1  #undef  temp1
564  #undef  temp2  #undef  temp2
565    
# Line 581  Line 571 
571  #if (MAX_PROCS > 1)  #if (MAX_PROCS > 1)
572  #  error multiple processors not supported  #  error multiple processors not supported
573  #else /* (MAX_PROCS == 1) */  #else /* (MAX_PROCS == 1) */
574          movl    (stdarg), temp          /* Get old value of lock. */          MOV_L(REGIND(stdarg), temp)     /* Get old value of lock. */
575          movl    IMMED(1), (stdarg)      /* Set the lock to ML_false. */          MOV_L(CONST(1), REGIND(stdarg)) /* Set the lock to ML_false. */
576          movl    temp, stdarg            /* Return old value of lock. */          MOV_L(temp, stdarg)             /* Return old value of lock. */
577          CONTINUE          CONTINUE
578  #endif  #endif
579    
# Line 593  Line 583 
583  #if (MAX_PROCS > 1)  #if (MAX_PROCS > 1)
584  #  error multiple processors not supported  #  error multiple processors not supported
585  #else /* (MAX_PROCS == 1) */  #else /* (MAX_PROCS == 1) */
586          movl    IMMED(3), (stdarg)              /* Store ML_true into lock. */          MOV_L(CONST(3), REGIND(stdarg))         /* Store ML_true into lock. */
587          movl    IMMED(1), stdarg                /* Return unit. */          MOV_L(CONST(1), stdarg)         /* Return unit. */
588          CONTINUE          CONTINUE
589  #endif  #endif
590    
# Line 629  Line 619 
619   * NB: this cannot trash any registers because it's called from request_fault.   * NB: this cannot trash any registers because it's called from request_fault.
620   */   */
621  ENTRY(FPEEnable)  ENTRY(FPEEnable)
622          finit          FINIT
623          subl    IMMED(4), %esp  /* Temp space.  Keep stack aligned. */          SUB_L(CONST(4), ESP)    /* Temp space.  Keep stack aligned. */
624          fstcw   (%esp)          /* Store FP control word. */          FSTCW(REGIND(ESP))      /* Store FP control word. */
625          andw    IMMED(0xf0c0), (%esp)   /* Keep undefined fields, clear others. */                                  /* Keep undefined fields, clear others. */
626          orw     IMMED(0x023f), (%esp)   /* Set fields (see above). */          AND_W(CONST(0xf0c0), REGIND(ESP))
627          fldcw   (%esp)          /* Install new control word. */          OR_W(CONST(0x023f), REGIND(ESP)) /* Set fields (see above). */
628          addl    IMMED(4), %esp          FLDCW(REGIND(ESP))      /* Install new control word. */
629          ret          ADD_L(CONST(4), ESP)
630            RET
631    
632  #if (defined(OPSYS_LINUX) || defined(OPSYS_SOLARIS))  #if (defined(OPSYS_LINUX) || defined(OPSYS_SOLARIS))
633  ENTRY(fegetround)  ENTRY(fegetround)
634          subl    IMMED(4), %esp  /* allocate temporary space */          SUB_L(CONST(4), ESP)    /* allocate temporary space */
635          fstcw   (%esp)          /* store fp control word */          FSTCW(REGIND(ESP))      /* store fp control word */
636          sarl    IMMED(10),(%esp)/* rounding mode is at bit 10 and 11 */          SAR_L(CONST(10),REGIND(ESP))/* rounding mode is at bit 10 and 11 */
637          andl    IMMED(3), (%esp)/* mask two bits */          AND_L(CONST(3), REGIND(ESP))/* mask two bits */
638          movl    (%esp),%eax     /* return rounding mode */          MOV_L(REGIND(ESP),EAX)  /* return rounding mode */
639          addl    IMMED(4), %esp  /* deallocate space */          ADD_L(CONST(4), ESP)    /* deallocate space */
640          ret          RET
641    
642  ENTRY(fesetround)  ENTRY(fesetround)
643          subl    IMMED(4), %esp  /* allocate temporary space */          SUB_L(CONST(4), ESP)    /* allocate temporary space */
644          fstcw   (%esp)          /* store fp control word */          FSTCW(REGIND(ESP))      /* store fp control word */
645          andw    IMMED(0xf3ff), (%esp)   /* Clear rounding field. */          AND_W(CONST(0xf3ff), REGIND(ESP))       /* Clear rounding field. */
646          movl    8(%esp), %eax   /* new rounding mode */          MOV_L(REGOFF(8,ESP), EAX)       /* new rounding mode */
647          sall    IMMED(10), %eax /* move to right place */          SAL_L(CONST(10), EAX)   /* move to right place */
648          orl     %eax,(%esp)     /* new control word */          OR_L(EAX,REGIND(ESP))   /* new control word */
649          fldcw   (%esp)          /* load new control word */          FLDCW(REGIND(ESP))      /* load new control word */
650          addl    IMMED(4), %esp  /* deallocate space */          ADD_L(CONST(4), ESP)    /* deallocate space */
651          ret          RET
652  #endif  #endif
653    
 /* Save the state of the floating point unit. */  
 ENTRY(savefpregs)  
         movl    4(%esp), temp           /* Get pointer argument. */  
         fsave   (temp)  
         ret  
   
 /* Restore the state of the floating point unit. */  
 ENTRY(restorefpregs)  
         movl    4(%esp), temp           /* Arg is an ML string. */  
         frstor  (temp)  
         ret  
654    
655  /* floor : real -> int  /* floor : real -> int
656     Return the nearest integer that is less or equal to the argument.     Return the nearest integer that is less or equal to the argument.
657           Caller's responsibility to make sure arg is in range. */           Caller's responsibility to make sure arg is in range. */
658    
659  ML_CODE_HDR(floor_a)  ML_CODE_HDR(floor_a)
660          fstcw   old_controlwd           /* Get FP control word. */          FSTCW(old_controlwd)            /* Get FP control word. */
661          movw    old_controlwd, %ax          MOV_W(old_controlwd, AX)
662          andw    IMMED(0xf3ff), %ax      /* Clear rounding field. */          AND_W(CONST(0xf3ff), AX)        /* Clear rounding field. */
663          orw     IMMED(0x0400), %ax      /* Round towards neg. infinity. */          OR_W(CONST(0x0400), AX) /* Round towards neg. infinity. */
664          movw    %ax, new_controlwd          MOV_W(AX, new_controlwd)
665          fldcw   new_controlwd           /* Install new control word. */          FLDCW(new_controlwd)            /* Install new control word. */
666    
667          fldl    (stdarg)                /* Load argument. */          FLD_D(REGIND(stdarg))
668          subl    IMMED(4), %esp          SUB_L(CONST(4), ESP)
669          fistpl  (%esp)                  /* Round, store, and pop. */          FISTP_L(REGIND(ESP))                    /* Round, store, and pop. */
670          popl    stdarg          POP_L(stdarg)
671          sall    IMMED(1), stdarg                /* Tag the resulting integer. */          SAL_L(CONST(1), stdarg)         /* Tag the resulting integer. */
672          incl    stdarg          INC_L(stdarg)
673    
674          fldcw   old_controlwd           /* Restore old FP control word. */          FLDCW(old_controlwd)            /* Restore old FP control word. */
675          CONTINUE          CONTINUE
676    
677  /* logb : real -> int  /* logb : real -> int
# Line 699  Line 679 
679   * Note: Using fxtract, and fistl does not work for inf's and nan's.   * Note: Using fxtract, and fistl does not work for inf's and nan's.
680   */   */
681  ML_CODE_HDR(logb_a)  ML_CODE_HDR(logb_a)
682          movl    4(stdarg),temp          /* msb for little endian arch */          MOV_L(REGOFF(4,stdarg),temp)            /* msb for little endian arch */
683          sarl    IMMED(20), temp         /* throw out 20 bits */          SAR_L(CONST(20), temp)          /* throw out 20 bits */
684          andl    IMMED(0x7ff),temp       /* clear all but 11 low bits */          AND_L(CONST(0x7ff),temp)        /* clear all but 11 low bits */
685          subl    IMMED(1023), temp       /* unbias */          SUB_L(CONST(1023), temp)        /* unbias */
686          sall    IMMED(1), temp          /* room for tag bit */          SAL_L(CONST(1), temp)           /* room for tag bit */
687          addl    IMMED(1), temp          /* tag bit */          ADD_L(CONST(1), temp)           /* tag bit */
688          movl    temp, stdarg          MOV_L(temp, stdarg)
689          CONTINUE          CONTINUE
690    
691    
# Line 717  Line 697 
697    
698  ML_CODE_HDR(scalb_a)  ML_CODE_HDR(scalb_a)
699          CHECKLIMIT          CHECKLIMIT
700          pushl   4(stdarg)               /* Get copy of scalar. */          PUSH_L(REGOFF(4,stdarg))                /* Get copy of scalar. */
701          sarl    IMMED(1), (%esp)        /* Untag it. */          SAR_L(CONST(1), REGIND(ESP))    /* Untag it. */
702          fildl   (%esp)                  /* Load it ... */          FILD_L(REGIND(ESP))                     /* Load it ... */
703  /*      fstp    %st(1) */               /* ... into 1st FP reg. */  /*      fstp    %st(1) */               /* ... into 1st FP reg. */
704          movl    (stdarg), temp          /* Get pointer to real. */          MOV_L(REGIND(stdarg), temp)             /* Get pointer to real. */
705          fldl    (temp)                  /* Load it into temp. */          FLD_D(REGIND(temp))                     /* Load it into temp. */
   
         fscale                          /* Multiply exponent by scalar. */  
         movl    IMMED(DESC_reald), (allocptr)  
         fstpl   4(allocptr)             /* Store resulting float. */  
         addl    IMMED(4), allocptr      /* Allocate word for tag. */  
         movl    allocptr, stdarg        /* Return a pointer to the float. */  
         addl    IMMED(8), allocptr      /* Allocate room for float. */  
         fstpl   (%esp)  
         addl    IMMED(4), %esp          /* Discard copy of scalar. */  
706    
707            FSCALE                          /* Multiply exponent by scalar. */
708            MOV_L(CONST(DESC_reald), REGIND(allocptr))
709            FSTP_D(REGOFF(4,allocptr))              /* Store resulting float. */
710            ADD_L(CONST(4), allocptr)       /* Allocate word for tag. */
711            MOV_L(allocptr, stdarg)         /* Return a pointer to the float. */
712            ADD_L(CONST(8), allocptr)       /* Allocate room for float. */
713            FSTP_D(REGIND(ESP))
714            ADD_L(CONST(4), ESP)            /* Discard copy of scalar. */
715          CONTINUE          CONTINUE
716    
717  /* end of X86.prim.asm */  /* end of X86.prim.asm */

Legend:
Removed from v.438  
changed lines
  Added in v.439

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