LCOV - code coverage report
Current view: top level - vm/jit/x86_64 - md-abi.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 49 51 96.1 %
Date: 2015-06-10 18:10:59 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* src/vm/jit/x86_64/md-abi.cpp - functions for x86_64 Linux ABI
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : 
      26             : #include "config.h"
      27             : #include "vm/types.hpp"
      28             : 
      29             : #include "vm/jit/x86_64/md-abi.hpp"
      30             : 
      31             : #include "vm/descriptor.hpp"
      32             : #include "vm/global.hpp"
      33             : #include "vm/method.hpp"
      34             : 
      35             : #include "vm/jit/abi.hpp"
      36             : #include "vm/jit/code.hpp"
      37             : #include "vm/jit/jit.hpp" /* for REG_* (maybe can be removed) */
      38             : #include "vm/jit/stack.hpp"
      39             : 
      40             : 
      41             : /* register descripton array **************************************************/
      42             : 
      43             : s4 nregdescint[] = {
      44             :     REG_RET, REG_ARG, REG_ARG, REG_TMP, REG_RES, REG_SAV, REG_ARG, REG_ARG,
      45             :     REG_ARG, REG_ARG, REG_RES, REG_RES, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
      46             :     REG_END
      47             : };
      48             : 
      49             : const char *abi_registers_integer_name[] = {
      50             :         "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
      51             :         "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15"
      52             : };
      53             : 
      54             : const s4 abi_registers_integer_argument[] = {
      55             :         7,  /* a0 */
      56             :         6,  /* a1 */
      57             :         2,  /* a2 */
      58             :         1,  /* a3 */
      59             :         8,  /* a4 */
      60             :         9,  /* a5 */
      61             : };
      62             : 
      63             : const s4 abi_registers_integer_saved[] = {
      64             :         5,  /* s0 */
      65             :         12, /* s1 */
      66             :         13, /* s2 */
      67             :         14, /* s3 */
      68             :         15, /* s4 */
      69             : };
      70             : 
      71             : const s4 abi_registers_integer_temporary[] = {
      72             :         3,  /* t0 */
      73             : };
      74             : 
      75             : 
      76             : /* float registers *************************************************************
      77             : 
      78             :    xmm0,   xmm1,   xmm2,   xmm3,   xmm4,   xmm5,   xmm6,   xmm7,
      79             :    (fa0)   (fa1)   (fa2)   (fa3)   (fa4)   (fa5)   (fa6)   (fa7)
      80             : 
      81             :    xmm8,   xmm9,   xmm10,  xmm11,  xmm12,  xmm13,  xmm14,  xmm15
      82             :    (ftmp1) (ftmp2) (ftmp3) (ft0)   (ft1)   (ft2)   (ft3)   (ft4)
      83             : 
      84             : *******************************************************************************/
      85             : 
      86             : s4 nregdescfloat[] = {
      87             :     REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
      88             :     REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
      89             :     REG_END
      90             : };
      91             : 
      92             : 
      93             : const s4 abi_registers_float_argument[] = {
      94             :         0,  /* fa0 */
      95             :         1,  /* fa1 */
      96             :         2,  /* fa2 */
      97             :         3,  /* fa3 */
      98             :         4,  /* fa4 */
      99             :         5,  /* fa5 */
     100             :         6,  /* fa6 */
     101             :         7,  /* fa7 */
     102             : };
     103             : 
     104             : const s4 abi_registers_float_saved[] = {
     105             :         -1,
     106             : };
     107             : 
     108             : const s4 abi_registers_float_temporary[] = {
     109             :         11, /* ft0 */
     110             :         12, /* ft1 */
     111             :         13, /* ft2 */
     112             :         14, /* ft3 */
     113             :         15, /* ft4 */
     114             : };
     115             : 
     116             : 
     117             : /* md_param_alloc **************************************************************
     118             : 
     119             :    XXX
     120             : 
     121             : *******************************************************************************/
     122             : 
     123      658717 : void md_param_alloc(methoddesc *md)
     124             : {
     125             :         paramdesc *pd;
     126             :         s4         i;
     127             :         s4         iarg;
     128             :         s4         farg;
     129             :         s4         stacksize;
     130             : 
     131             :         /* set default values */
     132             : 
     133      658717 :         iarg      = 0;
     134      658717 :         farg      = 0;
     135      658717 :         stacksize = 0;
     136             : 
     137             :         /* get params field of methoddesc */
     138             : 
     139      658717 :         pd = md->params;
     140             : 
     141     1796353 :         for (i = 0; i < md->paramcount; i++, pd++) {
     142     1137636 :                 switch (md->paramtypes[i].type) {
     143             :                 case TYPE_INT:
     144             :                 case TYPE_ADR:
     145             :                 case TYPE_LNG:
     146     1117581 :                         if (iarg < INT_ARG_CNT) {
     147     1111285 :                                 pd->inmemory = false;
     148     1111285 :                                 pd->index    = iarg;
     149     1111285 :                                 pd->regoff   = abi_registers_integer_argument[iarg];
     150     1111285 :                                 iarg++;
     151             :                         }
     152             :                         else {
     153        6296 :                                 pd->inmemory = true;
     154        6296 :                                 pd->index    = stacksize;
     155        6296 :                                 pd->regoff   = stacksize * 8;
     156        6296 :                                 stacksize++;
     157             :                         }
     158     1117581 :                         break;
     159             : 
     160             :                 case TYPE_FLT:
     161             :                 case TYPE_DBL:
     162       20055 :                         if (farg < FLT_ARG_CNT) {
     163       19911 :                                 pd->inmemory = false;
     164       19911 :                                 pd->index    = farg;
     165       19911 :                                 pd->regoff   = abi_registers_float_argument[farg];
     166       19911 :                                 farg++;
     167             :                         }
     168             :                         else {
     169         144 :                                 pd->inmemory = true;
     170         144 :                                 pd->index    = stacksize;
     171         144 :                                 pd->regoff   = stacksize * 8;
     172         144 :                                 stacksize++;
     173             :                         }
     174       20055 :                         break;
     175             :                 default:
     176           0 :                         assert(false);
     177             :                         break;
     178             :                 }
     179             :         }
     180             : 
     181             :         /* Since XMM0 (==A0) is used for passing return values, this
     182             :            argument register usage has to be regarded, too. */
     183             : 
     184      658717 :         if (IS_FLT_DBL_TYPE(md->returntype.type))
     185      224107 :                 if (farg < 1)
     186      215236 :                         farg = 1;
     187             : 
     188             :         /* fill register and stack usage */
     189             : 
     190      658717 :         md->argintreguse = iarg;
     191      658717 :         md->argfltreguse = farg;
     192      658717 :         md->memuse       = stacksize;
     193      658717 : }
     194             : 
     195             : 
     196             : /* md_param_alloc_native *******************************************************
     197             : 
     198             :    Pre-allocate arguments according the native ABI.
     199             : 
     200             : *******************************************************************************/
     201             : 
     202       15176 : void md_param_alloc_native(methoddesc *md)
     203             : {
     204             :         /* On x86_64 we use the same ABI for JIT method calls as for
     205             :            native method calls. */
     206             : 
     207       15176 :         md_param_alloc(md);
     208       15176 : }
     209             : 
     210             : 
     211             : /* md_return_alloc *************************************************************
     212             : 
     213             :    Precolor the Java Stackelement containing the Return Value. Only
     214             :    for float/ double types straight forward possible, since INT_LNG
     215             :    types use "reserved" registers Float/Double values use a00 as
     216             :    return register.
     217             : 
     218             :    --- in
     219             :    jd:                      jitdata of the current method
     220             :    stackslot:               Java Stackslot to contain the Return Value
     221             : 
     222             :    --- out
     223             :    if precoloring was possible:
     224             :    VAR(stackslot->varnum)->flags     = PREALLOC
     225             :                                      ->vv.regoff = [REG_RESULT|REG_FRESULT]
     226             :    rd->arg[flt|int]reguse   set to a value according the register usage
     227             : 
     228             :    NOTE: Do not pass a LOCALVAR in stackslot->varnum.
     229             : 
     230             : *******************************************************************************/
     231             : 
     232       43733 : void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
     233             : {
     234             :         methodinfo   *m;
     235             :         codeinfo     *code;
     236             :         registerdata *rd;
     237             :         methoddesc   *md;
     238             : 
     239             :         /* get required compiler data */
     240             : 
     241       43733 :         m    = jd->m;
     242       43733 :         code = jd->code;
     243       43733 :         rd   = jd->rd;
     244             : 
     245       43733 :         md = m->parseddesc;
     246             : 
     247             :         /* precoloring only straightforward possible with flt/dbl types
     248             :            For Address/Integer/Long REG_RESULT == rax == REG_ITMP1 and so
     249             :            could be destroyed if the return value Stack Slot "lives too
     250             :            long" */
     251             : 
     252       43733 :         if (IS_FLT_DBL_TYPE(md->returntype.type)) {
     253             :                 /* In Leafmethods Local Vars holding parameters are precolored
     254             :                    to their argument register -> so leafmethods with
     255             :                    paramcount > 0 could already use a00! */
     256             : 
     257         163 :                 if (!code_is_leafmethod(code) || (md->paramcount == 0)) {
     258             :                         /* Only precolor the stackslot, if it is not a SAVEDVAR
     259             :                            <-> has not to survive method invokations */
     260             : 
     261           9 :                         if (!(stackslot->flags & SAVEDVAR)) {
     262             : 
     263           9 :                                 VAR(stackslot->varnum)->flags = PREALLOC;
     264             : 
     265             :                             /* float/double */
     266           9 :                                 if (rd->argfltreguse < 1)
     267           0 :                                         rd->argfltreguse = 1;
     268             : 
     269           9 :                                 VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
     270             :                         }
     271             :                 }
     272             :         }
     273       43733 : }
     274             : 
     275             : 
     276             : /*
     277             :  * These are local overrides for various environment variables in Emacs.
     278             :  * Please do not remove this and leave it at the end of the file, where
     279             :  * Emacs will automagically detect them.
     280             :  * ---------------------------------------------------------------------
     281             :  * Local variables:
     282             :  * mode: c++
     283             :  * indent-tabs-mode: t
     284             :  * c-basic-offset: 4
     285             :  * tab-width: 4
     286             :  * End:
     287             :  * vim:noexpandtab:sw=4:ts=4:
     288             :  */

Generated by: LCOV version 1.11