LCOV - code coverage report
Current view: top level - vm/jit - emit-common.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 86 127 67.7 %
Date: 2015-06-10 18:10:59 Functions: 17 28 60.7 %

          Line data    Source code
       1             : /* src/vm/jit/emit-common.cpp - common code emitter functions
       2             : 
       3             :    Copyright (C) 2006-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             : #include "vm/jit/emit-common.hpp"
      26             : #include "config.h"
      27             : #include <algorithm>
      28             : #include <cassert>                      // for assert
      29             : #include <stdint.h>                     // for int32_t, uint32_t
      30             : #include <list>                         // for _List_iterator, etc
      31             : #include "arch.hpp"
      32             : #include "codegen.hpp"
      33             : #include "codegen-common.hpp"           // for codegendata, etc
      34             : #include "toolbox/list.hpp"             // for DumpList, LockedList, List
      35             : #include "vm/jit/code.hpp"              // for codeinfo
      36             : #include "vm/jit/ir/instruction.hpp"    // for instruction, etc
      37             : #include "vm/jit/jit.hpp"               // for basicblock, jitdata
      38             : #include "vm/jit/patcher-common.hpp"    // for patchref_t
      39             : #include "vm/options.hpp"
      40             : #include "vm/statistics.hpp"
      41             : #include "vm/types.hpp"                 // for s4, u1, u4
      42             : 
      43             : struct varinfo;
      44             : 
      45             : STAT_REGISTER_VAR(int,count_branches_resolved,0,"resolved branches","resolved branches")
      46             : 
      47             : STAT_REGISTER_VAR_EXTERN(int,count_mov_reg_reg,0,"count_mov_reg_reg","Moves reg -> reg")
      48             : STAT_REGISTER_VAR_EXTERN(int,count_mov_mem_reg,0,"count_mov_mem_reg","Moves mem -> reg")
      49             : STAT_REGISTER_VAR_EXTERN(int,count_mov_reg_mem,0,"count_mov_reg_mem","Moves reg -> mem")
      50             : //STAT_REGISTER_VAR_EXTERN(int,count_mov_mem_mem,0,"count_mov_mem_mem","Moves mem -> mem")
      51             : 
      52             : STAT_REGISTER_SUM_GROUP(emit_branch_stat,"emit branch","Number of branch_emit (total)")
      53             : STAT_REGISTER_GROUP_VAR(int,count_emit_branch_8bit,0,"emit branch 8bit","Number of branch_emit ( 8bit offset)",emit_branch_stat)
      54             : STAT_REGISTER_GROUP_VAR(int,count_emit_branch_16bit,0,"emit branch 16bit","Number of branch_emit (16bit offset)",emit_branch_stat)
      55             : STAT_REGISTER_GROUP_VAR(int,count_emit_branch_32bit,0,"emit branch 32bit","Number of branch_emit (32bit offset)",emit_branch_stat)
      56             : STAT_REGISTER_GROUP_VAR(int,count_emit_branch_64bit,0,"emit branch 64bit","Number of branch_emit (64bit offset)",emit_branch_stat)
      57             : /* emit_load_s1 ****************************************************************
      58             : 
      59             :    Emits a possible load of the first source operand.
      60             : 
      61             : *******************************************************************************/
      62             : 
      63     1103293 : s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
      64             : {
      65             :         varinfo *src;
      66             :         s4       reg;
      67             : 
      68     1103293 :         src = VAROP(iptr->s1);
      69             : 
      70     1103293 :         reg = emit_load(jd, iptr, src, tempreg);
      71             : 
      72     1103293 :         return reg;
      73             : }
      74             : 
      75             : 
      76             : /* emit_load_s2 ****************************************************************
      77             : 
      78             :    Emits a possible load of the second source operand.
      79             : 
      80             : *******************************************************************************/
      81             : 
      82      747869 : s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
      83             : {
      84             :         varinfo *src;
      85             :         s4       reg;
      86             : 
      87      747869 :         src = VAROP(iptr->sx.s23.s2);
      88             : 
      89      747869 :         reg = emit_load(jd, iptr, src, tempreg);
      90             : 
      91      747869 :         return reg;
      92             : }
      93             : 
      94             : 
      95             : /* emit_load_s3 ****************************************************************
      96             : 
      97             :    Emits a possible load of the third source operand.
      98             : 
      99             : *******************************************************************************/
     100             : 
     101      130682 : s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
     102             : {
     103             :         varinfo *src;
     104             :         s4       reg;
     105             : 
     106      130682 :         src = VAROP(iptr->sx.s23.s3);
     107             : 
     108      130682 :         reg = emit_load(jd, iptr, src, tempreg);
     109             : 
     110      130682 :         return reg;
     111             : }
     112             : 
     113             : 
     114             : /* emit_load_s1_low ************************************************************
     115             : 
     116             :    Emits a possible load of the low 32-bits of the first long source
     117             :    operand.
     118             : 
     119             : *******************************************************************************/
     120             : 
     121             : #if SIZEOF_VOID_P == 4
     122             : s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
     123             : {
     124             :         varinfo *src;
     125             :         s4       reg;
     126             : 
     127             :         src = VAROP(iptr->s1);
     128             : 
     129             :         reg = emit_load_low(jd, iptr, src, tempreg);
     130             : 
     131             :         return reg;
     132             : }
     133             : #endif
     134             : 
     135             : 
     136             : /* emit_load_s2_low ************************************************************
     137             : 
     138             :    Emits a possible load of the low 32-bits of the second long source
     139             :    operand.
     140             : 
     141             : *******************************************************************************/
     142             : 
     143             : #if SIZEOF_VOID_P == 4
     144             : s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
     145             : {
     146             :         varinfo *src;
     147             :         s4       reg;
     148             : 
     149             :         src = VAROP(iptr->sx.s23.s2);
     150             : 
     151             :         reg = emit_load_low(jd, iptr, src, tempreg);
     152             : 
     153             :         return reg;
     154             : }
     155             : #endif
     156             : 
     157             : 
     158             : /* emit_load_s3_low ************************************************************
     159             : 
     160             :    Emits a possible load of the low 32-bits of the third long source
     161             :    operand.
     162             : 
     163             : *******************************************************************************/
     164             : 
     165             : #if SIZEOF_VOID_P == 4
     166             : s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg)
     167             : {
     168             :         varinfo *src;
     169             :         s4       reg;
     170             : 
     171             :         src = VAROP(iptr->sx.s23.s3);
     172             : 
     173             :         reg = emit_load_low(jd, iptr, src, tempreg);
     174             : 
     175             :         return reg;
     176             : }
     177             : #endif
     178             : 
     179             : 
     180             : /* emit_load_s1_high ***********************************************************
     181             : 
     182             :    Emits a possible load of the high 32-bits of the first long source
     183             :    operand.
     184             : 
     185             : *******************************************************************************/
     186             : 
     187             : #if SIZEOF_VOID_P == 4
     188             : s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
     189             : {
     190             :         varinfo *src;
     191             :         s4       reg;
     192             : 
     193             :         src = VAROP(iptr->s1);
     194             : 
     195             :         reg = emit_load_high(jd, iptr, src, tempreg);
     196             : 
     197             :         return reg;
     198             : }
     199             : #endif
     200             : 
     201             : 
     202             : /* emit_load_s2_high ***********************************************************
     203             : 
     204             :    Emits a possible load of the high 32-bits of the second long source
     205             :    operand.
     206             : 
     207             : *******************************************************************************/
     208             : 
     209             : #if SIZEOF_VOID_P == 4
     210             : s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
     211             : {
     212             :         varinfo *src;
     213             :         s4       reg;
     214             : 
     215             :         src = VAROP(iptr->sx.s23.s2);
     216             : 
     217             :         reg = emit_load_high(jd, iptr, src, tempreg);
     218             : 
     219             :         return reg;
     220             : }
     221             : #endif
     222             : 
     223             : 
     224             : /* emit_load_s3_high ***********************************************************
     225             : 
     226             :    Emits a possible load of the high 32-bits of the third long source
     227             :    operand.
     228             : 
     229             : *******************************************************************************/
     230             : 
     231             : #if SIZEOF_VOID_P == 4
     232             : s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg)
     233             : {
     234             :         varinfo *src;
     235             :         s4       reg;
     236             : 
     237             :         src = VAROP(iptr->sx.s23.s3);
     238             : 
     239             :         reg = emit_load_high(jd, iptr, src, tempreg);
     240             : 
     241             :         return reg;
     242             : }
     243             : #endif
     244             : 
     245             : 
     246             : /* emit_store_dst **************************************************************
     247             : 
     248             :    This function generates the code to store the result of an
     249             :    operation back into a spilled pseudo-variable.  If the
     250             :    pseudo-variable has not been spilled in the first place, this
     251             :    function will generate nothing.
     252             :     
     253             : *******************************************************************************/
     254             : 
     255     1315942 : void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
     256             : {
     257     1315942 :         emit_store(jd, iptr, VAROP(iptr->dst), d);
     258     1315942 : }
     259             : 
     260             : 
     261             : /* emit_patcher_traps **********************************************************
     262             : 
     263             :    Generates the code for the patcher traps.
     264             : 
     265             : *******************************************************************************/
     266             : 
     267       86399 : void emit_patcher_traps(jitdata *jd)
     268             : {
     269             :         codegendata *cd;
     270             :         codeinfo    *code;
     271             :         u1          *savedmcodeptr;
     272             :         u1          *tmpmcodeptr;
     273             :         uint32_t     mcode;
     274             : 
     275             :         /* get required compiler data */
     276             : 
     277       86399 :         cd   = jd->cd;
     278       86399 :         code = jd->code;
     279             : 
     280             :         // Generate patcher traps code.
     281      228922 :         for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
     282      142523 :                 patchref_t& pr = *it;
     283             : 
     284             :                 /* Calculate the patch position where the original machine
     285             :                    code is located and the trap should be placed. */
     286             : 
     287      142523 :                 tmpmcodeptr = (u1 *) (cd->mcodebase + pr.mpc);
     288             : 
     289             :                 /* Patch in the trap to call the signal handler (done at
     290             :                    compile time). */
     291             : 
     292      142523 :                 savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
     293      142523 :                 cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
     294             : 
     295      142523 :                 mcode = emit_trap(cd);
     296             : 
     297      142523 :                 cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
     298             : 
     299             :                 /* Remember the original machine code which is patched
     300             :                    back in later (done at runtime). */
     301             : 
     302      142523 :                 pr.mcode = mcode;
     303             :         }
     304       86399 : }
     305             : 
     306             : 
     307             : /* emit_bccz *******************************************************************
     308             : 
     309             :    Emit conditional and unconditional branch instructions on integer
     310             :    regiseters.
     311             : 
     312             : *******************************************************************************/
     313             : 
     314      270405 : void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
     315             : {
     316             :         s4 branchmpc;
     317             :         s4 disp;
     318             : 
     319             :         /* Target basic block already has an PC, so we can generate the
     320             :            branch immediately. */
     321             : 
     322      270405 :         if ((target->mpc >= 0)) {
     323             :                 STATISTICS(count_branches_resolved++);
     324             : 
     325             :                 /* calculate the mpc of the branch instruction */
     326             : 
     327      141437 :                 branchmpc = cd->mcodeptr - cd->mcodebase;
     328      141437 :                 disp      = target->mpc - branchmpc;
     329             : 
     330             : #if defined(ENABLE_STATISTICS)
     331             :                 if ((int8_t)disp == disp)  count_emit_branch_8bit++;
     332             :                 else if ((int16_t)disp == disp) count_emit_branch_16bit++;
     333             :                 else if ((int32_t)disp == disp) count_emit_branch_32bit++;
     334             : # if SIZEOF_VOID_P == 8
     335             :                 else if ((int64_t)disp == disp) count_emit_branch_64bit++;
     336             : # endif
     337             : #endif
     338             : 
     339      141437 :                 emit_branch(cd, disp, condition, reg, options);
     340             :         }
     341             :         else {
     342             :                 /* current mcodeptr is the correct position,
     343             :                    afterwards emit the NOPs */
     344             : 
     345      128968 :                 codegen_add_branch_ref(cd, target, condition, reg, options);
     346             : 
     347             :                 /* generate NOPs as placeholder for branch code */
     348             : 
     349      128968 :                 BRANCH_NOPS;
     350             :         }
     351      270405 : }
     352             : 
     353             : 
     354             : /* emit_bcc ********************************************************************
     355             : 
     356             :    Emit conditional and unconditional branch instructions on condition
     357             :    codes.
     358             : 
     359             : *******************************************************************************/
     360             : 
     361      141437 : void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
     362             : {
     363      141437 :         emit_bccz(cd, target, condition, -1, options);
     364      141437 : }
     365             : 
     366             : 
     367             : /* emit_br *********************************************************************
     368             : 
     369             :    Wrapper for unconditional branches.
     370             : 
     371             : *******************************************************************************/
     372             : 
     373       34830 : void emit_br(codegendata *cd, basicblock *target)
     374             : {
     375       34830 :         emit_bcc(cd, target, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
     376       34830 : }
     377             : 
     378             : 
     379             : /* emit_bxxz *******************************************************************
     380             : 
     381             :    Wrappers for branches on one integer register.
     382             : 
     383             : *******************************************************************************/
     384             : 
     385             : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
     386             : 
     387             : void emit_beqz(codegendata *cd, basicblock *target, s4 reg)
     388             : {
     389             :         emit_bccz(cd, target, BRANCH_EQ, reg, BRANCH_OPT_NONE);
     390             : }
     391             : 
     392             : void emit_bnez(codegendata *cd, basicblock *target, s4 reg)
     393             : {
     394             :         emit_bccz(cd, target, BRANCH_NE, reg, BRANCH_OPT_NONE);
     395             : }
     396             : 
     397             : void emit_bltz(codegendata *cd, basicblock *target, s4 reg)
     398             : {
     399             :         emit_bccz(cd, target, BRANCH_LT, reg, BRANCH_OPT_NONE);
     400             : }
     401             : 
     402             : void emit_bgez(codegendata *cd, basicblock *target, s4 reg)
     403             : {
     404             :         emit_bccz(cd, target, BRANCH_GE, reg, BRANCH_OPT_NONE);
     405             : }
     406             : 
     407             : void emit_bgtz(codegendata *cd, basicblock *target, s4 reg)
     408             : {
     409             :         emit_bccz(cd, target, BRANCH_GT, reg, BRANCH_OPT_NONE);
     410             : }
     411             : 
     412             : void emit_blez(codegendata *cd, basicblock *target, s4 reg)
     413             : {
     414             :         emit_bccz(cd, target, BRANCH_LE, reg, BRANCH_OPT_NONE);
     415             : }
     416             : 
     417             : #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
     418             : 
     419             : 
     420             : /* emit_bxx ********************************************************************
     421             : 
     422             :    Wrappers for branches on two integer registers.
     423             : 
     424             :    We use PACK_REGS here, so we don't have to change the branchref
     425             :    data structure and the emit_bccz function.
     426             : 
     427             : *******************************************************************************/
     428             : 
     429             : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
     430             : 
     431             : void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2)
     432             : {
     433             :         emit_bccz(cd, target, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
     434             : }
     435             : 
     436             : void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2)
     437             : {
     438             :         emit_bccz(cd, target, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
     439             : }
     440             : 
     441             : #endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */
     442             : 
     443             : 
     444             : /* emit_bxx ********************************************************************
     445             : 
     446             :    Wrappers for branches on condition codes.
     447             : 
     448             : *******************************************************************************/
     449             : 
     450             : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
     451             : 
     452         480 : void emit_beq(codegendata *cd, basicblock *target)
     453             : {
     454         480 :         emit_bcc(cd, target, BRANCH_EQ, BRANCH_OPT_NONE);
     455         480 : }
     456             : 
     457           0 : void emit_bne(codegendata *cd, basicblock *target)
     458             : {
     459           0 :         emit_bcc(cd, target, BRANCH_NE, BRANCH_OPT_NONE);
     460           0 : }
     461             : 
     462           0 : void emit_blt(codegendata *cd, basicblock *target)
     463             : {
     464           0 :         emit_bcc(cd, target, BRANCH_LT, BRANCH_OPT_NONE);
     465           0 : }
     466             : 
     467           0 : void emit_bge(codegendata *cd, basicblock *target)
     468             : {
     469           0 :         emit_bcc(cd, target, BRANCH_GE, BRANCH_OPT_NONE);
     470           0 : }
     471             : 
     472           0 : void emit_bgt(codegendata *cd, basicblock *target)
     473             : {
     474           0 :         emit_bcc(cd, target, BRANCH_GT, BRANCH_OPT_NONE);
     475           0 : }
     476             : 
     477           0 : void emit_ble(codegendata *cd, basicblock *target)
     478             : {
     479           0 :         emit_bcc(cd, target, BRANCH_LE, BRANCH_OPT_NONE);
     480           0 : }
     481             : 
     482             : #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
     483           0 : void emit_bult(codegendata *cd, basicblock *target)
     484             : {
     485           0 :         emit_bcc(cd, target, BRANCH_ULT, BRANCH_OPT_NONE);
     486           0 : }
     487             : 
     488           0 : void emit_bule(codegendata *cd, basicblock *target)
     489             : {
     490           0 :         emit_bcc(cd, target, BRANCH_ULE, BRANCH_OPT_NONE);
     491           0 : }
     492             : 
     493           0 : void emit_buge(codegendata *cd, basicblock *target)
     494             : {
     495           0 :         emit_bcc(cd, target, BRANCH_UGE, BRANCH_OPT_NONE);
     496           0 : }
     497             : 
     498          72 : void emit_bugt(codegendata *cd, basicblock *target)
     499             : {
     500          72 :         emit_bcc(cd, target, BRANCH_UGT, BRANCH_OPT_NONE);
     501          72 : }
     502             : #endif
     503             : 
     504             : #if defined(__POWERPC__) || defined(__POWERPC64__)
     505             : void emit_bnan(codegendata *cd, basicblock *target)
     506             : {
     507             :         emit_bcc(cd, target, BRANCH_NAN, BRANCH_OPT_NONE);
     508             : }
     509             : #endif
     510             : 
     511             : #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
     512             : 
     513             : 
     514             : /* emit_label_bccz *************************************************************
     515             : 
     516             :    Emit a branch to a label.  Possibly emit the branch, if it is a
     517             :    backward branch.
     518             : 
     519             : *******************************************************************************/
     520             : 
     521       29858 : void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
     522             : {
     523             :         // Search if the label is already in the list.
     524       29858 :         DumpList<branch_label_ref_t*>::iterator it;
     525       63938 :         for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
     526       34080 :                 branch_label_ref_t* br = *it;
     527             : 
     528             :                 /* is this entry the correct label? */
     529             : 
     530       34080 :                 if (br->label == label)
     531           0 :                         break;
     532             :         }
     533             : 
     534       29858 :         if (it == cd->brancheslabel->end()) {
     535             :                 /* current mcodeptr is the correct position,
     536             :                    afterwards emit the NOPs */
     537             : 
     538       29858 :                 codegen_branch_label_add(cd, label, condition, reg, options);
     539             : 
     540             :                 /* generate NOPs as placeholder for branch code */
     541             : 
     542       29858 :                 BRANCH_NOPS;
     543       29858 :                 return;
     544             :         }
     545             : 
     546             :         // Branch reference was found.
     547           0 :         branch_label_ref_t* br = *it;
     548             : 
     549             :         /* calculate the mpc of the branch instruction */
     550             : 
     551           0 :         int32_t mpc  = cd->mcodeptr - cd->mcodebase;
     552           0 :         int32_t disp = br->mpc - mpc;
     553             : 
     554             : #if defined(ENABLE_STATISTICS)
     555             :         if ((int8_t)disp == disp)  count_emit_branch_8bit++;
     556             :         else if ((int16_t)disp == disp) count_emit_branch_16bit++;
     557             :         else if ((int32_t)disp == disp) count_emit_branch_32bit++;
     558             : # if SIZEOF_VOID_P == 8
     559             :         else if ((int64_t)disp == disp) count_emit_branch_64bit++;
     560             : # endif
     561             : #endif
     562             : 
     563           0 :         emit_branch(cd, disp, condition, reg, options);
     564             : 
     565             :         // Now remove the branch reference.
     566           0 :         cd->brancheslabel->remove(br);
     567             : }
     568             : 
     569             : 
     570             : /* emit_label ******************************************************************
     571             : 
     572             :    Emit a label for a branch.  Possibly emit the branch, if it is a
     573             :    forward branch.
     574             : 
     575             : *******************************************************************************/
     576             : 
     577       29858 : void emit_label(codegendata *cd, s4 label)
     578             : {
     579             :         u1* mcodeptr;
     580             : 
     581             :         // Search if the label is already in the list.
     582       29858 :         DumpList<branch_label_ref_t*>::iterator it;
     583       56122 :         for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
     584       56122 :                 branch_label_ref_t* br = *it;
     585             : 
     586             :                 /* is this entry the correct label? */
     587             : 
     588       56122 :                 if (br->label == label)
     589       29858 :                         break;
     590             :         }
     591             : 
     592       29858 :         if (it == cd->brancheslabel->end()) {
     593             :                 /* No branch reference found, add the label to the list (use
     594             :                    invalid values for condition and register). */
     595             : 
     596           0 :                 codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
     597           0 :                 return;
     598             :         }
     599             : 
     600             :         // Branch reference was found.
     601       29858 :         branch_label_ref_t* br = *it;
     602             : 
     603             :         // Calculate the mpc of the branch instruction.
     604       29858 :         int32_t mpc  = cd->mcodeptr - cd->mcodebase;
     605       29858 :         int32_t disp = mpc - br->mpc;
     606             : 
     607             :         /* temporary set the mcodeptr */
     608             : 
     609       29858 :         mcodeptr     = cd->mcodeptr;
     610       29858 :         cd->mcodeptr = cd->mcodebase + br->mpc;
     611             : 
     612             : #if defined(ENABLE_STATISTICS)
     613             :         if ((int8_t)disp == disp)  count_emit_branch_8bit++;
     614             :         else if ((int16_t)disp == disp) count_emit_branch_16bit++;
     615             :         else if ((int32_t)disp == disp) count_emit_branch_32bit++;
     616             : # if SIZEOF_VOID_P == 8
     617             :         else if ((int64_t)disp == disp) count_emit_branch_64bit++;
     618             : # endif
     619             : #endif
     620             : 
     621       29858 :         emit_branch(cd, disp, br->condition, br->reg, br->options);
     622             : 
     623             :         /* restore mcodeptr */
     624             : 
     625       29858 :         cd->mcodeptr = mcodeptr;
     626             : 
     627             :         // Now remove the branch reference.
     628       29858 :         cd->brancheslabel->remove(br);
     629             : }
     630             : 
     631             : 
     632             : /* emit_label_bcc **************************************************************
     633             : 
     634             :    Emit conditional and unconditional label-branch instructions on
     635             :    condition codes.
     636             : 
     637             : *******************************************************************************/
     638             : 
     639       29858 : void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options)
     640             : {
     641       29858 :         emit_label_bccz(cd, label, condition, -1, options);
     642       29858 : }
     643             : 
     644             : 
     645             : /* emit_label_br ***************************************************************
     646             : 
     647             :    Wrapper for unconditional label-branches.
     648             : 
     649             : *******************************************************************************/
     650             : 
     651        2260 : void emit_label_br(codegendata *cd, s4 label)
     652             : {
     653        2260 :         emit_label_bcc(cd, label, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE);
     654        2260 : }
     655             : 
     656             : 
     657             : /* emit_label_bxxz *************************************************************
     658             : 
     659             :    Wrappers for label-branches on one integer register.
     660             : 
     661             : *******************************************************************************/
     662             : 
     663             : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
     664             : 
     665             : void emit_label_beqz(codegendata* cd, int label, int reg)
     666             : {
     667             :         emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE);
     668             : }
     669             : 
     670             : void emit_label_bnez(codegendata* cd, int label, int reg)
     671             : {
     672             :         emit_label_bccz(cd, label, BRANCH_NE, reg, BRANCH_OPT_NONE);
     673             : }
     674             : 
     675             : void emit_label_bltz(codegendata* cd, int label, int reg)
     676             : {
     677             :         emit_label_bccz(cd, label, BRANCH_LT, reg, BRANCH_OPT_NONE);
     678             : }
     679             : 
     680             : void emit_label_bgtz(codegendata* cd, int label, int reg)
     681             : {
     682             :         emit_label_bccz(cd, label, BRANCH_GT, reg, BRANCH_OPT_NONE);
     683             : }
     684             : 
     685             : #endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
     686             : 
     687             : 
     688             : /* emit_label_bxx **************************************************************
     689             : 
     690             :    Wrappers for label-branches on two integer registers.
     691             : 
     692             :    We use PACK_REGS here, so we don't have to change the branchref
     693             :    data structure and the emit_bccz function.
     694             : 
     695             : *******************************************************************************/
     696             : 
     697             : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
     698             : 
     699             : void emit_label_beq(codegendata* cd, int label, int s1, int s2)
     700             : {
     701             :         emit_label_bccz(cd, label, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
     702             : }
     703             : 
     704             : void emit_label_bne(codegendata* cd, int label, int s1, int s2)
     705             : {
     706             :         emit_label_bccz(cd, label, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
     707             : }
     708             : 
     709             : #endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */
     710             : 
     711             : 
     712             : /* emit_label_bxx **************************************************************
     713             : 
     714             :    Wrappers for label-branches on condition codes.
     715             : 
     716             : *******************************************************************************/
     717             : 
     718             : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
     719             : 
     720       15197 : void emit_label_beq(codegendata *cd, s4 label)
     721             : {
     722       15197 :         emit_label_bcc(cd, label, BRANCH_EQ, BRANCH_OPT_NONE);
     723       15197 : }
     724             : 
     725       10271 : void emit_label_bne(codegendata *cd, s4 label)
     726             : {
     727       10271 :         emit_label_bcc(cd, label, BRANCH_NE, BRANCH_OPT_NONE);
     728       10271 : }
     729             : 
     730           0 : void emit_label_blt(codegendata *cd, s4 label)
     731             : {
     732           0 :         emit_label_bcc(cd, label, BRANCH_LT, BRANCH_OPT_NONE);
     733           0 : }
     734             : 
     735           0 : void emit_label_bge(codegendata *cd, s4 label)
     736             : {
     737           0 :         emit_label_bcc(cd, label, BRANCH_GE, BRANCH_OPT_NONE);
     738           0 : }
     739             : 
     740        2130 : void emit_label_bgt(codegendata *cd, s4 label)
     741             : {
     742        2130 :         emit_label_bcc(cd, label, BRANCH_GT, BRANCH_OPT_NONE);
     743        2130 : }
     744             : 
     745           0 : void emit_label_ble(codegendata *cd, s4 label)
     746             : {
     747           0 :         emit_label_bcc(cd, label, BRANCH_LE, BRANCH_OPT_NONE);
     748           0 : }
     749             : 
     750             : #endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */
     751             : 
     752             : 
     753             : /*
     754             :  * These are local overrides for various environment variables in Emacs.
     755             :  * Please do not remove this and leave it at the end of the file, where
     756             :  * Emacs will automagically detect them.
     757             :  * ---------------------------------------------------------------------
     758             :  * Local variables:
     759             :  * mode: c++
     760             :  * indent-tabs-mode: t
     761             :  * c-basic-offset: 4
     762             :  * tab-width: 4
     763             :  * End:
     764             :  * vim:noexpandtab:sw=4:ts=4:
     765             :  */

Generated by: LCOV version 1.11