regtest: add a fdleak filter for write on write on linux arm64
[valgrind.git] / coregrind / m_dispatch / dispatch-nanomips-linux.S
blob30d54994fd0cc3a3e60939de1cafa0dae46a4c7e
1 /*--------------------------------------------------------------------*/
2 /*--- The core dispatch loop, for jumping to a code address.       ---*/
3 /*---                                    dispatch-nanomips-linux.S ---*/
4 /*--------------------------------------------------------------------*/
6 #   This file is part of Valgrind, a dynamic binary instrumentation
7 #   framework.
9 #   Copyright (C) 2017-2018 RT-RK
11 #   This program is free software; you can redistribute it and/or
12 #   modify it under the terms of the GNU General Public License as
13 #   published by the Free Software Foundation; either version 2 of the
14 #   License, or (at your option) any later version.
16 #   This program is distributed in the hope that it will be useful, but
17 #   WITHOUT ANY WARRANTY; without even the implied warranty of
18 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 #   General Public License for more details.
21 #    You should have received a copy of the GNU General Public License
22 #    along with this program; if not, write to the Free Software
23 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 #    02111-1307, USA.
26 #   The GNU General Public License is contained in the file COPYING.
28 #include "pub_core_basics_asm.h"
30 #if defined(VGP_nanomips_linux)
32 #include "pub_core_dispatch_asm.h"
33 #include "pub_core_transtab_asm.h"
34 #include "libvex_guest_offsets.h"   /* for OFFSET_mips_PC */
36 # Signature:
37 # void VG_(disp_run_translations)( UWord* two_words,
38 #                                  void*  guest_state,
39 #                                  Addr   host_addr);
41 # The dispatch loop.  VG_(disp_run_translations) is used to run all
42 # translations, including no-redir ones.
44 .text
45 .globl VG_(disp_run_translations)
46 VG_(disp_run_translations):
47 # a0 holds two_words
48 # a1 holds guest_state
49 # a2 holds host_addr
50    save 32, $s0-$s7
51    save 32, $fp-$ra
52    sw $gp, 20($sp)
53    sw $a0, 16($sp)
55 # Load address of guest_state into guest state register ($s7)
56    move $s7, $a1
58 # And jump into the code cache.  Chained translations in
59 # the code cache run, until for whatever reason, they can't
60 # continue.  When that happens, the translation in question
61 # will jump (or call) to one of the continuation points
62 # VG_(cp_...) below.
64    jrc $a2
66 # * Postamble and exit:
67    postamble:
68 # At this point, $t4 and $t5 contain two
69 # words to be returned to the caller.  $t4
70 # holds a TRC value, and $t5 optionally may
71 # hold another word (for CHAIN_ME exits, the
72 # address of the place to patch.)
74 #  Restore $a0 from stack; holds address of two_words
75    lw $a0, 16($sp)
76    sw $t4, 0($a0)      # Store $t4 to two_words[0]
77    sw $t5, 4($a0)      # Store $t5 to two_words[1]
79    lw $gp, 20($sp)
80    restore 32, $fp-$ra
81    restore 32, $s0-$s7
83    jrc $ra
85 # * Continuation points:
87 .global VG_(disp_cp_chain_me_to_slowEP)
88 VG_(disp_cp_chain_me_to_slowEP):
89 # We got called.  The return address indicates
90 # where the patching needs to happen. Collect
91 # the return address and, exit back to C land,
92 # handing the caller the pair (Chain_me_S, RA) */
93    li $t4, VG_TRC_CHAIN_ME_TO_SLOW_EP
94 #  8 = mkLoadImm32_EXACTLY2
95 #  4 = jalrc $9
96    addiu  $t5, $ra, -12
97    bc postamble
99 .global VG_(disp_cp_chain_me_to_fastEP)
100 VG_(disp_cp_chain_me_to_fastEP):
101 # We got called. The return address indicates
102 # where the patching needs to happen. Collect
103 # the return address and, exit back to C land,
104 # handing the caller the pair (Chain_me_S, RA) */
105    li $t4, VG_TRC_CHAIN_ME_TO_FAST_EP
106 #  8 = mkLoadImm32_EXACTLY2
107 #  4 = jalrc $9
108    addiu  $t5, $ra, -12
109    bc postamble
111 .global VG_(disp_cp_xindir)
112 VG_(disp_cp_xindir):
113 # /* Where are we going? */
114    lw $a7, OFFSET_mips32_PC($s7)
115    lw $t1, VG_(stats__n_xIndirs_32)
116    addiu $t1, $t1, 1
117    sw $t1, VG_(stats__n_xIndirs_32)
119 # try a fast lookup in the translation cache
120 # t2 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
121 #    = (t2 >> 2 & VG_TT_FAST_MASK)  << 3
122    move $t2, $a7
123    li $t0, VG_TT_FAST_MASK
124    srl $t2, $t2, 2
125    and $t2, $t2, $t0
126    sll $t2, $t2, 3
128 # t1 = (addr of VG_(tt_fast)) + t2
129    la $t1, VG_(tt_fast)
130    addu $t1, $t1, $t2
132 # t9 = VG_(tt_fast)[hash] :: ULong*
133    lw $t0, 0($t1)
134    addiu $t1, $t1, 4
135    lw $t9, 0($t1)
137 # little-endian, so comparing 1st 32bit word
138    bnec $t0, $a7, fast_lookup_failed
139    jrc $t9
141    fast_lookup_failed:
142 #  %PC is up to date */
143 #  back out decrement of the dispatch counter */
144 #  hold dispatch_ctr in t0 (r8) */
145    lw $t1, VG_(stats__n_xIndirs_32)
146    addiu $t1, $t1, 0x1
147    sw $t1, VG_(stats__n_xIndirs_32)
148    li $t4, VG_TRC_INNER_FASTMISS
149    move $t5, $zero
150    bc postamble
152 .global VG_(disp_cp_xassisted)
153 VG_(disp_cp_xassisted):
154 # guest-state-pointer contains the TRC. Put the value into the
155 # return register
156    move $t4, $s7
157    move $t5, $zero
158    bc postamble
160 .global VG_(disp_cp_evcheck_fail)
161 VG_(disp_cp_evcheck_fail):
162    li $t4, VG_TRC_INNER_COUNTERZERO
163    move $t5, $zero
164    bc postamble
166 .size VG_(disp_run_translations), . - VG_(disp_run_translations)
168 #endif
170 # Let the linker know we don't need an executable stack
171 MARK_STACK_NO_EXEC
173 /*--------------------------------------------------------------------*/
174 /*--- end                               dispatch-nanomips-linux.S  ---*/
175 /*--------------------------------------------------------------------*/