Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / lwp / process.amd64.s
1 /* $Id$ */
2
3 /*
4 * Copyright (c) 2003,2005 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 /* x86_64 Assembly
37 *
38 * By Harald Barth <haba@stacken.kth.se> after looking
39 * at Derek Atkins' i386 routines and realizing that
40 * there were some differences and it was not enough
41 * just renaming the registers.
42 */
43
44 #ifdef HAVE_MACHINE_ASM_H
45 #include <machine/asm.h>
46 #endif
47
48 #include <lwp_elf.h>
49
50 .file "process.s"
51 .data
52 .text
53
54 /*
55 * struct savearea {
56 * char *topstack;
57 * }
58 */
59
60 .set topstack,0
61
62 /*
63 * savecontext(int (*f)(), struct savearea *area1, char *newsp)
64 */
65
66 /*
67 * In spite of passing arguments in registers, gcc first copies the content of the
68 * registers onto the stack. I do not know why gcc does this, but for now I mimic
69 * gcc's behaviour. Here are the offsets the arguments are copied to.
70 */
71 .set f,-8
72 .set area1,-16
73 .set newsp,-24
74
75 .globl _C_LABEL(PRE_Block)
76 .globl _C_LABEL(savecontext)
77
78 ENTRY(savecontext)
79 pushq %rbp /* The frame setup is just like gcc */
80 movq %rsp,%rbp
81 subq $32, %rsp /* make room for args on the stack */
82 movq %rdi, f(%rbp) /* (3*8=24 but increments seem to */
83 movq %rsi, area1(%rbp) /* i multiples of 24, so 32 it is) */
84 movq %rdx, newsp(%rbp) /* and copy them there. */
85
86 movq _C_LABEL(PRE_Block)@GOTPCREL(%rip), %rax
87 movl $1,(%rax) /* Do not allow any interrupts */
88
89 pushq %rsp /* Push all registers onto the stack */
90 pushq %rax /* Probably not _all_ are necessary */
91 pushq %rcx /* but better one too much than one */
92 pushq %rdx /* forgotten */
93 pushq %rbx
94 pushq %rbp
95 pushq %rsi
96 pushq %rdi
97 pushq %r8
98 pushq %r9
99 pushq %r10
100 pushq %r11
101 pushq %r12
102 pushq %r13
103 pushq %r14
104 pushq %r15 /* Btw, the pusha instruction is no more */
105
106 movq area1(%rbp),%rax /* rax = base of savearea */
107 movq %rsp,topstack(%rax) /* area->topstack = rsp */
108 movq newsp(%rbp),%rax /* rax = new sp */
109 cmpq $0,%rax
110 je L1 /* if new sp is 0 then dont change rsp */
111 movq %rax,%rsp /* Change rsp to the new sp */
112 L1:
113 jmp *f(%rbp) /* jump to function pointer passed in arg */
114
115 /* Shouldnt be here....*/
116 call _C_LABEL(abort)
117
118 /*
119 * returnto(struct savearea *area2)
120 */
121
122 /* Offset where we put arg - se savecontext */
123 .set area2,-8
124
125 .globl _C_LABEL(returnto)
126
127 ENTRY(returnto)
128 pushq %rbp /* New frame, gcc style */
129 movq %rsp, %rbp /* See savecontext above */
130 subq $16, %rsp /* Make room for 2 args */
131 movq %rdi, area2(%rbp) /* use room to copy 1 arg */
132 movq area2(%rbp),%rax /* rax = area2 */
133 movq topstack(%rax),%rsp /* restore rsp from place relative rbp*/
134
135 popq %r15 /* Restore regs */
136 popq %r14
137 popq %r13
138 popq %r12
139 popq %r11
140 popq %r10
141 popq %r9
142 popq %r8
143 popq %rdi
144 popq %rsi
145 popq %rbp
146 popq %rbx
147 popq %rdx
148 popq %rcx
149 popq %rax
150 popq %rsp /* See savecontext */
151
152 movq _C_LABEL(PRE_Block)@GOTPCREL(%rip), %rax
153 movl $0,(%rax)
154 addq $32, %rsp /* We did rsp-32 above, correct that */
155 popq %rbp
156 ret
157
158 /* We never should get here, put in emergency brake as in i386 code */
159 pushq $1234
160 call _C_LABEL(abort)
161
162 #if defined(__linux__) && defined(__ELF__)
163 .section .note.GNU-stack,"",%progbits
164 #endif