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 126postamble: 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 267fast_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