blob: 8df8c78914d21ac5b452b0c5414b4c97f9a86847 [file] [log] [blame]
njnc9539842002-10-02 13:26:35 +00001
njn25e49d8e72002-09-23 09:36:25 +00002/*--------------------------------------------------------------------*/
3/*--- Higher-level UCode sequence builders ---*/
4/*--- vg_instrument.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
njnc9539842002-10-02 13:26:35 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
njn25e49d8e72002-09-23 09:36:25 +000010
nethercotebb1c9912004-01-04 16:43:23 +000011 Copyright (C) 2000-2004 Nicholas Nethercote
njn25e49d8e72002-09-23 09:36:25 +000012 njn25@cam.ac.uk
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
nethercote46063202004-09-02 08:51:43 +000032/* We only import tool.h here, because this file only provides functions
nethercote996901a2004-08-03 13:29:09 +000033 for doing things that could be done directly by the tool -- it's just to
34 make tools' lives easier, rather than let them do something they
njn25e49d8e72002-09-23 09:36:25 +000035 couldn't otherwise do. */
nethercote46063202004-09-02 08:51:43 +000036#include "tool.h"
njn25e49d8e72002-09-23 09:36:25 +000037
njn25e49d8e72002-09-23 09:36:25 +000038
nethercote7afcec12004-02-23 16:10:06 +000039void VG_(lit_to_reg)(UCodeBlock* cb, UInt lit, UInt t)
40{
41 uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t);
42 uLiteral(cb, lit);
43}
44
45UInt VG_(lit_to_newreg)(UCodeBlock* cb, UInt lit)
46{
47 UInt t = newTemp(cb);
48 uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t);
49 uLiteral(cb, lit);
50 return t;
51}
52
53// f()
54void VG_(ccall_0_0)(UCodeBlock* cb, Addr f)
njn25e49d8e72002-09-23 09:36:25 +000055{
56 uInstr0(cb, CCALL, 0);
nethercote7afcec12004-02-23 16:10:06 +000057 uCCall(cb, f, 0, 0, /*retval*/False);
58}
59
60// f(reg)
61void VG_(ccall_R_0)(UCodeBlock* cb, Addr f, UInt t1, UInt regparms_n)
62{
63 sk_assert(regparms_n <= 1);
64 uInstr1(cb, CCALL, 0, TempReg, t1);
65 uCCall(cb, f, 1, regparms_n, /*retval*/False);
66}
67
68// f(lit)
69void VG_(ccall_L_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt regparms_n)
70{
71 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
72 VG_(ccall_R_0)(cb, f, t1, regparms_n);
73}
74
75// reg = f(reg)
76void VG_(ccall_R_R)(UCodeBlock* cb, Addr f, UInt t1, UInt t_ret,
77 UInt regparms_n)
78{
79 sk_assert(regparms_n <= 1);
80 sk_assert(t1 < VG_(get_num_temps)(cb)); // help catch lits accidentally passed in
81 uInstr3(cb, CCALL, 0, TempReg, t1, NoValue, 0, TempReg, t_ret);
82 uCCall(cb, f, 1, regparms_n, /*retval*/True);
83}
84
85// reg = f(lit)
86void VG_(ccall_L_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt t_ret,
87 UInt regparms_n)
88{
89 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
90 VG_(ccall_R_R)(cb, f, t1, t_ret, regparms_n);
91}
92
93// f(reg, reg)
94void VG_(ccall_RR_0)(UCodeBlock* cb, Addr f, UInt t1, UInt t2, UInt regparms_n)
95{
96 sk_assert(regparms_n <= 2);
97 sk_assert(t1 < VG_(get_num_temps)(cb));
98 sk_assert(t2 < VG_(get_num_temps)(cb));
99 uInstr2(cb, CCALL, 0, TempReg, t1, TempReg, t2);
100 uCCall(cb, f, 2, regparms_n, /*retval*/False);
101}
102
103// f(reg, lit)
104void VG_(ccall_RL_0)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2,
105 UInt regparms_n)
106{
107 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
108 VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n);
109}
110
111// f(lit, reg)
112void VG_(ccall_LR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2,
113 UInt regparms_n)
114{
115 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
116 VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n);
117}
118
119// f(lit, lit)
120void VG_(ccall_LL_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2,
121 UInt regparms_n)
122{
123 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
124 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
125 VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n);
126}
127
128// reg = f(reg, reg)
129void VG_(ccall_RR_R)(UCodeBlock* cb, Addr f, UInt t1, UInt t2, UInt t_ret,
130 UInt regparms_n)
131{
132 sk_assert(regparms_n <= 2);
133 sk_assert(t1 < VG_(get_num_temps)(cb));
134 sk_assert(t2 < VG_(get_num_temps)(cb));
135 uInstr3(cb, CCALL, 0, TempReg, t1, TempReg, t2, TempReg, t_ret);
136 uCCall(cb, f, 2, regparms_n, /*retval*/True);
137}
138
139// reg = f(reg, lit)
140void VG_(ccall_RL_R)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2, UInt t_ret,
141 UInt regparms_n)
142{
143 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
144 VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n);
145}
146
147// reg = f(lit, reg)
148void VG_(ccall_LR_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2, UInt t_ret,
149 UInt regparms_n)
150{
151 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
152 VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n);
153}
154
155// reg = f(lit, lit)
156void VG_(ccall_LL_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2, UInt t_ret,
157 UInt regparms_n)
158{
159 UInt t1 = VG_(lit_to_newreg)(cb, lit2);
160 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
161 VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n);
162}
163
164// f(reg, reg, reg)
165void VG_(ccall_RRR_0)(UCodeBlock* cb, Addr f, UInt t1, UInt t2,
166 UInt t3, UInt regparms_n)
167{
168 sk_assert(regparms_n <= 3);
169 sk_assert(t1 < VG_(get_num_temps)(cb));
170 sk_assert(t2 < VG_(get_num_temps)(cb));
171 sk_assert(t3 < VG_(get_num_temps)(cb));
172 uInstr3(cb, CCALL, 0, TempReg, t1, TempReg, t2, TempReg, t3);
173 uCCall(cb, f, 3, regparms_n, /*retval*/False);
174}
175
176// f(reg, lit, lit)
177void VG_(ccall_RLL_0)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2,
178 UInt lit3, UInt regparms_n)
179{
180 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
181 UInt t3 = VG_(lit_to_newreg)(cb, lit3);
182 VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n);
183}
184
nethercotec7438502004-07-19 08:18:00 +0000185// f(lit, reg, reg)
186void VG_(ccall_LRR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2,
187 UInt t3, UInt regparms_n)
188{
189 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
190 VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n);
191}
192
nethercote7afcec12004-02-23 16:10:06 +0000193// f(lit, lit, reg)
194void VG_(ccall_LLR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2,
195 UInt t3, UInt regparms_n)
196{
197 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
198 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
199 VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n);
200}
201
202// f(lit, lit, lit)
203void VG_(ccall_LLL_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2,
204 UInt lit3, UInt regparms_n)
205{
206 UInt t1 = VG_(lit_to_newreg)(cb, lit1);
207 UInt t2 = VG_(lit_to_newreg)(cb, lit2);
208 UInt t3 = VG_(lit_to_newreg)(cb, lit3);
209 VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n);
210}
211
212void VG_(reg_to_globvar)(UCodeBlock* cb, UInt t, UInt* globvar_ptr)
213{
214 Int t_gv = VG_(lit_to_newreg)(cb, (UInt)globvar_ptr);
215 uInstr2(cb, STORE, 4, TempReg, t, TempReg, t_gv);
216}
217
218void VG_(lit_to_globvar)(UCodeBlock* cb, UInt lit, UInt* globvar_ptr)
219{
220 Int t_lit = VG_(lit_to_newreg)(cb, lit);
221 VG_(reg_to_globvar)(cb, t_lit, globvar_ptr);
222}
223
224/*--------------------------------------------------------------------
225 Old versions of these functions, for backwards compatibility
226 --------------------------------------------------------------------*/
227
228void VG_(call_helper_0_0)(UCodeBlock* cb, Addr f)
229{
230 VG_(ccall_0_0)(cb, f);
njn25e49d8e72002-09-23 09:36:25 +0000231}
232
njn4ba5a792002-09-30 10:23:54 +0000233void VG_(call_helper_1_0)(UCodeBlock* cb, Addr f, UInt arg1, UInt regparms_n)
njn25e49d8e72002-09-23 09:36:25 +0000234{
nethercote7afcec12004-02-23 16:10:06 +0000235 VG_(ccall_L_0)(cb, f, arg1, regparms_n);
njn25e49d8e72002-09-23 09:36:25 +0000236}
237
njn4ba5a792002-09-30 10:23:54 +0000238void VG_(call_helper_2_0)(UCodeBlock* cb, Addr f, UInt arg1, UInt arg2,
njn25e49d8e72002-09-23 09:36:25 +0000239 UInt regparms_n)
240{
nethercote7afcec12004-02-23 16:10:06 +0000241 VG_(ccall_LL_0)(cb, f, arg1, arg2, regparms_n);
njn25e49d8e72002-09-23 09:36:25 +0000242}
243
244void VG_(set_global_var)(UCodeBlock* cb, Addr globvar_ptr, UInt val)
245{
nethercote7afcec12004-02-23 16:10:06 +0000246 VG_(lit_to_globvar)(cb, val, (UInt*)globvar_ptr);
njn25e49d8e72002-09-23 09:36:25 +0000247}
248
njn6fefa1b2003-02-24 10:32:51 +0000249void VG_(set_global_var_tempreg)(UCodeBlock* cb, Addr globvar_ptr, UInt t_val)
250{
nethercote7afcec12004-02-23 16:10:06 +0000251 VG_(reg_to_globvar)(cb, t_val, (UInt*)globvar_ptr);
njn6fefa1b2003-02-24 10:32:51 +0000252}
253
njn25e49d8e72002-09-23 09:36:25 +0000254/*--------------------------------------------------------------------*/
255/*--- end vg_instrument.c ---*/
256/*--------------------------------------------------------------------*/
257
nethercote7afcec12004-02-23 16:10:06 +0000258