Home | History | Annotate | Download | only in m_dispatch
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- The core dispatch loop, for jumping to a code address.       ---*/
      4 /*---                                        dispatch-mips-linux.S ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8   This file is part of Valgrind, a dynamic binary instrumentation
      9   framework.
     10 
     11   Copyright (C) 2000-2012 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 
     33 #if defined(VGP_mips32_linux)
     34 
     35 #include "pub_core_basics_asm.h"
     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 8 aligned (at least) */
     67     addiu $29, -56
     68 
     69     /* Save ra */
     70     sw  $31, 0($29)
     71 
     72     /* ... and orig guest state*/
     73     sw $5, 4($29)
     74 
     75     /* ... and s0 - s7 */
     76     sw $16, 8($29)
     77     sw $17, 12($29)
     78     sw $18, 16($29)
     79     sw $19, 20($29)
     80     sw $20, 24($29)
     81     sw $21, 28($29)
     82     sw $22, 32($29)
     83     sw $23, 36($29)
     84 
     85     /* ... and gp, fp/s8 */
     86     sw $28, 40($29)
     87     sw $30, 44($29)
     88 
     89     /* Save a0 ($4) on stack. In postamble it will be restored such that the
     90        return values can be written */
     91     sw $4, 48($29)
     92 
     93     /* Load address of guest state into guest state register (r10) */
     94     move $10, $5
     95 
     96     /* and jump into the code cache.  Chained translations in
     97            the code cache run, until for whatever reason, they can't
     98            continue.  When that happens, the translation in question
     99            will jump (or call) to one of the continuation points
    100            VG_(cp_...) below. */
    101     jr $6
    102     /*NOTREACHED*/
    103 
    104 /*----------------------------------------------------*/
    105 /*--- Postamble and exit.                          ---*/
    106 /*----------------------------------------------------*/
    107 
    108 postamble:
    109         /* At this point, r2 and r3 contain two
    110            words to be returned to the caller.  r2
    111            holds a TRC value, and r3 optionally may
    112            hold another word (for CHAIN_ME exits, the
    113            address of the place to patch.) */
    114 
    115     /* Restore $4 from stack; holds address of two_words */
    116     lw $4, 48($29)
    117     sw  $2, 0($4)         /* Store $2 to two_words[0] */
    118     sw  $3, 4($4)         /* Store $3 to two_words[1] */
    119 
    120     /* Restore callee-saved registers... */
    121 
    122     /* Restore ra */
    123     lw $31, 0($29)
    124 
    125     /* ... and s0 - s7 */
    126     lw $16, 8($29)
    127     lw $17, 12($29)
    128     lw $18, 16($29)
    129     lw $19, 20($29)
    130     lw $20, 24($29)
    131     lw $21, 28($29)
    132     lw $22, 32($29)
    133     lw $23, 36($29)
    134 
    135     /* ... and gp, fp/s8 */
    136     lw $28, 40($29)
    137     lw $30, 44($29)
    138 
    139 
    140     addiu $29, 56   /* stack_size */
    141     jr $31
    142     nop
    143 
    144 /*----------------------------------------------------*/
    145 /*--- Continuation points                          ---*/
    146 /*----------------------------------------------------*/
    147 
    148 /* ------ Chain me to slow entry point ------ */
    149 .global VG_(disp_cp_chain_me_to_slowEP)
    150 VG_(disp_cp_chain_me_to_slowEP):
    151         /* We got called.  The return address indicates
    152            where the patching needs to happen.  Collect
    153            the return address and, exit back to C land,
    154            handing the caller the pair (Chain_me_S, RA) */
    155         li $2, VG_TRC_CHAIN_ME_TO_SLOW_EP
    156         move $3, $31
    157         /* 8 = mkLoadImm_EXACTLY2or5
    158            4 = jalr $9
    159            4 = nop */
    160         addiu  $3, $3, -16
    161         b    postamble
    162 
    163 /* ------ Chain me to slow entry point ------ */
    164 .global VG_(disp_cp_chain_me_to_fastEP)
    165 VG_(disp_cp_chain_me_to_fastEP):
    166         /* We got called.  The return address indicates
    167            where the patching needs to happen.  Collect
    168            the return address and, exit back to C land,
    169            handing the caller the pair (Chain_me_S, RA) */
    170         li $2, VG_TRC_CHAIN_ME_TO_FAST_EP
    171         move $3, $31
    172         /* 8 = mkLoadImm_EXACTLY2or5
    173            4 = jalr $9
    174            4 = nop */
    175         addiu  $3, $3, -16
    176         b    postamble
    177 
    178 /* ------ Indirect but boring jump ------ */
    179 .global VG_(disp_cp_xindir)
    180 VG_(disp_cp_xindir):
    181         /* Where are we going? */
    182         lw  $11, OFFSET_mips32_PC($10)
    183 
    184         lw $13, vgPlain_stats__n_xindirs_32
    185         addiu $13, $13, 0x1
    186         sw $13, vgPlain_stats__n_xindirs_32
    187 
    188         /* try a fast lookup in the translation cache */
    189         /* t1 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
    190                 = (t8 >> 2 & VG_TT_FAST_MASK)  << 3 */
    191 
    192         move $14, $11
    193         li $12, VG_TT_FAST_MASK
    194         srl $14, $14, 2
    195         and $14, $14, $12
    196         sll $14, $14, 3
    197 
    198         /* t2 = (addr of VG_(tt_fast)) + t1 */
    199         la $13, VG_(tt_fast)
    200         addu $13, $13, $14
    201 
    202         lw $12, 0($13) /* t3 = VG_(tt_fast)[hash] :: ULong* */
    203         addi $13, $13, 4
    204         lw $25, 0($13) /* little-endian, so comparing 1st 32bit word */
    205         nop
    206 
    207 check:
    208         bne $12, $11, fast_lookup_failed
    209         /* run the translation */
    210         jr $25
    211         .long   0x0   /* persuade insn decoders not to speculate past here */
    212 
    213 fast_lookup_failed:
    214         /* %PC is up to date */
    215         /* back out decrement of the dispatch counter */
    216         /* hold dispatch_ctr in t0 (r8) */
    217         lw $13, vgPlain_stats__n_xindirs_32
    218         addiu $13, $13, 0x1
    219         sw $13, vgPlain_stats__n_xindirs_32
    220         li $2, VG_TRC_INNER_FASTMISS
    221         li $3, 0
    222         b       postamble
    223 
    224 /* ------ Assisted jump ------ */
    225         .global VG_(disp_cp_xassisted)
    226 VG_(disp_cp_xassisted):
    227         /* guest-state-pointer contains the TRC. Put the value into the
    228            return register */
    229         move    $2, $10
    230         move    $3, $0
    231         b       postamble
    232 
    233 /* ------ Event check failed ------ */
    234         .global VG_(disp_cp_evcheck_fail)
    235 VG_(disp_cp_evcheck_fail):
    236         li      $2, VG_TRC_INNER_COUNTERZERO
    237         move    $3, $0
    238         b       postamble
    239 
    240 .size VG_(disp_run_translations), .-VG_(disp_run_translations)
    241 
    242 
    243 /* Let the linker know we do not need an executable stack */
    244 .section .note.GNU-stack,"",@progbits
    245 
    246 #endif // defined(VGP_mips32_linux)
    247 /*--------------------------------------------------------------------*/
    248 /*--- end                                                          ---*/
    249 /*--------------------------------------------------------------------*/
    250