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 7351 2007-02-13 21:32:36Z 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;
180 pd->regoff = stacksize;
186 if (i < FLT_ARG_CNT) {
187 pd->inmemory = false;
190 md->argfltreguse = reguse;
193 pd->regoff = stacksize;
199 /* register type is the same as java type */
201 pd->type = md->paramtypes[i].type;
203 #else /* SIZEOF_VOID_P == 8 */
205 #if !defined(ENABLE_SOFT_FLOAT)
207 #define ALIGN_2_WORD(s) ((s) & 1) ? ++(s) : (s)
209 t = md->paramtypes[i].type;
211 if (IS_FLT_DBL_TYPE(t) &&
213 ((i == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type)))) {
214 if (IS_2_WORD_TYPE(t)) {
226 md->argfltreguse = reguse;
230 if (IS_2_WORD_TYPE(t)) {
231 ALIGN_2_WORD(reguse);
234 if (reguse < INT_ARG_CNT) {
235 pd->inmemory = false;
236 # if WORDS_BIGENDIAN == 1
237 pd->regoff = PACK_REGS(reguse + 1, reguse);
239 pd->regoff = PACK_REGS(reguse, reguse + 1);
242 md->argintreguse = reguse;
246 pd->regoff = ALIGN_2_WORD(stacksize);
253 if (reguse < INT_ARG_CNT) {
254 pd->inmemory = false;
257 md->argintreguse = reguse;
261 pd->regoff = stacksize;
267 #else /* !defined(ENABLE_SOFT_FLOAT) */
268 #error never actually tested!
270 switch (md->paramtypes[i].type) {
276 if (i < INT_ARG_CNT) {
277 pd->inmemory = false;
280 md->argintreguse = reguse;
283 pd->regoff = stacksize;
291 if (i < INT_ARG_CNT) {
292 pd->inmemory = false;
293 #if WORDS_BIGENDIAN == 1
294 pd->regoff = PACK_REGS(reguse + 1, reguse);
296 pd->regoff = PACK_REGS(reguse, reguse + 1);
299 md->argintreguse = reguse;
302 pd->regoff = stacksize;
309 #endif /* !defined(ENABLE_SOFT_FLOAT) */
311 #endif /* SIZEOF_VOID_P == 8 */
314 /* fill register and stack usage */
316 md->memuse = stacksize;
320 /* md_param_alloc_native *******************************************************
322 Pre-allocate arguments according the native ABI.
324 *******************************************************************************/
326 void md_param_alloc_native(methoddesc *md)
328 /* On MIPS we use the same ABI for JIT method calls as for native
335 /* md_return_alloc *************************************************************
337 Precolor the Java Stackelement containing the Return Value. Since
338 mips has a dedicated return register (not an reused arg or reserved
339 reg), this is striaghtforward possible, as long, as this
340 stackelement does not have to survive a method invokation
344 jd: jitdata of the current method
345 stackslot: Java Stackslot to contain the Return Value
348 if precoloring was possible:
349 VAR(stackslot->varnum)->flags = PREALLOC
350 ->regoff = [REG_RESULT|REG_FRESULT]
352 *******************************************************************************/
354 void md_return_alloc(jitdata *jd, stackptr stackslot)
359 /* get required compiler data */
365 /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has
366 not to survive method invokations. */
368 if (!(stackslot->flags & SAVEDVAR)) {
369 VAR(stackslot->varnum)->flags = PREALLOC;
371 if (IS_INT_LNG_TYPE(md->returntype.type)) {
372 #if SIZEOF_VOID_P == 4
373 if (IS_2_WORD_TYPE(md->returntype.type))
374 VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED;
377 VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
380 VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
386 * These are local overrides for various environment variables in Emacs.
387 * Please do not remove this and leave it at the end of the file, where
388 * Emacs will automagically detect them.
389 * ---------------------------------------------------------------------
392 * indent-tabs-mode: t