mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 10:21:20 +00:00
176 lines
5.1 KiB
ArmAsm
176 lines
5.1 KiB
ArmAsm
/*--------------------------------------------------------------------*/
|
|
/*--- The core dispatch loop, for jumping to a code address. ---*/
|
|
/*--- dispatch-nanomips-linux.S ---*/
|
|
/*--------------------------------------------------------------------*/
|
|
|
|
# This file is part of Valgrind, a dynamic binary instrumentation
|
|
# framework.
|
|
|
|
# Copyright (C) 2017-2018 RT-RK
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License as
|
|
# published by the Free Software Foundation; either version 2 of the
|
|
# License, or (at your option) any later version.
|
|
|
|
# This program is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
# 02111-1307, USA.
|
|
|
|
# The GNU General Public License is contained in the file COPYING.
|
|
|
|
#include "pub_core_basics_asm.h"
|
|
|
|
#if defined(VGP_nanomips_linux)
|
|
|
|
#include "pub_core_dispatch_asm.h"
|
|
#include "pub_core_transtab_asm.h"
|
|
#include "libvex_guest_offsets.h" /* for OFFSET_mips_PC */
|
|
|
|
# Signature:
|
|
# void VG_(disp_run_translations)( UWord* two_words,
|
|
# void* guest_state,
|
|
# Addr host_addr);
|
|
|
|
# The dispatch loop. VG_(disp_run_translations) is used to run all
|
|
# translations, including no-redir ones.
|
|
|
|
.text
|
|
.globl VG_(disp_run_translations)
|
|
VG_(disp_run_translations):
|
|
# a0 holds two_words
|
|
# a1 holds guest_state
|
|
# a2 holds host_addr
|
|
save 32, $s0-$s7
|
|
save 32, $fp-$ra
|
|
sw $gp, 20($sp)
|
|
sw $a0, 16($sp)
|
|
|
|
# Load address of guest_state into guest state register ($s7)
|
|
move $s7, $a1
|
|
|
|
# And jump into the code cache. Chained translations in
|
|
# the code cache run, until for whatever reason, they can't
|
|
# continue. When that happens, the translation in question
|
|
# will jump (or call) to one of the continuation points
|
|
# VG_(cp_...) below.
|
|
|
|
jrc $a2
|
|
|
|
# * Postamble and exit:
|
|
postamble:
|
|
# At this point, $t4 and $t5 contain two
|
|
# words to be returned to the caller. $t4
|
|
# holds a TRC value, and $t5 optionally may
|
|
# hold another word (for CHAIN_ME exits, the
|
|
# address of the place to patch.)
|
|
|
|
# Restore $a0 from stack; holds address of two_words
|
|
lw $a0, 16($sp)
|
|
sw $t4, 0($a0) # Store $t4 to two_words[0]
|
|
sw $t5, 4($a0) # Store $t5 to two_words[1]
|
|
|
|
lw $gp, 20($sp)
|
|
restore 32, $fp-$ra
|
|
restore 32, $s0-$s7
|
|
|
|
jrc $ra
|
|
|
|
# * Continuation points:
|
|
|
|
.global VG_(disp_cp_chain_me_to_slowEP)
|
|
VG_(disp_cp_chain_me_to_slowEP):
|
|
# We got called. The return address indicates
|
|
# where the patching needs to happen. Collect
|
|
# the return address and, exit back to C land,
|
|
# handing the caller the pair (Chain_me_S, RA) */
|
|
li $t4, VG_TRC_CHAIN_ME_TO_SLOW_EP
|
|
# 8 = mkLoadImm32_EXACTLY2
|
|
# 4 = jalrc $9
|
|
addiu $t5, $ra, -12
|
|
bc postamble
|
|
|
|
.global VG_(disp_cp_chain_me_to_fastEP)
|
|
VG_(disp_cp_chain_me_to_fastEP):
|
|
# We got called. The return address indicates
|
|
# where the patching needs to happen. Collect
|
|
# the return address and, exit back to C land,
|
|
# handing the caller the pair (Chain_me_S, RA) */
|
|
li $t4, VG_TRC_CHAIN_ME_TO_FAST_EP
|
|
# 8 = mkLoadImm32_EXACTLY2
|
|
# 4 = jalrc $9
|
|
addiu $t5, $ra, -12
|
|
bc postamble
|
|
|
|
.global VG_(disp_cp_xindir)
|
|
VG_(disp_cp_xindir):
|
|
# /* Where are we going? */
|
|
lw $a7, OFFSET_mips32_PC($s7)
|
|
lw $t1, VG_(stats__n_xIndirs_32)
|
|
addiu $t1, $t1, 1
|
|
sw $t1, VG_(stats__n_xIndirs_32)
|
|
|
|
# try a fast lookup in the translation cache
|
|
# t2 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
|
|
# = (t2 >> 2 & VG_TT_FAST_MASK) << 3
|
|
move $t2, $a7
|
|
li $t0, VG_TT_FAST_MASK
|
|
srl $t2, $t2, 2
|
|
and $t2, $t2, $t0
|
|
sll $t2, $t2, 3
|
|
|
|
# t1 = (addr of VG_(tt_fast)) + t2
|
|
la $t1, VG_(tt_fast)
|
|
addu $t1, $t1, $t2
|
|
|
|
# t9 = VG_(tt_fast)[hash] :: ULong*
|
|
lw $t0, 0($t1)
|
|
addiu $t1, $t1, 4
|
|
lw $t9, 0($t1)
|
|
|
|
# little-endian, so comparing 1st 32bit word
|
|
bnec $t0, $a7, fast_lookup_failed
|
|
jrc $t9
|
|
|
|
fast_lookup_failed:
|
|
# %PC is up to date */
|
|
# back out decrement of the dispatch counter */
|
|
# hold dispatch_ctr in t0 (r8) */
|
|
lw $t1, VG_(stats__n_xIndirs_32)
|
|
addiu $t1, $t1, 0x1
|
|
sw $t1, VG_(stats__n_xIndirs_32)
|
|
li $t4, VG_TRC_INNER_FASTMISS
|
|
move $t5, $zero
|
|
bc postamble
|
|
|
|
.global VG_(disp_cp_xassisted)
|
|
VG_(disp_cp_xassisted):
|
|
# guest-state-pointer contains the TRC. Put the value into the
|
|
# return register
|
|
move $t4, $s7
|
|
move $t5, $zero
|
|
bc postamble
|
|
|
|
.global VG_(disp_cp_evcheck_fail)
|
|
VG_(disp_cp_evcheck_fail):
|
|
li $t4, VG_TRC_INNER_COUNTERZERO
|
|
move $t5, $zero
|
|
bc postamble
|
|
|
|
.size VG_(disp_run_translations), . - VG_(disp_run_translations)
|
|
|
|
#endif
|
|
|
|
# Let the linker know we don't need an executable stack
|
|
MARK_STACK_NO_EXEC
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/*--- end dispatch-nanomips-linux.S ---*/
|
|
/*--------------------------------------------------------------------*/
|