blob: 49590ee5988e72fa8b59508974f6e0c728addcb4 [file] [log] [blame]
nethercotebb1c9912004-01-04 16:43:23 +00001
njn25e49d8e72002-09-23 09:36:25 +00002/*--------------------------------------------------------------------*/
sewardj95448072004-11-22 20:19:51 +00003/*--- Instrument IR to perform memory checking operations. ---*/
njn25cac76cb2002-09-23 11:21:57 +00004/*--- mc_translate.c ---*/
njn25e49d8e72002-09-23 09:36:25 +00005/*--------------------------------------------------------------------*/
njnc9539842002-10-02 13:26:35 +00006
njn25e49d8e72002-09-23 09:36:25 +00007/*
nethercote137bc552003-11-14 17:47:54 +00008 This file is part of MemCheck, a heavyweight Valgrind tool for
njnc9539842002-10-02 13:26:35 +00009 detecting memory errors.
njn25e49d8e72002-09-23 09:36:25 +000010
njn53612422005-03-12 16:22:54 +000011 Copyright (C) 2000-2005 Julian Seward
njn25e49d8e72002-09-23 09:36:25 +000012 jseward@acm.org
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
njnc7561b92005-06-19 01:24:32 +000032#include "pub_tool_basics.h"
33#include "pub_tool_hashtable.h" // For mac_shared.h
njn132bfcc2005-06-04 19:16:06 +000034#include "pub_tool_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000035#include "pub_tool_libcprint.h"
njnc7561b92005-06-19 01:24:32 +000036#include "pub_tool_profile.h"
37#include "pub_tool_tooliface.h"
38#include "mc_include.h"
njn25e49d8e72002-09-23 09:36:25 +000039
njn25e49d8e72002-09-23 09:36:25 +000040
sewardj95448072004-11-22 20:19:51 +000041/*------------------------------------------------------------*/
42/*--- Forward decls ---*/
43/*------------------------------------------------------------*/
44
45struct _MCEnv;
46
47static IRType shadowType ( IRType ty );
48static IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e );
49
50
51/*------------------------------------------------------------*/
52/*--- Memcheck running state, and tmp management. ---*/
53/*------------------------------------------------------------*/
54
55/* Carries around state during memcheck instrumentation. */
56typedef
57 struct _MCEnv {
58 /* MODIFIED: the bb being constructed. IRStmts are added. */
59 IRBB* bb;
60
61 /* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps
62 original temps to their current their current shadow temp.
63 Initially all entries are IRTemp_INVALID. Entries are added
64 lazily since many original temps are not used due to
65 optimisation prior to instrumentation. Note that floating
66 point original tmps are shadowed by integer tmps of the same
67 size, and Bit-typed original tmps are shadowed by the type
68 Ity_I8. See comment below. */
69 IRTemp* tmpMap;
70 Int n_originalTmps; /* for range checking */
71
sewardjd5204dc2004-12-31 01:16:11 +000072 /* MODIFIED: indicates whether "bogus" literals have so far been
73 found. Starts off False, and may change to True. */
74 Bool bogusLiterals;
75
sewardj95448072004-11-22 20:19:51 +000076 /* READONLY: the guest layout. This indicates which parts of
77 the guest state should be regarded as 'always defined'. */
78 VexGuestLayout* layout;
79 /* READONLY: the host word type. Needed for constructing
80 arguments of type 'HWord' to be passed to helper functions.
81 Ity_I32 or Ity_I64 only. */
82 IRType hWordTy;
83 }
84 MCEnv;
85
86/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on
87 demand), as they are encountered. This is for two reasons.
88
89 (1) (less important reason): Many original tmps are unused due to
90 initial IR optimisation, and we do not want to spaces in tables
91 tracking them.
92
93 Shadow IRTemps are therefore allocated on demand. mce.tmpMap is a
94 table indexed [0 .. n_types-1], which gives the current shadow for
95 each original tmp, or INVALID_IRTEMP if none is so far assigned.
96 It is necessary to support making multiple assignments to a shadow
97 -- specifically, after testing a shadow for definedness, it needs
98 to be made defined. But IR's SSA property disallows this.
99
100 (2) (more important reason): Therefore, when a shadow needs to get
101 a new value, a new temporary is created, the value is assigned to
102 that, and the tmpMap is updated to reflect the new binding.
103
104 A corollary is that if the tmpMap maps a given tmp to
105 INVALID_IRTEMP and we are hoping to read that shadow tmp, it means
106 there's a read-before-write error in the original tmps. The IR
107 sanity checker should catch all such anomalies, however.
njn25e49d8e72002-09-23 09:36:25 +0000108*/
sewardj95448072004-11-22 20:19:51 +0000109
110/* Find the tmp currently shadowing the given original tmp. If none
111 so far exists, allocate one. */
112static IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig )
njn25e49d8e72002-09-23 09:36:25 +0000113{
sewardj95448072004-11-22 20:19:51 +0000114 tl_assert(orig < mce->n_originalTmps);
115 if (mce->tmpMap[orig] == IRTemp_INVALID) {
116 mce->tmpMap[orig]
117 = newIRTemp(mce->bb->tyenv,
118 shadowType(mce->bb->tyenv->types[orig]));
njn25e49d8e72002-09-23 09:36:25 +0000119 }
sewardj95448072004-11-22 20:19:51 +0000120 return mce->tmpMap[orig];
njn25e49d8e72002-09-23 09:36:25 +0000121}
122
sewardj95448072004-11-22 20:19:51 +0000123/* Allocate a new shadow for the given original tmp. This means any
124 previous shadow is abandoned. This is needed because it is
125 necessary to give a new value to a shadow once it has been tested
126 for undefinedness, but unfortunately IR's SSA property disallows
127 this. Instead we must abandon the old shadow, allocate a new one
128 and use that instead. */
129static void newShadowTmp ( MCEnv* mce, IRTemp orig )
njn25e49d8e72002-09-23 09:36:25 +0000130{
sewardj95448072004-11-22 20:19:51 +0000131 tl_assert(orig < mce->n_originalTmps);
132 mce->tmpMap[orig]
133 = newIRTemp(mce->bb->tyenv,
134 shadowType(mce->bb->tyenv->types[orig]));
135}
136
137
138/*------------------------------------------------------------*/
139/*--- IRAtoms -- a subset of IRExprs ---*/
140/*------------------------------------------------------------*/
141
142/* An atom is either an IRExpr_Const or an IRExpr_Tmp, as defined by
sewardj710d6c22005-03-20 18:55:15 +0000143 isIRAtom() in libvex_ir.h. Because this instrumenter expects flat
sewardj95448072004-11-22 20:19:51 +0000144 input, most of this code deals in atoms. Usefully, a value atom
145 always has a V-value which is also an atom: constants are shadowed
146 by constants, and temps are shadowed by the corresponding shadow
147 temporary. */
148
149typedef IRExpr IRAtom;
150
151/* (used for sanity checks only): is this an atom which looks
152 like it's from original code? */
153static Bool isOriginalAtom ( MCEnv* mce, IRAtom* a1 )
154{
155 if (a1->tag == Iex_Const)
156 return True;
157 if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp < mce->n_originalTmps)
158 return True;
159 return False;
160}
161
162/* (used for sanity checks only): is this an atom which looks
163 like it's from shadow code? */
164static Bool isShadowAtom ( MCEnv* mce, IRAtom* a1 )
165{
166 if (a1->tag == Iex_Const)
167 return True;
168 if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp >= mce->n_originalTmps)
169 return True;
170 return False;
171}
172
173/* (used for sanity checks only): check that both args are atoms and
174 are identically-kinded. */
175static Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 )
176{
177 if (a1->tag == Iex_Tmp && a1->tag == Iex_Tmp)
178 return True;
179 if (a1->tag == Iex_Const && a1->tag == Iex_Const)
180 return True;
181 return False;
182}
183
184
185/*------------------------------------------------------------*/
186/*--- Type management ---*/
187/*------------------------------------------------------------*/
188
189/* Shadow state is always accessed using integer types. This returns
190 an integer type with the same size (as per sizeofIRType) as the
191 given type. The only valid shadow types are Bit, I8, I16, I32,
sewardj3245c912004-12-10 14:58:26 +0000192 I64, V128. */
sewardj95448072004-11-22 20:19:51 +0000193
194static IRType shadowType ( IRType ty )
195{
196 switch (ty) {
197 case Ity_I1:
198 case Ity_I8:
199 case Ity_I16:
200 case Ity_I32:
sewardj6cf40ff2005-04-20 22:31:26 +0000201 case Ity_I64:
202 case Ity_I128: return ty;
sewardj3245c912004-12-10 14:58:26 +0000203 case Ity_F32: return Ity_I32;
204 case Ity_F64: return Ity_I64;
205 case Ity_V128: return Ity_V128;
sewardj95448072004-11-22 20:19:51 +0000206 default: ppIRType(ty);
207 VG_(tool_panic)("memcheck:shadowType");
208 }
209}
210
211/* Produce a 'defined' value of the given shadow type. Should only be
212 supplied shadow types (Bit/I8/I16/I32/UI64). */
213static IRExpr* definedOfType ( IRType ty ) {
214 switch (ty) {
sewardj170ee212004-12-10 18:57:51 +0000215 case Ity_I1: return IRExpr_Const(IRConst_U1(False));
216 case Ity_I8: return IRExpr_Const(IRConst_U8(0));
217 case Ity_I16: return IRExpr_Const(IRConst_U16(0));
218 case Ity_I32: return IRExpr_Const(IRConst_U32(0));
219 case Ity_I64: return IRExpr_Const(IRConst_U64(0));
220 case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000));
sewardj95448072004-11-22 20:19:51 +0000221 default: VG_(tool_panic)("memcheck:definedOfType");
njn25e49d8e72002-09-23 09:36:25 +0000222 }
223}
224
225
sewardj95448072004-11-22 20:19:51 +0000226/*------------------------------------------------------------*/
227/*--- Constructing IR fragments ---*/
228/*------------------------------------------------------------*/
229
230/* assign value to tmp */
231#define assign(_bb,_tmp,_expr) \
232 addStmtToIRBB((_bb), IRStmt_Tmp((_tmp),(_expr)))
233
234/* add stmt to a bb */
235#define stmt(_bb,_stmt) \
236 addStmtToIRBB((_bb), (_stmt))
237
238/* build various kinds of expressions */
239#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
240#define unop(_op, _arg) IRExpr_Unop((_op),(_arg))
241#define mkU8(_n) IRExpr_Const(IRConst_U8(_n))
242#define mkU16(_n) IRExpr_Const(IRConst_U16(_n))
243#define mkU32(_n) IRExpr_Const(IRConst_U32(_n))
244#define mkU64(_n) IRExpr_Const(IRConst_U64(_n))
sewardj170ee212004-12-10 18:57:51 +0000245#define mkV128(_n) IRExpr_Const(IRConst_V128(_n))
sewardj95448072004-11-22 20:19:51 +0000246#define mkexpr(_tmp) IRExpr_Tmp((_tmp))
247
248/* bind the given expression to a new temporary, and return the
249 temporary. This effectively converts an arbitrary expression into
250 an atom. */
251static IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) {
252 IRTemp t = newIRTemp(mce->bb->tyenv, ty);
253 assign(mce->bb, t, e);
254 return mkexpr(t);
255}
256
257
258/*------------------------------------------------------------*/
259/*--- Constructing definedness primitive ops ---*/
260/*------------------------------------------------------------*/
261
262/* --------- Defined-if-either-defined --------- */
263
264static IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
265 tl_assert(isShadowAtom(mce,a1));
266 tl_assert(isShadowAtom(mce,a2));
267 return assignNew(mce, Ity_I8, binop(Iop_And8, a1, a2));
268}
269
270static IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
271 tl_assert(isShadowAtom(mce,a1));
272 tl_assert(isShadowAtom(mce,a2));
273 return assignNew(mce, Ity_I16, binop(Iop_And16, a1, a2));
274}
275
276static IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
277 tl_assert(isShadowAtom(mce,a1));
278 tl_assert(isShadowAtom(mce,a2));
279 return assignNew(mce, Ity_I32, binop(Iop_And32, a1, a2));
280}
281
sewardj7010f6e2004-12-10 13:35:22 +0000282static IRAtom* mkDifD64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
283 tl_assert(isShadowAtom(mce,a1));
284 tl_assert(isShadowAtom(mce,a2));
285 return assignNew(mce, Ity_I64, binop(Iop_And64, a1, a2));
286}
287
sewardj20d38f22005-02-07 23:50:18 +0000288static IRAtom* mkDifDV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
sewardj170ee212004-12-10 18:57:51 +0000289 tl_assert(isShadowAtom(mce,a1));
290 tl_assert(isShadowAtom(mce,a2));
sewardj20d38f22005-02-07 23:50:18 +0000291 return assignNew(mce, Ity_V128, binop(Iop_AndV128, a1, a2));
sewardj170ee212004-12-10 18:57:51 +0000292}
293
sewardj95448072004-11-22 20:19:51 +0000294/* --------- Undefined-if-either-undefined --------- */
295
296static IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
297 tl_assert(isShadowAtom(mce,a1));
298 tl_assert(isShadowAtom(mce,a2));
299 return assignNew(mce, Ity_I8, binop(Iop_Or8, a1, a2));
300}
301
302static IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
303 tl_assert(isShadowAtom(mce,a1));
304 tl_assert(isShadowAtom(mce,a2));
305 return assignNew(mce, Ity_I16, binop(Iop_Or16, a1, a2));
306}
307
308static IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
309 tl_assert(isShadowAtom(mce,a1));
310 tl_assert(isShadowAtom(mce,a2));
311 return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2));
312}
313
314static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
315 tl_assert(isShadowAtom(mce,a1));
316 tl_assert(isShadowAtom(mce,a2));
317 return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2));
318}
319
sewardj20d38f22005-02-07 23:50:18 +0000320static IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
sewardj3245c912004-12-10 14:58:26 +0000321 tl_assert(isShadowAtom(mce,a1));
322 tl_assert(isShadowAtom(mce,a2));
sewardj20d38f22005-02-07 23:50:18 +0000323 return assignNew(mce, Ity_V128, binop(Iop_OrV128, a1, a2));
sewardj3245c912004-12-10 14:58:26 +0000324}
325
sewardje50a1b12004-12-17 01:24:54 +0000326static IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) {
sewardj95448072004-11-22 20:19:51 +0000327 switch (vty) {
sewardje50a1b12004-12-17 01:24:54 +0000328 case Ity_I8: return mkUifU8(mce, a1, a2);
sewardja1d93302004-12-12 16:45:06 +0000329 case Ity_I16: return mkUifU16(mce, a1, a2);
330 case Ity_I32: return mkUifU32(mce, a1, a2);
331 case Ity_I64: return mkUifU64(mce, a1, a2);
sewardj20d38f22005-02-07 23:50:18 +0000332 case Ity_V128: return mkUifUV128(mce, a1, a2);
sewardj95448072004-11-22 20:19:51 +0000333 default:
334 VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n");
335 VG_(tool_panic)("memcheck:mkUifU");
njn25e49d8e72002-09-23 09:36:25 +0000336 }
337}
338
sewardj95448072004-11-22 20:19:51 +0000339/* --------- The Left-family of operations. --------- */
njn25e49d8e72002-09-23 09:36:25 +0000340
sewardj95448072004-11-22 20:19:51 +0000341static IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) {
342 tl_assert(isShadowAtom(mce,a1));
343 /* It's safe to duplicate a1 since it's only an atom */
344 return assignNew(mce, Ity_I8,
345 binop(Iop_Or8, a1,
346 assignNew(mce, Ity_I8,
sewardj37c31cc2005-04-26 23:49:24 +0000347 unop(Iop_Neg8, a1))));
sewardj95448072004-11-22 20:19:51 +0000348}
349
350static IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) {
351 tl_assert(isShadowAtom(mce,a1));
352 /* It's safe to duplicate a1 since it's only an atom */
353 return assignNew(mce, Ity_I16,
354 binop(Iop_Or16, a1,
355 assignNew(mce, Ity_I16,
sewardj37c31cc2005-04-26 23:49:24 +0000356 unop(Iop_Neg16, a1))));
sewardj95448072004-11-22 20:19:51 +0000357}
358
359static IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) {
360 tl_assert(isShadowAtom(mce,a1));
361 /* It's safe to duplicate a1 since it's only an atom */
362 return assignNew(mce, Ity_I32,
363 binop(Iop_Or32, a1,
364 assignNew(mce, Ity_I32,
sewardj37c31cc2005-04-26 23:49:24 +0000365 unop(Iop_Neg32, a1))));
sewardj95448072004-11-22 20:19:51 +0000366}
367
sewardj681be302005-01-15 20:43:58 +0000368static IRAtom* mkLeft64 ( MCEnv* mce, IRAtom* a1 ) {
369 tl_assert(isShadowAtom(mce,a1));
370 /* It's safe to duplicate a1 since it's only an atom */
371 return assignNew(mce, Ity_I64,
372 binop(Iop_Or64, a1,
373 assignNew(mce, Ity_I64,
sewardj37c31cc2005-04-26 23:49:24 +0000374 unop(Iop_Neg64, a1))));
sewardj681be302005-01-15 20:43:58 +0000375}
376
sewardj95448072004-11-22 20:19:51 +0000377/* --------- 'Improvement' functions for AND/OR. --------- */
378
379/* ImproveAND(data, vbits) = data OR vbits. Defined (0) data 0s give
380 defined (0); all other -> undefined (1).
381*/
382static IRAtom* mkImproveAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
njn25e49d8e72002-09-23 09:36:25 +0000383{
sewardj95448072004-11-22 20:19:51 +0000384 tl_assert(isOriginalAtom(mce, data));
385 tl_assert(isShadowAtom(mce, vbits));
386 tl_assert(sameKindedAtoms(data, vbits));
387 return assignNew(mce, Ity_I8, binop(Iop_Or8, data, vbits));
388}
njn25e49d8e72002-09-23 09:36:25 +0000389
sewardj95448072004-11-22 20:19:51 +0000390static IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
391{
392 tl_assert(isOriginalAtom(mce, data));
393 tl_assert(isShadowAtom(mce, vbits));
394 tl_assert(sameKindedAtoms(data, vbits));
395 return assignNew(mce, Ity_I16, binop(Iop_Or16, data, vbits));
396}
njn25e49d8e72002-09-23 09:36:25 +0000397
sewardj95448072004-11-22 20:19:51 +0000398static IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
399{
400 tl_assert(isOriginalAtom(mce, data));
401 tl_assert(isShadowAtom(mce, vbits));
402 tl_assert(sameKindedAtoms(data, vbits));
403 return assignNew(mce, Ity_I32, binop(Iop_Or32, data, vbits));
404}
njn25e49d8e72002-09-23 09:36:25 +0000405
sewardj7010f6e2004-12-10 13:35:22 +0000406static IRAtom* mkImproveAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
407{
408 tl_assert(isOriginalAtom(mce, data));
409 tl_assert(isShadowAtom(mce, vbits));
410 tl_assert(sameKindedAtoms(data, vbits));
411 return assignNew(mce, Ity_I64, binop(Iop_Or64, data, vbits));
412}
413
sewardj20d38f22005-02-07 23:50:18 +0000414static IRAtom* mkImproveANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
sewardj170ee212004-12-10 18:57:51 +0000415{
416 tl_assert(isOriginalAtom(mce, data));
417 tl_assert(isShadowAtom(mce, vbits));
418 tl_assert(sameKindedAtoms(data, vbits));
sewardj20d38f22005-02-07 23:50:18 +0000419 return assignNew(mce, Ity_V128, binop(Iop_OrV128, data, vbits));
sewardj170ee212004-12-10 18:57:51 +0000420}
421
sewardj95448072004-11-22 20:19:51 +0000422/* ImproveOR(data, vbits) = ~data OR vbits. Defined (0) data 1s give
423 defined (0); all other -> undefined (1).
424*/
425static IRAtom* mkImproveOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
426{
427 tl_assert(isOriginalAtom(mce, data));
428 tl_assert(isShadowAtom(mce, vbits));
429 tl_assert(sameKindedAtoms(data, vbits));
430 return assignNew(
431 mce, Ity_I8,
432 binop(Iop_Or8,
433 assignNew(mce, Ity_I8, unop(Iop_Not8, data)),
434 vbits) );
435}
njn25e49d8e72002-09-23 09:36:25 +0000436
sewardj95448072004-11-22 20:19:51 +0000437static IRAtom* mkImproveOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
438{
439 tl_assert(isOriginalAtom(mce, data));
440 tl_assert(isShadowAtom(mce, vbits));
441 tl_assert(sameKindedAtoms(data, vbits));
442 return assignNew(
443 mce, Ity_I16,
444 binop(Iop_Or16,
445 assignNew(mce, Ity_I16, unop(Iop_Not16, data)),
446 vbits) );
447}
njn25e49d8e72002-09-23 09:36:25 +0000448
sewardj95448072004-11-22 20:19:51 +0000449static IRAtom* mkImproveOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
450{
451 tl_assert(isOriginalAtom(mce, data));
452 tl_assert(isShadowAtom(mce, vbits));
453 tl_assert(sameKindedAtoms(data, vbits));
454 return assignNew(
455 mce, Ity_I32,
456 binop(Iop_Or32,
457 assignNew(mce, Ity_I32, unop(Iop_Not32, data)),
458 vbits) );
459}
460
sewardj7010f6e2004-12-10 13:35:22 +0000461static IRAtom* mkImproveOR64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
462{
463 tl_assert(isOriginalAtom(mce, data));
464 tl_assert(isShadowAtom(mce, vbits));
465 tl_assert(sameKindedAtoms(data, vbits));
466 return assignNew(
467 mce, Ity_I64,
468 binop(Iop_Or64,
469 assignNew(mce, Ity_I64, unop(Iop_Not64, data)),
470 vbits) );
471}
472
sewardj20d38f22005-02-07 23:50:18 +0000473static IRAtom* mkImproveORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
sewardj170ee212004-12-10 18:57:51 +0000474{
475 tl_assert(isOriginalAtom(mce, data));
476 tl_assert(isShadowAtom(mce, vbits));
477 tl_assert(sameKindedAtoms(data, vbits));
478 return assignNew(
479 mce, Ity_V128,
sewardj20d38f22005-02-07 23:50:18 +0000480 binop(Iop_OrV128,
481 assignNew(mce, Ity_V128, unop(Iop_NotV128, data)),
sewardj170ee212004-12-10 18:57:51 +0000482 vbits) );
483}
484
sewardj95448072004-11-22 20:19:51 +0000485/* --------- Pessimising casts. --------- */
486
487static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits )
488{
sewardj7cf97ee2004-11-28 14:25:01 +0000489 IRType ty;
490 IRAtom* tmp1;
sewardj95448072004-11-22 20:19:51 +0000491 /* Note, dst_ty is a shadow type, not an original type. */
492 /* First of all, collapse vbits down to a single bit. */
493 tl_assert(isShadowAtom(mce,vbits));
sewardj7cf97ee2004-11-28 14:25:01 +0000494 ty = typeOfIRExpr(mce->bb->tyenv, vbits);
495 tmp1 = NULL;
sewardj95448072004-11-22 20:19:51 +0000496 switch (ty) {
497 case Ity_I1:
498 tmp1 = vbits;
njn25e49d8e72002-09-23 09:36:25 +0000499 break;
sewardj95448072004-11-22 20:19:51 +0000500 case Ity_I8:
sewardj37c31cc2005-04-26 23:49:24 +0000501 tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ8, vbits));
sewardj95448072004-11-22 20:19:51 +0000502 break;
503 case Ity_I16:
sewardj37c31cc2005-04-26 23:49:24 +0000504 tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ16, vbits));
sewardj95448072004-11-22 20:19:51 +0000505 break;
506 case Ity_I32:
sewardj37c31cc2005-04-26 23:49:24 +0000507 tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ32, vbits));
sewardj95448072004-11-22 20:19:51 +0000508 break;
509 case Ity_I64:
sewardj37c31cc2005-04-26 23:49:24 +0000510 tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ64, vbits));
sewardj95448072004-11-22 20:19:51 +0000511 break;
sewardj69a13322005-04-23 01:14:51 +0000512 case Ity_I128: {
513 /* Gah. Chop it in half, OR the halves together, and compare
514 that with zero. */
515 IRAtom* tmp2 = assignNew(mce, Ity_I64, unop(Iop_128HIto64, vbits));
516 IRAtom* tmp3 = assignNew(mce, Ity_I64, unop(Iop_128to64, vbits));
517 IRAtom* tmp4 = assignNew(mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3));
518 tmp1 = assignNew(mce, Ity_I1,
sewardj37c31cc2005-04-26 23:49:24 +0000519 unop(Iop_CmpNEZ64, tmp4));
sewardj69a13322005-04-23 01:14:51 +0000520 break;
521 }
sewardj95448072004-11-22 20:19:51 +0000522 default:
sewardj69a13322005-04-23 01:14:51 +0000523 ppIRType(ty);
sewardj95448072004-11-22 20:19:51 +0000524 VG_(tool_panic)("mkPCastTo(1)");
525 }
526 tl_assert(tmp1);
527 /* Now widen up to the dst type. */
528 switch (dst_ty) {
529 case Ity_I1:
530 return tmp1;
531 case Ity_I8:
532 return assignNew(mce, Ity_I8, unop(Iop_1Sto8, tmp1));
533 case Ity_I16:
534 return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1));
535 case Ity_I32:
536 return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1));
537 case Ity_I64:
538 return assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
sewardja1d93302004-12-12 16:45:06 +0000539 case Ity_V128:
540 tmp1 = assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
sewardj20d38f22005-02-07 23:50:18 +0000541 tmp1 = assignNew(mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1));
sewardja1d93302004-12-12 16:45:06 +0000542 return tmp1;
sewardj69a13322005-04-23 01:14:51 +0000543 case Ity_I128:
544 tmp1 = assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
545 tmp1 = assignNew(mce, Ity_I128, binop(Iop_64HLto128, tmp1, tmp1));
546 return tmp1;
sewardj95448072004-11-22 20:19:51 +0000547 default:
548 ppIRType(dst_ty);
549 VG_(tool_panic)("mkPCastTo(2)");
550 }
551}
552
sewardjd5204dc2004-12-31 01:16:11 +0000553/* --------- Accurate interpretation of CmpEQ/CmpNE. --------- */
554/*
555 Normally, we can do CmpEQ/CmpNE by doing UifU on the arguments, and
556 PCasting to Ity_U1. However, sometimes it is necessary to be more
557 accurate. The insight is that the result is defined if two
558 corresponding bits can be found, one from each argument, so that
559 both bits are defined but are different -- that makes EQ say "No"
560 and NE say "Yes". Hence, we compute an improvement term and DifD
561 it onto the "normal" (UifU) result.
562
563 The result is:
564
565 PCastTo<1> (
sewardje6f8af42005-07-06 18:48:59 +0000566 -- naive version
567 PCastTo<sz>( UifU<sz>(vxx, vyy) )
568
sewardjd5204dc2004-12-31 01:16:11 +0000569 `DifD<sz>`
sewardje6f8af42005-07-06 18:48:59 +0000570
571 -- improvement term
572 PCastTo<sz>( PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) ) )
sewardjd5204dc2004-12-31 01:16:11 +0000573 )
sewardje6f8af42005-07-06 18:48:59 +0000574
sewardjd5204dc2004-12-31 01:16:11 +0000575 where
576 vec contains 0 (defined) bits where the corresponding arg bits
sewardje6f8af42005-07-06 18:48:59 +0000577 are defined but different, and 1 bits otherwise.
sewardjd5204dc2004-12-31 01:16:11 +0000578
sewardje6f8af42005-07-06 18:48:59 +0000579 vec = Or<sz>( vxx, // 0 iff bit defined
580 vyy, // 0 iff bit defined
581 Not<sz>(Xor<sz>( xx, yy )) // 0 iff bits different
582 )
583
584 If any bit of vec is 0, the result is defined and so the
585 improvement term should produce 0...0, else it should produce
586 1...1.
587
588 Hence require for the improvement term:
589
590 if vec == 1...1 then 1...1 else 0...0
591 ->
592 PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) )
593
594 This was extensively re-analysed and checked on 6 July 05.
sewardjd5204dc2004-12-31 01:16:11 +0000595*/
596static IRAtom* expensiveCmpEQorNE ( MCEnv* mce,
597 IRType ty,
598 IRAtom* vxx, IRAtom* vyy,
599 IRAtom* xx, IRAtom* yy )
600{
sewardje6f8af42005-07-06 18:48:59 +0000601 IRAtom *naive, *vec, *improvement_term;
602 IRAtom *improved, *final_cast, *top;
603 IROp opDIFD, opUIFU, opXOR, opNOT, opCMP, opOR;
sewardjd5204dc2004-12-31 01:16:11 +0000604
605 tl_assert(isShadowAtom(mce,vxx));
606 tl_assert(isShadowAtom(mce,vyy));
607 tl_assert(isOriginalAtom(mce,xx));
608 tl_assert(isOriginalAtom(mce,yy));
609 tl_assert(sameKindedAtoms(vxx,xx));
610 tl_assert(sameKindedAtoms(vyy,yy));
611
612 switch (ty) {
613 case Ity_I32:
sewardje6f8af42005-07-06 18:48:59 +0000614 opOR = Iop_Or32;
sewardjd5204dc2004-12-31 01:16:11 +0000615 opDIFD = Iop_And32;
616 opUIFU = Iop_Or32;
617 opNOT = Iop_Not32;
618 opXOR = Iop_Xor32;
619 opCMP = Iop_CmpEQ32;
620 top = mkU32(0xFFFFFFFF);
621 break;
tomcd986332005-04-26 07:44:48 +0000622 case Ity_I64:
sewardje6f8af42005-07-06 18:48:59 +0000623 opOR = Iop_Or64;
tomcd986332005-04-26 07:44:48 +0000624 opDIFD = Iop_And64;
625 opUIFU = Iop_Or64;
626 opNOT = Iop_Not64;
627 opXOR = Iop_Xor64;
628 opCMP = Iop_CmpEQ64;
sewardj37c31cc2005-04-26 23:49:24 +0000629 top = mkU64(0xFFFFFFFFFFFFFFFFULL);
tomcd986332005-04-26 07:44:48 +0000630 break;
sewardjd5204dc2004-12-31 01:16:11 +0000631 default:
632 VG_(tool_panic)("expensiveCmpEQorNE");
633 }
634
635 naive
636 = mkPCastTo(mce,ty, assignNew(mce, ty, binop(opUIFU, vxx, vyy)));
637
638 vec
639 = assignNew(
640 mce,ty,
sewardje6f8af42005-07-06 18:48:59 +0000641 binop( opOR,
642 assignNew(mce,ty, binop(opOR, vxx, vyy)),
sewardjd5204dc2004-12-31 01:16:11 +0000643 assignNew(
644 mce,ty,
645 unop( opNOT,
646 assignNew(mce,ty, binop(opXOR, xx, yy))))));
647
sewardje6f8af42005-07-06 18:48:59 +0000648 improvement_term
sewardjd5204dc2004-12-31 01:16:11 +0000649 = mkPCastTo( mce,ty, assignNew(mce,Ity_I1, binop(opCMP, vec, top)));
650
651 improved
sewardje6f8af42005-07-06 18:48:59 +0000652 = assignNew( mce,ty, binop(opDIFD, naive, improvement_term) );
sewardjd5204dc2004-12-31 01:16:11 +0000653
654 final_cast
655 = mkPCastTo( mce, Ity_I1, improved );
656
657 return final_cast;
658}
659
sewardj95448072004-11-22 20:19:51 +0000660
661/*------------------------------------------------------------*/
662/*--- Emit a test and complaint if something is undefined. ---*/
663/*------------------------------------------------------------*/
664
665/* Set the annotations on a dirty helper to indicate that the stack
666 pointer and instruction pointers might be read. This is the
667 behaviour of all 'emit-a-complaint' style functions we might
668 call. */
669
670static void setHelperAnns ( MCEnv* mce, IRDirty* di ) {
671 di->nFxState = 2;
672 di->fxState[0].fx = Ifx_Read;
673 di->fxState[0].offset = mce->layout->offset_SP;
674 di->fxState[0].size = mce->layout->sizeof_SP;
675 di->fxState[1].fx = Ifx_Read;
676 di->fxState[1].offset = mce->layout->offset_IP;
677 di->fxState[1].size = mce->layout->sizeof_IP;
678}
679
680
681/* Check the supplied **original** atom for undefinedness, and emit a
682 complaint if so. Once that happens, mark it as defined. This is
683 possible because the atom is either a tmp or literal. If it's a
684 tmp, it will be shadowed by a tmp, and so we can set the shadow to
685 be defined. In fact as mentioned above, we will have to allocate a
686 new tmp to carry the new 'defined' shadow value, and update the
687 original->tmp mapping accordingly; we cannot simply assign a new
688 value to an existing shadow tmp as this breaks SSAness -- resulting
689 in the post-instrumentation sanity checker spluttering in disapproval.
690*/
691static void complainIfUndefined ( MCEnv* mce, IRAtom* atom )
692{
sewardj7cf97ee2004-11-28 14:25:01 +0000693 IRAtom* vatom;
694 IRType ty;
695 Int sz;
696 IRDirty* di;
697 IRAtom* cond;
698
sewardj95448072004-11-22 20:19:51 +0000699 /* Since the original expression is atomic, there's no duplicated
700 work generated by making multiple V-expressions for it. So we
701 don't really care about the possibility that someone else may
702 also create a V-interpretion for it. */
703 tl_assert(isOriginalAtom(mce, atom));
sewardj7cf97ee2004-11-28 14:25:01 +0000704 vatom = expr2vbits( mce, atom );
sewardj95448072004-11-22 20:19:51 +0000705 tl_assert(isShadowAtom(mce, vatom));
706 tl_assert(sameKindedAtoms(atom, vatom));
707
sewardj7cf97ee2004-11-28 14:25:01 +0000708 ty = typeOfIRExpr(mce->bb->tyenv, vatom);
sewardj95448072004-11-22 20:19:51 +0000709
710 /* sz is only used for constructing the error message */
sewardj7cf97ee2004-11-28 14:25:01 +0000711 sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
sewardj95448072004-11-22 20:19:51 +0000712
sewardj7cf97ee2004-11-28 14:25:01 +0000713 cond = mkPCastTo( mce, Ity_I1, vatom );
sewardj95448072004-11-22 20:19:51 +0000714 /* cond will be 0 if all defined, and 1 if any not defined. */
715
sewardj95448072004-11-22 20:19:51 +0000716 switch (sz) {
717 case 0:
718 di = unsafeIRDirty_0_N( 0/*regparms*/,
719 "MC_(helperc_value_check0_fail)",
720 &MC_(helperc_value_check0_fail),
721 mkIRExprVec_0()
722 );
723 break;
724 case 1:
725 di = unsafeIRDirty_0_N( 0/*regparms*/,
726 "MC_(helperc_value_check1_fail)",
727 &MC_(helperc_value_check1_fail),
728 mkIRExprVec_0()
729 );
730 break;
731 case 4:
732 di = unsafeIRDirty_0_N( 0/*regparms*/,
733 "MC_(helperc_value_check4_fail)",
734 &MC_(helperc_value_check4_fail),
735 mkIRExprVec_0()
736 );
737 break;
sewardj11bcc4e2005-04-23 22:38:38 +0000738 case 8:
739 di = unsafeIRDirty_0_N( 0/*regparms*/,
740 "MC_(helperc_value_check8_fail)",
741 &MC_(helperc_value_check8_fail),
742 mkIRExprVec_0()
743 );
744 break;
sewardj95448072004-11-22 20:19:51 +0000745 default:
746 di = unsafeIRDirty_0_N( 1/*regparms*/,
747 "MC_(helperc_complain_undef)",
748 &MC_(helperc_complain_undef),
749 mkIRExprVec_1( mkIRExpr_HWord( sz ))
750 );
751 break;
752 }
753 di->guard = cond;
754 setHelperAnns( mce, di );
755 stmt( mce->bb, IRStmt_Dirty(di));
756
757 /* Set the shadow tmp to be defined. First, update the
758 orig->shadow tmp mapping to reflect the fact that this shadow is
759 getting a new value. */
sewardj710d6c22005-03-20 18:55:15 +0000760 tl_assert(isIRAtom(vatom));
sewardj95448072004-11-22 20:19:51 +0000761 /* sameKindedAtoms ... */
762 if (vatom->tag == Iex_Tmp) {
763 tl_assert(atom->tag == Iex_Tmp);
764 newShadowTmp(mce, atom->Iex.Tmp.tmp);
765 assign(mce->bb, findShadowTmp(mce, atom->Iex.Tmp.tmp),
766 definedOfType(ty));
767 }
768}
769
770
771/*------------------------------------------------------------*/
772/*--- Shadowing PUTs/GETs, and indexed variants thereof ---*/
773/*------------------------------------------------------------*/
774
775/* Examine the always-defined sections declared in layout to see if
776 the (offset,size) section is within one. Note, is is an error to
777 partially fall into such a region: (offset,size) should either be
778 completely in such a region or completely not-in such a region.
779*/
780static Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size )
781{
782 Int minoffD, maxoffD, i;
783 Int minoff = offset;
784 Int maxoff = minoff + size - 1;
785 tl_assert((minoff & ~0xFFFF) == 0);
786 tl_assert((maxoff & ~0xFFFF) == 0);
787
788 for (i = 0; i < mce->layout->n_alwaysDefd; i++) {
789 minoffD = mce->layout->alwaysDefd[i].offset;
790 maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1;
791 tl_assert((minoffD & ~0xFFFF) == 0);
792 tl_assert((maxoffD & ~0xFFFF) == 0);
793
794 if (maxoff < minoffD || maxoffD < minoff)
795 continue; /* no overlap */
796 if (minoff >= minoffD && maxoff <= maxoffD)
797 return True; /* completely contained in an always-defd section */
798
799 VG_(tool_panic)("memcheck:isAlwaysDefd:partial overlap");
800 }
801 return False; /* could not find any containing section */
802}
803
804
805/* Generate into bb suitable actions to shadow this Put. If the state
806 slice is marked 'always defined', do nothing. Otherwise, write the
807 supplied V bits to the shadow state. We can pass in either an
808 original atom or a V-atom, but not both. In the former case the
809 relevant V-bits are then generated from the original.
810*/
811static
812void do_shadow_PUT ( MCEnv* mce, Int offset,
813 IRAtom* atom, IRAtom* vatom )
814{
sewardj7cf97ee2004-11-28 14:25:01 +0000815 IRType ty;
sewardj95448072004-11-22 20:19:51 +0000816 if (atom) {
817 tl_assert(!vatom);
818 tl_assert(isOriginalAtom(mce, atom));
819 vatom = expr2vbits( mce, atom );
820 } else {
821 tl_assert(vatom);
822 tl_assert(isShadowAtom(mce, vatom));
823 }
824
sewardj7cf97ee2004-11-28 14:25:01 +0000825 ty = typeOfIRExpr(mce->bb->tyenv, vatom);
sewardj95448072004-11-22 20:19:51 +0000826 tl_assert(ty != Ity_I1);
827 if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
828 /* later: no ... */
829 /* emit code to emit a complaint if any of the vbits are 1. */
830 /* complainIfUndefined(mce, atom); */
831 } else {
832 /* Do a plain shadow Put. */
833 stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) );
834 }
835}
836
837
838/* Return an expression which contains the V bits corresponding to the
839 given GETI (passed in in pieces).
840*/
841static
842void do_shadow_PUTI ( MCEnv* mce,
843 IRArray* descr, IRAtom* ix, Int bias, IRAtom* atom )
844{
sewardj7cf97ee2004-11-28 14:25:01 +0000845 IRAtom* vatom;
846 IRType ty, tyS;
847 Int arrSize;;
848
sewardj95448072004-11-22 20:19:51 +0000849 tl_assert(isOriginalAtom(mce,atom));
sewardj7cf97ee2004-11-28 14:25:01 +0000850 vatom = expr2vbits( mce, atom );
sewardj95448072004-11-22 20:19:51 +0000851 tl_assert(sameKindedAtoms(atom, vatom));
sewardj7cf97ee2004-11-28 14:25:01 +0000852 ty = descr->elemTy;
853 tyS = shadowType(ty);
854 arrSize = descr->nElems * sizeofIRType(ty);
sewardj95448072004-11-22 20:19:51 +0000855 tl_assert(ty != Ity_I1);
856 tl_assert(isOriginalAtom(mce,ix));
857 complainIfUndefined(mce,ix);
858 if (isAlwaysDefd(mce, descr->base, arrSize)) {
859 /* later: no ... */
860 /* emit code to emit a complaint if any of the vbits are 1. */
861 /* complainIfUndefined(mce, atom); */
862 } else {
863 /* Do a cloned version of the Put that refers to the shadow
864 area. */
865 IRArray* new_descr
866 = mkIRArray( descr->base + mce->layout->total_sizeB,
867 tyS, descr->nElems);
868 stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom ));
869 }
870}
871
872
873/* Return an expression which contains the V bits corresponding to the
874 given GET (passed in in pieces).
875*/
876static
877IRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty )
878{
879 IRType tyS = shadowType(ty);
880 tl_assert(ty != Ity_I1);
881 if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
882 /* Always defined, return all zeroes of the relevant type */
883 return definedOfType(tyS);
884 } else {
885 /* return a cloned version of the Get that refers to the shadow
886 area. */
887 return IRExpr_Get( offset + mce->layout->total_sizeB, tyS );
888 }
889}
890
891
892/* Return an expression which contains the V bits corresponding to the
893 given GETI (passed in in pieces).
894*/
895static
896IRExpr* shadow_GETI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias )
897{
898 IRType ty = descr->elemTy;
899 IRType tyS = shadowType(ty);
900 Int arrSize = descr->nElems * sizeofIRType(ty);
901 tl_assert(ty != Ity_I1);
902 tl_assert(isOriginalAtom(mce,ix));
903 complainIfUndefined(mce,ix);
904 if (isAlwaysDefd(mce, descr->base, arrSize)) {
905 /* Always defined, return all zeroes of the relevant type */
906 return definedOfType(tyS);
907 } else {
908 /* return a cloned version of the Get that refers to the shadow
909 area. */
910 IRArray* new_descr
911 = mkIRArray( descr->base + mce->layout->total_sizeB,
912 tyS, descr->nElems);
913 return IRExpr_GetI( new_descr, ix, bias );
914 }
915}
916
917
918/*------------------------------------------------------------*/
919/*--- Generating approximations for unknown operations, ---*/
920/*--- using lazy-propagate semantics ---*/
921/*------------------------------------------------------------*/
922
923/* Lazy propagation of undefinedness from two values, resulting in the
924 specified shadow type.
925*/
926static
927IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
928{
sewardj95448072004-11-22 20:19:51 +0000929 IRAtom* at;
sewardj37c31cc2005-04-26 23:49:24 +0000930 IRType t1 = typeOfIRExpr(mce->bb->tyenv, va1);
931 IRType t2 = typeOfIRExpr(mce->bb->tyenv, va2);
sewardj95448072004-11-22 20:19:51 +0000932 tl_assert(isShadowAtom(mce,va1));
933 tl_assert(isShadowAtom(mce,va2));
sewardj37c31cc2005-04-26 23:49:24 +0000934
935 /* The general case is inefficient because PCast is an expensive
936 operation. Here are some special cases which use PCast only
937 once rather than twice. */
938
939 /* I64 x I64 -> I64 */
940 if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I64) {
941 if (0) VG_(printf)("mkLazy2: I64 x I64 -> I64\n");
942 at = mkUifU(mce, Ity_I64, va1, va2);
943 at = mkPCastTo(mce, Ity_I64, at);
944 return at;
945 }
946
947 /* I64 x I64 -> I32 */
948 if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I32) {
949 if (0) VG_(printf)("mkLazy2: I64 x I64 -> I32\n");
950 at = mkUifU(mce, Ity_I64, va1, va2);
951 at = mkPCastTo(mce, Ity_I32, at);
952 return at;
953 }
954
955 if (0) {
956 VG_(printf)("mkLazy2 ");
957 ppIRType(t1);
958 VG_(printf)("_");
959 ppIRType(t2);
960 VG_(printf)("_");
961 ppIRType(finalVty);
962 VG_(printf)("\n");
963 }
964
965 /* General case: force everything via 32-bit intermediaries. */
sewardj95448072004-11-22 20:19:51 +0000966 at = mkPCastTo(mce, Ity_I32, va1);
967 at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2));
968 at = mkPCastTo(mce, finalVty, at);
969 return at;
970}
971
972
973/* Do the lazy propagation game from a null-terminated vector of
974 atoms. This is presumably the arguments to a helper call, so the
975 IRCallee info is also supplied in order that we can know which
976 arguments should be ignored (via the .mcx_mask field).
977*/
978static
979IRAtom* mkLazyN ( MCEnv* mce,
980 IRAtom** exprvec, IRType finalVtype, IRCallee* cee )
981{
982 Int i;
983 IRAtom* here;
984 IRAtom* curr = definedOfType(Ity_I32);
985 for (i = 0; exprvec[i]; i++) {
986 tl_assert(i < 32);
987 tl_assert(isOriginalAtom(mce, exprvec[i]));
988 /* Only take notice of this arg if the callee's mc-exclusion
989 mask does not say it is to be excluded. */
990 if (cee->mcx_mask & (1<<i)) {
991 /* the arg is to be excluded from definedness checking. Do
992 nothing. */
993 if (0) VG_(printf)("excluding %s(%d)\n", cee->name, i);
994 } else {
995 /* calculate the arg's definedness, and pessimistically merge
996 it in. */
997 here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, exprvec[i]) );
998 curr = mkUifU32(mce, here, curr);
999 }
1000 }
1001 return mkPCastTo(mce, finalVtype, curr );
1002}
1003
1004
1005/*------------------------------------------------------------*/
1006/*--- Generating expensive sequences for exact carry-chain ---*/
1007/*--- propagation in add/sub and related operations. ---*/
1008/*------------------------------------------------------------*/
1009
1010static
sewardjd5204dc2004-12-31 01:16:11 +00001011IRAtom* expensiveAddSub ( MCEnv* mce,
1012 Bool add,
1013 IRType ty,
1014 IRAtom* qaa, IRAtom* qbb,
1015 IRAtom* aa, IRAtom* bb )
sewardj95448072004-11-22 20:19:51 +00001016{
sewardj7cf97ee2004-11-28 14:25:01 +00001017 IRAtom *a_min, *b_min, *a_max, *b_max;
sewardjd5204dc2004-12-31 01:16:11 +00001018 IROp opAND, opOR, opXOR, opNOT, opADD, opSUB;
sewardj7cf97ee2004-11-28 14:25:01 +00001019
sewardj95448072004-11-22 20:19:51 +00001020 tl_assert(isShadowAtom(mce,qaa));
1021 tl_assert(isShadowAtom(mce,qbb));
1022 tl_assert(isOriginalAtom(mce,aa));
1023 tl_assert(isOriginalAtom(mce,bb));
1024 tl_assert(sameKindedAtoms(qaa,aa));
1025 tl_assert(sameKindedAtoms(qbb,bb));
1026
sewardjd5204dc2004-12-31 01:16:11 +00001027 switch (ty) {
1028 case Ity_I32:
1029 opAND = Iop_And32;
1030 opOR = Iop_Or32;
1031 opXOR = Iop_Xor32;
1032 opNOT = Iop_Not32;
1033 opADD = Iop_Add32;
1034 opSUB = Iop_Sub32;
1035 break;
tomd9774d72005-06-27 08:11:01 +00001036 case Ity_I64:
1037 opAND = Iop_And64;
1038 opOR = Iop_Or64;
1039 opXOR = Iop_Xor64;
1040 opNOT = Iop_Not64;
1041 opADD = Iop_Add64;
1042 opSUB = Iop_Sub64;
1043 break;
sewardjd5204dc2004-12-31 01:16:11 +00001044 default:
1045 VG_(tool_panic)("expensiveAddSub");
1046 }
sewardj95448072004-11-22 20:19:51 +00001047
1048 // a_min = aa & ~qaa
1049 a_min = assignNew(mce,ty,
1050 binop(opAND, aa,
1051 assignNew(mce,ty, unop(opNOT, qaa))));
1052
1053 // b_min = bb & ~qbb
1054 b_min = assignNew(mce,ty,
1055 binop(opAND, bb,
1056 assignNew(mce,ty, unop(opNOT, qbb))));
1057
1058 // a_max = aa | qaa
1059 a_max = assignNew(mce,ty, binop(opOR, aa, qaa));
1060
1061 // b_max = bb | qbb
1062 b_max = assignNew(mce,ty, binop(opOR, bb, qbb));
1063
sewardjd5204dc2004-12-31 01:16:11 +00001064 if (add) {
1065 // result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max))
1066 return
1067 assignNew(mce,ty,
1068 binop( opOR,
1069 assignNew(mce,ty, binop(opOR, qaa, qbb)),
1070 assignNew(mce,ty,
1071 binop( opXOR,
1072 assignNew(mce,ty, binop(opADD, a_min, b_min)),
1073 assignNew(mce,ty, binop(opADD, a_max, b_max))
1074 )
sewardj95448072004-11-22 20:19:51 +00001075 )
sewardjd5204dc2004-12-31 01:16:11 +00001076 )
1077 );
1078 } else {
1079 // result = (qaa | qbb) | ((a_min - b_max) ^ (a_max + b_min))
1080 return
1081 assignNew(mce,ty,
1082 binop( opOR,
1083 assignNew(mce,ty, binop(opOR, qaa, qbb)),
1084 assignNew(mce,ty,
1085 binop( opXOR,
1086 assignNew(mce,ty, binop(opSUB, a_min, b_max)),
1087 assignNew(mce,ty, binop(opSUB, a_max, b_min))
1088 )
1089 )
1090 )
1091 );
1092 }
1093
sewardj95448072004-11-22 20:19:51 +00001094}
1095
1096
1097/*------------------------------------------------------------*/
sewardj3245c912004-12-10 14:58:26 +00001098/*--- Helpers for dealing with vector primops. ---*/
1099/*------------------------------------------------------------*/
1100
sewardja1d93302004-12-12 16:45:06 +00001101/* Vector pessimisation -- pessimise within each lane individually. */
1102
1103static IRAtom* mkPCast8x16 ( MCEnv* mce, IRAtom* at )
1104{
1105 return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ8x16, at));
1106}
1107
1108static IRAtom* mkPCast16x8 ( MCEnv* mce, IRAtom* at )
1109{
1110 return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ16x8, at));
1111}
1112
1113static IRAtom* mkPCast32x4 ( MCEnv* mce, IRAtom* at )
1114{
1115 return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ32x4, at));
1116}
1117
1118static IRAtom* mkPCast64x2 ( MCEnv* mce, IRAtom* at )
1119{
1120 return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ64x2, at));
1121}
1122
sewardjacd2e912005-01-13 19:17:06 +00001123static IRAtom* mkPCast32x2 ( MCEnv* mce, IRAtom* at )
1124{
1125 return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ32x2, at));
1126}
1127
1128static IRAtom* mkPCast16x4 ( MCEnv* mce, IRAtom* at )
1129{
1130 return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ16x4, at));
1131}
1132
1133static IRAtom* mkPCast8x8 ( MCEnv* mce, IRAtom* at )
1134{
1135 return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ8x8, at));
1136}
1137
sewardja1d93302004-12-12 16:45:06 +00001138
sewardj3245c912004-12-10 14:58:26 +00001139/* Here's a simple scheme capable of handling ops derived from SSE1
1140 code and while only generating ops that can be efficiently
1141 implemented in SSE1. */
1142
1143/* All-lanes versions are straightforward:
1144
sewardj20d38f22005-02-07 23:50:18 +00001145 binary32Fx4(x,y) ==> PCast32x4(UifUV128(x#,y#))
sewardj3245c912004-12-10 14:58:26 +00001146
1147 unary32Fx4(x,y) ==> PCast32x4(x#)
1148
1149 Lowest-lane-only versions are more complex:
1150
sewardj20d38f22005-02-07 23:50:18 +00001151 binary32F0x4(x,y) ==> SetV128lo32(
sewardj3245c912004-12-10 14:58:26 +00001152 x#,
sewardj20d38f22005-02-07 23:50:18 +00001153 PCast32(V128to32(UifUV128(x#,y#)))
sewardj3245c912004-12-10 14:58:26 +00001154 )
1155
1156 This is perhaps not so obvious. In particular, it's faster to
sewardj20d38f22005-02-07 23:50:18 +00001157 do a V128-bit UifU and then take the bottom 32 bits than the more
sewardj3245c912004-12-10 14:58:26 +00001158 obvious scheme of taking the bottom 32 bits of each operand
1159 and doing a 32-bit UifU. Basically since UifU is fast and
1160 chopping lanes off vector values is slow.
1161
1162 Finally:
1163
sewardj20d38f22005-02-07 23:50:18 +00001164 unary32F0x4(x) ==> SetV128lo32(
sewardj3245c912004-12-10 14:58:26 +00001165 x#,
sewardj20d38f22005-02-07 23:50:18 +00001166 PCast32(V128to32(x#))
sewardj3245c912004-12-10 14:58:26 +00001167 )
1168
1169 Where:
1170
1171 PCast32(v#) = 1Sto32(CmpNE32(v#,0))
1172 PCast32x4(v#) = CmpNEZ32x4(v#)
1173*/
1174
1175static
1176IRAtom* binary32Fx4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
1177{
1178 IRAtom* at;
1179 tl_assert(isShadowAtom(mce, vatomX));
1180 tl_assert(isShadowAtom(mce, vatomY));
sewardj20d38f22005-02-07 23:50:18 +00001181 at = mkUifUV128(mce, vatomX, vatomY);
sewardja1d93302004-12-12 16:45:06 +00001182 at = assignNew(mce, Ity_V128, mkPCast32x4(mce, at));
sewardj3245c912004-12-10 14:58:26 +00001183 return at;
1184}
1185
1186static
1187IRAtom* unary32Fx4 ( MCEnv* mce, IRAtom* vatomX )
1188{
1189 IRAtom* at;
1190 tl_assert(isShadowAtom(mce, vatomX));
sewardja1d93302004-12-12 16:45:06 +00001191 at = assignNew(mce, Ity_V128, mkPCast32x4(mce, vatomX));
sewardj3245c912004-12-10 14:58:26 +00001192 return at;
1193}
1194
1195static
1196IRAtom* binary32F0x4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
1197{
1198 IRAtom* at;
1199 tl_assert(isShadowAtom(mce, vatomX));
1200 tl_assert(isShadowAtom(mce, vatomY));
sewardj20d38f22005-02-07 23:50:18 +00001201 at = mkUifUV128(mce, vatomX, vatomY);
1202 at = assignNew(mce, Ity_I32, unop(Iop_V128to32, at));
sewardj3245c912004-12-10 14:58:26 +00001203 at = mkPCastTo(mce, Ity_I32, at);
sewardj20d38f22005-02-07 23:50:18 +00001204 at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
sewardj3245c912004-12-10 14:58:26 +00001205 return at;
1206}
1207
1208static
1209IRAtom* unary32F0x4 ( MCEnv* mce, IRAtom* vatomX )
1210{
1211 IRAtom* at;
1212 tl_assert(isShadowAtom(mce, vatomX));
sewardj20d38f22005-02-07 23:50:18 +00001213 at = assignNew(mce, Ity_I32, unop(Iop_V128to32, vatomX));
sewardj3245c912004-12-10 14:58:26 +00001214 at = mkPCastTo(mce, Ity_I32, at);
sewardj20d38f22005-02-07 23:50:18 +00001215 at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
sewardj3245c912004-12-10 14:58:26 +00001216 return at;
1217}
1218
sewardj0b070592004-12-10 21:44:22 +00001219/* --- ... and ... 64Fx2 versions of the same ... --- */
1220
1221static
1222IRAtom* binary64Fx2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
1223{
1224 IRAtom* at;
1225 tl_assert(isShadowAtom(mce, vatomX));
1226 tl_assert(isShadowAtom(mce, vatomY));
sewardj20d38f22005-02-07 23:50:18 +00001227 at = mkUifUV128(mce, vatomX, vatomY);
sewardja1d93302004-12-12 16:45:06 +00001228 at = assignNew(mce, Ity_V128, mkPCast64x2(mce, at));
sewardj0b070592004-12-10 21:44:22 +00001229 return at;
1230}
1231
1232static
1233IRAtom* unary64Fx2 ( MCEnv* mce, IRAtom* vatomX )
1234{
1235 IRAtom* at;
1236 tl_assert(isShadowAtom(mce, vatomX));
sewardja1d93302004-12-12 16:45:06 +00001237 at = assignNew(mce, Ity_V128, mkPCast64x2(mce, vatomX));
sewardj0b070592004-12-10 21:44:22 +00001238 return at;
1239}
1240
1241static
1242IRAtom* binary64F0x2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
1243{
1244 IRAtom* at;
1245 tl_assert(isShadowAtom(mce, vatomX));
1246 tl_assert(isShadowAtom(mce, vatomY));
sewardj20d38f22005-02-07 23:50:18 +00001247 at = mkUifUV128(mce, vatomX, vatomY);
1248 at = assignNew(mce, Ity_I64, unop(Iop_V128to64, at));
sewardj0b070592004-12-10 21:44:22 +00001249 at = mkPCastTo(mce, Ity_I64, at);
sewardj20d38f22005-02-07 23:50:18 +00001250 at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
sewardj0b070592004-12-10 21:44:22 +00001251 return at;
1252}
1253
1254static
1255IRAtom* unary64F0x2 ( MCEnv* mce, IRAtom* vatomX )
1256{
1257 IRAtom* at;
1258 tl_assert(isShadowAtom(mce, vatomX));
sewardj20d38f22005-02-07 23:50:18 +00001259 at = assignNew(mce, Ity_I64, unop(Iop_V128to64, vatomX));
sewardj0b070592004-12-10 21:44:22 +00001260 at = mkPCastTo(mce, Ity_I64, at);
sewardj20d38f22005-02-07 23:50:18 +00001261 at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
sewardj0b070592004-12-10 21:44:22 +00001262 return at;
1263}
1264
sewardja1d93302004-12-12 16:45:06 +00001265/* --- --- Vector saturated narrowing --- --- */
1266
1267/* This is quite subtle. What to do is simple:
1268
1269 Let the original narrowing op be QNarrowW{S,U}xN. Produce:
1270
1271 the-narrowing-op( PCastWxN(vatom1), PCastWxN(vatom2))
1272
1273 Why this is right is not so simple. Consider a lane in the args,
1274 vatom1 or 2, doesn't matter.
1275
1276 After the PCast, that lane is all 0s (defined) or all
1277 1s(undefined).
1278
1279 Both signed and unsigned saturating narrowing of all 0s produces
1280 all 0s, which is what we want.
1281
1282 The all-1s case is more complex. Unsigned narrowing interprets an
1283 all-1s input as the largest unsigned integer, and so produces all
1284 1s as a result since that is the largest unsigned value at the
1285 smaller width.
1286
1287 Signed narrowing interprets all 1s as -1. Fortunately, -1 narrows
1288 to -1, so we still wind up with all 1s at the smaller width.
1289
1290 So: In short, pessimise the args, then apply the original narrowing
1291 op.
1292*/
1293static
sewardj20d38f22005-02-07 23:50:18 +00001294IRAtom* vectorNarrowV128 ( MCEnv* mce, IROp narrow_op,
sewardja1d93302004-12-12 16:45:06 +00001295 IRAtom* vatom1, IRAtom* vatom2)
1296{
1297 IRAtom *at1, *at2, *at3;
1298 IRAtom* (*pcast)( MCEnv*, IRAtom* );
1299 switch (narrow_op) {
1300 case Iop_QNarrow32Sx4: pcast = mkPCast32x4; break;
1301 case Iop_QNarrow16Sx8: pcast = mkPCast16x8; break;
1302 case Iop_QNarrow16Ux8: pcast = mkPCast16x8; break;
sewardj20d38f22005-02-07 23:50:18 +00001303 default: VG_(tool_panic)("vectorNarrowV128");
sewardja1d93302004-12-12 16:45:06 +00001304 }
1305 tl_assert(isShadowAtom(mce,vatom1));
1306 tl_assert(isShadowAtom(mce,vatom2));
1307 at1 = assignNew(mce, Ity_V128, pcast(mce, vatom1));
1308 at2 = assignNew(mce, Ity_V128, pcast(mce, vatom2));
1309 at3 = assignNew(mce, Ity_V128, binop(narrow_op, at1, at2));
1310 return at3;
1311}
1312
sewardjacd2e912005-01-13 19:17:06 +00001313static
1314IRAtom* vectorNarrow64 ( MCEnv* mce, IROp narrow_op,
1315 IRAtom* vatom1, IRAtom* vatom2)
1316{
1317 IRAtom *at1, *at2, *at3;
1318 IRAtom* (*pcast)( MCEnv*, IRAtom* );
1319 switch (narrow_op) {
1320 case Iop_QNarrow32Sx2: pcast = mkPCast32x2; break;
1321 case Iop_QNarrow16Sx4: pcast = mkPCast16x4; break;
1322 case Iop_QNarrow16Ux4: pcast = mkPCast16x4; break;
1323 default: VG_(tool_panic)("vectorNarrow64");
1324 }
1325 tl_assert(isShadowAtom(mce,vatom1));
1326 tl_assert(isShadowAtom(mce,vatom2));
1327 at1 = assignNew(mce, Ity_I64, pcast(mce, vatom1));
1328 at2 = assignNew(mce, Ity_I64, pcast(mce, vatom2));
1329 at3 = assignNew(mce, Ity_I64, binop(narrow_op, at1, at2));
1330 return at3;
1331}
1332
sewardja1d93302004-12-12 16:45:06 +00001333
1334/* --- --- Vector integer arithmetic --- --- */
1335
1336/* Simple ... UifU the args and per-lane pessimise the results. */
sewardjacd2e912005-01-13 19:17:06 +00001337
sewardj20d38f22005-02-07 23:50:18 +00001338/* --- V128-bit versions --- */
sewardjacd2e912005-01-13 19:17:06 +00001339
sewardja1d93302004-12-12 16:45:06 +00001340static
1341IRAtom* binary8Ix16 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1342{
1343 IRAtom* at;
sewardj20d38f22005-02-07 23:50:18 +00001344 at = mkUifUV128(mce, vatom1, vatom2);
sewardja1d93302004-12-12 16:45:06 +00001345 at = mkPCast8x16(mce, at);
1346 return at;
1347}
1348
1349static
1350IRAtom* binary16Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1351{
1352 IRAtom* at;
sewardj20d38f22005-02-07 23:50:18 +00001353 at = mkUifUV128(mce, vatom1, vatom2);
sewardja1d93302004-12-12 16:45:06 +00001354 at = mkPCast16x8(mce, at);
1355 return at;
1356}
1357
1358static
1359IRAtom* binary32Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1360{
1361 IRAtom* at;
sewardj20d38f22005-02-07 23:50:18 +00001362 at = mkUifUV128(mce, vatom1, vatom2);
sewardja1d93302004-12-12 16:45:06 +00001363 at = mkPCast32x4(mce, at);
1364 return at;
1365}
1366
1367static
1368IRAtom* binary64Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1369{
1370 IRAtom* at;
sewardj20d38f22005-02-07 23:50:18 +00001371 at = mkUifUV128(mce, vatom1, vatom2);
sewardja1d93302004-12-12 16:45:06 +00001372 at = mkPCast64x2(mce, at);
1373 return at;
1374}
sewardj3245c912004-12-10 14:58:26 +00001375
sewardjacd2e912005-01-13 19:17:06 +00001376/* --- 64-bit versions --- */
1377
1378static
1379IRAtom* binary8Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1380{
1381 IRAtom* at;
1382 at = mkUifU64(mce, vatom1, vatom2);
1383 at = mkPCast8x8(mce, at);
1384 return at;
1385}
1386
1387static
1388IRAtom* binary16Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1389{
1390 IRAtom* at;
1391 at = mkUifU64(mce, vatom1, vatom2);
1392 at = mkPCast16x4(mce, at);
1393 return at;
1394}
1395
1396static
1397IRAtom* binary32Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1398{
1399 IRAtom* at;
1400 at = mkUifU64(mce, vatom1, vatom2);
1401 at = mkPCast32x2(mce, at);
1402 return at;
1403}
1404
sewardj3245c912004-12-10 14:58:26 +00001405
1406/*------------------------------------------------------------*/
sewardj95448072004-11-22 20:19:51 +00001407/*--- Generate shadow values from all kinds of IRExprs. ---*/
1408/*------------------------------------------------------------*/
1409
1410static
1411IRAtom* expr2vbits_Binop ( MCEnv* mce,
1412 IROp op,
1413 IRAtom* atom1, IRAtom* atom2 )
1414{
1415 IRType and_or_ty;
1416 IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*);
1417 IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*);
1418 IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*);
1419
1420 IRAtom* vatom1 = expr2vbits( mce, atom1 );
1421 IRAtom* vatom2 = expr2vbits( mce, atom2 );
1422
1423 tl_assert(isOriginalAtom(mce,atom1));
1424 tl_assert(isOriginalAtom(mce,atom2));
1425 tl_assert(isShadowAtom(mce,vatom1));
1426 tl_assert(isShadowAtom(mce,vatom2));
1427 tl_assert(sameKindedAtoms(atom1,vatom1));
1428 tl_assert(sameKindedAtoms(atom2,vatom2));
1429 switch (op) {
1430
sewardjacd2e912005-01-13 19:17:06 +00001431 /* 64-bit SIMD */
1432
1433 case Iop_ShrN16x4:
1434 case Iop_ShrN32x2:
1435 case Iop_SarN16x4:
1436 case Iop_SarN32x2:
1437 case Iop_ShlN16x4:
1438 case Iop_ShlN32x2:
1439 /* Same scheme as with all other shifts. */
1440 complainIfUndefined(mce, atom2);
1441 return assignNew(mce, Ity_I64, binop(op, vatom1, atom2));
1442
1443 case Iop_QNarrow32Sx2:
1444 case Iop_QNarrow16Sx4:
1445 case Iop_QNarrow16Ux4:
1446 return vectorNarrow64(mce, op, vatom1, vatom2);
1447
1448 case Iop_Min8Ux8:
1449 case Iop_Max8Ux8:
1450 case Iop_Avg8Ux8:
1451 case Iop_QSub8Sx8:
1452 case Iop_QSub8Ux8:
1453 case Iop_Sub8x8:
1454 case Iop_CmpGT8Sx8:
1455 case Iop_CmpEQ8x8:
1456 case Iop_QAdd8Sx8:
1457 case Iop_QAdd8Ux8:
1458 case Iop_Add8x8:
1459 return binary8Ix8(mce, vatom1, vatom2);
1460
1461 case Iop_Min16Sx4:
1462 case Iop_Max16Sx4:
1463 case Iop_Avg16Ux4:
1464 case Iop_QSub16Ux4:
1465 case Iop_QSub16Sx4:
1466 case Iop_Sub16x4:
1467 case Iop_Mul16x4:
1468 case Iop_MulHi16Sx4:
1469 case Iop_MulHi16Ux4:
1470 case Iop_CmpGT16Sx4:
1471 case Iop_CmpEQ16x4:
1472 case Iop_QAdd16Sx4:
1473 case Iop_QAdd16Ux4:
1474 case Iop_Add16x4:
1475 return binary16Ix4(mce, vatom1, vatom2);
1476
1477 case Iop_Sub32x2:
1478 case Iop_CmpGT32Sx2:
1479 case Iop_CmpEQ32x2:
1480 case Iop_Add32x2:
1481 return binary32Ix2(mce, vatom1, vatom2);
1482
1483 /* 64-bit data-steering */
1484 case Iop_InterleaveLO32x2:
1485 case Iop_InterleaveLO16x4:
1486 case Iop_InterleaveLO8x8:
1487 case Iop_InterleaveHI32x2:
1488 case Iop_InterleaveHI16x4:
1489 case Iop_InterleaveHI8x8:
1490 return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
1491
sewardj20d38f22005-02-07 23:50:18 +00001492 /* V128-bit SIMD */
sewardj0b070592004-12-10 21:44:22 +00001493
sewardja1d93302004-12-12 16:45:06 +00001494 case Iop_ShrN16x8:
1495 case Iop_ShrN32x4:
1496 case Iop_ShrN64x2:
1497 case Iop_SarN16x8:
1498 case Iop_SarN32x4:
1499 case Iop_ShlN16x8:
1500 case Iop_ShlN32x4:
1501 case Iop_ShlN64x2:
1502 /* Same scheme as with all other shifts. */
1503 complainIfUndefined(mce, atom2);
1504 return assignNew(mce, Ity_V128, binop(op, vatom1, atom2));
1505
1506 case Iop_QSub8Ux16:
1507 case Iop_QSub8Sx16:
1508 case Iop_Sub8x16:
1509 case Iop_Min8Ux16:
1510 case Iop_Max8Ux16:
1511 case Iop_CmpGT8Sx16:
1512 case Iop_CmpEQ8x16:
1513 case Iop_Avg8Ux16:
1514 case Iop_QAdd8Ux16:
1515 case Iop_QAdd8Sx16:
1516 case Iop_Add8x16:
1517 return binary8Ix16(mce, vatom1, vatom2);
1518
1519 case Iop_QSub16Ux8:
1520 case Iop_QSub16Sx8:
1521 case Iop_Sub16x8:
1522 case Iop_Mul16x8:
1523 case Iop_MulHi16Sx8:
1524 case Iop_MulHi16Ux8:
1525 case Iop_Min16Sx8:
1526 case Iop_Max16Sx8:
1527 case Iop_CmpGT16Sx8:
1528 case Iop_CmpEQ16x8:
1529 case Iop_Avg16Ux8:
1530 case Iop_QAdd16Ux8:
1531 case Iop_QAdd16Sx8:
1532 case Iop_Add16x8:
1533 return binary16Ix8(mce, vatom1, vatom2);
1534
1535 case Iop_Sub32x4:
1536 case Iop_CmpGT32Sx4:
1537 case Iop_CmpEQ32x4:
1538 case Iop_Add32x4:
1539 return binary32Ix4(mce, vatom1, vatom2);
1540
1541 case Iop_Sub64x2:
1542 case Iop_Add64x2:
1543 return binary64Ix2(mce, vatom1, vatom2);
1544
1545 case Iop_QNarrow32Sx4:
1546 case Iop_QNarrow16Sx8:
1547 case Iop_QNarrow16Ux8:
sewardj20d38f22005-02-07 23:50:18 +00001548 return vectorNarrowV128(mce, op, vatom1, vatom2);
sewardja1d93302004-12-12 16:45:06 +00001549
sewardj0b070592004-12-10 21:44:22 +00001550 case Iop_Sub64Fx2:
1551 case Iop_Mul64Fx2:
1552 case Iop_Min64Fx2:
1553 case Iop_Max64Fx2:
1554 case Iop_Div64Fx2:
1555 case Iop_CmpLT64Fx2:
1556 case Iop_CmpLE64Fx2:
1557 case Iop_CmpEQ64Fx2:
1558 case Iop_Add64Fx2:
1559 return binary64Fx2(mce, vatom1, vatom2);
1560
1561 case Iop_Sub64F0x2:
1562 case Iop_Mul64F0x2:
1563 case Iop_Min64F0x2:
1564 case Iop_Max64F0x2:
1565 case Iop_Div64F0x2:
1566 case Iop_CmpLT64F0x2:
1567 case Iop_CmpLE64F0x2:
1568 case Iop_CmpEQ64F0x2:
1569 case Iop_Add64F0x2:
1570 return binary64F0x2(mce, vatom1, vatom2);
1571
sewardj170ee212004-12-10 18:57:51 +00001572 case Iop_Sub32Fx4:
1573 case Iop_Mul32Fx4:
1574 case Iop_Min32Fx4:
1575 case Iop_Max32Fx4:
1576 case Iop_Div32Fx4:
1577 case Iop_CmpLT32Fx4:
1578 case Iop_CmpLE32Fx4:
1579 case Iop_CmpEQ32Fx4:
sewardj3245c912004-12-10 14:58:26 +00001580 case Iop_Add32Fx4:
1581 return binary32Fx4(mce, vatom1, vatom2);
1582
sewardj170ee212004-12-10 18:57:51 +00001583 case Iop_Sub32F0x4:
1584 case Iop_Mul32F0x4:
1585 case Iop_Min32F0x4:
1586 case Iop_Max32F0x4:
1587 case Iop_Div32F0x4:
1588 case Iop_CmpLT32F0x4:
1589 case Iop_CmpLE32F0x4:
1590 case Iop_CmpEQ32F0x4:
1591 case Iop_Add32F0x4:
1592 return binary32F0x4(mce, vatom1, vatom2);
1593
sewardj20d38f22005-02-07 23:50:18 +00001594 /* V128-bit data-steering */
1595 case Iop_SetV128lo32:
1596 case Iop_SetV128lo64:
1597 case Iop_64HLtoV128:
sewardja1d93302004-12-12 16:45:06 +00001598 case Iop_InterleaveLO64x2:
1599 case Iop_InterleaveLO32x4:
1600 case Iop_InterleaveLO16x8:
1601 case Iop_InterleaveLO8x16:
1602 case Iop_InterleaveHI64x2:
1603 case Iop_InterleaveHI32x4:
1604 case Iop_InterleaveHI16x8:
1605 case Iop_InterleaveHI8x16:
sewardj170ee212004-12-10 18:57:51 +00001606 return assignNew(mce, Ity_V128, binop(op, vatom1, vatom2));
1607
sewardj69a13322005-04-23 01:14:51 +00001608 /* I128-bit data-steering */
1609 case Iop_64HLto128:
1610 return assignNew(mce, Ity_I128, binop(op, vatom1, vatom2));
1611
sewardj3245c912004-12-10 14:58:26 +00001612 /* Scalar floating point */
1613
sewardj95448072004-11-22 20:19:51 +00001614 case Iop_RoundF64:
1615 case Iop_F64toI64:
sewardje9e16d32004-12-10 13:17:55 +00001616 case Iop_I64toF64:
1617 /* First arg is I32 (rounding mode), second is F64 or I64
1618 (data). */
sewardj95448072004-11-22 20:19:51 +00001619 return mkLazy2(mce, Ity_I64, vatom1, vatom2);
1620
1621 case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
1622 /* Takes two F64 args. */
1623 case Iop_F64toI32:
sewardje9e16d32004-12-10 13:17:55 +00001624 case Iop_F64toF32:
sewardj95448072004-11-22 20:19:51 +00001625 /* First arg is I32 (rounding mode), second is F64 (data). */
1626 return mkLazy2(mce, Ity_I32, vatom1, vatom2);
1627
1628 case Iop_F64toI16:
1629 /* First arg is I32 (rounding mode), second is F64 (data). */
1630 return mkLazy2(mce, Ity_I16, vatom1, vatom2);
1631
1632 case Iop_ScaleF64:
1633 case Iop_Yl2xF64:
1634 case Iop_Yl2xp1F64:
1635 case Iop_PRemF64:
sewardj96403eb2005-04-01 20:20:12 +00001636 case Iop_PRem1F64:
sewardj95448072004-11-22 20:19:51 +00001637 case Iop_AtanF64:
1638 case Iop_AddF64:
1639 case Iop_DivF64:
1640 case Iop_SubF64:
1641 case Iop_MulF64:
1642 return mkLazy2(mce, Ity_I64, vatom1, vatom2);
1643
1644 case Iop_CmpF64:
1645 return mkLazy2(mce, Ity_I32, vatom1, vatom2);
1646
1647 /* non-FP after here */
1648
1649 case Iop_DivModU64to32:
1650 case Iop_DivModS64to32:
1651 return mkLazy2(mce, Ity_I64, vatom1, vatom2);
1652
sewardj69a13322005-04-23 01:14:51 +00001653 case Iop_DivModU128to64:
1654 case Iop_DivModS128to64:
1655 return mkLazy2(mce, Ity_I128, vatom1, vatom2);
1656
sewardj95448072004-11-22 20:19:51 +00001657 case Iop_16HLto32:
sewardj170ee212004-12-10 18:57:51 +00001658 return assignNew(mce, Ity_I32, binop(op, vatom1, vatom2));
sewardj95448072004-11-22 20:19:51 +00001659 case Iop_32HLto64:
sewardj170ee212004-12-10 18:57:51 +00001660 return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
sewardj95448072004-11-22 20:19:51 +00001661
sewardj6cf40ff2005-04-20 22:31:26 +00001662 case Iop_MullS64:
1663 case Iop_MullU64: {
1664 IRAtom* vLo64 = mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
1665 IRAtom* vHi64 = mkPCastTo(mce, Ity_I64, vLo64);
1666 return assignNew(mce, Ity_I128, binop(Iop_64HLto128, vHi64, vLo64));
1667 }
1668
sewardj95448072004-11-22 20:19:51 +00001669 case Iop_MullS32:
1670 case Iop_MullU32: {
1671 IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
1672 IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32);
1673 return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32));
1674 }
1675
1676 case Iop_MullS16:
1677 case Iop_MullU16: {
1678 IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2));
1679 IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16);
1680 return assignNew(mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16));
1681 }
1682
1683 case Iop_MullS8:
1684 case Iop_MullU8: {
1685 IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2));
1686 IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8);
1687 return assignNew(mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8));
1688 }
1689
cerion9e591082005-06-23 15:28:34 +00001690 case Iop_DivS32:
1691 case Iop_DivU32:
1692 return mkLazy2(mce, Ity_I32, vatom1, vatom2);
1693
sewardj95448072004-11-22 20:19:51 +00001694 case Iop_Add32:
sewardjd5204dc2004-12-31 01:16:11 +00001695 if (mce->bogusLiterals)
1696 return expensiveAddSub(mce,True,Ity_I32,
1697 vatom1,vatom2, atom1,atom2);
1698 else
1699 goto cheap_AddSub32;
sewardj95448072004-11-22 20:19:51 +00001700 case Iop_Sub32:
sewardjd5204dc2004-12-31 01:16:11 +00001701 if (mce->bogusLiterals)
1702 return expensiveAddSub(mce,False,Ity_I32,
1703 vatom1,vatom2, atom1,atom2);
1704 else
1705 goto cheap_AddSub32;
1706
1707 cheap_AddSub32:
sewardj95448072004-11-22 20:19:51 +00001708 case Iop_Mul32:
1709 return mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
1710
sewardj681be302005-01-15 20:43:58 +00001711 case Iop_Add64:
tomd9774d72005-06-27 08:11:01 +00001712 if (mce->bogusLiterals)
1713 return expensiveAddSub(mce,True,Ity_I64,
1714 vatom1,vatom2, atom1,atom2);
1715 else
1716 goto cheap_AddSub64;
sewardj681be302005-01-15 20:43:58 +00001717 case Iop_Sub64:
tomd9774d72005-06-27 08:11:01 +00001718 if (mce->bogusLiterals)
1719 return expensiveAddSub(mce,False,Ity_I64,
1720 vatom1,vatom2, atom1,atom2);
1721 else
1722 goto cheap_AddSub64;
1723
1724 cheap_AddSub64:
1725 case Iop_Mul64:
sewardj681be302005-01-15 20:43:58 +00001726 return mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
1727
sewardj95448072004-11-22 20:19:51 +00001728 case Iop_Mul16:
1729 case Iop_Add16:
1730 case Iop_Sub16:
1731 return mkLeft16(mce, mkUifU16(mce, vatom1,vatom2));
1732
1733 case Iop_Sub8:
1734 case Iop_Add8:
1735 return mkLeft8(mce, mkUifU8(mce, vatom1,vatom2));
1736
sewardj69a13322005-04-23 01:14:51 +00001737 case Iop_CmpEQ64:
sewardje6f8af42005-07-06 18:48:59 +00001738 case Iop_CmpNE64:
sewardj69a13322005-04-23 01:14:51 +00001739 if (mce->bogusLiterals)
1740 return expensiveCmpEQorNE(mce,Ity_I64, vatom1,vatom2, atom1,atom2 );
1741 else
1742 goto cheap_cmp64;
1743 cheap_cmp64:
tomcd986332005-04-26 07:44:48 +00001744 case Iop_CmpLE64S: case Iop_CmpLE64U:
1745 case Iop_CmpLT64U: case Iop_CmpLT64S:
sewardj69a13322005-04-23 01:14:51 +00001746 return mkPCastTo(mce, Ity_I1, mkUifU64(mce, vatom1,vatom2));
1747
sewardjd5204dc2004-12-31 01:16:11 +00001748 case Iop_CmpEQ32:
sewardje6f8af42005-07-06 18:48:59 +00001749 case Iop_CmpNE32:
sewardjd5204dc2004-12-31 01:16:11 +00001750 if (mce->bogusLiterals)
1751 return expensiveCmpEQorNE(mce,Ity_I32, vatom1,vatom2, atom1,atom2 );
1752 else
1753 goto cheap_cmp32;
sewardjd5204dc2004-12-31 01:16:11 +00001754 cheap_cmp32:
sewardj95448072004-11-22 20:19:51 +00001755 case Iop_CmpLE32S: case Iop_CmpLE32U:
1756 case Iop_CmpLT32U: case Iop_CmpLT32S:
sewardj95448072004-11-22 20:19:51 +00001757 return mkPCastTo(mce, Ity_I1, mkUifU32(mce, vatom1,vatom2));
1758
1759 case Iop_CmpEQ16: case Iop_CmpNE16:
1760 return mkPCastTo(mce, Ity_I1, mkUifU16(mce, vatom1,vatom2));
1761
1762 case Iop_CmpEQ8: case Iop_CmpNE8:
1763 return mkPCastTo(mce, Ity_I1, mkUifU8(mce, vatom1,vatom2));
1764
1765 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
1766 /* Complain if the shift amount is undefined. Then simply
1767 shift the first arg's V bits by the real shift amount. */
1768 complainIfUndefined(mce, atom2);
1769 return assignNew(mce, Ity_I32, binop(op, vatom1, atom2));
1770
sewardjdb67f5f2004-12-14 01:15:31 +00001771 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
sewardj95448072004-11-22 20:19:51 +00001772 /* Same scheme as with 32-bit shifts. */
1773 complainIfUndefined(mce, atom2);
1774 return assignNew(mce, Ity_I16, binop(op, vatom1, atom2));
1775
1776 case Iop_Shl8: case Iop_Shr8:
1777 /* Same scheme as with 32-bit shifts. */
1778 complainIfUndefined(mce, atom2);
1779 return assignNew(mce, Ity_I8, binop(op, vatom1, atom2));
1780
sewardj69a13322005-04-23 01:14:51 +00001781 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
sewardj95448072004-11-22 20:19:51 +00001782 /* Same scheme as with 32-bit shifts. */
1783 complainIfUndefined(mce, atom2);
1784 return assignNew(mce, Ity_I64, binop(op, vatom1, atom2));
1785
sewardj20d38f22005-02-07 23:50:18 +00001786 case Iop_AndV128:
1787 uifu = mkUifUV128; difd = mkDifDV128;
1788 and_or_ty = Ity_V128; improve = mkImproveANDV128; goto do_And_Or;
sewardj7010f6e2004-12-10 13:35:22 +00001789 case Iop_And64:
1790 uifu = mkUifU64; difd = mkDifD64;
1791 and_or_ty = Ity_I64; improve = mkImproveAND64; goto do_And_Or;
sewardj95448072004-11-22 20:19:51 +00001792 case Iop_And32:
1793 uifu = mkUifU32; difd = mkDifD32;
1794 and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or;
1795 case Iop_And16:
1796 uifu = mkUifU16; difd = mkDifD16;
1797 and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or;
1798 case Iop_And8:
1799 uifu = mkUifU8; difd = mkDifD8;
1800 and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or;
1801
sewardj20d38f22005-02-07 23:50:18 +00001802 case Iop_OrV128:
1803 uifu = mkUifUV128; difd = mkDifDV128;
1804 and_or_ty = Ity_V128; improve = mkImproveORV128; goto do_And_Or;
sewardj7010f6e2004-12-10 13:35:22 +00001805 case Iop_Or64:
1806 uifu = mkUifU64; difd = mkDifD64;
1807 and_or_ty = Ity_I64; improve = mkImproveOR64; goto do_And_Or;
sewardj95448072004-11-22 20:19:51 +00001808 case Iop_Or32:
1809 uifu = mkUifU32; difd = mkDifD32;
1810 and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or;
1811 case Iop_Or16:
1812 uifu = mkUifU16; difd = mkDifD16;
1813 and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or;
1814 case Iop_Or8:
1815 uifu = mkUifU8; difd = mkDifD8;
1816 and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or;
1817
1818 do_And_Or:
1819 return
1820 assignNew(
1821 mce,
1822 and_or_ty,
1823 difd(mce, uifu(mce, vatom1, vatom2),
1824 difd(mce, improve(mce, atom1, vatom1),
1825 improve(mce, atom2, vatom2) ) ) );
1826
1827 case Iop_Xor8:
1828 return mkUifU8(mce, vatom1, vatom2);
1829 case Iop_Xor16:
1830 return mkUifU16(mce, vatom1, vatom2);
1831 case Iop_Xor32:
1832 return mkUifU32(mce, vatom1, vatom2);
sewardj7010f6e2004-12-10 13:35:22 +00001833 case Iop_Xor64:
1834 return mkUifU64(mce, vatom1, vatom2);
sewardj20d38f22005-02-07 23:50:18 +00001835 case Iop_XorV128:
1836 return mkUifUV128(mce, vatom1, vatom2);
njn25e49d8e72002-09-23 09:36:25 +00001837
1838 default:
sewardj95448072004-11-22 20:19:51 +00001839 ppIROp(op);
1840 VG_(tool_panic)("memcheck:expr2vbits_Binop");
njn25e49d8e72002-09-23 09:36:25 +00001841 }
njn25e49d8e72002-09-23 09:36:25 +00001842}
1843
njn25e49d8e72002-09-23 09:36:25 +00001844
sewardj95448072004-11-22 20:19:51 +00001845static
1846IRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom )
1847{
1848 IRAtom* vatom = expr2vbits( mce, atom );
1849 tl_assert(isOriginalAtom(mce,atom));
1850 switch (op) {
1851
sewardj0b070592004-12-10 21:44:22 +00001852 case Iop_Sqrt64Fx2:
1853 return unary64Fx2(mce, vatom);
1854
1855 case Iop_Sqrt64F0x2:
1856 return unary64F0x2(mce, vatom);
1857
sewardj170ee212004-12-10 18:57:51 +00001858 case Iop_Sqrt32Fx4:
1859 case Iop_RSqrt32Fx4:
1860 case Iop_Recip32Fx4:
1861 return unary32Fx4(mce, vatom);
1862
1863 case Iop_Sqrt32F0x4:
1864 case Iop_RSqrt32F0x4:
1865 case Iop_Recip32F0x4:
1866 return unary32F0x4(mce, vatom);
1867
sewardj20d38f22005-02-07 23:50:18 +00001868 case Iop_32UtoV128:
1869 case Iop_64UtoV128:
sewardj170ee212004-12-10 18:57:51 +00001870 return assignNew(mce, Ity_V128, unop(op, vatom));
1871
sewardj95448072004-11-22 20:19:51 +00001872 case Iop_F32toF64:
1873 case Iop_I32toF64:
sewardj95448072004-11-22 20:19:51 +00001874 case Iop_NegF64:
1875 case Iop_SinF64:
1876 case Iop_CosF64:
1877 case Iop_TanF64:
1878 case Iop_SqrtF64:
1879 case Iop_AbsF64:
1880 case Iop_2xm1F64:
sewardj39cc7352005-06-09 21:31:55 +00001881 case Iop_Clz64:
1882 case Iop_Ctz64:
sewardj95448072004-11-22 20:19:51 +00001883 return mkPCastTo(mce, Ity_I64, vatom);
1884
sewardj95448072004-11-22 20:19:51 +00001885 case Iop_Clz32:
1886 case Iop_Ctz32:
1887 return mkPCastTo(mce, Ity_I32, vatom);
1888
sewardjd9dbc192005-04-27 11:40:27 +00001889 case Iop_1Uto64:
1890 case Iop_8Uto64:
1891 case Iop_8Sto64:
1892 case Iop_16Uto64:
1893 case Iop_16Sto64:
sewardj95448072004-11-22 20:19:51 +00001894 case Iop_32Sto64:
1895 case Iop_32Uto64:
sewardj20d38f22005-02-07 23:50:18 +00001896 case Iop_V128to64:
1897 case Iop_V128HIto64:
sewardj6cf40ff2005-04-20 22:31:26 +00001898 case Iop_128HIto64:
1899 case Iop_128to64:
sewardj95448072004-11-22 20:19:51 +00001900 return assignNew(mce, Ity_I64, unop(op, vatom));
1901
1902 case Iop_64to32:
1903 case Iop_64HIto32:
1904 case Iop_1Uto32:
1905 case Iop_8Uto32:
1906 case Iop_16Uto32:
1907 case Iop_16Sto32:
1908 case Iop_8Sto32:
1909 return assignNew(mce, Ity_I32, unop(op, vatom));
1910
1911 case Iop_8Sto16:
1912 case Iop_8Uto16:
1913 case Iop_32to16:
1914 case Iop_32HIto16:
sewardjd9dbc192005-04-27 11:40:27 +00001915 case Iop_64to16:
sewardj95448072004-11-22 20:19:51 +00001916 return assignNew(mce, Ity_I16, unop(op, vatom));
1917
1918 case Iop_1Uto8:
1919 case Iop_16to8:
1920 case Iop_32to8:
sewardjd9dbc192005-04-27 11:40:27 +00001921 case Iop_64to8:
sewardj95448072004-11-22 20:19:51 +00001922 return assignNew(mce, Ity_I8, unop(op, vatom));
1923
1924 case Iop_32to1:
1925 return assignNew(mce, Ity_I1, unop(Iop_32to1, vatom));
1926
sewardjd9dbc192005-04-27 11:40:27 +00001927 case Iop_64to1:
1928 return assignNew(mce, Ity_I1, unop(Iop_64to1, vatom));
1929
sewardj95448072004-11-22 20:19:51 +00001930 case Iop_ReinterpF64asI64:
1931 case Iop_ReinterpI64asF64:
sewardj0b070592004-12-10 21:44:22 +00001932 case Iop_ReinterpI32asF32:
sewardj20d38f22005-02-07 23:50:18 +00001933 case Iop_NotV128:
sewardj7010f6e2004-12-10 13:35:22 +00001934 case Iop_Not64:
sewardj95448072004-11-22 20:19:51 +00001935 case Iop_Not32:
1936 case Iop_Not16:
1937 case Iop_Not8:
1938 case Iop_Not1:
1939 return vatom;
sewardj7010f6e2004-12-10 13:35:22 +00001940
sewardje53bd992005-05-03 12:22:00 +00001941 /* Neg* really fall under the Add/Sub banner, and as such you
1942 might think would qualify for the 'expensive add/sub'
1943 treatment. However, in this case since the implied literal
1944 is zero (0 - arg), we just do the cheap thing anyway. */
1945 case Iop_Neg8:
1946 return mkLeft8(mce, vatom);
1947 case Iop_Neg16:
1948 return mkLeft16(mce, vatom);
1949 case Iop_Neg32:
1950 return mkLeft32(mce, vatom);
1951
sewardj95448072004-11-22 20:19:51 +00001952 default:
1953 ppIROp(op);
1954 VG_(tool_panic)("memcheck:expr2vbits_Unop");
1955 }
1956}
1957
1958
sewardj170ee212004-12-10 18:57:51 +00001959/* Worker function; do not call directly. */
sewardj95448072004-11-22 20:19:51 +00001960static
sewardj2e595852005-06-30 23:33:37 +00001961IRAtom* expr2vbits_Load_WRK ( MCEnv* mce,
1962 IREndness end, IRType ty,
1963 IRAtom* addr, UInt bias )
sewardj95448072004-11-22 20:19:51 +00001964{
1965 void* helper;
1966 Char* hname;
1967 IRDirty* di;
1968 IRTemp datavbits;
1969 IRAtom* addrAct;
1970
1971 tl_assert(isOriginalAtom(mce,addr));
sewardj2e595852005-06-30 23:33:37 +00001972 tl_assert(end == Iend_LE || end == Iend_BE);
sewardj95448072004-11-22 20:19:51 +00001973
1974 /* First, emit a definedness test for the address. This also sets
1975 the address (shadow) to 'defined' following the test. */
1976 complainIfUndefined( mce, addr );
1977
1978 /* Now cook up a call to the relevant helper function, to read the
1979 data V bits from shadow memory. */
1980 ty = shadowType(ty);
sewardj2e595852005-06-30 23:33:37 +00001981
1982 if (end == Iend_LE) {
1983 switch (ty) {
1984 case Ity_I64: helper = &MC_(helperc_LOADV8le);
1985 hname = "MC_(helperc_LOADV8le)";
1986 break;
1987 case Ity_I32: helper = &MC_(helperc_LOADV4le);
1988 hname = "MC_(helperc_LOADV4le)";
1989 break;
1990 case Ity_I16: helper = &MC_(helperc_LOADV2le);
1991 hname = "MC_(helperc_LOADV2le)";
1992 break;
sewardj8cf88b72005-07-08 01:29:33 +00001993 case Ity_I8: helper = &MC_(helperc_LOADV1);
1994 hname = "MC_(helperc_LOADV1)";
sewardj2e595852005-06-30 23:33:37 +00001995 break;
1996 default: ppIRType(ty);
1997 VG_(tool_panic)("memcheck:do_shadow_Load(LE)");
1998 }
1999 } else {
sewardj8cf88b72005-07-08 01:29:33 +00002000 switch (ty) {
2001 case Ity_I64: helper = &MC_(helperc_LOADV8be);
2002 hname = "MC_(helperc_LOADV8be)";
2003 break;
2004 case Ity_I32: helper = &MC_(helperc_LOADV4be);
2005 hname = "MC_(helperc_LOADV4be)";
2006 break;
2007 case Ity_I16: helper = &MC_(helperc_LOADV2be);
2008 hname = "MC_(helperc_LOADV2be)";
2009 break;
2010 case Ity_I8: helper = &MC_(helperc_LOADV1);
2011 hname = "MC_(helperc_LOADV1)";
2012 break;
2013 default: ppIRType(ty);
2014 VG_(tool_panic)("memcheck:do_shadow_Load(BE)");
2015 }
sewardj95448072004-11-22 20:19:51 +00002016 }
2017
2018 /* Generate the actual address into addrAct. */
2019 if (bias == 0) {
2020 addrAct = addr;
2021 } else {
sewardj7cf97ee2004-11-28 14:25:01 +00002022 IROp mkAdd;
2023 IRAtom* eBias;
sewardj95448072004-11-22 20:19:51 +00002024 IRType tyAddr = mce->hWordTy;
2025 tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
sewardj7cf97ee2004-11-28 14:25:01 +00002026 mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
2027 eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
sewardj95448072004-11-22 20:19:51 +00002028 addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
2029 }
2030
2031 /* We need to have a place to park the V bits we're just about to
2032 read. */
2033 datavbits = newIRTemp(mce->bb->tyenv, ty);
2034 di = unsafeIRDirty_1_N( datavbits,
2035 1/*regparms*/, hname, helper,
2036 mkIRExprVec_1( addrAct ));
2037 setHelperAnns( mce, di );
2038 stmt( mce->bb, IRStmt_Dirty(di) );
2039
2040 return mkexpr(datavbits);
2041}
2042
2043
2044static
sewardj2e595852005-06-30 23:33:37 +00002045IRAtom* expr2vbits_Load ( MCEnv* mce,
2046 IREndness end, IRType ty,
2047 IRAtom* addr, UInt bias )
sewardj170ee212004-12-10 18:57:51 +00002048{
2049 IRAtom *v64hi, *v64lo;
sewardj2e595852005-06-30 23:33:37 +00002050 tl_assert(end == Iend_LE || end == Iend_BE);
sewardj170ee212004-12-10 18:57:51 +00002051 switch (shadowType(ty)) {
2052 case Ity_I8:
2053 case Ity_I16:
2054 case Ity_I32:
2055 case Ity_I64:
sewardj2e595852005-06-30 23:33:37 +00002056 return expr2vbits_Load_WRK(mce, end, ty, addr, bias);
sewardj170ee212004-12-10 18:57:51 +00002057 case Ity_V128:
sewardj2e595852005-06-30 23:33:37 +00002058 if (end == Iend_LE) {
2059 v64lo = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias);
2060 v64hi = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias+8);
2061 } else {
2062 tl_assert(0 /* awaiting test case */);
2063 v64hi = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias);
2064 v64lo = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias+8);
2065 }
sewardj170ee212004-12-10 18:57:51 +00002066 return assignNew( mce,
2067 Ity_V128,
sewardj20d38f22005-02-07 23:50:18 +00002068 binop(Iop_64HLtoV128, v64hi, v64lo));
sewardj170ee212004-12-10 18:57:51 +00002069 default:
sewardj2e595852005-06-30 23:33:37 +00002070 VG_(tool_panic)("expr2vbits_Load");
sewardj170ee212004-12-10 18:57:51 +00002071 }
2072}
2073
2074
2075static
sewardj95448072004-11-22 20:19:51 +00002076IRAtom* expr2vbits_Mux0X ( MCEnv* mce,
2077 IRAtom* cond, IRAtom* expr0, IRAtom* exprX )
2078{
2079 IRAtom *vbitsC, *vbits0, *vbitsX;
2080 IRType ty;
2081 /* Given Mux0X(cond,expr0,exprX), generate
2082 Mux0X(cond,expr0#,exprX#) `UifU` PCast(cond#)
2083 That is, steer the V bits like the originals, but trash the
2084 result if the steering value is undefined. This gives
2085 lazy propagation. */
2086 tl_assert(isOriginalAtom(mce, cond));
2087 tl_assert(isOriginalAtom(mce, expr0));
2088 tl_assert(isOriginalAtom(mce, exprX));
2089
2090 vbitsC = expr2vbits(mce, cond);
2091 vbits0 = expr2vbits(mce, expr0);
2092 vbitsX = expr2vbits(mce, exprX);
2093 ty = typeOfIRExpr(mce->bb->tyenv, vbits0);
2094
2095 return
2096 mkUifU(mce, ty, assignNew(mce, ty, IRExpr_Mux0X(cond, vbits0, vbitsX)),
2097 mkPCastTo(mce, ty, vbitsC) );
2098}
2099
2100/* --------- This is the main expression-handling function. --------- */
2101
2102static
2103IRExpr* expr2vbits ( MCEnv* mce, IRExpr* e )
2104{
2105 switch (e->tag) {
2106
2107 case Iex_Get:
2108 return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty );
2109
2110 case Iex_GetI:
2111 return shadow_GETI( mce, e->Iex.GetI.descr,
2112 e->Iex.GetI.ix, e->Iex.GetI.bias );
2113
2114 case Iex_Tmp:
2115 return IRExpr_Tmp( findShadowTmp(mce, e->Iex.Tmp.tmp) );
2116
2117 case Iex_Const:
2118 return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)));
2119
2120 case Iex_Binop:
2121 return expr2vbits_Binop(
2122 mce,
2123 e->Iex.Binop.op,
2124 e->Iex.Binop.arg1, e->Iex.Binop.arg2
2125 );
2126
2127 case Iex_Unop:
2128 return expr2vbits_Unop( mce, e->Iex.Unop.op, e->Iex.Unop.arg );
2129
sewardj2e595852005-06-30 23:33:37 +00002130 case Iex_Load:
2131 return expr2vbits_Load( mce, e->Iex.Load.end,
2132 e->Iex.Load.ty,
2133 e->Iex.Load.addr, 0/*addr bias*/ );
sewardj95448072004-11-22 20:19:51 +00002134
2135 case Iex_CCall:
2136 return mkLazyN( mce, e->Iex.CCall.args,
2137 e->Iex.CCall.retty,
2138 e->Iex.CCall.cee );
2139
2140 case Iex_Mux0X:
2141 return expr2vbits_Mux0X( mce, e->Iex.Mux0X.cond, e->Iex.Mux0X.expr0,
2142 e->Iex.Mux0X.exprX);
njn25e49d8e72002-09-23 09:36:25 +00002143
2144 default:
sewardj95448072004-11-22 20:19:51 +00002145 VG_(printf)("\n");
2146 ppIRExpr(e);
2147 VG_(printf)("\n");
2148 VG_(tool_panic)("memcheck: expr2vbits");
njn25e49d8e72002-09-23 09:36:25 +00002149 }
njn25e49d8e72002-09-23 09:36:25 +00002150}
2151
2152/*------------------------------------------------------------*/
sewardj95448072004-11-22 20:19:51 +00002153/*--- Generate shadow stmts from all kinds of IRStmts. ---*/
njn25e49d8e72002-09-23 09:36:25 +00002154/*------------------------------------------------------------*/
2155
sewardj95448072004-11-22 20:19:51 +00002156/* Widen a value to the host word size. */
njn25e49d8e72002-09-23 09:36:25 +00002157
2158static
sewardj95448072004-11-22 20:19:51 +00002159IRExpr* zwidenToHostWord ( MCEnv* mce, IRAtom* vatom )
njn25e49d8e72002-09-23 09:36:25 +00002160{
sewardj7cf97ee2004-11-28 14:25:01 +00002161 IRType ty, tyH;
2162
sewardj95448072004-11-22 20:19:51 +00002163 /* vatom is vbits-value and as such can only have a shadow type. */
2164 tl_assert(isShadowAtom(mce,vatom));
njn25e49d8e72002-09-23 09:36:25 +00002165
sewardj7cf97ee2004-11-28 14:25:01 +00002166 ty = typeOfIRExpr(mce->bb->tyenv, vatom);
2167 tyH = mce->hWordTy;
njn25e49d8e72002-09-23 09:36:25 +00002168
sewardj95448072004-11-22 20:19:51 +00002169 if (tyH == Ity_I32) {
2170 switch (ty) {
2171 case Ity_I32: return vatom;
2172 case Ity_I16: return assignNew(mce, tyH, unop(Iop_16Uto32, vatom));
2173 case Ity_I8: return assignNew(mce, tyH, unop(Iop_8Uto32, vatom));
2174 default: goto unhandled;
sewardj8ec2cfc2002-10-13 00:57:26 +00002175 }
sewardj6cf40ff2005-04-20 22:31:26 +00002176 } else
2177 if (tyH == Ity_I64) {
2178 switch (ty) {
2179 case Ity_I32: return assignNew(mce, tyH, unop(Iop_32Uto64, vatom));
sewardj69a13322005-04-23 01:14:51 +00002180 case Ity_I16: return assignNew(mce, tyH, unop(Iop_32Uto64,
2181 assignNew(mce, Ity_I32, unop(Iop_16Uto32, vatom))));
2182 case Ity_I8: return assignNew(mce, tyH, unop(Iop_32Uto64,
2183 assignNew(mce, Ity_I32, unop(Iop_8Uto32, vatom))));
sewardj6cf40ff2005-04-20 22:31:26 +00002184 default: goto unhandled;
2185 }
sewardj95448072004-11-22 20:19:51 +00002186 } else {
2187 goto unhandled;
sewardj8ec2cfc2002-10-13 00:57:26 +00002188 }
sewardj95448072004-11-22 20:19:51 +00002189 unhandled:
2190 VG_(printf)("\nty = "); ppIRType(ty); VG_(printf)("\n");
2191 VG_(tool_panic)("zwidenToHostWord");
njn25e49d8e72002-09-23 09:36:25 +00002192}
2193
njn25e49d8e72002-09-23 09:36:25 +00002194
sewardj95448072004-11-22 20:19:51 +00002195/* Generate a shadow store. addr is always the original address atom.
2196 You can pass in either originals or V-bits for the data atom, but
2197 obviously not both. */
njn25e49d8e72002-09-23 09:36:25 +00002198
sewardj95448072004-11-22 20:19:51 +00002199static
sewardj2e595852005-06-30 23:33:37 +00002200void do_shadow_Store ( MCEnv* mce,
2201 IREndness end,
2202 IRAtom* addr, UInt bias,
2203 IRAtom* data, IRAtom* vdata )
njn25e49d8e72002-09-23 09:36:25 +00002204{
sewardj170ee212004-12-10 18:57:51 +00002205 IROp mkAdd;
2206 IRType ty, tyAddr;
2207 IRDirty *di, *diLo64, *diHi64;
2208 IRAtom *addrAct, *addrLo64, *addrHi64;
2209 IRAtom *vdataLo64, *vdataHi64;
sewardj2e595852005-06-30 23:33:37 +00002210 IRAtom *eBias, *eBiasLo64, *eBiasHi64;
sewardj95448072004-11-22 20:19:51 +00002211 void* helper = NULL;
2212 Char* hname = NULL;
sewardj170ee212004-12-10 18:57:51 +00002213
2214 tyAddr = mce->hWordTy;
2215 mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
2216 tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
sewardj2e595852005-06-30 23:33:37 +00002217 tl_assert( end == Iend_LE || end == Iend_BE );
sewardj170ee212004-12-10 18:57:51 +00002218
2219 di = diLo64 = diHi64 = NULL;
sewardj2e595852005-06-30 23:33:37 +00002220 eBias = eBiasLo64 = eBiasHi64 = NULL;
sewardj170ee212004-12-10 18:57:51 +00002221 addrAct = addrLo64 = addrHi64 = NULL;
2222 vdataLo64 = vdataHi64 = NULL;
njn25e49d8e72002-09-23 09:36:25 +00002223
sewardj95448072004-11-22 20:19:51 +00002224 if (data) {
2225 tl_assert(!vdata);
2226 tl_assert(isOriginalAtom(mce, data));
2227 tl_assert(bias == 0);
2228 vdata = expr2vbits( mce, data );
2229 } else {
2230 tl_assert(vdata);
2231 }
njn25e49d8e72002-09-23 09:36:25 +00002232
sewardj95448072004-11-22 20:19:51 +00002233 tl_assert(isOriginalAtom(mce,addr));
2234 tl_assert(isShadowAtom(mce,vdata));
njn25e49d8e72002-09-23 09:36:25 +00002235
sewardj95448072004-11-22 20:19:51 +00002236 ty = typeOfIRExpr(mce->bb->tyenv, vdata);
njn25e49d8e72002-09-23 09:36:25 +00002237
sewardj95448072004-11-22 20:19:51 +00002238 /* First, emit a definedness test for the address. This also sets
2239 the address (shadow) to 'defined' following the test. */
2240 complainIfUndefined( mce, addr );
njn25e49d8e72002-09-23 09:36:25 +00002241
sewardj170ee212004-12-10 18:57:51 +00002242 /* Now decide which helper function to call to write the data V
2243 bits into shadow memory. */
sewardj2e595852005-06-30 23:33:37 +00002244 if (end == Iend_LE) {
2245 switch (ty) {
2246 case Ity_V128: /* we'll use the helper twice */
2247 case Ity_I64: helper = &MC_(helperc_STOREV8le);
2248 hname = "MC_(helperc_STOREV8le)";
2249 break;
2250 case Ity_I32: helper = &MC_(helperc_STOREV4le);
2251 hname = "MC_(helperc_STOREV4le)";
2252 break;
2253 case Ity_I16: helper = &MC_(helperc_STOREV2le);
2254 hname = "MC_(helperc_STOREV2le)";
2255 break;
sewardj8cf88b72005-07-08 01:29:33 +00002256 case Ity_I8: helper = &MC_(helperc_STOREV1);
2257 hname = "MC_(helperc_STOREV1)";
sewardj2e595852005-06-30 23:33:37 +00002258 break;
2259 default: VG_(tool_panic)("memcheck:do_shadow_Store(LE)");
2260 }
2261 } else {
sewardj8cf88b72005-07-08 01:29:33 +00002262 switch (ty) {
2263 case Ity_V128: /* we'll use the helper twice */
2264 case Ity_I64: helper = &MC_(helperc_STOREV8be);
2265 hname = "MC_(helperc_STOREV8be)";
2266 break;
2267 case Ity_I32: helper = &MC_(helperc_STOREV4be);
2268 hname = "MC_(helperc_STOREV4be)";
2269 break;
2270 case Ity_I16: helper = &MC_(helperc_STOREV2be);
2271 hname = "MC_(helperc_STOREV2be)";
2272 break;
2273 case Ity_I8: helper = &MC_(helperc_STOREV1);
2274 hname = "MC_(helperc_STOREV1)";
2275 break;
2276 default: VG_(tool_panic)("memcheck:do_shadow_Store(BE)");
2277 }
sewardj95448072004-11-22 20:19:51 +00002278 }
njn25e49d8e72002-09-23 09:36:25 +00002279
sewardj170ee212004-12-10 18:57:51 +00002280 if (ty == Ity_V128) {
2281
sewardj20d38f22005-02-07 23:50:18 +00002282 /* V128-bit case */
sewardj170ee212004-12-10 18:57:51 +00002283 /* See comment in next clause re 64-bit regparms */
sewardj2e595852005-06-30 23:33:37 +00002284 /* also, need to be careful about endianness */
2285
2286 Int offLo64, offHi64;
2287 if (end == Iend_LE) {
2288 offLo64 = 0;
2289 offHi64 = 8;
2290 } else {
sewardj2e595852005-06-30 23:33:37 +00002291 offLo64 = 8;
2292 offHi64 = 0;
2293 }
2294
2295 eBiasLo64 = tyAddr==Ity_I32 ? mkU32(bias+offLo64) : mkU64(bias+offLo64);
2296 addrLo64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasLo64) );
sewardj20d38f22005-02-07 23:50:18 +00002297 vdataLo64 = assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata));
sewardj170ee212004-12-10 18:57:51 +00002298 diLo64 = unsafeIRDirty_0_N(
2299 1/*regparms*/, hname, helper,
2300 mkIRExprVec_2( addrLo64, vdataLo64 ));
2301
sewardj2e595852005-06-30 23:33:37 +00002302 eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64);
2303 addrHi64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasHi64) );
sewardj20d38f22005-02-07 23:50:18 +00002304 vdataHi64 = assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata));
sewardj170ee212004-12-10 18:57:51 +00002305 diHi64 = unsafeIRDirty_0_N(
2306 1/*regparms*/, hname, helper,
2307 mkIRExprVec_2( addrHi64, vdataHi64 ));
2308
2309 setHelperAnns( mce, diLo64 );
2310 setHelperAnns( mce, diHi64 );
2311 stmt( mce->bb, IRStmt_Dirty(diLo64) );
2312 stmt( mce->bb, IRStmt_Dirty(diHi64) );
2313
sewardj95448072004-11-22 20:19:51 +00002314 } else {
sewardj170ee212004-12-10 18:57:51 +00002315
2316 /* 8/16/32/64-bit cases */
2317 /* Generate the actual address into addrAct. */
2318 if (bias == 0) {
2319 addrAct = addr;
2320 } else {
2321 eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
2322 addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
2323 }
2324
2325 if (ty == Ity_I64) {
2326 /* We can't do this with regparm 2 on 32-bit platforms, since
2327 the back ends aren't clever enough to handle 64-bit
2328 regparm args. Therefore be different. */
2329 di = unsafeIRDirty_0_N(
2330 1/*regparms*/, hname, helper,
2331 mkIRExprVec_2( addrAct, vdata ));
2332 } else {
2333 di = unsafeIRDirty_0_N(
2334 2/*regparms*/, hname, helper,
2335 mkIRExprVec_2( addrAct,
2336 zwidenToHostWord( mce, vdata )));
2337 }
2338 setHelperAnns( mce, di );
2339 stmt( mce->bb, IRStmt_Dirty(di) );
sewardj95448072004-11-22 20:19:51 +00002340 }
njn25e49d8e72002-09-23 09:36:25 +00002341
sewardj95448072004-11-22 20:19:51 +00002342}
njn25e49d8e72002-09-23 09:36:25 +00002343
njn25e49d8e72002-09-23 09:36:25 +00002344
sewardj95448072004-11-22 20:19:51 +00002345/* Do lazy pessimistic propagation through a dirty helper call, by
2346 looking at the annotations on it. This is the most complex part of
2347 Memcheck. */
njn25e49d8e72002-09-23 09:36:25 +00002348
sewardj95448072004-11-22 20:19:51 +00002349static IRType szToITy ( Int n )
2350{
2351 switch (n) {
2352 case 1: return Ity_I8;
2353 case 2: return Ity_I16;
2354 case 4: return Ity_I32;
2355 case 8: return Ity_I64;
2356 default: VG_(tool_panic)("szToITy(memcheck)");
2357 }
2358}
njn25e49d8e72002-09-23 09:36:25 +00002359
sewardj95448072004-11-22 20:19:51 +00002360static
2361void do_shadow_Dirty ( MCEnv* mce, IRDirty* d )
2362{
sewardj2e595852005-06-30 23:33:37 +00002363 Int i, n, offset, toDo, gSz, gOff;
2364 IRAtom *src, *here, *curr;
2365 IRType tyAddr, tySrc, tyDst;
2366 IRTemp dst;
2367 IREndness end;
2368
2369 /* What's the native endianness? We need to know this. */
2370# if defined(VKI_BIG_ENDIAN)
2371 end = Iend_BE;
2372# elif defined(VKI_LITTLE_ENDIAN)
2373 end = Iend_LE;
2374# else
2375# error "Unknown endianness"
2376# endif
njn25e49d8e72002-09-23 09:36:25 +00002377
sewardj95448072004-11-22 20:19:51 +00002378 /* First check the guard. */
2379 complainIfUndefined(mce, d->guard);
2380
2381 /* Now round up all inputs and PCast over them. */
sewardj7cf97ee2004-11-28 14:25:01 +00002382 curr = definedOfType(Ity_I32);
sewardj95448072004-11-22 20:19:51 +00002383
2384 /* Inputs: unmasked args */
2385 for (i = 0; d->args[i]; i++) {
2386 if (d->cee->mcx_mask & (1<<i)) {
2387 /* ignore this arg */
njn25e49d8e72002-09-23 09:36:25 +00002388 } else {
sewardj95448072004-11-22 20:19:51 +00002389 here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, d->args[i]) );
2390 curr = mkUifU32(mce, here, curr);
njn25e49d8e72002-09-23 09:36:25 +00002391 }
2392 }
sewardj95448072004-11-22 20:19:51 +00002393
2394 /* Inputs: guest state that we read. */
2395 for (i = 0; i < d->nFxState; i++) {
2396 tl_assert(d->fxState[i].fx != Ifx_None);
2397 if (d->fxState[i].fx == Ifx_Write)
2398 continue;
sewardja7203252004-11-26 19:17:47 +00002399
2400 /* Ignore any sections marked as 'always defined'. */
2401 if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) {
sewardje9e16d32004-12-10 13:17:55 +00002402 if (0)
sewardja7203252004-11-26 19:17:47 +00002403 VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n",
2404 d->fxState[i].offset, d->fxState[i].size );
2405 continue;
2406 }
2407
sewardj95448072004-11-22 20:19:51 +00002408 /* This state element is read or modified. So we need to
sewardje9e16d32004-12-10 13:17:55 +00002409 consider it. If larger than 8 bytes, deal with it in 8-byte
2410 chunks. */
2411 gSz = d->fxState[i].size;
2412 gOff = d->fxState[i].offset;
2413 tl_assert(gSz > 0);
2414 while (True) {
2415 if (gSz == 0) break;
2416 n = gSz <= 8 ? gSz : 8;
2417 /* update 'curr' with UifU of the state slice
2418 gOff .. gOff+n-1 */
2419 tySrc = szToITy( n );
2420 src = assignNew( mce, tySrc,
2421 shadow_GET(mce, gOff, tySrc ) );
2422 here = mkPCastTo( mce, Ity_I32, src );
2423 curr = mkUifU32(mce, here, curr);
2424 gSz -= n;
2425 gOff += n;
2426 }
2427
sewardj95448072004-11-22 20:19:51 +00002428 }
2429
2430 /* Inputs: memory. First set up some info needed regardless of
2431 whether we're doing reads or writes. */
2432 tyAddr = Ity_INVALID;
2433
2434 if (d->mFx != Ifx_None) {
2435 /* Because we may do multiple shadow loads/stores from the same
2436 base address, it's best to do a single test of its
2437 definedness right now. Post-instrumentation optimisation
2438 should remove all but this test. */
2439 tl_assert(d->mAddr);
2440 complainIfUndefined(mce, d->mAddr);
2441
2442 tyAddr = typeOfIRExpr(mce->bb->tyenv, d->mAddr);
2443 tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
2444 tl_assert(tyAddr == mce->hWordTy); /* not really right */
2445 }
2446
2447 /* Deal with memory inputs (reads or modifies) */
2448 if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) {
2449 offset = 0;
2450 toDo = d->mSize;
sewardj2e595852005-06-30 23:33:37 +00002451 /* chew off 32-bit chunks. We don't care about the endianness
2452 since it's all going to be condensed down to a single bit,
2453 but nevertheless choose an endianness which is hopefully
2454 native to the platform. */
sewardj95448072004-11-22 20:19:51 +00002455 while (toDo >= 4) {
2456 here = mkPCastTo(
2457 mce, Ity_I32,
sewardj2e595852005-06-30 23:33:37 +00002458 expr2vbits_Load ( mce, end, Ity_I32,
sewardj95448072004-11-22 20:19:51 +00002459 d->mAddr, d->mSize - toDo )
2460 );
2461 curr = mkUifU32(mce, here, curr);
2462 toDo -= 4;
2463 }
2464 /* chew off 16-bit chunks */
2465 while (toDo >= 2) {
2466 here = mkPCastTo(
2467 mce, Ity_I32,
sewardj2e595852005-06-30 23:33:37 +00002468 expr2vbits_Load ( mce, end, Ity_I16,
sewardj95448072004-11-22 20:19:51 +00002469 d->mAddr, d->mSize - toDo )
2470 );
2471 curr = mkUifU32(mce, here, curr);
2472 toDo -= 2;
2473 }
2474 tl_assert(toDo == 0); /* also need to handle 1-byte excess */
2475 }
2476
2477 /* Whew! So curr is a 32-bit V-value summarising pessimistically
2478 all the inputs to the helper. Now we need to re-distribute the
2479 results to all destinations. */
2480
2481 /* Outputs: the destination temporary, if there is one. */
2482 if (d->tmp != IRTemp_INVALID) {
2483 dst = findShadowTmp(mce, d->tmp);
2484 tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp);
2485 assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) );
2486 }
2487
2488 /* Outputs: guest state that we write or modify. */
2489 for (i = 0; i < d->nFxState; i++) {
2490 tl_assert(d->fxState[i].fx != Ifx_None);
2491 if (d->fxState[i].fx == Ifx_Read)
2492 continue;
sewardja7203252004-11-26 19:17:47 +00002493 /* Ignore any sections marked as 'always defined'. */
2494 if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size ))
2495 continue;
sewardje9e16d32004-12-10 13:17:55 +00002496 /* This state element is written or modified. So we need to
2497 consider it. If larger than 8 bytes, deal with it in 8-byte
2498 chunks. */
2499 gSz = d->fxState[i].size;
2500 gOff = d->fxState[i].offset;
2501 tl_assert(gSz > 0);
2502 while (True) {
2503 if (gSz == 0) break;
2504 n = gSz <= 8 ? gSz : 8;
2505 /* Write suitably-casted 'curr' to the state slice
2506 gOff .. gOff+n-1 */
2507 tyDst = szToITy( n );
2508 do_shadow_PUT( mce, gOff,
2509 NULL, /* original atom */
2510 mkPCastTo( mce, tyDst, curr ) );
2511 gSz -= n;
2512 gOff += n;
2513 }
sewardj95448072004-11-22 20:19:51 +00002514 }
2515
sewardj2e595852005-06-30 23:33:37 +00002516 /* Outputs: memory that we write or modify. Same comments about
2517 endianness as above apply. */
sewardj95448072004-11-22 20:19:51 +00002518 if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) {
2519 offset = 0;
2520 toDo = d->mSize;
2521 /* chew off 32-bit chunks */
2522 while (toDo >= 4) {
sewardj2e595852005-06-30 23:33:37 +00002523 do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo,
2524 NULL, /* original data */
2525 mkPCastTo( mce, Ity_I32, curr ) );
sewardj95448072004-11-22 20:19:51 +00002526 toDo -= 4;
2527 }
2528 /* chew off 16-bit chunks */
2529 while (toDo >= 2) {
sewardj2e595852005-06-30 23:33:37 +00002530 do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo,
2531 NULL, /* original data */
2532 mkPCastTo( mce, Ity_I16, curr ) );
sewardj95448072004-11-22 20:19:51 +00002533 toDo -= 2;
2534 }
2535 tl_assert(toDo == 0); /* also need to handle 1-byte excess */
2536 }
2537
njn25e49d8e72002-09-23 09:36:25 +00002538}
2539
sewardj826ec492005-05-12 18:05:00 +00002540/* We have an ABI hint telling us that [base .. base+len-1] is to
2541 become undefined ("writable"). Generate code to call a helper to
2542 notify the A/V bit machinery of this fact.
2543
2544 We call
2545 void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len );
2546*/
2547static
2548void do_AbiHint ( MCEnv* mce, IRExpr* base, Int len )
2549{
2550 IRDirty* di;
2551 di = unsafeIRDirty_0_N(
2552 0/*regparms*/,
2553 "MC_(helperc_MAKE_STACK_UNINIT)",
2554 &MC_(helperc_MAKE_STACK_UNINIT),
2555 mkIRExprVec_2( base, mkIRExpr_HWord( (UInt)len) )
2556 );
2557 stmt( mce->bb, IRStmt_Dirty(di) );
2558}
2559
njn25e49d8e72002-09-23 09:36:25 +00002560
sewardj95448072004-11-22 20:19:51 +00002561/*------------------------------------------------------------*/
2562/*--- Memcheck main ---*/
2563/*------------------------------------------------------------*/
njn25e49d8e72002-09-23 09:36:25 +00002564
sewardj95448072004-11-22 20:19:51 +00002565static Bool isBogusAtom ( IRAtom* at )
njn25e49d8e72002-09-23 09:36:25 +00002566{
sewardj95448072004-11-22 20:19:51 +00002567 ULong n = 0;
2568 IRConst* con;
sewardj710d6c22005-03-20 18:55:15 +00002569 tl_assert(isIRAtom(at));
sewardj95448072004-11-22 20:19:51 +00002570 if (at->tag == Iex_Tmp)
2571 return False;
2572 tl_assert(at->tag == Iex_Const);
2573 con = at->Iex.Const.con;
2574 switch (con->tag) {
sewardjd5204dc2004-12-31 01:16:11 +00002575 case Ico_U1: return False;
2576 case Ico_U8: n = (ULong)con->Ico.U8; break;
2577 case Ico_U16: n = (ULong)con->Ico.U16; break;
2578 case Ico_U32: n = (ULong)con->Ico.U32; break;
2579 case Ico_U64: n = (ULong)con->Ico.U64; break;
2580 case Ico_F64: return False;
2581 case Ico_F64i: return False;
2582 case Ico_V128: return False;
sewardj95448072004-11-22 20:19:51 +00002583 default: ppIRExpr(at); tl_assert(0);
2584 }
2585 /* VG_(printf)("%llx\n", n); */
sewardj96a922e2005-04-23 23:26:29 +00002586 return (/*32*/ n == 0xFEFEFEFFULL
2587 /*32*/ || n == 0x80808080ULL
tomd9774d72005-06-27 08:11:01 +00002588 /*64*/ || n == 0xFFFFFFFFFEFEFEFFULL
sewardj96a922e2005-04-23 23:26:29 +00002589 /*64*/ || n == 0xFEFEFEFEFEFEFEFFULL
tomd9774d72005-06-27 08:11:01 +00002590 /*64*/ || n == 0x0000000000008080ULL
sewardj96a922e2005-04-23 23:26:29 +00002591 /*64*/ || n == 0x8080808080808080ULL
2592 /*64*/ || n == 0x0101010101010101ULL
2593 );
sewardj95448072004-11-22 20:19:51 +00002594}
njn25e49d8e72002-09-23 09:36:25 +00002595
sewardj95448072004-11-22 20:19:51 +00002596static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st )
2597{
sewardjd5204dc2004-12-31 01:16:11 +00002598 Int i;
2599 IRExpr* e;
2600 IRDirty* d;
sewardj95448072004-11-22 20:19:51 +00002601 switch (st->tag) {
2602 case Ist_Tmp:
2603 e = st->Ist.Tmp.data;
2604 switch (e->tag) {
2605 case Iex_Get:
2606 case Iex_Tmp:
2607 return False;
sewardjd5204dc2004-12-31 01:16:11 +00002608 case Iex_Const:
2609 return isBogusAtom(e);
sewardj95448072004-11-22 20:19:51 +00002610 case Iex_Unop:
2611 return isBogusAtom(e->Iex.Unop.arg);
sewardjd5204dc2004-12-31 01:16:11 +00002612 case Iex_GetI:
2613 return isBogusAtom(e->Iex.GetI.ix);
sewardj95448072004-11-22 20:19:51 +00002614 case Iex_Binop:
2615 return isBogusAtom(e->Iex.Binop.arg1)
2616 || isBogusAtom(e->Iex.Binop.arg2);
2617 case Iex_Mux0X:
2618 return isBogusAtom(e->Iex.Mux0X.cond)
2619 || isBogusAtom(e->Iex.Mux0X.expr0)
2620 || isBogusAtom(e->Iex.Mux0X.exprX);
sewardj2e595852005-06-30 23:33:37 +00002621 case Iex_Load:
2622 return isBogusAtom(e->Iex.Load.addr);
sewardj95448072004-11-22 20:19:51 +00002623 case Iex_CCall:
2624 for (i = 0; e->Iex.CCall.args[i]; i++)
2625 if (isBogusAtom(e->Iex.CCall.args[i]))
2626 return True;
2627 return False;
2628 default:
2629 goto unhandled;
2630 }
sewardjd5204dc2004-12-31 01:16:11 +00002631 case Ist_Dirty:
2632 d = st->Ist.Dirty.details;
2633 for (i = 0; d->args[i]; i++)
2634 if (isBogusAtom(d->args[i]))
2635 return True;
2636 if (d->guard && isBogusAtom(d->guard))
2637 return True;
2638 if (d->mAddr && isBogusAtom(d->mAddr))
2639 return True;
2640 return False;
sewardj95448072004-11-22 20:19:51 +00002641 case Ist_Put:
2642 return isBogusAtom(st->Ist.Put.data);
sewardjd5204dc2004-12-31 01:16:11 +00002643 case Ist_PutI:
2644 return isBogusAtom(st->Ist.PutI.ix)
2645 || isBogusAtom(st->Ist.PutI.data);
sewardj2e595852005-06-30 23:33:37 +00002646 case Ist_Store:
2647 return isBogusAtom(st->Ist.Store.addr)
2648 || isBogusAtom(st->Ist.Store.data);
sewardj95448072004-11-22 20:19:51 +00002649 case Ist_Exit:
sewardjd5204dc2004-12-31 01:16:11 +00002650 return isBogusAtom(st->Ist.Exit.guard);
sewardj826ec492005-05-12 18:05:00 +00002651 case Ist_AbiHint:
2652 return isBogusAtom(st->Ist.AbiHint.base);
sewardj21dc3452005-03-21 00:27:41 +00002653 case Ist_NoOp:
sewardj29faa502005-03-16 18:20:21 +00002654 case Ist_IMark:
sewardjbd598e12005-01-07 12:10:21 +00002655 case Ist_MFence:
2656 return False;
sewardj95448072004-11-22 20:19:51 +00002657 default:
2658 unhandled:
2659 ppIRStmt(st);
2660 VG_(tool_panic)("hasBogusLiterals");
2661 }
2662}
njn25e49d8e72002-09-23 09:36:25 +00002663
njn25e49d8e72002-09-23 09:36:25 +00002664
njn51d827b2005-05-09 01:02:08 +00002665IRBB* MC_(instrument) ( IRBB* bb_in, VexGuestLayout* layout,
sewardjd54babf2005-03-21 00:55:49 +00002666 IRType gWordTy, IRType hWordTy )
sewardj95448072004-11-22 20:19:51 +00002667{
sewardj151b90d2005-07-06 19:42:23 +00002668 Bool verboze = False; //True;
2669 Bool bogus;
sewardjd5204dc2004-12-31 01:16:11 +00002670 Int i, j, first_stmt;
sewardj95448072004-11-22 20:19:51 +00002671 IRStmt* st;
sewardjd5204dc2004-12-31 01:16:11 +00002672 MCEnv mce;
sewardjd54babf2005-03-21 00:55:49 +00002673 IRBB* bb;
2674
2675 if (gWordTy != hWordTy) {
2676 /* We don't currently support this case. */
2677 VG_(tool_panic)("host/guest word size mismatch");
2678 }
njn25e49d8e72002-09-23 09:36:25 +00002679
sewardj6cf40ff2005-04-20 22:31:26 +00002680 /* Check we're not completely nuts */
2681 tl_assert(sizeof(UWord) == sizeof(void*));
2682 tl_assert(sizeof(Word) == sizeof(void*));
2683 tl_assert(sizeof(ULong) == 8);
2684 tl_assert(sizeof(Long) == 8);
2685 tl_assert(sizeof(UInt) == 4);
2686 tl_assert(sizeof(Int) == 4);
2687
sewardj95448072004-11-22 20:19:51 +00002688 /* Set up BB */
sewardjd54babf2005-03-21 00:55:49 +00002689 bb = emptyIRBB();
sewardj95448072004-11-22 20:19:51 +00002690 bb->tyenv = dopyIRTypeEnv(bb_in->tyenv);
2691 bb->next = dopyIRExpr(bb_in->next);
2692 bb->jumpkind = bb_in->jumpkind;
njn25e49d8e72002-09-23 09:36:25 +00002693
sewardj95448072004-11-22 20:19:51 +00002694 /* Set up the running environment. Only .bb is modified as we go
2695 along. */
2696 mce.bb = bb;
2697 mce.layout = layout;
2698 mce.n_originalTmps = bb->tyenv->types_used;
2699 mce.hWordTy = hWordTy;
sewardjd5204dc2004-12-31 01:16:11 +00002700 mce.bogusLiterals = False;
sewardj95448072004-11-22 20:19:51 +00002701 mce.tmpMap = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
2702 for (i = 0; i < mce.n_originalTmps; i++)
2703 mce.tmpMap[i] = IRTemp_INVALID;
2704
sewardj151b90d2005-07-06 19:42:23 +00002705 /* Make a preliminary inspection of the statements, to see if there
2706 are any dodgy-looking literals. If there are, we generate
2707 extra-detailed (hence extra-expensive) instrumentation in
2708 places. Scan the whole bb even if dodgyness is found earlier,
2709 so that the flatness assertion is applied to all stmts. */
2710
2711 bogus = False;
sewardj95448072004-11-22 20:19:51 +00002712
2713 for (i = 0; i < bb_in->stmts_used; i++) {
sewardj151b90d2005-07-06 19:42:23 +00002714
sewardj95448072004-11-22 20:19:51 +00002715 st = bb_in->stmts[i];
sewardj21dc3452005-03-21 00:27:41 +00002716 tl_assert(st);
sewardj95448072004-11-22 20:19:51 +00002717 tl_assert(isFlatIRStmt(st));
2718
sewardj151b90d2005-07-06 19:42:23 +00002719 if (!bogus) {
2720 bogus = checkForBogusLiterals(st);
2721 if (0 && bogus) {
sewardj95448072004-11-22 20:19:51 +00002722 VG_(printf)("bogus: ");
2723 ppIRStmt(st);
2724 VG_(printf)("\n");
2725 }
2726 }
sewardjd5204dc2004-12-31 01:16:11 +00002727
sewardj151b90d2005-07-06 19:42:23 +00002728 }
2729
2730 mce.bogusLiterals = bogus;
2731
2732 /* Iterate over the stmts to generate instrumentation. */
2733
2734 for (i = 0; i < bb_in->stmts_used; i++) {
2735
2736 st = bb_in->stmts[i];
sewardj95448072004-11-22 20:19:51 +00002737 first_stmt = bb->stmts_used;
2738
2739 if (verboze) {
2740 ppIRStmt(st);
2741 VG_(printf)("\n\n");
2742 }
2743
sewardj29faa502005-03-16 18:20:21 +00002744 /* Generate instrumentation code for each stmt ... */
2745
sewardj95448072004-11-22 20:19:51 +00002746 switch (st->tag) {
2747
2748 case Ist_Tmp:
2749 assign( bb, findShadowTmp(&mce, st->Ist.Tmp.tmp),
2750 expr2vbits( &mce, st->Ist.Tmp.data) );
njn25e49d8e72002-09-23 09:36:25 +00002751 break;
2752
sewardj95448072004-11-22 20:19:51 +00002753 case Ist_Put:
2754 do_shadow_PUT( &mce,
2755 st->Ist.Put.offset,
2756 st->Ist.Put.data,
2757 NULL /* shadow atom */ );
njn25e49d8e72002-09-23 09:36:25 +00002758 break;
2759
sewardj95448072004-11-22 20:19:51 +00002760 case Ist_PutI:
2761 do_shadow_PUTI( &mce,
2762 st->Ist.PutI.descr,
2763 st->Ist.PutI.ix,
2764 st->Ist.PutI.bias,
2765 st->Ist.PutI.data );
njn25e49d8e72002-09-23 09:36:25 +00002766 break;
2767
sewardj2e595852005-06-30 23:33:37 +00002768 case Ist_Store:
2769 do_shadow_Store( &mce, st->Ist.Store.end,
2770 st->Ist.Store.addr, 0/* addr bias */,
2771 st->Ist.Store.data,
2772 NULL /* shadow data */ );
njn25e49d8e72002-09-23 09:36:25 +00002773 break;
2774
sewardj95448072004-11-22 20:19:51 +00002775 case Ist_Exit:
sewardjd5204dc2004-12-31 01:16:11 +00002776 complainIfUndefined( &mce, st->Ist.Exit.guard );
njn25e49d8e72002-09-23 09:36:25 +00002777 break;
2778
sewardj21dc3452005-03-21 00:27:41 +00002779 case Ist_NoOp:
sewardj29faa502005-03-16 18:20:21 +00002780 case Ist_IMark:
sewardjbd598e12005-01-07 12:10:21 +00002781 case Ist_MFence:
2782 break;
2783
sewardj95448072004-11-22 20:19:51 +00002784 case Ist_Dirty:
2785 do_shadow_Dirty( &mce, st->Ist.Dirty.details );
njn25e49d8e72002-09-23 09:36:25 +00002786 break;
2787
sewardj826ec492005-05-12 18:05:00 +00002788 case Ist_AbiHint:
2789 do_AbiHint( &mce, st->Ist.AbiHint.base, st->Ist.AbiHint.len );
2790 break;
2791
njn25e49d8e72002-09-23 09:36:25 +00002792 default:
sewardj95448072004-11-22 20:19:51 +00002793 VG_(printf)("\n");
2794 ppIRStmt(st);
2795 VG_(printf)("\n");
2796 VG_(tool_panic)("memcheck: unhandled IRStmt");
2797
2798 } /* switch (st->tag) */
2799
2800 if (verboze) {
2801 for (j = first_stmt; j < bb->stmts_used; j++) {
2802 VG_(printf)(" ");
2803 ppIRStmt(bb->stmts[j]);
2804 VG_(printf)("\n");
2805 }
2806 VG_(printf)("\n");
njn25e49d8e72002-09-23 09:36:25 +00002807 }
sewardj95448072004-11-22 20:19:51 +00002808
sewardj29faa502005-03-16 18:20:21 +00002809 /* ... and finally copy the stmt itself to the output. */
sewardj95448072004-11-22 20:19:51 +00002810 addStmtToIRBB(bb, st);
2811
njn25e49d8e72002-09-23 09:36:25 +00002812 }
njn25e49d8e72002-09-23 09:36:25 +00002813
sewardj95448072004-11-22 20:19:51 +00002814 /* Now we need to complain if the jump target is undefined. */
2815 first_stmt = bb->stmts_used;
njn25e49d8e72002-09-23 09:36:25 +00002816
sewardj95448072004-11-22 20:19:51 +00002817 if (verboze) {
2818 VG_(printf)("bb->next = ");
2819 ppIRExpr(bb->next);
2820 VG_(printf)("\n\n");
2821 }
njn25e49d8e72002-09-23 09:36:25 +00002822
sewardj95448072004-11-22 20:19:51 +00002823 complainIfUndefined( &mce, bb->next );
njn25e49d8e72002-09-23 09:36:25 +00002824
sewardj95448072004-11-22 20:19:51 +00002825 if (verboze) {
2826 for (j = first_stmt; j < bb->stmts_used; j++) {
2827 VG_(printf)(" ");
2828 ppIRStmt(bb->stmts[j]);
2829 VG_(printf)("\n");
njn25e49d8e72002-09-23 09:36:25 +00002830 }
sewardj95448072004-11-22 20:19:51 +00002831 VG_(printf)("\n");
njn25e49d8e72002-09-23 09:36:25 +00002832 }
njn25e49d8e72002-09-23 09:36:25 +00002833
sewardj95448072004-11-22 20:19:51 +00002834 return bb;
2835}
njn25e49d8e72002-09-23 09:36:25 +00002836
2837/*--------------------------------------------------------------------*/
njn25cac76cb2002-09-23 11:21:57 +00002838/*--- end mc_translate.c ---*/
njn25e49d8e72002-09-23 09:36:25 +00002839/*--------------------------------------------------------------------*/