/* src/vm/jit/arm/md-abi.c - functions for arm ABI
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ Copyright (C) 1996-2005, 2006, 2007 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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Michael Starzinger
-
- Changes: Christian Thalinger
-
- $Id: md-abi.c 6548 2006-10-01 22:18:38Z edwin $
-
*/
#include "vm/jit/arm/md-abi.h"
-#include "vm/descriptor.h"
#include "vm/global.h"
+
#include "vm/jit/abi.h"
+#include "vmcore/descriptor.h"
+
/* register descripton array **************************************************/
REG_END
};
+const char *abi_registers_integer_name[] = {
+ "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4",
+ "v5", "t3", "t1", "t2", "ip", "sp", "lr", "pc",
+};
+
+const s4 abi_registers_integer_argument[] = {
+ 0, /* a0 */
+ 1, /* a1 */
+ 2, /* a2 */
+ 3, /* a3 */
+ REG_SPLIT,
+};
+
+const s4 abi_registers_integer_saved[] = {
+ 4, /* s0 */
+ 5, /* s1 */
+ 6, /* s2 */
+ 7, /* s3 */
+ 8, /* s4 */
+};
+
+const s4 abi_registers_integer_temporary[] = {
+ -1,
+};
+
+
#if defined(ENABLE_SOFTFLOAT)
s4 nregdescfloat[] = {
REG_RES, REG_RES, REG_RES, REG_RES,
};
#endif /* defined(ENABLE_SOFTFLOAT) */
+const s4 abi_registers_float_argument[] = {
+ -1,
+};
+
+const s4 abi_registers_float_saved[] = {
+ -1,
+};
+
+const s4 abi_registers_float_temporary[] = {
+#if defined(ENABLE_SOFTFLOAT)
+ -1,
+#else
+ 0, /* ft0 */
+ 1, /* ft1 */
+ 2, /* ft2 */
+ 3, /* ft3 */
+ 4, /* ft4 */
+ 5, /* ft5 */
+#endif
+};
+
/* md_param_alloc **************************************************************
s4 stacksize;
/* set default values */
- reguse = 0;
+
+ reguse = 0;
stacksize = 0;
/* get params field of methoddesc */
+
pd = md->params;
for (i = 0; i < md->paramcount; i++, pd++) {
case TYPE_FLT:
if (reguse < INT_ARG_CNT) {
pd->inmemory = false;
- pd->regoff = reguse;
+ pd->index = reguse;
+ pd->regoff = abi_registers_integer_argument[reguse];
reguse++;
}
else {
pd->inmemory = true;
- pd->regoff = stacksize;
+ pd->index = stacksize;
+ pd->regoff = stacksize * 8;
stacksize++;
}
break;
case TYPE_LNG:
case TYPE_DBL:
- if (reguse+1 < INT_ARG_CNT) {
+ /* interally we use the EABI */
+
+ ALIGN_2(reguse);
+
+ if (reguse < INT_ARG_CNT) {
pd->inmemory = false;
#if defined(__ARMEL__)
- pd->regoff = PACK_REGS(reguse, reguse+1);
+ pd->index = PACK_REGS(reguse, reguse + 1);
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[reguse],
+ abi_registers_integer_argument[reguse + 1]);
#else
- pd->regoff = PACK_REGS(reguse+1, reguse);
+ pd->index = PACK_REGS(reguse + 1, reguse);
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[reguse + 1],
+ abi_registers_integer_argument[reguse]);
#endif
reguse += 2;
}
- else if (reguse < INT_ARG_CNT) {
+ else {
+
+ /*ALIGN_2(stacksize);*/
+
+ pd->inmemory = true;
+ pd->index = stacksize;
+ pd->regoff = stacksize * 8;
+ /*stacksize += 2;*/
+ stacksize++;
+ }
+ break;
+ }
+ }
+
+ /* Since R0/R1 (==A0/A1) are used for passing return values, this
+ argument register usage has to be regarded, too. */
+
+ if (md->returntype.type != TYPE_VOID) {
+ if (!IS_2_WORD_TYPE(md->returntype.type)) {
+ if (reguse < 1)
+ reguse = 1;
+ }
+ else {
+ if (reguse < 2)
+ reguse = 2;
+ }
+ }
+
+ /* fill register and stack usage */
+
+ md->argintreguse = reguse;
+ md->argfltreguse = 0;
+ md->memuse = stacksize;
+}
+
+
+/* md_param_alloc_native *******************************************************
+
+ Pre-allocate arguments according the native ABI.
+
+*******************************************************************************/
+
+void md_param_alloc_native(methoddesc *md)
+{
+ paramdesc *pd;
+ s4 i;
+ s4 reguse;
+ s4 stacksize;
+
+ /* set default values */
+
+ reguse = 0;
+ stacksize = 0;
+
+ /* get params field of methoddesc */
+
+ pd = md->params;
+
+ for (i = 0; i < md->paramcount; i++, pd++) {
+ switch (md->paramtypes[i].type) {
+ case TYPE_INT:
+ case TYPE_ADR:
+ case TYPE_FLT:
+ if (reguse < INT_ARG_CNT) {
+ pd->inmemory = false;
+ pd->index = -1;
+ pd->regoff = abi_registers_integer_argument[reguse];
+ reguse++;
+ }
+ else {
+ pd->inmemory = true;
+ pd->index = -1;
+ pd->regoff = stacksize * 4;
+ stacksize++;
+ }
+ break;
+
+ case TYPE_LNG:
+ case TYPE_DBL:
+ if (reguse < (INT_ARG_CNT - 1)) {
+#if defined(__ARM_EABI__)
+ ALIGN_2(reguse);
+#endif
pd->inmemory = false;
#if defined(__ARMEL__)
- pd->regoff = PACK_REGS(reguse, INT_ARG_CNT);
+ pd->index = -1;
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[reguse],
+ abi_registers_integer_argument[reguse + 1]);
#else
- pd->regoff = PACK_REGS(INT_ARG_CNT, reguse);
+ pd->index = -1;
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[reguse + 1],
+ abi_registers_integer_argument[reguse]);
#endif
+ reguse += 2;
+ }
+#if !defined(__ARM_EABI__)
+ else if (reguse < INT_ARG_CNT) {
+ pd->inmemory = false;
+# if defined(__ARMEL__)
+ pd->index = -1;
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[reguse],
+ abi_registers_integer_argument[INT_ARG_CNT]);
+# else
+ pd->index = -1;
+ pd->regoff =
+ PACK_REGS(abi_registers_integer_argument[INT_ARG_CNT],
+ abi_registers_integer_argument[reguse]);
+# endif
reguse++;
stacksize++;
}
+#endif
else {
- pd->inmemory = true;
- pd->regoff = stacksize;
- stacksize += 2;
+#if defined(__ARM_EABI__)
+ ALIGN_2(stacksize);
+#endif
+ pd->inmemory = true;
+ pd->index = -1;
+ pd->regoff = stacksize * 4;
+ reguse = INT_ARG_CNT;
+ stacksize += 2;
}
break;
}