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 7713 2007-04-15 21:49:48Z 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"
63 const s4 abi_registers_integer_argument[] = {
74 const s4 abi_registers_integer_saved[] = {
85 const s4 abi_registers_integer_temporary[] = {
94 s4 nregdescfloat[] = {
95 /* fv0, ftmp1, ftmp2, ftmp3, ft0, ft1, ft2, ft3, */
96 REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
98 /* ft4, ft5, ft6, ft7, fa0, fa1, fa2, fa3, */
99 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
101 /* fa4, fa5, fa6, fa7, ft8, ft9, ft10, ft11, */
102 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
104 /* fs0, ft12, fs1, ft13, fs2, ft14, fs3 ft15 */
105 REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP,
110 const s4 abi_registers_float_argument[] = {
121 const s4 abi_registers_float_saved[] = {
128 const s4 abi_registers_float_temporary[] = {
147 #else /* SIZEOF_VOID_P == 8 */
152 /* zero, itmp1, v0, v1, a0, a1, a2, a3, */
153 REG_RES, REG_RES, REG_RET, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
155 /* t0, t1, t2, t3, t4, t5, t6, t7, */
156 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
158 /* s0, s1, s2, s3, s4, s5, s6, s7, */
159 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
161 /*itmp2, itmp3, k0(sys), k1(sys), gp, sp, pv, ra */
162 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
167 const char *abi_registers_integer_name[] = {
168 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
169 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
170 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
171 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
174 const s4 abi_registers_integer_argument[] = {
181 const s4 abi_registers_integer_saved[] = {
192 const s4 abi_registers_integer_temporary[] = {
204 #if !defined(ENABLE_SOFT_FLOAT)
206 s4 nregdescfloat[] = {
207 /* fv0, ftmp1, ftmp2, ftmp3, */
208 REG_RET, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
210 /* ft0, ft1, fa0, fa1, */
211 REG_TMP, REG_RES, REG_TMP, REG_RES, REG_ARG, REG_RES, REG_ARG, REG_RES,
213 /* ft2, ft3, fs0, fs1, */
214 REG_TMP, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES,
216 /* fs2, fs3, fs4, fs5 */
217 REG_SAV, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_RES,
222 const s4 abi_registers_float_argument[] = {
227 const s4 abi_registers_float_saved[] = {
236 const s4 abi_registers_float_temporary[] = {
244 #else /* !defined(ENABLE_SOFT_FLOAT) */
246 s4 nregdescfloat[] = {
250 #endif /* !defined(ENABLE_SOFT_FLOAT) */
252 #endif /* SIZEOF_VOID_P == 8 */
255 /* md_param_alloc **************************************************************
257 Pre-allocate arguments according to the internal JIT ABI.
259 *******************************************************************************/
261 void md_param_alloc(methoddesc *md)
267 #if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
272 /* set default values */
276 #if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
280 /* get params field of methoddesc */
284 for (i = 0; i < md->paramcount; i++, pd++) {
285 #if SIZEOF_VOID_P == 8
287 switch (md->paramtypes[i].type) {
291 if (i < INT_ARG_CNT) {
292 pd->inmemory = false;
293 pd->regoff = abi_registers_integer_argument[reguse];
295 md->argintreguse = reguse;
299 pd->regoff = stacksize;
305 if (i < FLT_ARG_CNT) {
306 pd->inmemory = false;
307 pd->regoff = abi_registers_float_argument[reguse];
309 md->argfltreguse = reguse;
313 pd->regoff = stacksize;
319 /* register type is the same as java type */
321 pd->type = md->paramtypes[i].type;
323 #else /* SIZEOF_VOID_P == 8 */
325 #if !defined(ENABLE_SOFT_FLOAT)
327 #define ALIGN_2_WORD(s) ((s) & 1) ? ++(s) : (s)
329 t = md->paramtypes[i].type;
331 if (IS_FLT_DBL_TYPE(t) &&
333 ((i == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type)))) {
334 if (IS_2_WORD_TYPE(t)) {
336 pd->regoff = abi_registers_float_argument[reguse];
342 pd->regoff = abi_registers_float_argument[reguse];
346 md->argfltreguse = reguse;
350 if (IS_2_WORD_TYPE(t)) {
351 ALIGN_2_WORD(reguse);
354 if (reguse < INT_ARG_CNT) {
355 pd->inmemory = false;
356 # if WORDS_BIGENDIAN == 1
358 PACK_REGS(abi_registers_integer_argument[reguse + 1],
359 abi_registers_integer_argument[reguse]);
362 PACK_REGS(abi_registers_integer_argument[reguse],
363 abi_registers_integer_argument[reguse + 1]);
366 md->argintreguse = reguse;
370 pd->regoff = ALIGN_2_WORD(stacksize);
377 if (reguse < INT_ARG_CNT) {
378 pd->inmemory = false;
379 pd->regoff = abi_registers_integer_argument[reguse];
381 md->argintreguse = reguse;
385 pd->regoff = stacksize;
391 #else /* !defined(ENABLE_SOFT_FLOAT) */
392 #error never actually tested!
394 switch (md->paramtypes[i].type) {
400 if (i < INT_ARG_CNT) {
401 pd->inmemory = false;
402 pd->regoff = abi_registers_integer_argument[reguse];
404 md->argintreguse = reguse;
408 pd->regoff = stacksize;
416 if (i < INT_ARG_CNT) {
417 pd->inmemory = false;
418 #if WORDS_BIGENDIAN == 1
420 PACK_REGS(abi_registers_integer_argument[reguse + 1],
421 abi_registers_integer_argument[reguse]);
424 PACK_REGS(abi_registers_integer_argument[reguse],
425 abi_registers_integer_argument[reguse + 1]);
428 md->argintreguse = reguse;
432 pd->regoff = stacksize;
439 #endif /* !defined(ENABLE_SOFT_FLOAT) */
441 #endif /* SIZEOF_VOID_P == 8 */
444 /* fill register and stack usage */
446 md->memuse = stacksize;
450 /* md_param_alloc_native *******************************************************
452 Pre-allocate arguments according the native ABI.
454 *******************************************************************************/
456 void md_param_alloc_native(methoddesc *md)
458 /* On MIPS we use the same ABI for JIT method calls as for native
465 /* md_return_alloc *************************************************************
467 Precolor the Java Stackelement containing the Return Value. Since
468 mips has a dedicated return register (not an reused arg or reserved
469 reg), this is striaghtforward possible, as long, as this
470 stackelement does not have to survive a method invokation
474 jd: jitdata of the current method
475 stackslot: Java Stackslot to contain the Return Value
478 if precoloring was possible:
479 VAR(stackslot->varnum)->flags = PREALLOC
480 ->regoff = [REG_RESULT|REG_FRESULT]
482 *******************************************************************************/
484 void md_return_alloc(jitdata *jd, stackptr stackslot)
489 /* get required compiler data */
495 /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has
496 not to survive method invokations. */
498 if (!(stackslot->flags & SAVEDVAR)) {
499 VAR(stackslot->varnum)->flags = PREALLOC;
501 if (IS_INT_LNG_TYPE(md->returntype.type)) {
502 #if SIZEOF_VOID_P == 4
503 if (IS_2_WORD_TYPE(md->returntype.type))
504 VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED;
507 VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
510 VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
516 * These are local overrides for various environment variables in Emacs.
517 * Please do not remove this and leave it at the end of the file, where
518 * Emacs will automagically detect them.
519 * ---------------------------------------------------------------------
522 * indent-tabs-mode: t