X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fmd-abi.c;h=d20d0d19e90a68dd57a83c9024981050930ad9a7;hb=fa3fb41985bc911b5300f144b740159ac0c1eea0;hp=06bf85251387ef7831bd478d77e4541accb8037a;hpb=ad92477479aeed17382996ab43a7ca0dfab2ba93;p=cacao.git diff --git a/src/vm/jit/mips/md-abi.c b/src/vm/jit/mips/md-abi.c index 06bf85251..d20d0d19e 100644 --- a/src/vm/jit/mips/md-abi.c +++ b/src/vm/jit/mips/md-abi.c @@ -1,9 +1,7 @@ /* src/vm/jit/mips/md-abi.c - functions for MIPS ABI - Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,24 +20,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Christian Thalinger - - Changes: Christian Ullrich - - $Id: md-abi.c 4357 2006-01-22 23:33:38Z twisti $ - */ #include "config.h" + +#include +#include + #include "vm/types.h" #include "vm/jit/mips/md-abi.h" -#include "vm/descriptor.h" +#include "mm/memory.hpp" + +#include "vm/descriptor.hpp" #include "vm/global.h" +#include "vm/method.hpp" + +#include "vm/jit/abi.h" +#include "vm/jit/stack.h" /* register descripton array **************************************************/ @@ -56,6 +56,44 @@ s4 nregdescint[] = { REG_END }; +const char *abi_registers_integer_name[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" +}; + +const s4 abi_registers_integer_argument[] = { + 4, /* a0 */ + 5, /* a1 */ + 6, /* a2 */ + 7, /* a3 */ + 8, /* a4 */ + 9, /* a5 */ + 10, /* a6 */ + 11, /* a7 */ +}; + +const s4 abi_registers_integer_saved[] = { + 16, /* s0 */ + 17, /* s1 */ + 18, /* s2 */ + 19, /* s3 */ + 20, /* s4 */ + 21, /* s5 */ + 22, /* s6 */ + 23, /* s7 */ +}; + +const s4 abi_registers_integer_temporary[] = { + 12, /* t0 */ + 13, /* t1 */ + 14, /* t2 */ + 15, /* t3 */ + 24, /* t4 */ +}; + + s4 nregdescfloat[] = { /* fv0, ftmp1, ftmp2, ftmp3, ft0, ft1, ft2, ft3, */ REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, @@ -72,6 +110,43 @@ s4 nregdescfloat[] = { REG_END }; +const s4 abi_registers_float_argument[] = { + 12, /* fa0 */ + 13, /* fa1 */ + 14, /* fa2 */ + 15, /* fa3 */ + 16, /* fa4 */ + 17, /* fa5 */ + 18, /* fa6 */ + 19, /* fa7 */ +}; + +const s4 abi_registers_float_saved[] = { + 24, /* fs0 */ + 26, /* fs1 */ + 28, /* fs2 */ + 30, /* fs3 */ +}; + +const s4 abi_registers_float_temporary[] = { + 4, /* ft0 */ + 5, /* ft1 */ + 6, /* ft2 */ + 7, /* ft3 */ + 8, /* ft4 */ + 9, /* ft5 */ + 10, /* ft6 */ + 11, /* ft7 */ + 20, /* ft8 */ + 21, /* ft9 */ + 22, /* ft10 */ + 23, /* ft11 */ + 25, /* ft12 */ + 27, /* ft13 */ + 29, /* ft14 */ + 31, /* ft15 */ +}; + #else /* SIZEOF_VOID_P == 8 */ /* MIPS32 */ @@ -92,6 +167,43 @@ s4 nregdescint[] = { REG_END }; +const char *abi_registers_integer_name[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" +}; + +const s4 abi_registers_integer_argument[] = { + 4, /* a0 */ + 5, /* a1 */ + 6, /* a2 */ + 7, /* a3 */ +}; + +const s4 abi_registers_integer_saved[] = { + 16, /* s0 */ + 17, /* s1 */ + 18, /* s2 */ + 19, /* s3 */ + 20, /* s4 */ + 21, /* s5 */ + 22, /* s6 */ + 23, /* s7 */ +}; + +const s4 abi_registers_integer_temporary[] = { + 8, /* t0 */ + 9, /* t1 */ + 10, /* t2 */ + 11, /* t3 */ + 12, /* t4 */ + 13, /* t5 */ + 14, /* t6 */ + 15, /* t7 */ +}; + + #if !defined(ENABLE_SOFT_FLOAT) s4 nregdescfloat[] = { @@ -110,6 +222,28 @@ s4 nregdescfloat[] = { REG_END }; +const s4 abi_registers_float_argument[] = { + 12, /* fa0 */ + 14, /* fa1 */ +}; + +const s4 abi_registers_float_saved[] = { + 20, /* fs0 */ + 22, /* fs1 */ + 24, /* fs2 */ + 26, /* fs3 */ + 28, /* fs4 */ + 30, /* fs5 */ +}; + +const s4 abi_registers_float_temporary[] = { + 8, /* ft0 */ + 10, /* ft1 */ + 16, /* ft2 */ + 18, /* ft3 */ +}; + + #else /* !defined(ENABLE_SOFT_FLOAT) */ s4 nregdescfloat[] = { @@ -123,7 +257,7 @@ s4 nregdescfloat[] = { /* md_param_alloc ************************************************************** - XXX + Pre-allocate arguments according to the internal JIT ABI. *******************************************************************************/ @@ -136,88 +270,407 @@ void md_param_alloc(methoddesc *md) /* set default values */ - reguse = 0; - stacksize = 0; + reguse = 0; + stacksize = 0; /* get params field of methoddesc */ pd = md->params; +#if SIZEOF_VOID_P == 8 + for (i = 0; i < md->paramcount; i++, pd++) { switch (md->paramtypes[i].type) { case TYPE_INT: case TYPE_ADR: case TYPE_LNG: - if (i < INT_ARG_CNT) { + if (reguse < INT_ARG_CNT) { pd->inmemory = false; - pd->regoff = reguse; + pd->regoff = abi_registers_integer_argument[reguse]; reguse++; md->argintreguse = reguse; - } else { + } + else { pd->inmemory = true; - pd->regoff = stacksize; + pd->regoff = stacksize * 8; stacksize++; } break; + case TYPE_FLT: case TYPE_DBL: - if (i < FLT_ARG_CNT) { + if (reguse < FLT_ARG_CNT) { pd->inmemory = false; - pd->regoff = reguse; + pd->regoff = abi_registers_float_argument[reguse]; reguse++; md->argfltreguse = reguse; - } else { + } + else { + pd->inmemory = true; + pd->regoff = stacksize * 8; + stacksize++; + } + break; + } + + /* register type is the same as java type */ + + pd->type = md->paramtypes[i].type; + } + +#else /* SIZEOF_VOID_P == 8 */ + +# if !defined(ENABLE_SOFT_FLOAT) + + /* Set stacksize to 2, as 4 32-bit argument registers can be + stored. */ + /* XXX maybe this should be done in stack.c? */ + + stacksize = 2; + + for (i = 0; i < md->paramcount; i++, pd++) { + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_ADR: + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; + pd->index = reguse; + pd->regoff = abi_registers_integer_argument[reguse]; + reguse++; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->index = stacksize; + pd->regoff = stacksize * 8; + stacksize++; + } + break; + + case TYPE_LNG: + ALIGN_2(reguse); + + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; +# if WORDS_BIGENDIAN == 1 + pd->index = PACK_REGS(reguse + 1, reguse); + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse + 1], + abi_registers_integer_argument[reguse]); +# else + pd->index = PACK_REGS(reguse, reguse + 1); + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse], + abi_registers_integer_argument[reguse + 1]); +# endif + reguse += 2; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->index = stacksize; + pd->regoff = stacksize * 8; + stacksize++; + } + break; + + case TYPE_FLT: + case TYPE_DBL: + if (reguse < FLT_ARG_CNT) { + pd->inmemory = false; + pd->index = reguse; + pd->regoff = abi_registers_float_argument[reguse]; + reguse++; + md->argfltreguse = reguse; + } + else { + pd->inmemory = true; + pd->index = stacksize; + pd->regoff = stacksize * 8; + stacksize++; + } + break; + } + + /* register type is the same as java type */ + + pd->type = md->paramtypes[i].type; + } + +# else /* !defined(ENABLE_SOFT_FLOAT) */ +# error never actually tested! + + for (i = 0; i < md->paramcount; i++, pd++) { + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_ADR: + case TYPE_FLT: + pd->type = TYPE_INT; + + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; + pd->regoff = abi_registers_integer_argument[reguse]; + reguse++; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->regoff = stacksize * 8; + } + stacksize++; + break; + + case TYPE_LNG: + case TYPE_DBL: + pd->type = TYPE_LNG; + + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; +# if WORDS_BIGENDIAN == 1 + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse + 1], + abi_registers_integer_argument[reguse]); +# else + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse], + abi_registers_integer_argument[reguse + 1]); +# endif + reguse += 2; + md->argintreguse = reguse; + } + else { pd->inmemory = true; - pd->regoff = stacksize; + pd->regoff = stacksize * 8; + } + stacksize += 2; + break; + } + } + +# endif /* !defined(ENABLE_SOFT_FLOAT) */ +#endif /* SIZEOF_VOID_P == 8 */ + + /* fill register and stack usage */ + + md->memuse = stacksize; +} + + +/* md_param_alloc_native ******************************************************* + + Pre-allocate arguments according the native ABI. + +*******************************************************************************/ + +void md_param_alloc_native(methoddesc *md) +{ +#if SIZEOF_VOID_P == 8 + + /* On MIPS n64 we use the same ABI for JIT method calls as for + native method calls. */ + + md_param_alloc(md); + +#else /* SIZEOF_VOID_P == 8 */ + + paramdesc *pd; + s4 i; + s4 reguse; + s4 stacksize; +# if !defined(ENABLE_SOFT_FLOAT) + s4 t; + bool a0_is_float; +# endif + + /* set default values */ + + reguse = 0; + stacksize = 0; +# if !defined(ENABLE_SOFT_FLOAT) + a0_is_float = false; +# endif + + /* get params field of methoddesc */ + + pd = md->params; + +# if !defined(ENABLE_SOFT_FLOAT) + + for (i = 0; i < md->paramcount; i++, pd++) { + t = md->paramtypes[i].type; + + if (IS_FLT_DBL_TYPE(t) && + ((i == 0) || + ((i == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type)))) { + if (IS_2_WORD_TYPE(t)) { + pd->type = TYPE_DBL; + pd->regoff = abi_registers_float_argument[reguse]; + reguse++; + stacksize += 2; + } + else { + pd->type = TYPE_FLT; + pd->regoff = abi_registers_float_argument[reguse]; + reguse++; stacksize++; } + md->argfltreguse = reguse; + a0_is_float = true; + } + else { + if (IS_2_WORD_TYPE(t)) { + ALIGN_2(reguse); + pd->type = TYPE_LNG; + + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; +# if WORDS_BIGENDIAN == 1 + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse + 1], + abi_registers_integer_argument[reguse]); +# else + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse], + abi_registers_integer_argument[reguse + 1]); +# endif + reguse += 2; + md->argintreguse = reguse; + } + else { + ALIGN_2(stacksize); + + pd->inmemory = true; + pd->regoff = stacksize * 4; + } + stacksize += 2; + } + else { + pd->type = TYPE_INT; + + if (reguse < INT_ARG_CNT) { + pd->inmemory = false; + pd->regoff = abi_registers_integer_argument[reguse]; + reguse++; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->regoff = stacksize * 4; + } + stacksize++; + } + } + } + +# else /* !defined(ENABLE_SOFT_FLOAT) */ +# error never actually tested! + + for (i = 0; i < md->paramcount; i++, pd++) { + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_ADR: + case TYPE_FLT: + pd->type = TYPE_INT; + + if (i < INT_ARG_CNT) { + pd->inmemory = false; + pd->regoff = abi_registers_integer_argument[reguse]; + reguse++; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->regoff = stacksize * 4; + } + stacksize++; + break; + case TYPE_LNG: + case TYPE_DBL: + pd->type = TYPE_LNG; + + if (i < INT_ARG_CNT) { + pd->inmemory = false; +# if WORDS_BIGENDIAN == 1 + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse + 1], + abi_registers_integer_argument[reguse]); +# else + pd->regoff = + PACK_REGS(abi_registers_integer_argument[reguse], + abi_registers_integer_argument[reguse + 1]); +# endif + reguse += 2; + md->argintreguse = reguse; + } + else { + pd->inmemory = true; + pd->regoff = stacksize * 4; + } + stacksize += 2; break; } } +# endif /* !defined(ENABLE_SOFT_FLOAT) */ + /* fill register and stack usage */ md->memuse = stacksize; + +#endif /* SIZEOF_VOID_P == 8 */ } + /* md_return_alloc ************************************************************* - Precolor the Java Stackelement containing the Return Value. Since mips - has a dedicated return register (not an reused arg or reserved reg), this - is striaghtforward possible, as long, as this stackelement does not have to - survive a method invokation (SAVEDVAR) - ---- in -m: Methodinfo of current method -return_type: Return Type of the Method (TYPE_INT.. TYPE_ADR) - TYPE_VOID is not allowed! -stackslot: Java Stackslot to contain the Return Value - ---- out -if precoloring was possible: -stackslot->varkind =ARGVAR - ->varnum =-1 - ->flags =0 - ->regoff =[REG_RESULT, REG_FRESULT] - + Precolor the Java Stackelement containing the Return Value. Since + mips has a dedicated return register (not an reused arg or reserved + reg), this is striaghtforward possible, as long, as this + stackelement does not have to survive a method invokation + (SAVEDVAR) + + --- in + jd: jitdata of the current method + stackslot: Java Stackslot to contain the Return Value + + --- out + if precoloring was possible: + VAR(stackslot->varnum)->flags = PREALLOC + ->regoff = [REG_RESULT|REG_FRESULT] *******************************************************************************/ -void md_return_alloc(methodinfo *m, registerdata *rd, s4 return_type, - stackptr stackslot) { - /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has not */ - /* to survive method invokations */ + +void md_return_alloc(jitdata *jd, stackelement_t *stackslot) +{ + methodinfo *m; + methoddesc *md; + + /* get required compiler data */ + + m = jd->m; + + md = m->parseddesc; + + /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has + not to survive method invokations. */ + if (!(stackslot->flags & SAVEDVAR)) { - stackslot->varkind = ARGVAR; - stackslot->varnum = -1; - stackslot->flags = 0; - if ( IS_INT_LNG_TYPE(return_type) ) { - stackslot->regoff = REG_RESULT; - } else { /* float/double */ - stackslot->regoff = REG_FRESULT; + VAR(stackslot->varnum)->flags = PREALLOC; + + if (IS_INT_LNG_TYPE(md->returntype.type)) { +#if SIZEOF_VOID_P == 4 + if (IS_2_WORD_TYPE(md->returntype.type)) + VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED; + else +#endif + VAR(stackslot->varnum)->vv.regoff = REG_RESULT; } + else + VAR(stackslot->varnum)->vv.regoff = REG_FRESULT; } } + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where @@ -229,4 +682,5 @@ void md_return_alloc(methodinfo *m, registerdata *rd, s4 return_type, * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */