307cc26787024cf6288343f16cfe0898eef842a1
[cacao.git] / src / vm / jit / x86_64 / md-abi.c
1 /* src/vm/jit/x86_64/md-abi.c - functions for x86_64 Linux ABI
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: md-abi.c 7630 2007-04-02 19:56:14Z twisti $
26
27 */
28
29
30 #include "config.h"
31 #include "vm/types.h"
32
33 #include "vm/jit/x86_64/md-abi.h"
34
35 #include "vm/global.h"
36
37 #include "vm/jit/jit.h" /* for REG_* (maybe can be removed) */
38
39 #include "vmcore/descriptor.h"
40
41
42 /* register descripton array **************************************************/
43
44 s4 nregdescint[] = {
45     REG_RET, REG_ARG, REG_ARG, REG_TMP, REG_RES, REG_SAV, REG_ARG, REG_ARG,
46     REG_ARG, REG_ARG, REG_RES, REG_RES, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
47     REG_END
48 };
49
50 const char *abi_registers_integer_name[] = {
51         "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
52         "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15"
53 };
54
55 const s4 abi_registers_integer_argument[] = {
56         7,  /* a0 */
57         6,  /* a1 */
58         2,  /* a2 */
59         1,  /* a3 */
60         8,  /* a4 */
61         9,  /* a5 */
62 };
63
64 const s4 abi_registers_integer_saved[] = {
65         7,  /* s0 */
66         12, /* s1 */
67         13, /* s2 */
68         14, /* s3 */
69         15, /* s4 */
70 };
71
72 const s4 abi_registers_integer_temporary[] = {
73         3,  /* t0 */
74 };
75
76
77 s4 nregdescfloat[] = {
78     REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
79     REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
80     REG_END
81 };
82
83
84 /* md_param_alloc **************************************************************
85
86    XXX
87
88 *******************************************************************************/
89
90 void md_param_alloc(methoddesc *md)
91 {
92         paramdesc *pd;
93         s4         i;
94         s4         iarg;
95         s4         farg;
96         s4         stacksize;
97
98         /* set default values */
99
100         iarg = 0;
101         farg = 0;
102         stacksize = 0;
103
104         /* get params field of methoddesc */
105
106         pd = md->params;
107
108         for (i = 0; i < md->paramcount; i++, pd++) {
109                 switch (md->paramtypes[i].type) {
110                 case TYPE_INT:
111                 case TYPE_ADR:
112                 case TYPE_LNG:
113                         if (iarg < INT_ARG_CNT) {
114                                 pd->inmemory = false;
115                                 pd->regoff   = iarg;
116                                 iarg++;
117                         }
118                         else {
119                                 pd->inmemory = true;
120                                 pd->regoff   = stacksize;
121                                 stacksize++;
122                         }
123                         break;
124
125                 case TYPE_FLT:
126                 case TYPE_DBL:
127                         if (farg < FLT_ARG_CNT) {
128                                 pd->inmemory = false;
129                                 pd->regoff   = farg;
130                                 farg++;
131                         }
132                         else {
133                                 pd->inmemory = true;
134                                 pd->regoff   = stacksize;
135                                 stacksize++;
136                         }
137                         break;
138                 }
139         }
140
141         /* Since XMM0 (==A0) is used for passing return values, this
142            argument register usage has to be regarded, too. */
143
144         if (IS_FLT_DBL_TYPE(md->returntype.type))
145                 if (farg < 1)
146                         farg = 1;
147
148         /* fill register and stack usage */
149
150         md->argintreguse = iarg;
151         md->argfltreguse = farg;
152         md->memuse       = stacksize;
153 }
154
155
156 /* md_param_alloc_native *******************************************************
157
158    Pre-allocate arguments according the native ABI.
159
160 *******************************************************************************/
161
162 void md_param_alloc_native(methoddesc *md)
163 {
164         /* On x86_64 we use the same ABI for JIT method calls as for
165            native method calls. */
166
167         md_param_alloc(md);
168 }
169
170
171 /* md_return_alloc *************************************************************
172
173    Precolor the Java Stackelement containing the Return Value. Only
174    for float/ double types straight forward possible, since INT_LNG
175    types use "reserved" registers Float/Double values use a00 as
176    return register.
177
178    --- in
179    jd:                      jitdata of the current method
180    stackslot:               Java Stackslot to contain the Return Value
181
182    --- out
183    if precoloring was possible:
184    VAR(stackslot->varnum)->flags     = PREALLOC
185                                      ->vv.regoff = [REG_RESULT|REG_FRESULT]
186    rd->arg[flt|int]reguse   set to a value according the register usage
187
188    NOTE: Do not pass a LOCALVAR in stackslot->varnum.
189
190 *******************************************************************************/
191
192 void md_return_alloc(jitdata *jd, stackptr stackslot)
193 {
194         methodinfo   *m;
195         registerdata *rd;
196         methoddesc   *md;
197
198         /* get required compiler data */
199
200         m  = jd->m;
201         rd = jd->rd;
202
203         md = m->parseddesc;
204
205         /* precoloring only straightforward possible with flt/dbl types
206            For Address/Integer/Long REG_RESULT == rax == REG_ITMP1 and so
207            could be destroyed if the return value Stack Slot "lives too
208            long" */
209
210         if (IS_FLT_DBL_TYPE(md->returntype.type)) {
211                 /* In Leafmethods Local Vars holding parameters are precolored
212                    to their argument register -> so leafmethods with
213                    paramcount > 0 could already use a00! */
214
215                 if (!jd->isleafmethod || (md->paramcount == 0)) {
216                         /* Only precolor the stackslot, if it is not a SAVEDVAR
217                            <-> has not to survive method invokations */
218
219                         if (!(stackslot->flags & SAVEDVAR)) {
220
221                                 VAR(stackslot->varnum)->flags = PREALLOC;
222
223                             /* float/double */
224                                 if (rd->argfltreguse < 1)
225                                         rd->argfltreguse = 1;
226
227                                 VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
228                         }
229                 }
230         }
231 }
232
233
234 /*
235  * These are local overrides for various environment variables in Emacs.
236  * Please do not remove this and leave it at the end of the file, where
237  * Emacs will automagically detect them.
238  * ---------------------------------------------------------------------
239  * Local variables:
240  * mode: c
241  * indent-tabs-mode: t
242  * c-basic-offset: 4
243  * tab-width: 4
244  * End:
245  */