* Merged in twisti-branch.
[cacao.git] / src / vm / jit / powerpc64 / linux / md-abi.c
index 6f2dc48b9f291dddf52bdc71eafb8895011668e4..de93995d94d6ed3b0d755a332c7a5ec55805d78a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc64/linux/md-abi.c - functions for PowerPC64 Linux 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: Roland Lezuo
-
-   Changes: 
-
-   $Id: md-abi.c 5634 2006-10-02 14:18:04Z edwin $
+   $Id: md-abi.c 7452 2007-03-04 23:32:24Z twisti $
 
 */
 
 
 #include "config.h"
+
+#include <assert.h>
+
 #include "vm/types.h"
 
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
-#include "vm/descriptor.h"
 #include "vm/global.h"
+
 #include "vm/jit/abi.h"
 
+#include "vmcore/descriptor.h"
+
 
-#define _ALIGN(a)    do { if ((a) & 1) (a)++; } while (0)
+#define CACAO_ALIGN(a)    do { if ((a) & 1) (a)++; } while (0)
 
 
 /* register descripton array **************************************************/
 
 s4 nregdescint[] = {
-       /* zero,      sp,     TOC,   a0/v0,   a0/v1,      a2,      a3,      a4,   */
+       /* zero,      sp,     TOC,   a0/v0,   a1/v1,      a2,      a3,      a4,   */
        REG_RES, REG_RES, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
 
        /*   a5,      a6,      a7,   itmp1,   itmp2, NO(SYS),      pv,      s0,   */
@@ -64,7 +63,7 @@ s4 nregdescint[] = {
        REG_END
 };
 
-char *regs[] = {
+const char *abi_registers_integer_name[] = {
        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
        "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
@@ -76,13 +75,13 @@ s4 nregdescfloat[] = {
        /*ftmp3,  fa0/v0,     fa1,     fa2,     fa3,     fa4,     fa5,     fa6,   */
        REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
 
-       /*  fa7,     ft0,     ft1,     ft2,     ft3,     ft4,     fs0,     fs1,   */
-       REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_SAV, REG_SAV,
+       /*  fa7,     fa8,     fa9,    fa10,    fa11,    fa12,   ftmp1,   ftmp2,   */
+       REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_RES, REG_RES,
 
-       /*ftmp1,   ftmp2,     ft5,     ft6,     ft7,     ft8,     ft9,    ft10,   */
-       REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
+       /*  fs0,     fs1,     fs2,     fs3,     fs4,     fs5,     fs6,     fs7    */
+       REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
 
-       /*  fs2,     fs3,     fs4,     fs5,     fs6,     fs7,     fs8,     fs9    */
+       /*  fs8,     fs9,    fs10,    fs11,    fs12,    fs13,    fs14,    fs15    */
        REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
 
        REG_END
@@ -112,13 +111,17 @@ void md_param_alloc(methoddesc *md)
        s4         i;
        s4         iarg;
        s4         farg;
-       s4         stacksize;
+       s4         arg;
+       s4         stacksize, stackcount;
+
 
        /* set default values */
 
        iarg = 0;
        farg = 0;
-       stacksize = LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS;
+       arg = 0;
+       stacksize = LA_SIZE_IN_POINTERS;
+       stackcount = 0;
 
        /* get params field of methoddesc */
 
@@ -135,37 +138,31 @@ void md_param_alloc(methoddesc *md)
                                iarg++;
                        } else {
                                pd->inmemory = true;
-                               pd->regoff = stacksize;
-                               stacksize++;
+                               pd->regoff = stacksize + stackcount;
                        }
                        break;
                case TYPE_FLT:
-                       if (farg < FLT_ARG_CNT) {
-                               pd->inmemory = false;
-                               pd->regoff = farg;
-                               farg++;
-                       } else {
-                               pd->inmemory = true;
-                               pd->regoff = stacksize;
-                               stacksize++;
-                       }
-                       break;
                case TYPE_DBL:
                        if (farg < FLT_ARG_CNT) {
                                pd->inmemory = false;
                                pd->regoff = farg;
                                farg++;
+                               if (arg < INT_ARG_CNT) {
+                                       iarg++;         /* yes, that is true, floating arguments take int register slots away */
+                               }
                        } else {
-                               _ALIGN(stacksize);
                                pd->inmemory = true;
-                               pd->regoff = stacksize;
-                               stacksize += 2;
+                               pd->regoff = stacksize + stackcount ;
                        }
                        break;
+               default:
+                       assert(0);
                }
+               arg++;
+               stackcount++;
        }
 
-       /* Since R3/R4, F1 (==A0/A1, A0) are used for passing return values, this */
+       /* Since R3, F1 (==A0, A0) are used for passing return values, this */
        /* argument register usage has to be regarded, too                        */
        if (IS_INT_LNG_TYPE(md->returntype.type)) {
                if (iarg < 1)
@@ -175,11 +172,26 @@ void md_param_alloc(methoddesc *md)
                        farg = 1;
        }
 
-       /* fill register and stack usage */
+       /* fill register and stack usage, parameter areas is at least PA_SIZE_IN_POINTERS */
 
        md->argintreguse = iarg;
        md->argfltreguse = farg;
-       md->memuse = stacksize;
+       md->memuse = stacksize + (stackcount<PA_SIZE_IN_POINTERS? PA_SIZE_IN_POINTERS: stackcount);     
+}
+
+
+/* md_param_alloc_native *******************************************************
+
+   Pre-allocate arguments according the native ABI.
+
+*******************************************************************************/
+
+void md_param_alloc_native(methoddesc *md)
+{
+       /* On PowerPC64 we use the same ABI for JIT method calls as for
+          native method calls. */
+
+       md_param_alloc(md);
 }