⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysdepcallmethod.h

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 H
字号:
/* * s390/sysdepCallMethod.h (cloned from s390/common.h by ROSSP) * Common s390 configuration information. * * Copyright (c) 1996, 1997, 1998, 1999 * Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2003 * Kaffe.org contributors. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#ifndef __s390_sysdepCallMethod_h#define __s390_sysdepCallMethod_h#include "support.h"/* * Make a call to a native or Java (JIT) method. *  This assembly code should build a standard C call using the passed *  call information.  By its nature this is highly processor specific. *  This function is mandatory for both JIT and Interpreter (since stubs *  have now been deprecated). */#if NEED_sysdepCallMethod/* * The calling convention is as follows: * * Up to the first five up-to-32-bit integer values are passed in general * purpose registers 2 through 6, and the remainder go on the stack.   * Types shorter than 32 bits (i.e. byte, boolean, char and short) are  * promoted to 32 bits (i.e. to int). * * 64-bit integer values are intermingled with 32-bit values in the * order they appear in the argument list, and are passed in pairs of * registers (NOT even/odd pairs, just pairs) or on the stack.  If there  * is only one register available and the next integer argument is a * 64-bit value, that register is unused and all the remaining integer * values are passed on the stack. * * Floating point values are passed in floating point registers 0 and 2, * and then on the stack. *  * Function results are returned in GPR 2 (up-to-32-bit integer), GPRS 2 * and 3 (64-bit integer) or FPR 2 (floating point). *  * Values on the stack are intermingled in the order they appear. * * Based on implementation in config/arm/common.h, with guidance from * <http://ww2.biglobe.ne.jp/~inaba/sysdepCallMethod.html>,  * /usr/src/linux/Documentation/Debugging390.txt, and analysis of * assorted test programs compiled with gcc 2.95.2+IBM S/390 patches and * decompiled with objdump. * * Ross Patterson <Ross.Patterson@CA.Com> * Computer Associates International, Inc. */static inline void sysdepCallMethod(callMethodInfo *call){ /*  * argl is placed here to exploit a gcc artifact: the first  * automatic variable defined is placed at the lowest address on the  * stack frame.  Thus by judicious fiddling of the stack pointer,  * argl becomes the argument list to the callee function.  This  * is explained nicely at the URL above.  */  int argl[(CALL)->nrargs];                /* outgoing args on stack */  union {                                             /* fp reg args */      float f;      double d;        } fpr_args[2];  int gpr_args[5] = {0, 0, 0, 0, 0};                  /* gp reg args */    {      int *out_args = argl;                /* outgoing args on stack */      int argidx = {0};                           /* input arg index */      int fpr_argc = {0};                        /* fp reg arg count */      int gpr_argc = {0};                        /* gp reg arg count */      for(; argidx < (CALL)->nrargs; ++argidx) {         DBG(SYSDEPCALLMETHOD,             printf("sysdepCallMethod: arg[%2d]=%c/%d  V=%8x %8x\n",                    argidx, (CALL)->calltype[argidx],                    (CALL)->callsize[argidx],                    (&(CALL)->args[argidx].i)[0],                    (&(CALL)->args[argidx].i)[1]);            )         if ((CALL)->callsize[argidx] != 0) { /* if non-empty, copy: */           switch ((CALL)->calltype[argidx]) {           case 'B':                          /* 8-bit byte          */           case 'Z':                          /* 8-bit boolean       */           case 'C':                          /* 16-bit char         */           case 'S':                          /* 16-bit int          */           case 'I':                          /* 32-bit int          */           case 'L':                          /* 32-bit objectref    */             if (gpr_argc < 5)       /* if any gp regs left, use one */                gpr_args[gpr_argc++] = (CALL)->args[argidx].i;             else          /* otherwise, put it on the outgoing list */               *out_args++ = (CALL)->args[argidx].i;             break;           case 'J':                          /* 64-bit int          */             if (gpr_argc < 4) {    /* if two gp regs left, use them */                gpr_args[gpr_argc++] = (&(CALL)->args[argidx].i)[0];                gpr_args[gpr_argc++] = (&(CALL)->args[argidx].i)[1];             }             else {        /* otherwise, put it on the outgoing list */               *out_args++ = (&(CALL)->args[argidx].i)[0];               *out_args++ = (&(CALL)->args[argidx].i)[1];               if (gpr_argc == 4)                  gpr_argc++;        /* do not use last gpr for args */             }             break;           case 'F':                          /* 32-bit float        */             if (fpr_argc < 2)       /* if any fp regs left, use one */                fpr_args[fpr_argc++].f = (CALL)->args[argidx].f;             else          /* otherwise, put it on the outgoing list */               *out_args++ = (CALL)->args[argidx].i;             break;           case 'D':                          /* 64-bit float        */             if (fpr_argc < 2)       /* if any fp regs left, use one */                fpr_args[fpr_argc++].d = (CALL)->args[argidx].d;             else {        /* otherwise, put it on the outgoing list */               *out_args++ = (&(CALL)->args[argidx].i)[0];               *out_args++ = (&(CALL)->args[argidx].i)[1];             }             break;           default:             printf("sysdepCallMethod: unknown arg[%d] type %c\n",                argidx, ((CALL)->calltype[argidx]));           } /* switch ((CALL)->calltype[argidx]) */         } /* if ((CALL)->callsize[argidx] != 0) */      } /* for(; argidx < (CALL)->nrargs; ++argidx) */    }    asm (" \n""     ld    0,0(,%2)                        # Load fpr args         \n""     ld    2,8(,%2)                        #    into regs 0-2.     \n""     lm    2,6,0(%1)                       # Load gpr args into 2-6\n""     basr 14,%0                            # Call the routine.     \n""     stm   2,3,0(%1)                       # Save int result.      \n""     std   0,0(,%2)                        # Save float result.    \n""     "        :                                     /* sets these          */        : "ra" ((CALL)->function),            /* uses these          */          "ra" (gpr_args),          "ra" (fpr_args)        : "cc",                               /* clobbers these      */          "0", "1", "2", "3", "4", "5", "6", "7",                                        "14",          "16", "17", "18", "19",       "21",       "23",          "24", "25", "26", "27", "28", "29", "30", "31",          "memory"              /* just gpr_args[0..1] & fpr_args[0] */   );        DBG(SYSDEPCALLMETHOD,            printf("sysdepCallMethod: rettype=%c/%d R2=%8x R3=%8x F0=%8x %8x\n",                   (CALL)->rettype, (CALL)->retsize, gpr_args[0],                   gpr_args[1], ((int *)&fpr_args)[0],                   ((int *)&fpr_args)[1]);        )    switch ((CALL)->rettype) {                /* what kind of retval?*/    case 'D':                                 /* 64-bit float        */       (CALL)->ret->d = fpr_args[0].d;       break;    case 'F':                                 /* 32-bit float        */       (CALL)->ret->f = fpr_args[0].f;       break;    case 'J':                                 /* 64-bit int          */       (&(CALL)->ret->i)[1] = gpr_args[1];    default:                                  /* all shorter types   */       (CALL)->ret->i = gpr_args[0];    } /* switch ((CALL)->rettype) */}#endif /* NEED_sysdepCallMethod */#endif /* __s390_sysdepCallMethod_h */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -