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