Home | History | Annotate | Download | only in m_dispatch
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- The core dispatch loop, for jumping to a code address.       ---*/
      4 /*---                                      dispatch-mips64-linux.S ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8   This file is part of Valgrind, a dynamic binary instrumentation
      9   framework.
     10 
     11   Copyright (C) 2000-2015 RT-RK
     12      mips-valgrind (at) rt-rk.com
     13 
     14   This program is free software; you can redistribute it and/or
     15   modify it under the terms of the GNU General Public License as
     16   published by the Free Software Foundation; either version 2 of the
     17   License, or (at your option) any later version.
     18 
     19   This program is distributed in the hope that it will be useful, but
     20   WITHOUT ANY WARRANTY; without even the implied warranty of
     21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22   General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29   The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #include "pub_core_basics_asm.h"
     33 
     34 #if defined(VGP_mips64_linux)
     35 
     36 #include "pub_core_dispatch_asm.h"
     37 #include "pub_core_transtab_asm.h"
     38 #include "libvex_guest_offsets.h"	/* for OFFSET_mips_PC */
     39 
     40 
     41 /*------------------------------------------------------------*/
     42 /*---                                                      ---*/
     43 /*--- The dispatch loop.  VG_(disp_run_translations) is    ---*/
     44 /*--- used to run all translations,                        ---*/
     45 /*--- including no-redir ones.                             ---*/
     46 /*---                                                      ---*/
     47 /*------------------------------------------------------------*/
     48 
     49 /*----------------------------------------------------*/
     50 /*--- Entry and preamble (set everything up)       ---*/
     51 /*----------------------------------------------------*/
     52 
     53 /* signature:
     54 void VG_(disp_run_translations)( UWord* two_words,
     55                                  void*  guest_state,
     56                                  Addr   host_addr );
     57 */
     58 
     59 .text
     60 .globl VG_(disp_run_translations)
     61 VG_(disp_run_translations):
     62     /* a0 ($4) holds two_words   */
     63     /* a1 ($5) holds guest_state */
     64     /* a2 ($6) holds host_addr   */
     65 
     66     /* New stack frame.  Stack must remain 16 aligned (at least) */
     67     daddiu $29, -176
     68 
     69     /* Save ra */
     70     sd  $31, 72($29)
     71 
     72     /* ... and s0 - s7 */
     73     sd $16, 80($29)
     74     sd $17, 88($29)
     75     sd $18, 96($29)
     76     sd $19, 104($29)
     77     sd $20, 112($29)
     78     sd $21, 120($29)
     79     sd $22, 128($29)
     80     sd $23, 136($29)
     81 
     82     /* ... and gp, fp/s8 */
     83     sd $28, 144($29)
     84     sd $30, 152($29)
     85 
     86     /* Save a0 ($4) on stack. In postamble it will be restored such that the
     87        return values can be written */
     88     sd $4, 160($29)
     89 
     90     /* Load address of guest state into guest state register ($23) */
     91     move $23, $5
     92 
     93     /* and jump into the code cache.  Chained translations in
     94            the code cache run, until for whatever reason, they can't
     95            continue.  When that happens, the translation in question
     96            will jump (or call) to one of the continuation points
     97            VG_(cp_...) below. */
     98     jr $6
     99     /*NOTREACHED*/
    100 
    101 /*----------------------------------------------------*/
    102 /*--- Postamble and exit.                          ---*/
    103 /*----------------------------------------------------*/
    104 
    105 postamble:
    106         /* At this point, $2 and $3 contain two
    107            words to be returned to the caller.  $2
    108            holds a TRC value, and $3 optionally may
    109            hold another word (for CHAIN_ME exits, the
    110            address of the place to patch.) */
    111 
    112     /* Restore $4 from stack; holds address of two_words */
    113     ld $4, 160($29)
    114     sd  $2, 0($4)         /* Store $2 to two_words[0] */
    115     sd  $3, 8($4)         /* Store $3 to two_words[1] */
    116 
    117     /* Restore callee-saved registers... */
    118 
    119     /* Restore ra */
    120     ld $31, 72($29)
    121 
    122     /* ... and s0 - s7 */
    123     ld $16, 80($29)
    124     ld $17, 88($29)
    125     ld $18, 96($29)
    126     ld $19, 104($29)
    127     ld $20, 112($29)
    128     ld $21, 120($29)
    129     ld $22, 128($29)
    130     ld $23, 136($29)
    131 
    132     /* ... and gp, fp/s8 */
    133     ld $28, 144($29)
    134     ld $30, 152($29)
    135 
    136     daddiu $29, 176   /* stack_size */
    137     jr $31
    138     nop
    139 
    140 /*----------------------------------------------------*/
    141 /*--- Continuation points                          ---*/
    142 /*----------------------------------------------------*/
    143 
    144 /* ------ Chain me to slow entry point ------ */
    145 .global VG_(disp_cp_chain_me_to_slowEP)
    146 VG_(disp_cp_chain_me_to_slowEP):
    147         /* We got called.  The return address indicates
    148            where the patching needs to happen.  Collect
    149            the return address and, exit back to C land,
    150            handing the caller the pair (Chain_me_S, RA) */
    151         li $2, VG_TRC_CHAIN_ME_TO_SLOW_EP
    152         move $3, $31
    153         /* 8 = mkLoadImm_EXACTLY2or6
    154            4 = jalr $9
    155            4 = nop */
    156         daddiu  $3, $3, -32
    157         b    postamble
    158 
    159 /* ------ Chain me to slow entry point ------ */
    160 .global VG_(disp_cp_chain_me_to_fastEP)
    161 VG_(disp_cp_chain_me_to_fastEP):
    162         /* We got called.  The return address indicates
    163            where the patching needs to happen.  Collect
    164            the return address and, exit back to C land,
    165            handing the caller the pair (Chain_me_S, RA) */
    166         li $2, VG_TRC_CHAIN_ME_TO_FAST_EP
    167         move $3, $31
    168         /* 8 = mkLoadImm_EXACTLY2or6
    169            4 = jalr $9
    170            4 = nop */
    171         daddiu  $3, $3, -32
    172         b    postamble
    173 
    174 /* ------ Indirect but boring jump ------ */
    175 .global VG_(disp_cp_xindir)
    176 VG_(disp_cp_xindir):
    177         /* Where are we going? */
    178         ld  $11, OFFSET_mips64_PC($23)
    179 
    180         lw $13, vgPlain_stats__n_xindirs_32
    181         addiu $13, $13, 0x1
    182         sw $13, vgPlain_stats__n_xindirs_32
    183 
    184         /* try a fast lookup in the translation cache */
    185         /* t1 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
    186                 = (t8 >> 2 & VG_TT_FAST_MASK)  << 3 */
    187 
    188         move $14, $11
    189         li $12, VG_TT_FAST_MASK
    190         srl $14, $14, 2
    191         and $14, $14, $12
    192         sll $14, $14, 3
    193 
    194         /* t2 = (addr of VG_(tt_fast)) + t1 */
    195         dla $13, VG_(tt_fast)
    196         daddu $13, $13, $14
    197 
    198         ld $12, 0($13) /* t3 = VG_(tt_fast)[hash] :: ULong* */
    199         daddi $13, $13, 8
    200         ld $25, 0($13) /* little-endian, so comparing 1st 32bit word */
    201         nop
    202 
    203 check:
    204         bne $12, $11, fast_lookup_failed
    205         /* run the translation */
    206         jr $25
    207         .long   0x0   /* persuade insn decoders not to speculate past here */
    208 
    209 fast_lookup_failed:
    210         /* %PC is up to date */
    211         /* back out decrement of the dispatch counter */
    212         /* hold dispatch_ctr in t0 (r8) */
    213         lw $13, vgPlain_stats__n_xindirs_32
    214         addiu $13, $13, 0x1
    215         sw $13, vgPlain_stats__n_xindirs_32
    216         li $2, VG_TRC_INNER_FASTMISS
    217         li $3, 0
    218         b       postamble
    219 
    220 /* ------ Assisted jump ------ */
    221         .global VG_(disp_cp_xassisted)
    222 VG_(disp_cp_xassisted):
    223         /* guest-state-pointer contains the TRC. Put the value into the
    224            return register */
    225         move    $2, $23
    226         move    $3, $0
    227         b       postamble
    228 
    229 /* ------ Event check failed ------ */
    230         .global VG_(disp_cp_evcheck_fail)
    231 VG_(disp_cp_evcheck_fail):
    232         li      $2, VG_TRC_INNER_COUNTERZERO
    233         move    $3, $0
    234         b       postamble
    235 
    236 .size VG_(disp_run_translations), .-VG_(disp_run_translations)
    237 
    238 #endif // defined(VGP_mips64_linux)
    239 
    240 /* Let the linker know we don't need an executable stack */
    241 MARK_STACK_NO_EXEC
    242 
    243 /*--------------------------------------------------------------------*/
    244 /*--- end                                                          ---*/
    245 /*--------------------------------------------------------------------*/
    246