]> git.donarmstrong.com Git - lilypond.git/blob - guile18/qt/md/i386.s
New upstream version 2.19.65
[lilypond.git] / guile18 / qt / md / i386.s
1 /* i386.s -- assembly support. */
2
3 /*
4 // QuickThreads -- Threads-building toolkit.
5 // Copyright (c) 1993 by David Keppel
6 //
7 // Permission to use, copy, modify and distribute this software and
8 // its documentation for any purpose and without fee is hereby
9 // granted, provided that the above copyright notice and this notice
10 // appear in all copies.  This software is provided as a
11 // proof-of-concept and for demonstration purposes; there is no
12 // representation about the suitability of this software for any
13 // purpose. */
14
15 /* NOTE: double-labeled `_name' and `name' for System V compatability.  */
16 /* NOTE: Comment lines start like this one, or with '//' ONLY.  Sorry! */
17
18 /* Callee-save: %esi, %edi, %ebx, %ebp
19 // Caller-save: %eax, %ecx
20 // Can't tell: %edx (seems to work w/o saving it.)
21 //
22 // Assignment:
23 //
24 // See ``i386.h'' for the somewhat unconventional stack layout.  */
25
26
27         .text
28         .align 2
29
30         .globl _qt_abort
31         .globl qt_abort
32         .globl _qt_block
33         .globl qt_block
34         .globl _qt_blocki
35         .globl qt_blocki
36
37 /* These all have the type signature
38 //
39 //      void *blocking (helper, arg0, arg1, new)
40 //
41 // On procedure entry, the helper is at 4(sp), args at 8(sp) and
42 // 12(sp) and the new thread's sp at 16(sp).  It *appears* that the
43 // calling convention for the 8X86 requires the caller to save all
44 // floating-point registers, this makes our life easy.  */
45
46 /* Halt the currently-running thread.  Save it's callee-save regs on
47 // to the stack, 32 bytes.  Switch to the new stack (next == 16+32(sp))
48 // and call the user function (f == 4+32(sp) with arguments: old sp
49 // arg1 (8+32(sp)) and arg2 (12+32(sp)).  When the user function is
50 // done, restore the new thread's state and return.
51 //
52 // `qt_abort' is (currently) an alias for `qt_block' because most of
53 // the work is shared.  We could save the insns up to `qt_common' by
54 // replicating, but w/o replicating we need an inital subtract (to
55 // offset the stack as if it had been a qt_block) and then a jump
56 // to qt_common.  For the cost of a jump, we might as well just do
57 // all the work.
58 //
59 // The helper function (4(sp)) can return a void* that is returned
60 // by the call to `qt_blockk{,i}'.  Since we don't touch %eax in
61 // between, we get that ``for free''.  */
62
63 _qt_abort:
64 qt_abort:
65 _qt_block:
66 qt_block:
67 _qt_blocki:
68 qt_blocki:
69         pushl %ebp              /* Save callee-save, sp-=4. */
70         pushl %esi              /* Save callee-save, sp-=4. */
71         pushl %edi              /* Save callee-save, sp-=4. */
72         pushl %ebx              /* Save callee-save, sp-=4. */
73         movl %esp, %eax         /* Remember old stack pointer. */
74
75 qt_common:
76         movl 32(%esp), %esp     /* Move to new thread. */
77         pushl 28(%eax)          /* Push arg 2. */
78         pushl 24(%eax)          /* Push arg 1. */
79         pushl %eax              /* Push arg 0. */
80         movl 20(%eax), %ebx     /* Get function to call. */
81         call *%ebx              /* Call f. */
82         addl $12, %esp          /* Pop args. */
83
84         popl %ebx               /* Restore callee-save, sp+=4. */
85         popl %edi               /* Restore callee-save, sp+=4. */
86         popl %esi               /* Restore callee-save, sp+=4. */
87         popl %ebp               /* Restore callee-save, sp+=4. */
88         ret                     /* Resume the stopped function. */
89         hlt
90
91
92 /* Start a varargs thread. */
93
94         .globl _qt_vstart
95         .globl qt_vstart
96 _qt_vstart:
97 qt_vstart:
98         pushl %edi              /* Push `pt' arg to `startup'. */
99         call *%ebp              /* Call `startup'. */
100         popl %eax               /* Clean up the stack. */
101
102         call *%ebx              /* Call the user's function. */
103
104         pushl %eax              /* Push return from user's. */
105         pushl %edi              /* Push `pt' arg to `cleanup'. */
106         call *%esi              /* Call `cleanup'. */
107
108         hlt                     /* `cleanup' never returns. */