*** empty log message ***
[arla.git] / lwp / process.x86_64.S
blob4055ecaa5e63e023d2ea7124663e9df5a58871e0
1 /* $Id$ */
3 /*
4  * Copyright (c) 2003 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  */
36 #include <config.h>
38 #undef RCSID
40 /* x86_64 Assembly
41  *
42  * By Harald Barth <haba@stacken.kth.se> after looking
43  * at Derek Atkins' i386 routines and realizing that
44  * there were some differences and it was not enough
45  * just renaming the registers.
46  */
47         
48 #ifdef HAVE_MACHINE_ASM_H
49 #include <machine/asm.h>
50 #endif
52 #include <lwp_elf.h>
53         
54         .file "process.s"
55         .data
56         .text
59  * struct savearea {
60  *    char    *topstack;
61  * }
62  */
64         .set    topstack,0
67  * savecontext(int (*f)(), struct savearea *area1, char *newsp)
68  */
70 /* 
71  * In spite of passing arguments in registers, gcc first copies the content of the
72  * registers onto the stack. I do not know why gcc does this, but for now I mimic
73  * gcc's behaviour. Here are the offsets the arguments are copied to.
74  */
75         .set    f,-8
76         .set    area1,-16
77         .set    newsp,-24
79 .globl          _C_LABEL(PRE_Block)
80 .globl          _C_LABEL(savecontext)
82 ENTRY(savecontext)
83         pushq   %rbp                    /* The frame setup is just like gcc */
84         movq    %rsp,%rbp
85         subq    $32, %rsp               /* make room for args on the stack */
86         movq    %rdi, f(%rbp)           /* (3*8=24 but increments seem to */
87         movq    %rsi, area1(%rbp)       /* i multiples of 24, so 32 it is) */
88         movq    %rdx, newsp(%rbp)       /* and copy them there. */
90         movl    $1,_C_LABEL(PRE_Block)  /* Do not allow any interrupts */
92         pushq   %rsp                    /* Push all registers onto the stack */
93         pushq   %rax                    /* Probably not _all_ are necessary */
94         pushq   %rcx                    /* but better one too much than one */
95         pushq   %rdx                    /* forgotten */
96         pushq   %rbx
97         pushq   %rbp
98         pushq   %rsi
99         pushq   %rdi
100         pushq   %r8
101         pushq   %r9
102         pushq   %r10
103         pushq   %r11
104         pushq   %r12
105         pushq   %r13
106         pushq   %r14
107         pushq   %r15                    /* Btw, the pusha instruction is no more */
109         movq    area1(%rbp),%rax        /* rax = base of savearea */
110         movq    %rsp,topstack(%rax)     /* area->topstack = rsp */
111         movq    newsp(%rbp),%rax        /* rax = new sp */
112         cmpq    $0,%rax
113         je      L1                      /* if new sp is 0 then dont change rsp */
114         movq    %rax,%rsp               /* Change rsp to the new sp */
116         jmp     *f(%rbp)                /* jump to function pointer passed in arg */
118 /* Shouldnt be here....*/
119         call    _C_LABEL(abort)
122  * returnto(struct savearea *area2)
123  */
125 /* Offset where we put arg - se savecontext */
126         .set    area2,-8
128 .globl          _C_LABEL(returnto)
130 ENTRY(returnto)
131         pushq   %rbp                    /* New frame, gcc style */
132         movq    %rsp, %rbp              /* See savecontext above */
133         subq    $16, %rsp               /* Make room for 2 args */
134         movq    %rdi, area2(%rbp)       /* use room to copy 1 arg */
135         movq    area2(%rbp),%rax        /* rax = area2 */
136         movq    topstack(%rax),%rsp     /* restore rsp from place relative rbp*/
138         popq    %r15                    /* Restore regs */
139         popq    %r14
140         popq    %r13
141         popq    %r12
142         popq    %r11
143         popq    %r10
144         popq    %r9
145         popq    %r8
146         popq    %rdi
147         popq    %rsi
148         popq    %rbp
149         popq    %rbx
150         popq    %rdx
151         popq    %rcx
152         popq    %rax
153         popq    %rsp                    /* See savecontext */
154         
155         movl    $0,_C_LABEL(PRE_Block)  /* clear it up... */
156         addq    $32, %rsp               /* We did rsp-32 above, correct that */
157         popq    %rbp
158         ret
159         
160 /* We never should get here, put in emergency brake as in i386 code */
161         pushq   $1234
162         call    _C_LABEL(abort)