* src/vm/jit/sparc64/emit.c: emit_{load,store,copy} changed to switch/case for handli...
[cacao.git] / src / vm / jit / sparc64 / md-abi.c
1 /* src/vm/jit/sparc64/md-abi.c - functions for Sparc ABI
2
3    Copyright (C) 1996-2005, 2006 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.h 4357 2006-01-22 23:33:38Z twisti $
26
27 */
28
29
30 #include "config.h"
31 #include "vm/types.h"
32
33 #include "vm/jit/sparc64/md-abi.h"
34
35 #include "vm/global.h"
36
37 #include "vm/jit/abi.h"
38
39 #include "vmcore/descriptor.h"
40
41 /* temp */
42 #include "mm/memory.h"
43 #include <assert.h>
44
45
46 /* register descripton array **************************************************/
47
48 /* callee point-of-view, after SAVE has been called. */
49 s4 nregdescint[] = {
50         /* zero  itmp1/g1 itmp2/g2 itmp3/g3 temp/g4  temp/g5  sys/g6   sys/g7 */  
51         REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
52         
53         /* o0    o1       o2       o3       o4       pv/o5    sp/o6    ra/o7  */
54         REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_RES, REG_RES, REG_RES,
55         
56         /* l0    l1       l2       l3       l4       l5       l6       l7     */
57         REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
58         
59         /* i0/v0 i1       i2       i3       i4       pv/i5    fp/i6    ra/i7  */
60         REG_RET, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_RES, REG_RES,
61         REG_END
62         
63
64 };
65
66 const char *abi_registers_integer_name[] = {
67                 "zero",  "g1",  "g2",  "g3",  "g4",  "g5",  "g6",  "g7",
68                 "o0",    "o1",  "o2",  "o3",  "o4",  "o5",  "sp",  "o7",
69                 "l0",    "l1",  "l2",  "l3",  "l4",  "l5",  "l6",  "l7",
70                 "i0",    "i1",  "i2",  "i3",  "i4",  "i5",  "fp",  "i7"
71 };
72
73 s4 nregdescfloat[] = {
74         REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
75         REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
76         REG_END
77 };
78
79
80 s4 nat_argintregs[] = {
81         REG_OUT0, REG_OUT1, REG_OUT2, REG_OUT3, REG_OUT4, REG_OUT5
82 };
83
84
85 /* md_param_alloc **************************************************************
86
87    Allocate Arguments to Stackslots according the Calling Conventions
88
89    --- in
90    md->paramcount:           Number of arguments for this method
91    md->paramtypes[].type:    Argument types
92
93    --- out
94    md->params[].inmemory:    Argument spilled on stack
95    md->params[].regoff:      Stack offset or rd->arg[int|flt]regs index
96    md->memuse:               Stackslots needed for argument spilling
97    md->argintreguse:         max number of integer arguments used
98    md->argfltreguse:         max number of float arguments used
99
100 *******************************************************************************/
101
102 void md_param_alloc(methoddesc *md)
103 {
104         paramdesc *pd;
105         s4         i;
106         s4         reguse;
107         s4         stacksize;
108
109         /* set default values */
110
111         reguse = 0;
112         stacksize = 0;
113
114         /* get params field of methoddesc */
115
116         pd = md->params;
117
118         for (i = 0; i < md->paramcount; i++, pd++) {
119                 switch (md->paramtypes[i].type) {
120                 case TYPE_INT:
121                 case TYPE_ADR:
122                 case TYPE_LNG:
123                         if (i < INT_ARG_CNT) {
124                                 pd->inmemory = false;
125                                 pd->regoff = reguse;
126                                 reguse++;
127                                 md->argintreguse = reguse;
128
129                         } else {
130                                 pd->inmemory = true;
131                                 pd->regoff = stacksize;
132                                 stacksize++;
133                         }
134                         break;
135                 case TYPE_FLT:
136                 case TYPE_DBL:
137                         if (i < FLT_ARG_CNT) {
138                                 pd->inmemory = false;
139                                 pd->regoff = reguse;
140                                 reguse++;
141                                 md->argfltreguse = reguse;
142                         } else {
143                                 pd->inmemory = true;
144                                 pd->regoff = stacksize;
145                                 stacksize++;
146                         }
147                         break;
148                 }
149         }
150         
151         /* Since O0 is used for passing return values, this */
152         /* argument register usage has to be regarded, too                        */
153         if (IS_INT_LNG_TYPE(md->returntype.type)) {
154                 if (reguse < 1)
155                         md->argintreguse = 1;
156         }
157
158         /* fill register and stack usage */
159
160         md->memuse = stacksize;
161 }
162
163 /* md_native_param_alloc **************************************************************
164
165    XXX
166
167 *******************************************************************************/
168
169 void md_native_param_alloc(methoddesc *md)
170 {
171         paramdesc *pd;
172         s4         i;
173         s4         reguse;
174         s4         stacksize;
175
176         /* set default values */
177
178         reguse = 0;
179         stacksize = 6;
180
181         /* get params field of methoddesc */
182
183         pd = md->params;
184
185         for (i = 0; i < md->paramcount; i++, pd++) {
186                 switch (md->paramtypes[i].type) {
187                 case TYPE_INT:
188                 case TYPE_ADR:
189                 case TYPE_LNG:
190                         if (i < INT_NATARG_CNT) {
191                                 pd->inmemory = false;
192                                 pd->regoff = reguse;
193                                 reguse++;
194                                 md->argintreguse = reguse;
195
196                         } else {
197                                 pd->inmemory = true;
198                                 pd->regoff = reguse;
199                                 reguse++;
200                                 stacksize++;
201                         }
202                         break;
203                 case TYPE_FLT:
204                 case TYPE_DBL:
205                         if (i < FLT_NATARG_CNT) {
206                                 pd->inmemory = false;
207                                 pd->regoff = reguse;
208                                 reguse++;
209                                 md->argfltreguse = reguse;
210                         } else {
211                                 pd->inmemory = true;
212                                 pd->regoff = reguse;
213                                 reguse++;
214                                 stacksize++;
215                         }
216                         break;
217                 }
218         }
219         
220         /* Since O0 is used for passing return values, this */
221         /* argument register usage has to be regarded, too                        */
222         if (IS_INT_LNG_TYPE(md->returntype.type)) {
223                 if (reguse < 1)
224                         md->argintreguse = 1;
225         }
226
227         /* fill register and stack usage */
228
229         md->memuse = stacksize;
230 }
231
232 /* md_param_alloc_native *******************************************************
233  *
234  *    Pre-allocate arguments according to the native ABI.
235  *
236  *    *******************************************************************************/
237
238 void md_param_alloc_native(methoddesc *md)
239 {
240         /* XXX need to merge this with my hacked solution to the same problem */
241         md_param_alloc(md);
242 }
243
244 /* reg_setup *******************************************************************
245
246    TODO
247
248 *******************************************************************************/
249 #if 0
250 void md_native_reg_setup(jitdata *jd)
251 {
252         methodinfo   *m;
253         registerdata *rd;
254         s4            i;
255
256         /* get required compiler data */
257
258         m  = jd->m;
259         rd = jd->rd;
260
261         /* setup the integer register table */
262
263
264         rd->argintregs = DMNEW(s4, INT_NATARG_CNT);
265         rd->argintreguse = 0;
266
267         for (rd->argintreguse = 0, i = 8; rd->argintreguse < INT_NATARG_CNT; i++) {
268                 rd->argintregs[rd->argintreguse++] = i;
269         }
270         
271         assert(rd->argintreguse == INT_NATARG_CNT);
272                 
273         /* setup the float register table */
274
275         rd->argfltregs = DMNEW(s4, FLT_NATARG_CNT);
276
277         rd->argfltreguse = 0;
278
279
280         for (rd->argfltreguse = 0, i = 0; rd->argfltreguse < FLT_NATARG_CNT; i++) {
281                 rd->argfltregs[rd->argfltreguse++] = i;
282         }
283         assert(rd->argfltreguse == FLT_NATARG_CNT);
284
285 }
286 #endif
287 /* md_return_alloc *************************************************************
288
289   XXX
290
291 *******************************************************************************/
292
293 void md_return_alloc(jitdata *jd, stackptr stackslot)
294 {
295         /* XXX */
296 }
297
298
299 /*
300  * These are local overrides for various environment variables in Emacs.
301  * Please do not remove this and leave it at the end of the file, where
302  * Emacs will automagically detect them.
303  * ---------------------------------------------------------------------
304  * Local variables:
305  * mode: c
306  * indent-tabs-mode: t
307  * c-basic-offset: 4
308  * tab-width: 4
309  * End:
310  */