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/trunk/src/runtime/mach-dep/X86.prim.masm
ViewVC logotype

Diff of /sml/trunk/src/runtime/mach-dep/X86.prim.masm

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

revision 1316, Fri Mar 21 22:55:33 2003 UTC revision 1317, Tue Apr 8 20:42:37 2003 UTC
# Line 4  Line 4 
4   *   *
5   * derived from X86.prim.asm   * derived from X86.prim.asm
6   * derived from I386.prim.s, by Mark Leone (mleone@cs.cmu.edu)   * derived from I386.prim.s, by Mark Leone (mleone@cs.cmu.edu)
7     *
8     * new version derived from Lal George's completely rewritten
9     * X86.prim.asm, by Matthias Blume (blume@cs.uchicago.edu)
10   */   */
11    
12  #include "ml-base.h"  #include "ml-base.h"
# Line 14  Line 17 
17  #include "reg-mask.h"  #include "reg-mask.h"
18  #include "ml-limits.h"  #include "ml-limits.h"
19    
 /* 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  
  */  
   
 #ifndef VREGS  
 #  define VREGS  
 #endif  
   
20  /*  /*
21   *   *
22   * The 386 registers are used as follows:   * The 386 registers are used as follows:
23   *   *
24   * EAX - temp1 (see the code generator, x86/x86.sml)   * EAX - temp1 (see the code generator, x86/x86.sml)
25   * EBX - misc1   * EBX - misc0
26   * ECX - misc2   * ECX - misc1
27   * EDX - misc3   * EDX - misc2
28   * ESI - standard continuation (ml_cont, see ml_state.h)   * ESI - standard continuation (ml_cont, see ml_state.h)
29   * EBP - standard argument (ml_arg)   * EBP - standard argument (ml_arg)
30   * EDI - free space pointer (ml_allocptr)   * EDI - free space pointer (ml_allocptr)
# Line 40  Line 32 
32   * EIP - program counter (ml_pc)   * EIP - program counter (ml_pc)
33   */   */
34    
35    
36  /* Registers (see x86/x86.sml): */  /* Registers (see x86/x86.sml): */
37  #define temp            REG(eax)  #define temp            REG(eax)
38  #define misc1           REG(ebx)  #define misc0           REG(ebx)
39  #define misc2           REG(ecx)  #define misc1           REG(ecx)
40  #define misc3           REG(edx)  #define misc2           REG(edx)
41  #define stdcont         REG(esi)  #define stdcont         REG(esi)
42  #define stdarg          REG(ebp)  #define stdarg          REG(ebp)
43  #define allocptr        REG(edi)  #define allocptr        REG(edi)
44    #define stackptr        REG(esp)
45    
46    
47  /* other reg uses */  /* other reg uses */
48  #define creturn         REG(eax)  #define creturn         REG(eax)
49    
50  /*  #define REGOFF(o,r)     IND_DW_OFF(r,o)
  * Other values, which on most architectures would reside in registers,  
  * are stored on the stack:  
  *  
  * 0(ESP) - tempmem (used by the X86 code generator)  
  * 4(ESP) - tempmem2 (used by the X86 code generator)  
  * 8(ESP) - exception handler continuation (ml_exncont)  
  * 12(ESP) - data limit (ml_limitptr)  
  * 16(ESP) - standard closure (ml_closure)  
  * 20(ESP) - link register (ml_linkreg)  
  * 24(ESP) - store pointer (ml_storeptr)  
  * 28(ESP) - var pointer (ml_varptr)  
  *  
  */  
51    
52  /* Stack frame (see x86/x86.sml): */  /* Stack frame (see x86/x86.sml): */
53  #define tempmem         IND_DW_OFF(REG(esp),0)  #define tempmem         REGOFF(0,REG(esp))
54  #define tempmem2        IND_DW_OFF(REG(esp),4)  #define baseptr         REGOFF(4,REG(esp))
55  #define exncont         IND_DW_OFF(REG(esp),8)  #define exncont         REGOFF(8,REG(esp))
56  #define limitptr        IND_DW_OFF(REG(esp),12)  #define limitptr        REGOFF(12,REG(esp))
57  #define stdclos         IND_DW_OFF(REG(esp),16)  #define pc              REGOFF(16,REG(esp))
58  #define stdlink         IND_DW_OFF(REG(esp),20)  #define unused_1        REGOFF(20,REG(esp))
59  #define storeptr        IND_DW_OFF(REG(esp),24)  #define storeptr        REGOFF(24,REG(esp))
60  #define varptr          IND_DW_OFF(REG(esp),28)  #define varptr          REGOFF(28,REG(esp))
61  #define start_gc        IND_DW_OFF(REG(esp),32)  #define start_gc        REGOFF(32,REG(esp))
62  #define mask            IND_DW_OFF(REG(esp),36)  #define unused_2        REGOFF(36,REG(esp))
63  #define vreg0           IND_DW_OFF(REG(esp),40)  #define eaxSpill        REGOFF(40,REG(esp)) /* eax=0 */
64  #define vreg1           IND_DW_OFF(REG(esp),44)  #define ecxSpill        REGOFF(44,REG(esp)) /* ecx=1 */
65  #define vreg2           IND_DW_OFF(REG(esp),48)  #define edxSpill        REGOFF(48,REG(esp)) /* edx=2 */
66  #define vreg3           IND_DW_OFF(REG(esp),52)  #define ebxSpill        REGOFF(52,REG(esp)) /* ebx=3 */
67  #define vreg4           IND_DW_OFF(REG(esp),56)  #define espSpill        REGOFF(56,REG(esp)) /* esp=4 */
68  #define vreg5           IND_DW_OFF(REG(esp),60)  #define ebpSpill        REGOFF(60,REG(esp)) /* ebp=5 */
69  #define vreg6           IND_DW_OFF(REG(esp),64)  #define esiSpill        REGOFF(64,REG(esp)) /* esi=6 */
70  #define vreg7           IND_DW_OFF(REG(esp),68)  #define ediSpill        REGOFF(68,REG(esp)) /* edi=7 */
71  #define vreg8           IND_DW_OFF(REG(esp),72)  #define stdlink         REGOFF(72,REG(esp))
72  #define vreg9           IND_DW_OFF(REG(esp),76)  #define stdclos         REGOFF(76,REG(esp))
73  #define vreg10          IND_DW_OFF(REG(esp),80)  
74  #define vreg11          IND_DW_OFF(REG(esp),84)  #define ML_STATE_OFFSET 176
75  #define vreg12          IND_DW_OFF(REG(esp),88)     /* used as pseudo reg */  #define mlstate_ptr     REGOFF(ML_STATE_OFFSET,REG(esp))
76  #define vreg13          IND_DW_OFF(REG(esp),92)     /* used as pseudo reg */  #define freg8           184          /* double word aligned */
77  #define vreg14          IND_DW_OFF(REG(esp),96)     /* unused */  #define freg9           192
78  #define vreg15          IND_DW_OFF(REG(esp),100)    /* unused */  #define freg31          368          /* 152 + (31-8)*8 */
79  #define mlstate_ptr     IND_DW_OFF(REG(esp),104)  #define fpTempMem       376          /* freg31 + 8 */
80  #define ML_STATE_OFFSET 104  #define SpillAreaStart  512          /* starting offset */
81  #define ML_FRAME_SIZE   (ML_STATE_OFFSET+4)  #define ML_FRAME_SIZE   (8192)
   
   
 #define PSEUDOREG_1     vreg12  
 #define PSEUDOREG_2     vreg13  
82    
83  #define via  #define via
84    
# Line 109  Line 87 
87    
88          DATA          DATA
89          ALIGN4          ALIGN4
 WORD32(tempmem_w,0)     /* temp word for the code generator */  
 WORD32(tempmem2_w,0)    /* another temp word for the code generator */  
90  WORD32(request_w,0)     /* place to put the request code */  WORD32(request_w,0)     /* place to put the request code */
91    
92          GLOBAL(CSYM(ML_X86Frame))          GLOBAL(CSYM(ML_X86Frame))
93  WORD32(CSYM(ML_X86Frame),0) /* ptr to the ml frame (gives C access to limitptr) */  WORD32(CSYM(ML_X86Frame),0) /* ptr to the ml frame (gives C access to limitptr) */
94    
95  /*  WORD32(SavedSP,0)      /* Value of stack pointer to restore */
  * Note that the garbage collector only preserves root registers  
  * (EBX, ECX, EDX, ESI, EBP, EIP).  
  */  
   
96    
97  #include "mlstate-offsets.h"    /** this file is generated **/  #include "mlstate-offsets.h"    /** this file is generated **/
98    
   
99  /*  /*
100   * 386 function call conventions:   * 386 function call conventions:
101   *  [true for gcc and dynix3 cc; untested for others]   *  [true for gcc and dynix3 cc; untested for others]
# Line 163  Line 134 
134  #define MOVE(a,b,c) EXCHANGE_M a, b, c  #define MOVE(a,b,c) EXCHANGE_M a, b, c
135    
136  CONTINUE_M MACRO  CONTINUE_M MACRO
 #if (CALLEESAVE > 0)  
         CMPL    (limitptr, allocptr)  
137          JMP     via stdcont          JMP     via stdcont
 #else  
         MOVL    (IND_DW_OFF(stdcont,0), temp)  
         MOVL    (temp, stdlink)         /* Not really a register */  
         CMPL    (limitptr, allocptr)  
         JMP     via temp  
 #endif  
138  ENDM  ENDM
139  #define CONTINUE CONTINUE_M  #define CONTINUE CONTINUE_M
140    
141  CHECKLIMIT_M MACRO maskval  CHECKLIMIT_M MACRO
142   ANON_LAB:   ANON_LAB:
143            MOVE(stdlink, temp, pc)
144            CMPL(limitptr, allocptr)
145          jb      FLAB_ANON          jb      FLAB_ANON
146          LEA     (BLAB_ANON, temp)       /* temp holds resume address */          CALL    CSYM(saveregs)
147          MOVL    (IMMED(maskval), mask)          JMP     BLAB_ANON
         JMP     via CSYM(saveregs)  
148   ANON_LAB:   ANON_LAB:
149  ENDM  ENDM
150  #define CHECKLIMIT(mask) CHECKLIMIT_M mask  #define CHECKLIMIT CHECKLIMIT_M
151    
152  ENTRY_M MACRO id  ENTRY_M MACRO id
153          GLOBAL(CSYM(&id))          GLOBAL(CSYM(&id))
# Line 204  Line 168 
168          ALIGN4          ALIGN4
169    
170  ML_CODE_HDR(sigh_return_a)  ML_CODE_HDR(sigh_return_a)
171          MOVL    (mlstate_ptr, temp)          MOVL    (IMMED(ML_unit),stdlink)
172            MOVL    (IMMED(ML_unit),stdclos)
173            MOVL    (IMMED(ML_unit),pc)
174          MOVL    (IMMED(REQ_SIG_RETURN), request_w)          MOVL    (IMMED(REQ_SIG_RETURN), request_w)
         MOVL    (IMMED(RET_MASK), mask)  
175          JMP     CSYM(set_request)          JMP     CSYM(set_request)
176    
177  /* sigh_resume:  /* sigh_resume:
# Line 215  Line 180 
180   */   */
181    
182  ENTRY(sigh_resume)  ENTRY(sigh_resume)
         MOVL    (mlstate_ptr, temp)  
183          MOVL    (IMMED(REQ_SIG_RESUME), request_w)          MOVL    (IMMED(REQ_SIG_RESUME), request_w)
 /*      MOVL    (IMMED(RET_MASK), mask)  
  */  
         MOVL    (IMMED(FUN_MASK), mask)  
184          JMP     CSYM(set_request)          JMP     CSYM(set_request)
185    
186  /* pollh_return_a:  /* pollh_return_a:
187   * The return continuation for the ML poll handler.   * The return continuation for the ML poll handler.
188   */   */
189  ML_CODE_HDR(pollh_return_a)  ML_CODE_HDR(pollh_return_a)
         MOVL    (mlstate_ptr, temp)  
190          MOVL    (IMMED(REQ_POLL_RETURN), request_w)          MOVL    (IMMED(REQ_POLL_RETURN), request_w)
191          MOVL    (IMMED(RET_MASK), mask)          MOVL    (IMMED(ML_unit),stdlink)
192            MOVL    (IMMED(ML_unit),stdclos)
193            MOVL    (IMMED(ML_unit),pc)
194          JMP     CSYM(set_request)          JMP     CSYM(set_request)
195    
196  /* pollh_resume:  /* pollh_resume:
197   * Resume execution at the point at which a poll event occurred.   * Resume execution at the point at which a poll event occurred.
198   */   */
199  ENTRY(pollh_resume)  ENTRY(pollh_resume)
         MOVL    (mlstate_ptr, temp)  
200          MOVL    (IMMED(REQ_POLL_RESUME), request_w)          MOVL    (IMMED(REQ_POLL_RESUME), request_w)
 /*      MOVL    (IMMED(RET_MASK), mask)  
  */  
         MOVL    (IMMED(FUN_MASK), mask)  
201          JMP     CSYM(set_request)          JMP     CSYM(set_request)
202    
203  ML_CODE_HDR(handle_a)  ML_CODE_HDR(handle_a)
         MOVL    (mlstate_ptr, temp)  
204          MOVL    (IMMED(REQ_EXN), request_w)          MOVL    (IMMED(REQ_EXN), request_w)
205          MOVL    (IMMED(EXN_MASK), mask)          MOVE    (stdlink,temp,pc)
206          JMP     CSYM(set_request)          JMP     CSYM(set_request)
207    
208  ML_CODE_HDR(return_a)  ML_CODE_HDR(return_a)
         MOVL    (mlstate_ptr, temp)  
209          MOVL    (IMMED(REQ_RETURN), request_w)          MOVL    (IMMED(REQ_RETURN), request_w)
210          MOVL    (IMMED(RET_MASK), mask)          MOVL    (IMMED(ML_unit),stdlink)
211            MOVL    (IMMED(ML_unit),stdclos)
212            MOVL    (IMMED(ML_unit),pc)
213          JMP     CSYM(set_request)          JMP     CSYM(set_request)
214    
215  /* Request a fault.  The floating point coprocessor must be reset  /* Request a fault.  The floating point coprocessor must be reset
# Line 261  Line 219 
219   * the exception handler.   * the exception handler.
220   */   */
221  ENTRY(request_fault)  ENTRY(request_fault)
222          CALL    CSYM(FPEEnable)         /* Doesn't trash any general regs. */          CALL    CSYM(FPEEnable)
         MOVL    (mlstate_ptr, temp)  
223          MOVL    (IMMED(REQ_FAULT), request_w)          MOVL    (IMMED(REQ_FAULT), request_w)
224          MOVL    (IMMED(EXN_MASK), mask)          MOVE    (stdlink,temp,pc)
225          JMP     CSYM(set_request)          JMP     CSYM(set_request)
226    
227  /* bind_cfun : (string * string) -> c_function  /* bind_cfun : (string * string) -> c_function
228   */   */
229  ML_CODE_HDR(bind_cfun_a)  ML_CODE_HDR(bind_cfun_a)
230          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
         MOVL    (mlstate_ptr, temp)  
231          MOVL    (IMMED(REQ_BIND_CFUN), request_w)          MOVL    (IMMED(REQ_BIND_CFUN), request_w)
         MOVL    (IMMED(FUN_MASK), mask)  
232          JMP     CSYM(set_request)          JMP     CSYM(set_request)
233    
234  ML_CODE_HDR(build_literals_a)  ML_CODE_HDR(build_literals_a)
235          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
         MOVL    (mlstate_ptr, temp)  
236          MOVL    (IMMED(REQ_BUILD_LITERALS), request_w)          MOVL    (IMMED(REQ_BUILD_LITERALS), request_w)
         MOVL    (IMMED(FUN_MASK), mask)  
237          JMP     CSYM(set_request)          JMP     CSYM(set_request)
238    
239  ML_CODE_HDR(callc_a)  ML_CODE_HDR(callc_a)
240          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
         MOVL    (mlstate_ptr, temp)  
241          MOVL    (IMMED(REQ_CALLC), request_w)          MOVL    (IMMED(REQ_CALLC), request_w)
242          MOVL    (IMMED(FUN_MASK), mask)          JMP     CSYM(set_request)
243    
244    ENTRY(saveregs)
245            POPL    pc
246            MOVL    (IMMED(REQ_GC),request_w)
247          /* fall into set_request */          /* fall into set_request */
248    
249  ENTRY(set_request)  ENTRY(set_request)
250          /* temp holds mlstate_ptr, valid request in request_w  */          /* temp holds mlstate_ptr, valid request in request_w  */
251          /* Save registers */          /* Save registers */
252          MOVL    (allocptr,IND_DW_OFF(temp,AllocPtrOffMSP))          MOVL    (mlstate_ptr, temp)
253          MOVL    (stdarg,IND_DW_OFF(temp,StdArgOffMSP))          MOVL    (allocptr, REGOFF(AllocPtrOffMSP,temp))
254          MOVL    (stdcont,IND_DW_OFF(temp,StdContOffMSP))          MOVL    (stdarg, REGOFF(StdArgOffMSP,temp))
255            MOVL    (stdcont, REGOFF(StdContOffMSP,temp))
256    
257  #define temp2 allocptr  #define temp2 allocptr
258          /* note that we have left ML code */          /* note that we have left ML code */
259          MOVL    (IND_DW_OFF(temp,VProcOffMSP),temp2)          MOVL    (REGOFF(VProcOffMSP,temp),temp2)
260          MOVL    (IMMED(0), IND_DW_OFF(temp2,InMLOffVSP))          MOVL    (IMMED(0), REGOFF(InMLOffVSP,temp2))
   
 #if (CALLEESAVE > 0)  
         MOVL    (misc1, IND_DW_OFF(temp,MiscRegOffMSP(0)))  
 #if (CALLEESAVE > 1)  
         MOVL    (misc2, IND_DW_OFF(temp,MiscRegOffMSP(1)))  
 #if (CALLEESAVE > 2)  
         MOVL    (misc3, IND_DW_OFF(temp,MiscRegOffMSP(2)))  
   
         /* Save vregs before the stack frame is popped. */  
   
 #if (CALLEESAVE > 3)  
         MOVE(vreg0, temp2, IND_DW_OFF(temp,MiscRegOffMSP(3)))  
 #if (CALLEESAVE > 4)  
         MOVE(vreg1, temp2, IND_DW_OFF(temp,MiscRegOffMSP(4)))  
 #if (CALLEESAVE > 5)  
         MOVE(vreg2, temp2, IND_DW_OFF(temp,MiscRegOffMSP(5)))  
 #if (CALLEESAVE > 6)  
         MOVE(vreg3, temp2, IND_DW_OFF(temp,MiscRegOffMSP(6)))  
 #if (CALLEESAVE > 7)  
         MOVE(vreg4, temp2, IND_DW_OFF(temp,MiscRegOffMSP(7)))  
 #if (CALLEESAVE > 8)  
         MOVE(vreg5, temp2, IND_DW_OFF(temp,MiscRegOffMSP(8)))  
 #endif  
 #endif  
 #endif  
 #endif  
 #endif  
 #endif  
 #endif  
 #endif  
 #endif  
261    
262          MOVE(tempmem, temp2, tempmem_w)          MOVL    (misc0, REGOFF(Misc0RegOffMSP,temp))
263          MOVE(tempmem2,temp2, tempmem2_w)          MOVL    (misc1, REGOFF(Misc1RegOffMSP,temp))
264          MOVE(limitptr,temp2, IND_DW_OFF(temp,LimitPtrOffMSP))          MOVL    (misc2, REGOFF(Misc2RegOffMSP,temp))
265          MOVE(exncont, temp2, IND_DW_OFF(temp,ExnPtrOffMSP))  
266          MOVE(stdclos, temp2, IND_DW_OFF(temp,StdClosOffMSP))          /* Save vregs before stack frame is popped. (?? - Blume) */
267          MOVE(stdlink, temp2, IND_DW_OFF(temp,LinkRegOffMSP))          MOVE    (limitptr,temp2, REGOFF(LimitPtrOffMSP,temp))
268          MOVE(stdlink, temp2, IND_DW_OFF(temp,PCOffMSP))          MOVE    (exncont, temp2, REGOFF(ExnPtrOffMSP,temp))
269          MOVE(storeptr,temp2, IND_DW_OFF(temp,StorePtrOffMSP))          MOVE    (stdclos, temp2, REGOFF(StdClosOffMSP,temp))
270          MOVE(varptr,  temp2, IND_DW_OFF(temp,VarPtrOffMSP))          MOVE    (stdlink, temp2, REGOFF(LinkRegOffMSP,temp))
271          MOVE(mask,    temp2, IND_DW_OFF(temp,MaskOffMSP))          MOVE    (pc, temp2, REGOFF(PCOffMSP,temp))
272            MOVE    (storeptr,temp2, REGOFF(StorePtrOffMSP,temp))
273          /* pseudo regs */          MOVE    (varptr,  temp2, REGOFF(VarPtrOffMSP,temp))
         MOVE(PSEUDOREG_1,temp2,IND_DW_OFF(temp,PseudoReg1OffMSP))  
         MOVE(PSEUDOREG_2,temp2,IND_DW_OFF(temp,PseudoReg2OffMSP))  
274  #undef  temp2  #undef  temp2
275    
276          /* return val of function is request code */          /* return val of function is request code */
277          MOVL    (request_w,creturn)          MOVL    (request_w,creturn)
278    
279          /* Pop the stack frame and return to run_ml(). */          /* Pop the stack frame and return to run_ml(). */
280          ADDL    (IMMED(ML_FRAME_SIZE), REG(esp))          MOVL    (SavedSP, REG(esp))
281          CALLEE_RESTORE          CALLEE_RESTORE
282          RET          RET
283    
284          TEXT          TEXT
285          ALIGN4          ALIGN4
286    
287  ENTRY(saveregs)  ENTRY(restoreregs)
288          PUSHL   temp                    /* Contains "resume" address. */          MOVL    (REGOFF(4,REG(esp)), temp) /* get argument (MLState ptr) */
289          MOVL    (IND_DW_OFF(REG(esp),ML_STATE_OFFSET+4), temp)          CALLEE_SAVE
         POPL    IND_DW_OFF(temp,PCOffMSP)  
   
 #ifdef SOFT_POLL  
         /* free some regs */  
         MOVL    (misc1, IND_DW_OFF(temp,MiscRegOffMSP(0)))  
         MOVL    (misc2, IND_DW_OFF(temp,MiscRegOffMSP(1)))  
 #define tmpR    misc1  
 #define pfreq   misc2  
         /* check if polling enabled (PollFreq > 0) */  
         LEA     (CSYM(_PollFreq0),pfreq)        /* load contents of ref */  
         MOVL    (IND_DW_OFF(pfreq,4),pfreq)  
         SHRL    (IMMED(1),pfreq)                /* strip integer tag */  
         JZ      check_for_gc                    /* go check for real gc */  
         CMPL    (IMMED(0),IND_DW_OFF(temp,InPollHandlerOffMSP))  /* if we're in the handler */  
         JNE     reset_limit                     /* ignore poll events */  
         LEA     (CSYM(_PollEvent0),tmpR)        /* load contents of ref */  
         MOVL    (IND_DW_OFF(tmpR,4),tmpR)  
         SHRL    (IMMED(1),tmpR)  
         JZ      reset_limit                     /* check for poll event */  
         /* event occurred, so set ml_pollHandlerPending */  
         MOVL    (IMMED(1),IND_DW_OFF(temp,PollPendingOffMSP))  
         JMP     do_gc           /* and handle event in the C runtime */  
   
 reset_limit:    /* reset limit ptr */  
         SHLL    (IMMED(POLL_GRAIN_BITS),pfreq)  /* mult by POLL_GRAIN_CPSI */  
         MOVL    (allocptr,limitptr)  
         ADDL    (pfreq,limitptr)  
 #undef  pfreq  
   
 check_for_gc:  
         /* ensure real limit is >= limit */  
         MOVL    (IND_DW_OFF(temp,RealLimitOffMSP),tmpR)  
         CMPL    (limitptr,tmpR)  
         JA      ok_limit  
         MOVL    (tmpR,limitptr)  
 ok_limit:  
         ADDL    (IMMED(-4096),limitptr)  
         CMPL    (limitptr,allocptr)  
         JGE     do_gc                   /* gc *//* should be a common case */  
         ADDL    (IMMED(4096),limitptr)  
         /* since a signal also sets limitptr == allocptr to force a trap, */  
         /* we need to disambiguate poll-events/signals here */  
 #define vsp     misc2  
         MOVL    ($0,tmpR)  
         ADDL    (IND_DW_OFF(temp,PollPendingOffMSP),tmpR)  
         MOVL    (IND_DW_OFF(temp,VProcOffMSP),vsp)  
         ADDL    (IND_DW_OFF(vsp,NPendingOffVSP),tmpR)  
         ADDL    (IND_DW_OFF(vsp,NPendingSysOffVSP),tmpR)  
         JNZ     do_gc  
 #undef  vsp  
   
 no_gc:  /* an uneventful poll check, back to ML */  
         MOVL    (IND_DW_OFF(temp,MiscRegOffMSP(0)),misc1)  
         MOVL    (IND_DW_OFF(temp,MiscRegOffMSP(1)),misc2)  
         MOVL    (IND_DW_OFF(temp,PCOffMSP),temp)  
         CMPL    (limitptr, allocptr)  
         JMPL    temp  
   
 do_gc:  
         /* limitptr saved below */  
   
 #undef tmpR  
 #endif /* SOFT_POLL */  
   
   
         /* Save registers. */  
         MOVL    (allocptr, IND_DW_OFF(temp,AllocPtrOffMSP))  
         MOVL    (stdarg, IND_DW_OFF(temp,StdArgOffMSP))  
         MOVL    (stdcont, IND_DW_OFF(temp,StdContOffMSP))  
 #ifndef SOFT_POLL  /* misc1 & misc2 saved above for SOFT_POLL */  
         MOVL    (misc1, IND_DW_OFF(temp,MiscRegOffMSP(0)))  
         MOVL    (misc2, IND_DW_OFF(temp,MiscRegOffMSP(1)))  
 #endif  
         MOVL    (misc3, IND_DW_OFF(temp,MiscRegOffMSP(2)))  
   
 #define temp2 allocptr  
   
         /* note that we have left ML code */  
         MOVL    (IND_DW_OFF(temp,VProcOffMSP),temp2)  
         MOVL    (IMMED(0), IND_DW_OFF(temp2,InMLOffVSP))  
   
         /* vregs */  
 #ifdef VREGS  
         MOVE(vreg0, temp2, IND_DW_OFF(temp,MiscRegOffMSP(3)))  
         MOVE(vreg1, temp2, IND_DW_OFF(temp,MiscRegOffMSP(4)))  
         MOVE(vreg2, temp2, IND_DW_OFF(temp,MiscRegOffMSP(5)))  
         MOVE(vreg3, temp2, IND_DW_OFF(temp,MiscRegOffMSP(6)))  
         MOVE(vreg4, temp2, IND_DW_OFF(temp,MiscRegOffMSP(7)))  
         MOVE(vreg5, temp2, IND_DW_OFF(temp,MiscRegOffMSP(8)))  
         MOVE(vreg6, temp2, IND_DW_OFF(temp,MiscRegOffMSP(9)))  
         MOVE(vreg7, temp2, IND_DW_OFF(temp,MiscRegOffMSP(10)))  
         MOVE(vreg8, temp2, IND_DW_OFF(temp,MiscRegOffMSP(11)))  
         MOVE(vreg9, temp2, IND_DW_OFF(temp,MiscRegOffMSP(12)))  
         MOVE(vreg10, temp2, IND_DW_OFF(temp,MiscRegOffMSP(13)))  
         MOVE(vreg11, temp2, IND_DW_OFF(temp,MiscRegOffMSP(14)))  
 #endif  
290    
291          MOVE(tempmem, temp2, tempmem_w)          MOVL    (REG(esp), SavedSP)     /* save stack pointer */
         MOVE(tempmem2,temp2, tempmem2_w)  
         MOVE(exncont, temp2, IND_DW_OFF(temp,ExnPtrOffMSP))  
         MOVE(stdclos, temp2, IND_DW_OFF(temp,StdClosOffMSP))  
         MOVE(stdlink, temp2, IND_DW_OFF(temp,LinkRegOffMSP))  
         MOVE(storeptr,temp2, IND_DW_OFF(temp,StorePtrOffMSP))  
         MOVE(limitptr,temp2, IND_DW_OFF(temp,LimitPtrOffMSP))  
         MOVE(varptr,  temp2, IND_DW_OFF(temp,VarPtrOffMSP))  
         MOVE(mask,    temp2, IND_DW_OFF(temp,MaskOffMSP))  
   
         /* pseudo regs */  
         MOVE(PSEUDOREG_1,temp2,IND_DW_OFF(temp,PseudoReg1OffMSP))  
         MOVE(PSEUDOREG_2,temp2,IND_DW_OFF(temp,PseudoReg2OffMSP))  
 #undef  temp2  
292    
293          /* Pop the stack frame and return to run_ml(). */          /* Align on 8 byte boundary. Assumes that the stack starts
294          MOVL    (IMMED(REQ_GC),creturn)           * out being at least word aligned. But who knows... */
         ADDL    (IMMED(ML_FRAME_SIZE), REG(esp))  
         CALLEE_RESTORE  
         RET  
295    
296  ENTRY(asm_restoreregs)          ORL     (IMMED(4),REG(esp))
297          MOVL    (IND_DW_OFF(REG(esp),4), temp)/* Get argument (MLState ptr). */          SUBL    (IMMED(4),REG(esp))
         CALLEE_SAVE  
298    
299  #define temp2   REG(ebx)  #define temp2   REG(ebx)
300          /* Allocate and initialize the ML stack frame. */          /* Allocate and initialize the ML stack frame. */
301          SUBL    (IMMED(ML_FRAME_SIZE), REG(esp))          SUBL    (IMMED(ML_FRAME_SIZE), REG(esp))
302          MOVE(   tempmem_w,  temp2, tempmem)          MOVE    (REGOFF(ExnPtrOffMSP,temp),temp2,exncont)
303          MOVE(   tempmem2_w, temp2, tempmem2)          MOVE    (REGOFF(LimitPtrOffMSP,temp),temp2,limitptr)
304          MOVE(   IND_DW_OFF(temp,ExnPtrOffMSP), temp2, exncont)          MOVE    (REGOFF(StorePtrOffMSP,temp),temp2,varptr)
         MOVE(   IND_DW_OFF(temp,LimitPtrOffMSP), temp2, limitptr)  
         MOVE(   IND_DW_OFF(temp,StdClosOffMSP), temp2, stdclos)  
         MOVE(   IND_DW_OFF(temp,LinkRegOffMSP), temp2, stdlink)  
         MOVE(   IND_DW_OFF(temp,StorePtrOffMSP), temp2, storeptr)  
         MOVE(   IND_DW_OFF(temp,VarPtrOffMSP), temp2, varptr)  
         MOVE(   IND_DW_OFF(temp,MaskOffMSP), temp2, mask)  
305          LEA     (CSYM(saveregs), temp2)          LEA     (CSYM(saveregs), temp2)
306          MOVL    (temp2,start_gc)          MOVL    (temp2,start_gc)
307          MOVL    (temp, mlstate_ptr)          MOVL    (temp, mlstate_ptr)
308    
309          /* vregs */          /* vregs */
310  #ifdef VREGS          MOVE    (REGOFF(LinkRegOffMSP,temp),temp2,stdlink)
311          MOVE(IND_DW_OFF(temp,MiscRegOffMSP(3)),temp2,vreg0)          MOVE    (REGOFF(StdClosOffMSP,temp),temp2,stdclos)
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(4)),temp2,vreg1)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(5)),temp2,vreg2)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(6)),temp2,vreg3)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(7)), temp2, vreg4)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(8)), temp2, vreg5)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(9)), temp2, vreg6)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(10)), temp2, vreg7)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(11)), temp2, vreg8)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(12)), temp2, vreg9)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(13)), temp2, vreg10)  
         MOVE(IND_DW_OFF(temp,MiscRegOffMSP(14)), temp2, vreg11)  
 #endif  
         /* pseudo regs */  
         MOVE(IND_DW_OFF(temp,PseudoReg1OffMSP),temp2,PSEUDOREG_1)  
         MOVE(IND_DW_OFF(temp,PseudoReg2OffMSP),temp2,PSEUDOREG_2)  
312    
313            /* PC */
314            MOVE    (REGOFF(PCOffMSP,temp),temp2,pc)
315  #undef  temp2  #undef  temp2
316    
317          /* Load ML registers. */          /* Load ML registers */
318          MOVL    (IND_DW_OFF(temp,AllocPtrOffMSP), allocptr)          MOVL    (REGOFF(AllocPtrOffMSP,temp),allocptr)
319          MOVL    (IND_DW_OFF(temp,StdContOffMSP), stdcont)          MOVL    (REGOFF(StdContOffMSP,temp),stdcont)
320          MOVL    (IND_DW_OFF(temp,StdArgOffMSP), stdarg)          MOVL    (REGOFF(StdArgOffMSP,temp),stdarg)
321          MOVL    (IND_DW_OFF(temp,MiscRegOffMSP(0)), misc1)          MOVL    (REGOFF(Misc0OffMSP,temp),misc0)
322          MOVL    (IND_DW_OFF(temp,MiscRegOffMSP(1)), misc2)          MOVL    (REGOFF(Misc1OffMSP,temp),misc1)
323          MOVL    (IND_DW_OFF(temp,MiscRegOffMSP(2)), misc3)          MOVL    (REGOFF(Misc2OffMSP,temp),misc2)
324    
325          MOVL    (REG(esp),CSYM(ML_X86Frame))/* frame ptr for signal handler. */          MOVL    (REG(esp),CSYM(ML_X86Frame))/* frame ptr for signal handler. */
326    
# Line 536  Line 328 
328          PUSHL   temp                    /* save msp temporarily */          PUSHL   temp                    /* save msp temporarily */
329    
330  #define tmpreg  misc2  #define tmpreg  misc2
   
331          /* note that we're entering ML */          /* note that we're entering ML */
332          MOVL    (IND_DW_OFF(temp,VProcOffMSP),temp)  /* temp is now vsp */          MOVL    (REGOFF(VProcOffMSP,temp),temp) /* temp is now vsp */
333  #define vsp     temp  #define vsp     temp
334          MOVL    (IMMED(1),IND_DW_OFF(vsp,InMLOffVSP))          MOVL    (IMMED(1),REGOFF(InMLOffVSP,vsp))
335    
336          /* handle signals */          /* handle signals */
337          MOVL    (IND_DW_OFF(vsp,NPendingSysOffVSP),tmpreg)          MOVL    (REGOFF(NPendingSysOffVSP,vsp),tmpreg)
338          ADDL    (IND_DW_OFF(vsp,NPendingOffVSP),tmpreg)          ADDL    (REGOFF(NPendingOffVSP,vsp),tmpreg)
339          CMPL    (IMMED(0),tmpreg)          CMPL    (IMMED(0),tmpreg)
340  #undef  tmpreg  #undef  tmpreg
341    
342          JNE     pending          JNE     pending
343    
344  restore_and_jmp_ml:  restore_and_jmp_ml:
# Line 554  Line 346 
346          POPL    misc2          POPL    misc2
347    
348  jmp_ml:  jmp_ml:
         MOVL    (IND_DW_OFF(temp,PCOffMSP),temp)  
349          CMPL    (limitptr, allocptr)          CMPL    (limitptr, allocptr)
350          JMP     temp                  /* Jump to ML code. */          JMP     (REGOFF(PCOffMSP,temp)) /* jump to ML code */
351    
352  pending:  pending:
353          CMPL    (IMMED(0),IND_DW_OFF(vsp,InSigHandlerOffVSP))   /* Currently handling signal? */          CMPL    (IMMED(0),REGOFF(InSigHandlerOffVSP,vsp))
354          JNE     restore_and_jmp_ml          JNE     restore_and_jmp_ml
355          MOVL    (IMMED(1),IND_DW_OFF(vsp,HandlerPendingOffVSP)) /* handler trap is now pending */  
356            MOVL    (IMMED(1),HandlerPendingOffVSP(vsp))
357    
358          /* must restore here because limitptr is on stack */          /* must restore here because limitptr is on stack */
359          POPL    temp                    /* restore temp to msp */          POPL    temp                    /* restore temp to msp */
360          POPL    misc2          POPL    misc2
361    
362          MOVL    (allocptr,limitptr)          MOVL    (allocptr,limitptr)
363          JMP     jmp_ml                  /* Jump to ML code. */          JMP     jmp_ml
   
364  #undef  vsp  #undef  vsp
365    
366    
367  /* ----------------------------------------------------------------------  /* ----------------------------------------------------------------------
368   * array : (int * 'a) -> 'a array   * array : (int * 'a) -> 'a array
369   * Allocate and initialize a new array.  This can cause GC.   * Allocate and initialize a new array.  This can cause GC.
370   */   */
371    
372  ML_CODE_HDR(array_a)  ML_CODE_HDR(array_a)
373          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
374          MOVL    (IND_DW_OFF(stdarg,0),temp)               /* desired length into temp */          MOVL    (REGOFF(0,stdarg),temp)         /* temp := length in words */
375          SARL    (IMMED(1),temp)                      /* untagged */          SARL    (IMMED(1),temp)                 /* temp := length untagged */
376          CMPL    (IMMED(SMALL_OBJ_SZW),temp)          CMPL    (IMMED(SMALL_OBJ_SZW),temp)     /* small object? */
377          JGE     FLAB(L1)          JGE     FLAB(ARRAR_A_LARGE)
378    
379  #define tmpreg  misc1  #define temp1 misc0
380          PUSHL   tmpreg  #define temp2 misc1
381            PUSHL   misc0                   /* free up misc0 */
382          MOVL    (temp,tmpreg)                /* build descriptor in tmpreg */          PUSHL   misc1                   /* free up misc1 */
383          SALL    (IMMED(TAG_SHIFTW),tmpreg)  
384          ORL     (IMMED(MAKE_TAG(DTAG_array)),tmpreg)          MOVL    (temp,temp1)
385          MOVL    (tmpreg,IND_DW_OFF(allocptr,0))      /* write descriptor */          SALL    (IMMED(TAG_SHIFTW),temp1)       /* build descriptor */
386            ORL     (IMMED(MAKE_TAG(DTAG_arr_data)),temp1)
387            MOVL    (temp1,REGOFF(0,allocptr))      /* store descriptor */
388            ADDL    (IMMED(4),allocptr)             /* allocptr++ */
389            MOVL    (allocptr,temp1)                /* temp1 := array data ptr */
390            MOVL    (REGOFF(4,stdarg),temp2)        /* temp2 := initial value */
391    ANON_LAB:
392            MOVL    (temp2,REGOFF(0,allocptr))      /* init array */
393          ADDL    (IMMED(4),allocptr)          ADDL    (IMMED(4),allocptr)
394          MOVL    (IND_DW_OFF(stdarg,4),tmpreg)        /* initial values */          SUBL    (IMMED(1),temp)
         MOVL    (allocptr,stdarg)            /* stdarg gets ptr to new array */  
         SALL    (IMMED(2),temp)              /* length in bytes */  
         ADDL    (allocptr,temp)  
         XCHGL   (tmpreg,temp)                /* tmpreg is end of array */  
 ANON_LAB:                                            /* loop: */  
         STOSL                                   /* 0(allocptr++) <- temp  */  
         CMPL    (allocptr,tmpreg)               /* check for end of array */  
395          JNE     BLAB_ANON          JNE     BLAB_ANON
396    
397          POPL    tmpreg          /* Allocate array header */
398  #undef  tmpreg          MOVL    (IMMED(DESC_polyarr),REGOFF(0,allocptr)) /* descriptor */
399            ADDL    (IMMED(4),allocptr)
400            MOVL    (REGOFF(0,stdarg),temp)         /* temp := length */
401            MOVL    (allocptr, stdarg)              /* result := header addr */
402            MOVL    (temp1, REGOFF(0,allocptr))     /* store pointer to data */
403            MOVL    (temp, REGOFF(4,allocptr))      /* store length */
404            ADDL    (IMMED(8),allocptr)
405    
406            POPL    misc1
407            POPL    misc2
408          CONTINUE          CONTINUE
409  LABEL(L1)  #undef temp1
410          MOVL    (mlstate_ptr, temp)  #undef temp2
411    
412    LABEL(ARRAY_A_LARGE)
413          MOVL    (IMMED(REQ_ALLOC_ARRAY), request_w)          MOVL    (IMMED(REQ_ALLOC_ARRAY), request_w)
414          MOVL    (IMMED(FUN_MASK), mask)          MOVE    (stdlink,temp,pc)
415          JMP     CSYM(set_request)          JMP     CSYM(set_request)
416    
417    
418  /* create_r : int -> realarray */  /* create_r : int -> realarray */
419  ML_CODE_HDR(create_r_a)  ML_CODE_HDR(create_r_a)
420          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
421          MOVL    (stdarg,temp)             /* desired length into temp */  #define temp1 misc0
422          SARL    (IMMED(1),temp)           /* untagged */          PUSHL   misc0                   /* free temp1 */
423          SHLL    (IMMED(1),temp)           /* size in words */          MOVL    (stdarg,temp)           /* temp := length */
424            SARL    (IMMED(1),temp)         /* temp := untagged length */
425            SHLL    (IMMED(1),temp)         /* temp := length in words */
426          CMPL    (IMMED(SMALL_OBJ_SZW),temp)          CMPL    (IMMED(SMALL_OBJ_SZW),temp)
427          JGE     FLAB_ANON          JGE     FANON_LAB
428    
429  #define tmpreg  misc1          ORL     (IMMED(4),allocptr)     /* align allocptr */
         PUSHL   tmpreg  
430    
431          SHRL    (IMMED(1),temp)              /* size in reals */          /* allocate the data object */
432          MOVL    (temp,tmpreg)                /* build descriptor in tmpreg */          MOVL    (temp,temp1)
433          SALL    (IMMED(TAG_SHIFTW),tmpreg)          SHLL    (IMMED(TAG_SHIFTW),temp1)       /* temp1 := descriptor */
434          ORL     (IMMED(MAKE_TAG(DTAG_realdarray)),tmpreg)          ORL     (IMMED(MAKE_TAG(DTAG_raw64)),temp1)
435          MOVL    (tmpreg,IND_DW_OFF(allocptr,0))      /* write descriptor */          MOVL    (temp1,REGOFF(0,allocptr))      /* store descriptor */
436          ADDL    (IMMED(4),allocptr)          ADDL    (IMMED(4),allocptr)             /* allocptr++ */
437          MOVL    (allocptr,stdarg)            /* stdarg gets ptr to new array */          MOVL    (allocptr,temp1)                /* temp1 := data object */
438          SALL    (IMMED(3),temp)              /* length in bytes */          SHLL    (IMMED(2),temp)                 /* temp := length in bytes */
439          ADDL    (temp,allocptr)              /* adjust allocptr past array */          ADDL    (temp,allocptr)                 /* allocptr += length */
440    
441            /* allocate the header object */
442            MOVL    (IMMED(DESC_real64arr),REGOFF(0,allocptr))
443            ADDL    (IMMED(4),allocptr)             /* allocptr++ */
444            MOVL    (temp1,REGOFF(0,allocptr))      /* header data */
445            MOVL    (stdarg,REGOFF(4,allocptr))     /* header length */
446            MOVL    (allocptr,stdarg)               /* stdarg := header obj */
447            ADDL    (IMMED(8),allocptr)             /* allocptr += 2 */
448    
449          POPL    tmpreg          POPL    misc0
 #undef  tmpreg  
450          CONTINUE          CONTINUE
451    
452  ANON_LAB:  ANON_LAB:
453          MOVL    (mlstate_ptr, temp)          POPL    misc0
454          MOVL    (IMMED(REQ_ALLOC_REALDARRAY), request_w)          MOVL    (IMMED(REQ_ALLOC_REALDARRAY), request_w)
455          MOVL    (IMMED(FUN_MASK), mask)          MOVE    (stdlink,temp,pc)
456          JMP     CSYM(set_request)          JMP     CSYM(set_request)
457    #undef temp1
458    
459    
460  /* create_b : int -> bytearray */  /* create_b : int -> bytearray */
461  ML_CODE_HDR(create_b_a)  ML_CODE_HDR(create_b_a)
462          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
463          MOVL    (stdarg,temp)                /* the length */          MOVL    (stdarg,temp)           /* temp is tagged length */
464          SARL    (IMMED(1),temp)              /* untagged */          SARL    (IMMED(1),temp)         /* temp is untagged length */
465          ADDL    (IMMED(3),temp)              /* round */          ADDL    (IMMED(3),temp)
466          SARL    (IMMED(2),temp)              /* to words */          SARL    (IMMED(2),temp)         /* temp is length in words */
467          CMPL    (IMMED(SMALL_OBJ_SZW),temp)          CMPL    (IMMED(SMALL_OBJ_SZW),temp)
468          JGE     FLAB_ANON          JMP     FLAB_ANON
469            JGE     FLAB_ANON               /* XXXXX */
470    
471  #define tmpreg  misc1  #define temp1 misc0
472          PUSHL   tmpreg          PUSHL   misc0
473    
474          MOVL    (stdarg,tmpreg)              /* build descriptor in tmpreg */          /* allocate the data object */
475          SARL    (IMMED(1),tmpreg)          MOVL    (temp,temp1)
476          SALL    (IMMED(TAG_SHIFTW),tmpreg)          SHLL    (IMMED(TAG_SHIFTW),temp1)
477          ORL     (IMMED(MAKE_TAG(DTAG_bytearray)),tmpreg)          ORL     (IMMED(MAKE_TAG(DTAG_raw32)),temp1)
478          MOVL    (tmpreg,IND_DW_OFF(allocptr,0))      /* write descriptor */          MOVL    (temp1,REGOFF(0,allocptr))      /* store descriptor */
479          ADDL    (IMMED(4),allocptr)          ADDL    (IMMED(4),allocptr)
480          MOVL    (allocptr,stdarg)            /* stdarg gets ptr to new str */          MOVL    (allocptr,temp1)                /* temp1 is data object */
481          SALL    (IMMED(2),temp)              /* length in bytes (untagged) */          SHLL    (IMMED(2),temp)                 /* temp is size in bytes */
482          ADDL    (temp,allocptr)              /* allocptr += total length */          ADDL    (temp,allocptr)                 /* allocptr += length */
   
         POPL    tmpreg  
 #undef  tmpreg  
483    
484            /* allocate the header object */
485            MOVL    (IMMED(DESC_word8arr),REGOFF(0,allocptr))
486            ADDL    (IMMED(4),allocptr)
487            MOVL    (temp1,REGOFF(0,allocptr))
488            MOVL    (stdarg,REGOFF(4,allocptr))
489            MOVL    (allocptr,stdarg)               /* stdarg := header */
490            ADDL    (IMMED(8),allocptr)             /* allocptr += 2 */
491            POPL    misc0
492          CONTINUE          CONTINUE
493    #undef temp1
494    
495  ANON_LAB:  ANON_LAB:
         MOVL    (mlstate_ptr, temp)  
496          MOVL    (IMMED(REQ_ALLOC_BYTEARRAY), request_w)          MOVL    (IMMED(REQ_ALLOC_BYTEARRAY), request_w)
497          MOVL    (IMMED(FUN_MASK), mask)          MOVE    (stdlink,temp,pc)
498          JMP     CSYM(set_request)          JMP     CSYM(set_request)
499    
500    
501  /* create_s : int -> string */  /* create_s : int -> string */
502  ML_CODE_HDR(create_s_a)  ML_CODE_HDR(create_s_a)
503          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
504          MOVL    (stdarg,temp)           /* the length */          MOVL    (stdarg,temp)
505          SARL    (IMMED(1),temp)         /* untagged */          SARL    (IMMED(1),temp)         /* untag */
506          ADDL    (IMMED(4),temp)         /* round */          ADDL    (IMMED(4),temp)         /* 3 + extra byte */
507          SARL    (IMMED(2),temp)         /* to words */          SARL    (IMMED(2),temp)         /* length in words */
508          CMPL    (IMMED(SMALL_OBJ_SZW),temp)          CMPL    (IMMED(SMALL_OBJ_SZW),temp)
509          JGE     FLAB_ANON          JGE     FLAB_ANON
510    
511  #define tmpreg  misc1          PUSHL   misc0
512          PUSHL   tmpreg  #define temp1 misc0
513    
514          MOVL    (stdarg,tmpreg)              /* build descriptor in tmpreg */          MOVL    (temp,temp1)
515          SARL    (IMMED(1),tmpreg)          SHLL    (IMMED(TAG_SHIFTW,temp1))
516          SALL    (IMMED(TAG_SHIFTW),tmpreg)          ORL     (IMMED(MAKE_TAG(DTAG_raw32)),temp1)
517          ORL     (IMMED(MAKE_TAG(DTAG_string)),tmpreg)          MOVL    (temp1,REGOFF(0,allocptr))      /* store descriptor */
518          MOVL    (tmpreg,IND_DW_OFF(allocptr,0))      /* write descriptor */          ADD     (IMMED(4),allocptr)
519    
520            MOVL    (allocptr,temp1)                /* temp1 is data obj */
521            SHLL    (IMMED(2),temp)                 /* bytes len */
522            ADDL    (temp,allocptr)                 /* allocptr += length */
523            MOVL    (IMMED(0),REGOFF(-4,allocptr))  /* zero out last word */
524    
525            /* allocate header obj */
526            MOVL    (IMMED(DESC_string),temp)       /* hdr descr */
527            MOVL    (temp,REGOFF(0,allocptr))
528          ADDL    (IMMED(4),allocptr)          ADDL    (IMMED(4),allocptr)
529          MOVL    (allocptr,stdarg)            /* stdarg gets ptr to new str */          MOVL    (temp1,REGOFF(0,allocptr))      /* hdr data */
530          SALL    (IMMED(2),temp)              /* length in bytes (untagged) */          MOVL    (stdarg,REGOFF(4,allocptr))     /* hdr length */
531          ADDL    (temp,allocptr)              /* allocptr += total length */          MOVL    (allocptr, stdarg)              /* stdarg is hdr obj */
532          MOVL    (IMMED(0),IND_DW_OFF(allocptr,(-4)))    /* for fast strcmp */          ADDL    (IMMED(8),allocptr)             /* allocptr += 2 */
   
         POPL    tmpreg  
 #undef  tmpreg  
533    
534            POPL    misc0
535    #undef temp1
536          CONTINUE          CONTINUE
537    
538  ANON_LAB:  ANON_LAB:
         MOVL    (mlstate_ptr, temp)  
539          MOVL    (IMMED(REQ_ALLOC_STRING), request_w)          MOVL    (IMMED(REQ_ALLOC_STRING), request_w)
540          MOVL    (IMMED(FUN_MASK), mask)          MOVE    (stdlink, temp, gc)
541          JMP     CSYM(set_request)          JMP     CSYM(set_request)
542    
543    
544  /* create_v_a : int * 'a list -> 'a vector  /* create_v_a : int * 'a list -> 'a vector
545   *      creates a vector with elements taken from a list.   *      creates a vector with elements taken from a list.
546   *      n.b. The frontend ensures that list cannot be nil.   *      n.b. The frontend ensures that list cannot be nil.
547   */   */
548  ML_CODE_HDR(create_v_a)  ML_CODE_HDR(create_v_a)
549          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
550          MOVL    (IND_DW_OFF(stdarg,0),temp)     /* desired length into temp */          PUSHL   misc0
551          SARL    (IMMED(1),temp)                 /* untagged */          PUSHL   misc1
552          CMPL    (IMMED(SMALL_OBJ_SZW),temp)  #define temp1 misc0
553          JGE     FLAB(L2)  #define temp2 misc1
554            MOVL    (REGOFF(0,stdarg),temp)         /* len tagged */
555  #define tmpreg  misc1          MOVL    (temp,temp1)
556          PUSHL   tmpreg          SARL    (IMMED(1),temp1)                /* untag */
557            CMPL    (IMMED(SMALL_OBJ_SZW),temp1)
558            JGE     FLAB(CREATE_V_A_LARGE)
559    
560            SHLL    (IMMED(TAG_SHIFTW),temp1)
561            ORL     (IMMED(MAKE_TAG(DTAG_vec_data)),temp1)
562            MOVL    (temp1,REGOFF(0,allocptr))
563            ADDL    (IMMED(4),allocptr)
564            MOVL    (REGOFF(4,stdarg),temp1)        /* temp1 is list */
565            MOVL    (allocptr,stdarg)               /* stdarg is vector */
566    
567          MOVL    (temp,tmpreg)                /* build descriptor in tmpreg */  ANON_LAB:
568          SALL    (IMMED(TAG_SHIFTW),tmpreg)          MOVL    (REGOFF(0,temp1),temp2)         /* hd */
569          ORL     (IMMED(MAKE_TAG(DTAG_vector)),tmpreg)          MOVL    (temp2,REGOFF(0,allocptr))      /* store into vector */
         MOVL    (tmpreg,IND_DW_OFF(allocptr,0)) /* write descriptor */  
570          ADDL    (IMMED(4),allocptr)          ADDL    (IMMED(4),allocptr)
571          MOVL    (IND_DW_OFF(stdarg,4),tmpreg)/* list of initial values */          MOVL    (REGOFF(4,temp1),temp1)         /* tl */
572          MOVL    (allocptr,stdarg)            /* stdarg gets ptr to new array */          CMPL    (IMMED(ML_nil),temp1)           /* isNull */
 ANON_LAB:                                            /* loop: */  
         MOVL    (IND_DW_OFF(tmpreg,0),temp)     /* temp <- hd(tmpreg) */  
         STOSL                                   /* 0(allocptr++) <- temp */  
         MOVL    (IND_DW_OFF(tmpreg,4),tmpreg)   /* tmpreg <- tl(tmpreg) */  
         CMPL    (IMMED(ML_nil),tmpreg)          /* end of list */  
573          JNE     BLAB_ANON          JNE     BLAB_ANON
574    
575          POPL    tmpreg          /* allocate header object */
576  #undef  tmpreg          MOVL    (IMMED(DESC_polyvec),temp1)
577            MOVL    (temp1,REGOFF(0,allocptr))
578            ADDL    (IMMED(4),allocptr)
579            MOVL    (stdarg,REGOFF(0,allocptr))     /* data */
580            MOVL    (temp,REGOFF(4,allocptr))       /* len */
581            MOVL    (allocptr,stdarg)               /* result */
582            ADDL    (IMMED(8),allocptr)             /* allocptr += 2 */
583    
584            POPL    misc1
585            POPL    misc0
586          CONTINUE          CONTINUE
587  LABEL(L2)  
588          MOVL    (mlstate_ptr, temp)  LABEL(CREATE_V_A_LARGE)
589            POPL    misc1
590            POPL    misc0
591          MOVL    (IMMED(REQ_ALLOC_VECTOR), request_w)          MOVL    (IMMED(REQ_ALLOC_VECTOR), request_w)
592          MOVL    (IMMED(FUN_MASK), mask)          MOVE    (stdlink, temp, pc)
593          JMP     CSYM(set_request)          JMP     CSYM(set_request)
594    #undef temp1
595    #undef temp2
596    
597    
598  /* try_lock: spin_lock -> bool.  /* try_lock: spin_lock -> bool.
599   * low-level test-and-set style primitive for mutual-exclusion among   * low-level test-and-set style primitive for mutual-exclusion among
# Line 811  Line 655 
655          /* Temp space.Keep stack aligned. */          /* Temp space.Keep stack aligned. */
656          SUBL    (IMMED(4), REG(esp))          SUBL    (IMMED(4), REG(esp))
657          /* Store FP control word. */          /* Store FP control word. */
658          fstcw   IND_W_OFF(REG(esp),0)          fstcw   REGOFF(0,REG(esp))
659          /* Keep undefined fields, clear others. */          /* Keep undefined fields, clear others. */
660          ANDW    (IMMED(HEXLIT(f0c0)), IND_W_OFF(REG(esp),0))          ANDW    (IMMED(HEXLIT(f0c0)), REGOFF(0,REG(esp)))
661          /* Set fields (see above). */          /* Set fields (see above). */
662          ORW     (IMMED(HEXLIT(023f)), IND_W_OFF(REG(esp),0))          ORW     (IMMED(HEXLIT(023f)), REGOFF(0,REG(esp)))
663          fldcw   IND_W_OFF(REG(esp),0)   /* Install new control word. */          fldcw   REGOFF(0,REG(esp)) /* Install new control word. */
664          ADDL    (IMMED(4), REG(esp))          ADDL    (IMMED(4), REG(esp))
         fldz                    /* Push a zero onto the register stack. */  
         fld     FP_REG(st)      /* Copy it 6 times. */  
         fld     FP_REG(st)  
         fld     FP_REG(st)  
         fld     FP_REG(st)  
         fld     FP_REG(st)  
         fld     FP_REG(st)  
665          RET          RET
666    
667  ENTRY(fegetround)  ENTRY(fegetround)
668        SUBL    (IMMED(4),REG(esp))                /* allocate temporary space */        SUBL    (IMMED(4),REG(esp))                /* allocate temporary space */
669        FSTCW   IND_W_OFF(REG(esp),0)              /* store fp control word */        FSTCW   REGOFF(0,REG(esp))          /* store fp control word */
670          /* rounding mode is at bit 10 and 11 */          /* rounding mode is at bit 10 and 11 */
671        SARL    (IMMED(10),IND_DW_OFF(REG(esp),0))        SARL    (IMMED(10),REGOFF(0,REG(esp)))
672        ANDL    (IMMED(3),IND_DW_OFF(REG(esp),0))  /* mask two bits */        ANDL    (IMMED(3),REGOFF(0,REG(esp)))  /* mask two bits */
673        MOVL    (IND_DW_OFF(REG(esp),0),REG(eax))  /* return rounding mode */        MOVL    (REGOFF(0,REG(esp)),REG(eax))  /* return rounding mode */
674        ADDL    (IMMED(4),REG(esp))                /* deallocate space */        ADDL    (IMMED(4),REG(esp))                /* deallocate space */
675        RET        RET
676    
677  ENTRY(fesetround)  ENTRY(fesetround)
678        SUBL    (IMMED(4),REG(esp))                /* allocate temporary space */        SUBL    (IMMED(4),REG(esp))                /* allocate temporary space */
679        FSTCW   IND_W_OFF(REG(esp),0)              /* store fp control word */        FSTCW   REGOFF(0,REG(esp))        /* store fp control word */
680          /* Clear rounding field. */          /* Clear rounding field. */
681        ANDW    (IMMED(HEXLIT(f3ff)),IND_W_OFF(REG(esp),0))        ANDW    (IMMED(HEXLIT(f3ff)),REGOFF(0,REG(esp)))
682        MOVL    (IND_DW_OFF(REG(esp),8),REG(eax))  /* new rounding mode */        MOVL    (REGOFF(8,REG(esp)),REG(eax))     /* new rounding mode */
683        SALL    (IMMED(10),REG(eax))               /* move to right place */        SALL    (IMMED(10),REG(eax))               /* move to right place */
684        ORL     (REG(eax),IND_DW_OFF(REG(esp)))    /* new control word */        ORL     (REG(eax),REGOFF(0,REG(esp)))     /* new control word */
685        FLDCW   IND_W_OFF(REG(esp),0)              /* load new control word */        FLDCW   REGOFF(0,REG(esp))                /* load new control word */
686        ADDL    (IMMED(4),REG(esp))                /* deallocate space */        ADDL    (IMMED(4),REG(esp))                /* deallocate space */
687        RET        RET
688    
 /* Save the state of the floating point unit. */  
 ENTRY(savefpregs)  
         MOVL    (IND_DW_OFF(REG(esp),4), temp)  /* Get pointer argument. */  
         fsave   IND_DW_OFF(temp,0)  
         RET  
   
 /* Restore the state of the floating point unit. */  
 ENTRY(restorefpregs)  
         MOVL    (IND_DW_OFF(REG(esp),4), temp)  /* Arg is an ML string. */  
         frstor  IND_DW_OFF(temp,0)  
         RET  
689    
690  /* floor : real -> int  /* floor : real -> int
691     Return the nearest integer that is less or equal to the argument.     Return the nearest integer that is less or equal to the argument.
# Line 876  Line 702 
702          MOVW    (REG(ax), new_controlwd)          MOVW    (REG(ax), new_controlwd)
703          fldcw   new_controlwd           /* Install new control word. */          fldcw   new_controlwd           /* Install new control word. */
704    
705          FLDL    IND_OFF(REAL8,stdarg,0) /* Load argument. */          FLDD    REGOFF(0,stdarg)
706          SUBL    (IMMED(4), REG(esp))          SUBL    (IMMED(4), REG(esp))
707          FISTPL  IND_DW_OFF(REG(esp),0)  /* Round, store, and pop. */          FISTPL  REGOFF(0,REG(esp))
708          POPL    stdarg          POPL    stdarg
709          SALL    (IMMED(1), stdarg)      /* Tag the resulting integer. */          SALL    (IMMED(1),stdarg)
710          INCL    stdarg          INCL    stdarg
711    
712          fldcw   old_controlwd           /* Restore old FP control word. */          FLDCW   old_controlwd
713          CONTINUE          CONTINUE
714    
715    
716  /* logb : real -> int  /* logb : real -> int
717   * Extract the unbiased exponent pointed to by stdarg.   * Extract the unbiased exponent pointed to by stdarg.
718   * 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.
719   */   */
720  ML_CODE_HDR(logb_a)  ML_CODE_HDR(logb_a)
721          MOVL    (IND_DW_OFF(stdarg,4),temp) /* msb for little endian arch */          MOVL    (REGOFF(4,stdarg),temp) /* msb for little endian arch */
722          SARL    (IMMED(20),temp)            /* throw out 20 bits */          SARL    (IMMED(20),temp)            /* throw out 20 bits */
723          ANDL    (IMMED(HEXLIT(7ff)),temp)   /* clear all but 11 low bits */          ANDL    (IMMED(HEXLIT(7ff)),temp)   /* clear all but 11 low bits */
724          SUBL    (IMMED(1023),temp)          /* unbias */          SUBL    (IMMED(1023),temp)          /* unbias */
# Line 908  Line 735 
735   * caller-save, so we can use it here (see x86/x86.sml). */   * caller-save, so we can use it here (see x86/x86.sml). */
736    
737  ML_CODE_HDR(scalb_a)  ML_CODE_HDR(scalb_a)
738          CHECKLIMIT(FUN_MASK)          CHECKLIMIT
739          PUSHL   IND_DW_OFF(stdarg,4)            /* Get copy of scalar. */          PUSHL   REGOFF(4,stdarg)                /* Get copy of scalar. */
740          SARL    (IMMED(1),IND_DW_OFF(REG(esp),0))       /* Untag it. */          SARL    (IMMED(1),REGOFF(0,REG(esp)))   /* Untag it. */
741          FILDL   IND_DW_OFF(REG(esp),0)                  /* Load it ... */          FILDL   REGOFF(0,REG(esp))                      /* Load it ... */
742          fstp    FP_REG(st)(1)                   /* ... into 1st FP reg. */  /*      fstp    FP_REG(st)(1) */                /* ... into 1st FP reg. */
743          ADDL    (IMMED(4), REG(esp))            /* Discard copy of scalar. */  /*      ADDL    (IMMED(4), REG(esp)) */         /* Discard copy of scalar. */
744    
745          MOVL    (IND_DW_OFF(stdarg,0), temp)    /* Get pointer to real. */          MOVL    (REGOFF(0,stdarg), temp)        /* Get pointer to real. */
746          FLDL    IND_OFF(REAL8,temp,0)           /* Load it into temp. */          FLDD    REGOFF(0,temp))                 /* Load it into temp. */
747    
748          fscale                          /* Multiply exponent by scalar. */          fscale                          /* Multiply exponent by scalar. */
749          MOVL    (IMMED(DESC_reald), IND_DW_OFF(allocptr,0))          MOVL    (IMMED(DESC_reald), REGOFF(0,allocptr))
750          FSTPL   IND_OFF(REAL8,allocptr,4)       /* Store resulting float. */          FSTPD   REGOFF(4,allocptr)      /* Store resulting float. */
751          ADDL    (IMMED(4),allocptr)             /* Allocate word for tag. */          ADDL    (IMMED(4),allocptr)             /* Allocate word for tag. */
752          MOVL    (allocptr, stdarg)      /* Return a pointer to the float. */          MOVL    (allocptr, stdarg)      /* Return a pointer to the float. */
753          ADDL    (IMMED(8), allocptr)            /* Allocate room for float. */          ADDL    (IMMED(8), allocptr)            /* Allocate room for float. */
754            FSTPD   (REGOFF(0,REG(esp))     /* ?? */
755            ADDL    (IMMED(4),REG(esp))     /* discard copy of scalar */
756          CONTINUE          CONTINUE
757    
758  END  END
759    
760  /* end of X86.prim.masm (MS assembler) */  /* end of X86.prim.masm (MS assembler) */
   
   

Legend:
Removed from v.1316  
changed lines
  Added in v.1317

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