1 /* src/vm/jit/mips/md-abi.c - functions for MIPS ABI
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
8 This file is part of CACAO.
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.
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.
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
25 $Id: md-abi.c 7699 2007-04-13 10:42:05Z twisti $
33 #include "vm/jit/mips/md-abi.h"
35 #include "vm/global.h"
37 #include "vm/jit/abi.h"
39 #include "vmcore/descriptor.h"
42 /* register descripton array **************************************************/
44 #if SIZEOF_VOID_P == 8
49 REG_RES, REG_RES, REG_RET, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
50 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
51 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
52 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
56 const char *abi_registers_integer_name[] = {
57 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
58 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
59 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
60 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
64 s4 nregdescfloat[] = {
65 /* fv0, ftmp1, ftmp2, ftmp3, ft0, ft1, ft2, ft3, */
66 REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
68 /* ft4, ft5, ft6, ft7, fa0, fa1, fa2, fa3, */
69 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
71 /* fa4, fa5, fa6, fa7, ft8, ft9, ft10, ft11, */
72 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
74 /* fs0, ft12, fs1, ft13, fs2, ft14, fs3 ft15 */
75 REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP,
80 #else /* SIZEOF_VOID_P == 8 */
85 /* zero, itmp1, v0, v1, a0, a1, a2, a3, */
86 REG_RES, REG_RES, REG_RET, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
88 /* t0, t1, t2, t3, t4, t5, t6, t7, */
89 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
91 /* s0, s1, s2, s3, s4, s5, s6, s7, */
92 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
94 /*itmp2, itmp3, k0(sys), k1(sys), gp, sp, pv, ra */
95 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
100 const char *abi_registers_integer_name[] = {
101 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
102 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
103 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
104 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
108 #if !defined(ENABLE_SOFT_FLOAT)
110 s4 nregdescfloat[] = {
111 /* fv0, ftmp1, ftmp2, ftmp3, */
112 REG_RET, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
114 /* ft0, ft1, fa0, fa1, */
115 REG_TMP, REG_RES, REG_TMP, REG_RES, REG_ARG, REG_RES, REG_ARG, REG_RES,
117 /* ft2, ft3, fs0, fs1, */
118 REG_TMP, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES,
120 /* fs2, fs3, fs4, fs5 */
121 REG_SAV, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES,
126 #else /* !defined(ENABLE_SOFT_FLOAT) */
128 s4 nregdescfloat[] = {
132 #endif /* !defined(ENABLE_SOFT_FLOAT) */
134 #endif /* SIZEOF_VOID_P == 8 */
137 /* md_param_alloc **************************************************************
139 Pre-allocate arguments according to the internal JIT ABI.
141 *******************************************************************************/
143 void md_param_alloc(methoddesc *md)
149 #if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
154 /* set default values */
158 #if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
162 /* get params field of methoddesc */
166 for (i = 0; i < md->paramcount; i++, pd++) {
167 #if SIZEOF_VOID_P == 8
169 switch (md->paramtypes[i].type) {
173 if (i < INT_ARG_CNT) {
174 pd->inmemory = false;
177 md->argintreguse = reguse;
181 pd->regoff = stacksize;
187 if (i < FLT_ARG_CNT) {
188 pd->inmemory = false;
191 md->argfltreguse = reguse;
195 pd->regoff = stacksize;
201 /* register type is the same as java type */
203 pd->type = md->paramtypes[i].type;
205 #else /* SIZEOF_VOID_P == 8 */
207 #if !defined(ENABLE_SOFT_FLOAT)
209 #define ALIGN_2_WORD(s) ((s) & 1) ? ++(s) : (s)
211 t = md->paramtypes[i].type;
213 if (IS_FLT_DBL_TYPE(t) &&
215 ((i == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type)))) {
216 if (IS_2_WORD_TYPE(t)) {
228 md->argfltreguse = reguse;
232 if (IS_2_WORD_TYPE(t)) {
233 ALIGN_2_WORD(reguse);
236 if (reguse < INT_ARG_CNT) {
237 pd->inmemory = false;
238 # if WORDS_BIGENDIAN == 1
239 pd->regoff = PACK_REGS(reguse + 1, reguse);
241 pd->regoff = PACK_REGS(reguse, reguse + 1);
244 md->argintreguse = reguse;
248 pd->regoff = ALIGN_2_WORD(stacksize);
255 if (reguse < INT_ARG_CNT) {
256 pd->inmemory = false;
259 md->argintreguse = reguse;
263 pd->regoff = stacksize;
269 #else /* !defined(ENABLE_SOFT_FLOAT) */
270 #error never actually tested!
272 switch (md->paramtypes[i].type) {
278 if (i < INT_ARG_CNT) {
279 pd->inmemory = false;
282 md->argintreguse = reguse;
286 pd->regoff = stacksize;
294 if (i < INT_ARG_CNT) {
295 pd->inmemory = false;
296 #if WORDS_BIGENDIAN == 1
297 pd->regoff = PACK_REGS(reguse + 1, reguse);
299 pd->regoff = PACK_REGS(reguse, reguse + 1);
302 md->argintreguse = reguse;
306 pd->regoff = stacksize;
313 #endif /* !defined(ENABLE_SOFT_FLOAT) */
315 #endif /* SIZEOF_VOID_P == 8 */
318 /* fill register and stack usage */
320 md->memuse = stacksize;
324 /* md_param_alloc_native *******************************************************
326 Pre-allocate arguments according the native ABI.
328 *******************************************************************************/
330 void md_param_alloc_native(methoddesc *md)
332 /* On MIPS we use the same ABI for JIT method calls as for native
339 /* md_return_alloc *************************************************************
341 Precolor the Java Stackelement containing the Return Value. Since
342 mips has a dedicated return register (not an reused arg or reserved
343 reg), this is striaghtforward possible, as long, as this
344 stackelement does not have to survive a method invokation
348 jd: jitdata of the current method
349 stackslot: Java Stackslot to contain the Return Value
352 if precoloring was possible:
353 VAR(stackslot->varnum)->flags = PREALLOC
354 ->regoff = [REG_RESULT|REG_FRESULT]
356 *******************************************************************************/
358 void md_return_alloc(jitdata *jd, stackptr stackslot)
363 /* get required compiler data */
369 /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has
370 not to survive method invokations. */
372 if (!(stackslot->flags & SAVEDVAR)) {
373 VAR(stackslot->varnum)->flags = PREALLOC;
375 if (IS_INT_LNG_TYPE(md->returntype.type)) {
376 #if SIZEOF_VOID_P == 4
377 if (IS_2_WORD_TYPE(md->returntype.type))
378 VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED;
381 VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
384 VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
390 * These are local overrides for various environment variables in Emacs.
391 * Please do not remove this and leave it at the end of the file, where
392 * Emacs will automagically detect them.
393 * ---------------------------------------------------------------------
396 * indent-tabs-mode: t