1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The core dispatch loop, for jumping to a code address. ---*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- dispatch-arm-linux.S ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2008-2011 Evan Geller 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gaze@bea.ms 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_arm_linux) 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .fpu vfp 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics_asm.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_dispatch_asm.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_transtab_asm.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_offsets.h" /* for OFFSET_arm_R* */ 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The dispatch loop. VG_(run_innerloop) is used to ---*/ 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- run all translations except no-redir ones. ---*/ 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Preamble (set everything up) ---*/ 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* signature: 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling ); 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.text 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.globl VG_(run_innerloop) 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_(run_innerloop): 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push {r0, r1, r4, r5, r6, r7, r8, r9, fp, lr} 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* set FPSCR to vex-required default value */ 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r4, #0 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fmxr fpscr, r4 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* r0 (hence also [sp,#0]) holds guest_state */ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* r1 holds do_profiling */ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r8, r0 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r0, [r8, #OFFSET_arm_R15T] 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* fall into main loop (the right one) */ 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmp r1, #0 /* do_profiling */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown beq VG_(run_innerloop__dispatch_unprofiled) 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b VG_(run_innerloop__dispatch_profiled) 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- NO-PROFILING (standard) dispatcher ---*/ 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Pairing of insns below is my guesstimate of how dual dispatch would 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov work on an A8. JRS, 2011-May-28 */ 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.global VG_(run_innerloop__dispatch_unprofiled) 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_(run_innerloop__dispatch_unprofiled): 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* AT ENTRY: r0 is next guest addr, r8 is possibly 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified guest state ptr */ 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Has the guest state pointer been messed with? If yes, exit. */ 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r3, #:lower16:VG_(dispatch_ctr) 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tst r8, #1 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movt r3, #:upper16:VG_(dispatch_ctr) 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bne gsp_changed 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* save the jump address in the guest state */ 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r0, [r8, #OFFSET_arm_R15T] 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Are we out of timeslice? If yes, defer to scheduler. */ 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldr r2, [r3] 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subs r2, r2, #1 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov str r2, [r3] 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown beq counter_is_zero 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* try a fast lookup in the translation cache */ 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r0 = next guest, r1,r2,r3,r4 scratch 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r1, #VG_TT_FAST_MASK // r1 = VG_TT_FAST_MASK 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r4, #:lower16:VG_(tt_fast) 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and r2, r1, r0, LSR #1 // r2 = entry # 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movt r4, #:upper16:VG_(tt_fast) // r4 = &VG_(tt_fast) 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov add r1, r4, r2, LSL #3 // r1 = &tt_fast[entry#] 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldrd r4, r5, [r1, #0] // r4 = .guest, r5 = .host 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov cmp r4, r0 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bne fast_lookup_failed 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r5: next-host r8: live, gsp 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r4: next-guest 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r2: entry # 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // LIVE: r5, r8; all others dead 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Found a match. Jump to .host. */ 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov blx r5 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b VG_(run_innerloop__dispatch_unprofiled) 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ltorg 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- PROFILING dispatcher (can be much slower) ---*/ 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.global VG_(run_innerloop__dispatch_profiled) 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_(run_innerloop__dispatch_profiled): 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* AT ENTRY: r0 is next guest addr, r8 is possibly 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified guest state ptr */ 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Has the guest state pointer been messed with? If yes, exit. */ 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r3, #:lower16:VG_(dispatch_ctr) 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tst r8, #1 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movt r3, #:upper16:VG_(dispatch_ctr) 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bne gsp_changed 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* save the jump address in the guest state */ 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r0, [r8, #OFFSET_arm_R15T] 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Are we out of timeslice? If yes, defer to scheduler. */ 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldr r2, [r3] 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subs r2, r2, #1 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov str r2, [r3] 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown beq counter_is_zero 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* try a fast lookup in the translation cache */ 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r0 = next guest, r1,r2,r3,r4 scratch 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r1, #VG_TT_FAST_MASK // r1 = VG_TT_FAST_MASK 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r4, #:lower16:VG_(tt_fast) 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and r2, r1, r0, LSR #1 // r2 = entry # 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movt r4, #:upper16:VG_(tt_fast) // r4 = &VG_(tt_fast) 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov add r1, r4, r2, LSL #3 // r1 = &tt_fast[entry#] 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldrd r4, r5, [r1, #0] // r4 = .guest, r5 = .host 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov cmp r4, r0 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bne fast_lookup_failed 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r5: next-host r8: live, gsp 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r4: next-guest 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // r2: entry # 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // LIVE: r5, r8; all others dead 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* increment bb profile counter */ 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movw r0, #:lower16:VG_(tt_fastN) 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov movt r0, #:upper16:VG_(tt_fastN) // r0 = &tt_fastN[0] 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldr r0, [r0, r2, LSL #2] // r0 = tt_fast[entry #] 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldr r3, [r0] // *r0 ++ 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add r3, r3, #1 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r3, [r0] 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Found a match. Jump to .host. */ 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov blx r5 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b VG_(run_innerloop__dispatch_profiled) 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- exit points ---*/ 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*----------------------------------------------------*/ 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browngsp_changed: 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // r0 = next guest addr (R15T), r8 = modified gsp 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Someone messed with the gsp. Have to 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown defer to scheduler to resolve this. dispatch ctr 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is not yet decremented, so no need to increment. */ 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* R15T is NOT up to date here. First, need to write 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r0 back to R15T, but without trashing r8 since 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that holds the value we want to return to the scheduler. 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Hence use r1 transiently for the guest state pointer. */ 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r1, [sp, #0] 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r0, [r1, #OFFSET_arm_R15T] 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r0, r8 // "return modified gsp" 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b run_innerloop_exit 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncounter_is_zero: 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* R15T is up to date here */ 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Back out increment of the dispatch ctr */ 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r1, =VG_(dispatch_ctr) 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r2, [r1] 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add r2, r2, #1 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r2, [r1] 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r0, #VG_TRC_INNER_COUNTERZERO 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b run_innerloop_exit 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfast_lookup_failed: 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* R15T is up to date here */ 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Back out increment of the dispatch ctr */ 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r1, =VG_(dispatch_ctr) 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r2, [r1] 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add r2, r2, #1 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r2, [r1] 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r0, #VG_TRC_INNER_FASTMISS 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b run_innerloop_exit 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* All exits from the dispatcher go through here. %r0 holds 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the return value. 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownrun_innerloop_exit: 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We're leaving. Check that nobody messed with 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown FPSCR in ways we don't expect. */ 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fmrx r4, fpscr 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bic r4, #0xF8000000 /* mask out NZCV and QC */ 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bic r4, #0x0000009F /* mask out IDC,IXC,UFC,OFC,DZC,IOC */ 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmp r4, #0 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bne invariant_violation 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b run_innerloop_exit_REALLY 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browninvariant_violation: 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov r0, #VG_TRC_INVARIANT_FAILED 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b run_innerloop_exit_REALLY 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownrun_innerloop_exit_REALLY: 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add sp, sp, #8 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pop {r4, r5, r6, r7, r8, r9, fp, pc} 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.size VG_(run_innerloop), .-VG_(run_innerloop) 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- A special dispatcher, for running no-redir ---*/ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- translations. Just runs the given translation once. ---*/ 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* signature: 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(run_a_noredir_translation) ( UWord* argblock ); 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Run a no-redir translation. argblock points to 4 UWords, 2 to carry args 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and 2 to carry results: 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0: input: ptr to translation 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1: input: ptr to guest state 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2: output: next guest PC 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3: output: guest state pointer afterwards (== thread return code) 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.global VG_(run_a_noredir_translation) 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_(run_a_noredir_translation): 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push {r0,r1 /* EABI compliance */, r4-r12, lr} 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr r8, [r0, #4] 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mov lr, pc 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ldr pc, [r0, #0] 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pop {r1} 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r0, [r1, #8] 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str r8, [r1, #12] 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pop {r1/*EABI compliance*/,r4-r12, pc} 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.size VG_(run_a_noredir_translation), .-VG_(run_a_noredir_translation) 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Let the linker know we don't need an executable stack */ 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.section .note.GNU-stack,"",%progbits 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGP_arm_linux) 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end dispatch-arm-linux.S ---*/ 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 301