Home | History | Annotate | Download | only in m_dispatch
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- begin                                dispatch-tilegx-linux.S ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7   This file is part of Valgrind, a dynamic binary instrumentation
      8   framework.
      9 
     10   Copyright (C) 2010-2013  Tilera Corp.
     11 
     12   This program is free software; you can redistribute it and/or
     13   modify it under the terms of the GNU General Public License as
     14   published by the Free Software Foundation; either version 2 of the
     15   License, or (at your option) any later version.
     16 
     17   This program is distributed in the hope that it will be useful, but
     18   WITHOUT ANY WARRANTY; without even the implied warranty of
     19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20   General Public License for more details.
     21 
     22   You should have received a copy of the GNU General Public License
     23   along with this program; if not, write to the Free Software
     24   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     25   02111-1307, USA.
     26 
     27   The GNU General Public License is contained in the file COPYING.
     28 */
     29 
     30 /* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
     31 
     32 #if defined(VGP_tilegx_linux)
     33 #include "pub_core_basics_asm.h"
     34 #include "pub_core_dispatch_asm.h"
     35 #include "pub_core_transtab_asm.h"
     36 #include "libvex_guest_offsets.h"       /* for OFFSET_tilegx_PC */
     37 
     38         /*------------------------------------------------------------*/
     39         /*---                                                      ---*/
     40         /*--- The dispatch loop.  VG_(run_innerloop) is used to    ---*/
     41         /*--- run all translations except no-redir ones.           ---*/
     42         /*---                                                      ---*/
     43         /*------------------------------------------------------------*/
     44 
     45         /*----------------------------------------------------*/
     46         /*--- Preamble (set everything up)                 ---*/
     47         /*----------------------------------------------------*/
     48 
     49         /* signature:
     50         void VG_(disp_run_translations)(UWord* two_words,
     51         void*  guest_state,
     52         Addr   host_addr );
     53         UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
     54         */
     55 
     56         .text
     57         .globl  VG_(disp_run_translations)
     58         VG_(disp_run_translations):
     59 
     60         /* r0 holds two_words
     61            r1 holds guest_state
     62            r2 holds host_addr */
     63 
     64         /* New stack frame */
     65         addli sp, sp, -256
     66         addi  r29, sp, 8
     67         /*
     68         high memory of stack
     69         216  lr
     70         208  r53
     71         200  r52
     72         192  r51
     73         ...
     74         48   r33
     75         40   r32
     76         32   r31
     77         24   r30
     78         16   r1 <---
     79         8    r0
     80         0       <-sp
     81         */
     82         st_add r29, r0, 8
     83         st_add r29, r1, 8
     84 
     85         /* ... and r30 - r53 */
     86         st_add  r29, r30, 8
     87         st_add  r29, r31, 8
     88         st_add  r29, r32, 8
     89         st_add  r29, r33, 8
     90         st_add  r29, r34, 8
     91         st_add  r29, r35, 8
     92         st_add  r29, r36, 8
     93         st_add  r29, r37, 8
     94         st_add  r29, r38, 8
     95         st_add  r29, r39, 8
     96         st_add  r29, r40, 8
     97         st_add  r29, r41, 8
     98         st_add  r29, r42, 8
     99         st_add  r29, r43, 8
    100         st_add  r29, r44, 8
    101         st_add  r29, r45, 8
    102         st_add  r29, r46, 8
    103         st_add  r29, r47, 8
    104         st_add  r29, r48, 8
    105         st_add  r29, r49, 8
    106         st_add  r29, r50, 8
    107         st_add  r29, r51, 8
    108         st_add  r29, r52, 8
    109         st_add  r29, r53, 8
    110         st      r29, lr
    111 
    112         /* Load the address of guest state into guest state register r50. */
    113         move r50, r1
    114 
    115         //j postamble
    116 
    117         /* jump to the code cache. */
    118         jr  r2
    119         /*NOTREACHED*/
    120 
    121 
    122        /*----------------------------------------------------*/
    123        /*--- Postamble and exit.                          ---*/
    124        /*----------------------------------------------------*/
    125 
    126 postamble:
    127         /* At this point, r12 and r13 contain two
    128         words to be returned to the caller.  r12
    129         holds a TRC value, and r13 optionally may
    130         hold another word (for CHAIN_ME exits, the
    131         address of the place to patch.) */
    132 
    133         /* run_innerloop_exit_REALLY:
    134         r50 holds VG_TRC_* value to return
    135         Return to parent stack
    136         addli  sp, sp, 256 */
    137 
    138         addi r29, sp, 8
    139 
    140         /* Restore r0 from stack; holding address of twp words */
    141         ld_add  r0, r29, 16
    142         /* store r12 in two_words[0] */
    143         st_add  r0, r12, 8
    144         /* store r13 in two_words[1] */
    145         st  r0, r13
    146 
    147         /* Restore callee-saved registers... */
    148         ld_add  r30, r29, 8
    149         ld_add  r31, r29, 8
    150         ld_add  r32, r29, 8
    151         ld_add  r33, r29, 8
    152         ld_add  r34, r29, 8
    153         ld_add  r35, r29, 8
    154         ld_add  r36, r29, 8
    155         ld_add  r37, r29, 8
    156         ld_add  r38, r29, 8
    157         ld_add  r39, r29, 8
    158         ld_add  r40, r29, 8
    159         ld_add  r41, r29, 8
    160         ld_add  r42, r29, 8
    161         ld_add  r43, r29, 8
    162         ld_add  r44, r29, 8
    163         ld_add  r45, r29, 8
    164         ld_add  r46, r29, 8
    165         ld_add  r47, r29, 8
    166         ld_add  r48, r29, 8
    167         ld_add  r49, r29, 8
    168         ld_add  r50, r29, 8
    169         ld_add  r51, r29, 8
    170         ld_add  r52, r29, 8
    171         ld_add  r53, r29, 8
    172         ld      lr, r29
    173         addli   sp, sp, 256   /* stack_size */
    174         jr      lr
    175         nop
    176 
    177 
    178        /*----------------------------------------------------*/
    179        /*---           Continuation points                ---*/
    180        /*----------------------------------------------------*/
    181 
    182        /* ------ Chain me to slow entry point ------ */
    183        .global VG_(disp_cp_chain_me_to_slowEP)
    184        VG_(disp_cp_chain_me_to_slowEP):
    185         /* We got called.  The return address indicates
    186         where the patching needs to happen.  Collect
    187         the return address and, exit back to C land,
    188         handing the caller the pair (Chain_me_S, RA) */
    189         # if (VG_TRC_CHAIN_ME_TO_SLOW_EP > 128)
    190         # error ("VG_TRC_CHAIN_ME_TO_SLOW_EP is > 128");
    191         # endif
    192         moveli r12, VG_TRC_CHAIN_ME_TO_SLOW_EP
    193         move   r13, lr
    194         /* 32 = mkLoadImm_EXACTLY4
    195         8 = jalr r9
    196         8 = nop */
    197         addi   r13, r13, -40
    198         j      postamble
    199 
    200         /* ------ Chain me to slow entry point ------ */
    201         .global VG_(disp_cp_chain_me_to_fastEP)
    202         VG_(disp_cp_chain_me_to_fastEP):
    203         /* We got called.  The return address indicates
    204         where the patching needs to happen.  Collect
    205         the return address and, exit back to C land,
    206         handing the caller the pair (Chain_me_S, RA) */
    207         # if (VG_TRC_CHAIN_ME_TO_FAST_EP > 128)
    208         # error ("VG_TRC_CHAIN_ME_TO_FAST_EP is > 128");
    209         # endif
    210         moveli r12, VG_TRC_CHAIN_ME_TO_FAST_EP
    211         move   r13, lr
    212         /* 32 = mkLoadImm_EXACTLY4
    213         8 = jalr r9
    214         8 = nop */
    215         addi   r13, r13, -40
    216         j      postamble
    217 
    218         /* ------ Indirect but boring jump ------ */
    219         .global VG_(disp_cp_xindir)
    220         VG_(disp_cp_xindir):
    221         /* Where are we going? */
    222         addli    r11, r50, OFFSET_tilegx_pc
    223         ld       r11, r11
    224 
    225         moveli      r7, hw2_last(VG_(stats__n_xindirs_32))
    226         shl16insli  r7, r7, hw1(VG_(stats__n_xindirs_32))
    227         shl16insli  r7, r7, hw0(VG_(stats__n_xindirs_32))
    228         ld4u   r6, r7
    229         addi   r6, r6, 1
    230         st4    r7, r6
    231 
    232         /* try a fast lookup in the translation cache */
    233         /* r14 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
    234         = (t8 >> 3 & VG_TT_FAST_MASK)  << 3 */
    235 
    236         move    r14, r11
    237         /* Assume VG_TT_FAST_MASK < 4G */
    238         moveli  r12, hw1(VG_TT_FAST_MASK)
    239         shl16insli r12, r12, hw0(VG_TT_FAST_MASK)
    240         shrui   r14, r14, 3
    241         and     r14, r14, r12
    242         shli    r14, r14, 4
    243         /* Note, each tt_fast hash entry has two pointers i.e. 16 Bytes. */
    244 
    245         /* r13 = (addr of VG_(tt_fast)) + r14 */
    246         moveli  r13, hw2_last(VG_(tt_fast))
    247         shl16insli   r13, r13, hw1(VG_(tt_fast))
    248         shl16insli   r13, r13, hw0(VG_(tt_fast))
    249 
    250         add     r13, r13, r14
    251 
    252         /* r12 = VG_(tt_fast)[hash] :: ULong* */
    253         ld_add  r12, r13, 8
    254 
    255         {
    256         ld      r25, r13
    257         sub     r7, r12, r11
    258         }
    259 
    260         bnez     r7, fast_lookup_failed
    261 
    262         /* Run the translation */
    263         jr      r25
    264 
    265         .quad   0x0
    266 
    267 fast_lookup_failed:
    268         /* %PC is up to date */
    269         /* back out decrement of the dispatch counter */
    270         /* hold dispatch_ctr in t0 (r8) */
    271 
    272         moveli      r7, hw2_last(VG_(stats__n_xindir_misses_32))
    273         shl16insli  r7, r7, hw1(VG_(stats__n_xindir_misses_32))
    274         shl16insli  r7, r7, hw0(VG_(stats__n_xindir_misses_32))
    275         ld4u  r6, r7
    276         addi  r6, r6, 1
    277         st4   r7, r6
    278         moveli  r12, VG_TRC_INNER_FASTMISS
    279         movei   r13, 0
    280         j       postamble
    281 
    282         /* ------ Assisted jump ------ */
    283         .global VG_(disp_cp_xassisted)
    284         VG_(disp_cp_xassisted):
    285         /* guest-state-pointer contains the TRC. Put the value into the
    286         return register */
    287         move    r12, r50
    288         movei   r13, 0
    289         j       postamble
    290 
    291         /* ------ Event check failed ------ */
    292         .global VG_(disp_cp_evcheck_fail)
    293         VG_(disp_cp_evcheck_fail):
    294         moveli  r12, VG_TRC_INNER_COUNTERZERO
    295         movei   r13, 0
    296         j       postamble
    297 
    298         .size VG_(disp_run_translations), .-VG_(disp_run_translations)
    299 
    300 
    301         /* Let the linker know we do not need an executable stack */
    302         .section .note.GNU-stack,"",@progbits
    303 
    304 #endif /* defined(VGP_tilegx_linux) */
    305 /*--------------------------------------------------------------------*/
    306 /*--- end                                                          ---*/
    307 /*--------------------------------------------------------------------*/
    308 
    309