LCOV - code coverage report
Current view: top level - vm/jit - emit-common.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 15 100.0 %
Date: 2017-07-14 10:03:36 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* src/vm/jit/emit-common.hpp - common code emitter functions
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             :    Copyright (C) 2009 Theobroma Systems Ltd.
       6             : 
       7             :    This file is part of CACAO.
       8             : 
       9             :    This program is free software; you can redistribute it and/or
      10             :    modify it under the terms of the GNU General Public License as
      11             :    published by the Free Software Foundation; either version 2, or (at
      12             :    your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful, but
      15             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :    General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program; if not, write to the Free Software
      21             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      22             :    02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : 
      27             : #ifndef EMIT_COMMON_HPP_
      28             : #define EMIT_COMMON_HPP_ 1
      29             : 
      30             : #include "config.h"
      31             : #include <cassert>                      // for assert
      32             : #include <stdint.h>                     // for int32_t, uint32_t
      33             : #include "arch.hpp"
      34             : #include "codegen.hpp"
      35             : #include "vm/jit/codegen-common.hpp"    // for codegendata
      36             : #include "vm/types.hpp"                 // for s4, u4, s8
      37             : 
      38             : struct basicblock;
      39             : struct codegendata;
      40             : struct codeinfo;
      41             : struct instruction;
      42             : struct jitdata;
      43             : struct varinfo;
      44             : 
      45             : /* branch labels **************************************************************/
      46             : 
      47             : #define BRANCH_LABEL_1    1
      48             : #define BRANCH_LABEL_2    2
      49             : #define BRANCH_LABEL_3    3
      50             : #define BRANCH_LABEL_4    4
      51             : #define BRANCH_LABEL_5    5
      52             : #define BRANCH_LABEL_6    6
      53             : #define BRANCH_LABEL_7    7
      54             : #define BRANCH_LABEL_8    8
      55             : #define BRANCH_LABEL_9    9
      56             : #define BRANCH_LABEL_10  10
      57             : 
      58             : 
      59             : /* constant range macros ******************************************************/
      60             : 
      61             : #if SIZEOF_VOID_P == 8
      62             : 
      63             : # define IS_IMM8(c) \
      64             :     (((s8) (c) >= -128) && ((s8) (c) <= 127))
      65             : 
      66             : # define IS_IMM32(c) \
      67             :     (((s8) (c) >= (-2147483647-1)) && ((s8) (c) <= 2147483647))
      68             : 
      69             : #else
      70             : 
      71             : # define IS_IMM8(c) \
      72             :     (((s4) (c) >= -128) && ((s4) (c) <= 127))
      73             : 
      74             : # define IS_IMM16(c) \
      75             :     (((s4) (c) >= -32768) && ((s4) (c) <= 32767))
      76             : 
      77             : #endif
      78             : 
      79             : 
      80             : /* code generation functions **************************************************/
      81             : 
      82             : s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
      83             : s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg);
      84             : s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg);
      85             : s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg);
      86             : 
      87             : #if SIZEOF_VOID_P == 4
      88             : s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
      89             : s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg);
      90             : s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg);
      91             : s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg);
      92             : 
      93             : s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
      94             : s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg);
      95             : s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg);
      96             : s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg);
      97             : #endif
      98             : 
      99             : void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
     100             : void emit_store_dst(jitdata *jd, instruction *iptr, s4 d);
     101             : 
     102             : #if SIZEOF_VOID_P == 4
     103             : void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
     104             : void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
     105             : #endif
     106             : 
     107             : void emit_copy(jitdata *jd, instruction *iptr);
     108             : 
     109             : void emit_iconst(codegendata *cd, s4 d, s4 value);
     110             : void emit_lconst(codegendata *cd, s4 d, s8 value);
     111             : 
     112             : /* compare-emitting functions targeting an integer register */
     113             : 
     114             : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
     115             : void emit_icmpeq_imm(codegendata* cd, int reg, int32_t value, int d);
     116             : #endif
     117             : 
     118             : /* compare-emitting functions targeting the condition register */
     119             : 
     120             : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
     121             : void emit_icmp_imm(codegendata* cd, int reg, int32_t value);
     122             : #endif
     123             : 
     124             : /* branch-emitting functions */
     125             : void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
     126             : void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options);
     127             : 
     128             : /* wrapper for unconditional branches */
     129             : void emit_br(codegendata *cd, basicblock *target);
     130             : 
     131             : /* wrappers for branches on one integer register */
     132             : 
     133             : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
     134             : void emit_beqz(codegendata *cd, basicblock *target, s4 reg);
     135             : void emit_bnez(codegendata *cd, basicblock *target, s4 reg);
     136             : void emit_bltz(codegendata *cd, basicblock *target, s4 reg);
     137             : void emit_bgez(codegendata *cd, basicblock *target, s4 reg);
     138             : void emit_bgtz(codegendata *cd, basicblock *target, s4 reg);
     139             : void emit_blez(codegendata *cd, basicblock *target, s4 reg);
     140             : #endif
     141             : 
     142             : /* wrappers for branches on two integer registers */
     143             : 
     144             : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
     145             : void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2);
     146             : void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2);
     147             : #endif
     148             : 
     149             : /* wrappers for branches on condition codes */
     150             : 
     151             : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
     152             : void emit_beq(codegendata *cd, basicblock *target);
     153             : void emit_bne(codegendata *cd, basicblock *target);
     154             : void emit_blt(codegendata *cd, basicblock *target);
     155             : void emit_bge(codegendata *cd, basicblock *target);
     156             : void emit_bgt(codegendata *cd, basicblock *target);
     157             : void emit_ble(codegendata *cd, basicblock *target);
     158             : #endif
     159             : 
     160             : #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
     161             : void emit_bult(codegendata *cd, basicblock *target);
     162             : void emit_bule(codegendata *cd, basicblock *target);
     163             : void emit_buge(codegendata *cd, basicblock *target);
     164             : void emit_bugt(codegendata *cd, basicblock *target);
     165             : #endif
     166             : 
     167             : #if defined(__POWERPC__) || defined(__POWERPC64__)
     168             : void emit_bnan(codegendata *cd, basicblock *target);
     169             : #endif
     170             : 
     171             : /* label-branches */
     172             : void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
     173             : void emit_label(codegendata *cd, s4 label);
     174             : void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options);
     175             : 
     176             : void emit_label_br(codegendata *cd, s4 label);
     177             : 
     178             : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
     179             : void emit_label_beqz(codegendata* cd, int label, int reg);
     180             : void emit_label_bnez(codegendata* cd, int label, int reg);
     181             : void emit_label_bltz(codegendata* cd, int label, int reg);
     182             : void emit_label_bgtz(codegendata* cd, int label, int reg);
     183             : #endif
     184             : 
     185             : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
     186             : void emit_label_beq(codegendata* cd, int label, int s1, int s2);
     187             : void emit_label_bne(codegendata* cd, int label, int s1, int s2);
     188             : #endif
     189             : 
     190             : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
     191             : void emit_label_beq(codegendata *cd, s4 label);
     192             : void emit_label_bne(codegendata *cd, s4 label);
     193             : void emit_label_blt(codegendata *cd, s4 label);
     194             : void emit_label_bge(codegendata *cd, s4 label);
     195             : void emit_label_bgt(codegendata *cd, s4 label);
     196             : void emit_label_ble(codegendata *cd, s4 label);
     197             : #endif
     198             : 
     199             : /* machine dependent branch-emitting function */
     200             : void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options);
     201             : 
     202             : void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg);
     203             : void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2);
     204             : void emit_arraystore_check(codegendata *cd, instruction *iptr);
     205             : void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1);
     206             : void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
     207             : void emit_exception_check(codegendata *cd, instruction *iptr);
     208             : 
     209             : void emit_trap_compiler(codegendata *cd);
     210             : void emit_trap_countdown(codegendata *cd, s4 *counter);
     211             : uint32_t emit_trap(codegendata *cd);
     212             : void emit_abstractmethoderror_trap(codegendata *cd);
     213             : 
     214             : void emit_patcher_traps(jitdata *jd);
     215             : 
     216             : void emit_recompute_pv(codegendata* cd);
     217             : 
     218             : /* machine dependent faspath-emitting functions */
     219             : void emit_fastpath_monitor_enter(jitdata* jd, instruction* iptr, int d);
     220             : void emit_fastpath_monitor_exit(jitdata* jd, instruction* iptr, int d);
     221             : 
     222             : void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset);
     223             : void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset);
     224             : 
     225             : #if defined(ENABLE_PROFILING)
     226             : void emit_profile_method(codegendata* cd, codeinfo* code);
     227             : void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr);
     228             : void emit_profile_cycle_start(codegendata* cd, codeinfo* code);
     229             : void emit_profile_cycle_stop(codegendata* cd, codeinfo* code);
     230             : #endif
     231             : 
     232             : void emit_verbosecall_enter(jitdata *jd);
     233             : void emit_verbosecall_exit(jitdata *jd);
     234             : 
     235             : /* inline code generation functions *******************************************/
     236             : 
     237             : /**
     238             :  * Generates an integer-move from register s to d. If s and d are
     239             :  * the same registers, no code will be generated.
     240             :  */
     241      802517 : static inline void emit_imove(codegendata* cd, int s, int d)
     242             : {
     243      802517 :         if (s != d)
     244             : #if defined(__ARM__)
     245             :                 // XXX Fix this!!!
     246             :                 M_MOV(d, s);
     247             : #else
     248      699030 :                 M_MOV(s, d);
     249             : #endif
     250      802517 : }
     251             : 
     252             : 
     253             : /**
     254             :  * Generates a long-move from register s to d. If s and d are
     255             :  * the same registers, no code will be generated.
     256             :  */
     257        1027 : static inline void emit_lmove(codegendata* cd, int s, int d)
     258             : {
     259             : #if SIZEOF_VOID_P == 8
     260        1027 :         emit_imove(cd, s, d);
     261             : #else
     262             :         if (GET_HIGH_REG(s) == GET_LOW_REG(d)) {
     263             :                 assert((GET_LOW_REG(s) != GET_HIGH_REG(d)));
     264             :                 emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
     265             :                 emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
     266             :         } else {
     267             :                 emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
     268             :                 emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
     269             :         }
     270             : #endif
     271        1027 : }
     272             : 
     273             : 
     274             : /**
     275             :  * Generates a float-move from register s to d. If s and d are
     276             :  * the same registers, no code will be generated.
     277             :  */
     278        4487 : static inline void emit_fmove(codegendata* cd, int s, int d)
     279             : {
     280        4487 :         if (s != d)
     281        2062 :                 M_FMOV(s, d);
     282        4487 : }
     283             : 
     284             : 
     285             : /**
     286             :  * Generates an double-move from register s to d. If s and d are
     287             :  * the same registers, no code will be generated.
     288             :  */
     289         295 : static inline void emit_dmove(codegendata* cd, int s, int d)
     290             : {
     291         295 :         if (s != d)
     292          13 :                 M_DMOV(s, d);
     293         295 : }
     294             : 
     295             : 
     296             : /* preserve compatibility with legacy code ************************************/
     297             : 
     298             : #define M_INTMOVE(a, b)      emit_imove(cd, a, b)
     299             : #define M_LNGMOVE(a, b)      emit_lmove(cd, a, b)
     300             : #define M_FLTMOVE(a, b)      emit_fmove(cd, a, b)
     301             : #define M_DBLMOVE(a, b)      emit_dmove(cd, a, b)
     302             : 
     303             : 
     304             : #endif // EMIT_COMMON_HPP_
     305             : 
     306             : 
     307             : /*
     308             :  * These are local overrides for various environment variables in Emacs.
     309             :  * Please do not remove this and leave it at the end of the file, where
     310             :  * Emacs will automagically detect them.
     311             :  * ---------------------------------------------------------------------
     312             :  * Local variables:
     313             :  * mode: c++
     314             :  * indent-tabs-mode: t
     315             :  * c-basic-offset: 4
     316             :  * tab-width: 4
     317             :  * End:
     318             :  * vim:noexpandtab:sw=4:ts=4:
     319             :  */

Generated by: LCOV version 1.11