mc_translate.c revision bef552a3841d959ca18fac4e5ac6925ea29dfd32
1bb1c99123c95fb9a4a2617d6e1d09559ac68db80nethercote
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/
395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Instrument IR to perform memory checking operations.         ---*/
4cac76cb18577b9c51d331f56e8ea241f6effaf31njn/*---                                               mc_translate.c ---*/
5e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/
6c953984b8ee34ac55830b9871138b409d9d9476cnjn
7e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*
8137bc55f216bc7d9528f159a78cdf9025e0b02ffnethercote   This file is part of MemCheck, a heavyweight Valgrind tool for
9c953984b8ee34ac55830b9871138b409d9d9476cnjn   detecting memory errors.
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
115361242f022b38fadb4cdf02428cea8b8d901a90njn   Copyright (C) 2000-2005 Julian Seward
12e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      jseward@acm.org
13e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
14e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   This program is free software; you can redistribute it and/or
15e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   modify it under the terms of the GNU General Public License as
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   published by the Free Software Foundation; either version 2 of the
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   License, or (at your option) any later version.
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   This program is distributed in the hope that it will be useful, but
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WITHOUT ANY WARRANTY; without even the implied warranty of
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   General Public License for more details.
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   You should have received a copy of the GNU General Public License
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   along with this program; if not, write to the Free Software
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   02111-1307, USA.
28e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   The GNU General Public License is contained in the file COPYING.
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn*/
31e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
32c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_tool_basics.h"
33c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_tool_hashtable.h"     // For mac_shared.h
34132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_tool_libcassert.h"
3536a20fa5f779a0a6fb7b4a90dcaa6376481f1faanjn#include "pub_tool_libcprint.h"
36c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_tool_profile.h"
37c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_tool_tooliface.h"
38c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "mc_include.h"
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
4195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
4295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Forward decls                                        ---*/
4395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
4495448075345dc73986042f6dc68eb464d02bc6a8sewardj
4595448075345dc73986042f6dc68eb464d02bc6a8sewardjstruct _MCEnv;
4695448075345dc73986042f6dc68eb464d02bc6a8sewardj
4795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRType  shadowType ( IRType ty );
4895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e );
4995448075345dc73986042f6dc68eb464d02bc6a8sewardj
5095448075345dc73986042f6dc68eb464d02bc6a8sewardj
5195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
5295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Memcheck running state, and tmp management.          ---*/
5395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
5595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Carries around state during memcheck instrumentation. */
5695448075345dc73986042f6dc68eb464d02bc6a8sewardjtypedef
5795448075345dc73986042f6dc68eb464d02bc6a8sewardj   struct _MCEnv {
5895448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* MODIFIED: the bb being constructed.  IRStmts are added. */
5995448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRBB* bb;
6095448075345dc73986042f6dc68eb464d02bc6a8sewardj
6195448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps
6295448075345dc73986042f6dc68eb464d02bc6a8sewardj         original temps to their current their current shadow temp.
6395448075345dc73986042f6dc68eb464d02bc6a8sewardj         Initially all entries are IRTemp_INVALID.  Entries are added
6495448075345dc73986042f6dc68eb464d02bc6a8sewardj         lazily since many original temps are not used due to
6595448075345dc73986042f6dc68eb464d02bc6a8sewardj         optimisation prior to instrumentation.  Note that floating
6695448075345dc73986042f6dc68eb464d02bc6a8sewardj         point original tmps are shadowed by integer tmps of the same
6795448075345dc73986042f6dc68eb464d02bc6a8sewardj         size, and Bit-typed original tmps are shadowed by the type
6895448075345dc73986042f6dc68eb464d02bc6a8sewardj         Ity_I8.  See comment below. */
6995448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRTemp* tmpMap;
7095448075345dc73986042f6dc68eb464d02bc6a8sewardj      Int     n_originalTmps; /* for range checking */
7195448075345dc73986042f6dc68eb464d02bc6a8sewardj
72d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      /* MODIFIED: indicates whether "bogus" literals have so far been
73d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         found.  Starts off False, and may change to True. */
74d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      Bool    bogusLiterals;
75d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
7695448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* READONLY: the guest layout.  This indicates which parts of
7795448075345dc73986042f6dc68eb464d02bc6a8sewardj         the guest state should be regarded as 'always defined'. */
7895448075345dc73986042f6dc68eb464d02bc6a8sewardj      VexGuestLayout* layout;
7995448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* READONLY: the host word type.  Needed for constructing
8095448075345dc73986042f6dc68eb464d02bc6a8sewardj         arguments of type 'HWord' to be passed to helper functions.
8195448075345dc73986042f6dc68eb464d02bc6a8sewardj         Ity_I32 or Ity_I64 only. */
8295448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRType hWordTy;
83e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
8495448075345dc73986042f6dc68eb464d02bc6a8sewardj   MCEnv;
8595448075345dc73986042f6dc68eb464d02bc6a8sewardj
8695448075345dc73986042f6dc68eb464d02bc6a8sewardj/* SHADOW TMP MANAGEMENT.  Shadow tmps are allocated lazily (on
8795448075345dc73986042f6dc68eb464d02bc6a8sewardj   demand), as they are encountered.  This is for two reasons.
8895448075345dc73986042f6dc68eb464d02bc6a8sewardj
8995448075345dc73986042f6dc68eb464d02bc6a8sewardj   (1) (less important reason): Many original tmps are unused due to
9095448075345dc73986042f6dc68eb464d02bc6a8sewardj   initial IR optimisation, and we do not want to spaces in tables
9195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tracking them.
9295448075345dc73986042f6dc68eb464d02bc6a8sewardj
9395448075345dc73986042f6dc68eb464d02bc6a8sewardj   Shadow IRTemps are therefore allocated on demand.  mce.tmpMap is a
9495448075345dc73986042f6dc68eb464d02bc6a8sewardj   table indexed [0 .. n_types-1], which gives the current shadow for
9595448075345dc73986042f6dc68eb464d02bc6a8sewardj   each original tmp, or INVALID_IRTEMP if none is so far assigned.
9695448075345dc73986042f6dc68eb464d02bc6a8sewardj   It is necessary to support making multiple assignments to a shadow
9795448075345dc73986042f6dc68eb464d02bc6a8sewardj   -- specifically, after testing a shadow for definedness, it needs
9895448075345dc73986042f6dc68eb464d02bc6a8sewardj   to be made defined.  But IR's SSA property disallows this.
9995448075345dc73986042f6dc68eb464d02bc6a8sewardj
10095448075345dc73986042f6dc68eb464d02bc6a8sewardj   (2) (more important reason): Therefore, when a shadow needs to get
10195448075345dc73986042f6dc68eb464d02bc6a8sewardj   a new value, a new temporary is created, the value is assigned to
10295448075345dc73986042f6dc68eb464d02bc6a8sewardj   that, and the tmpMap is updated to reflect the new binding.
10395448075345dc73986042f6dc68eb464d02bc6a8sewardj
10495448075345dc73986042f6dc68eb464d02bc6a8sewardj   A corollary is that if the tmpMap maps a given tmp to
10595448075345dc73986042f6dc68eb464d02bc6a8sewardj   INVALID_IRTEMP and we are hoping to read that shadow tmp, it means
10695448075345dc73986042f6dc68eb464d02bc6a8sewardj   there's a read-before-write error in the original tmps.  The IR
10795448075345dc73986042f6dc68eb464d02bc6a8sewardj   sanity checker should catch all such anomalies, however.
10895448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
109e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
11095448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Find the tmp currently shadowing the given original tmp.  If none
11195448075345dc73986042f6dc68eb464d02bc6a8sewardj   so far exists, allocate one.  */
11295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig )
113e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
11495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(orig < mce->n_originalTmps);
11595448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (mce->tmpMap[orig] == IRTemp_INVALID) {
11695448075345dc73986042f6dc68eb464d02bc6a8sewardj      mce->tmpMap[orig]
11795448075345dc73986042f6dc68eb464d02bc6a8sewardj         = newIRTemp(mce->bb->tyenv,
11895448075345dc73986042f6dc68eb464d02bc6a8sewardj                     shadowType(mce->bb->tyenv->types[orig]));
119e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
12095448075345dc73986042f6dc68eb464d02bc6a8sewardj   return mce->tmpMap[orig];
121e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
122e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
12395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Allocate a new shadow for the given original tmp.  This means any
12495448075345dc73986042f6dc68eb464d02bc6a8sewardj   previous shadow is abandoned.  This is needed because it is
12595448075345dc73986042f6dc68eb464d02bc6a8sewardj   necessary to give a new value to a shadow once it has been tested
12695448075345dc73986042f6dc68eb464d02bc6a8sewardj   for undefinedness, but unfortunately IR's SSA property disallows
12795448075345dc73986042f6dc68eb464d02bc6a8sewardj   this.  Instead we must abandon the old shadow, allocate a new one
12895448075345dc73986042f6dc68eb464d02bc6a8sewardj   and use that instead. */
12995448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic void newShadowTmp ( MCEnv* mce, IRTemp orig )
130e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
13195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(orig < mce->n_originalTmps);
13295448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce->tmpMap[orig]
13395448075345dc73986042f6dc68eb464d02bc6a8sewardj      = newIRTemp(mce->bb->tyenv,
13495448075345dc73986042f6dc68eb464d02bc6a8sewardj                  shadowType(mce->bb->tyenv->types[orig]));
135e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
136e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
137e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
13895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
13995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- IRAtoms -- a subset of IRExprs                       ---*/
14095448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
14195448075345dc73986042f6dc68eb464d02bc6a8sewardj
14295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* An atom is either an IRExpr_Const or an IRExpr_Tmp, as defined by
143710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj   isIRAtom() in libvex_ir.h.  Because this instrumenter expects flat
14495448075345dc73986042f6dc68eb464d02bc6a8sewardj   input, most of this code deals in atoms.  Usefully, a value atom
14595448075345dc73986042f6dc68eb464d02bc6a8sewardj   always has a V-value which is also an atom: constants are shadowed
14695448075345dc73986042f6dc68eb464d02bc6a8sewardj   by constants, and temps are shadowed by the corresponding shadow
14795448075345dc73986042f6dc68eb464d02bc6a8sewardj   temporary. */
14895448075345dc73986042f6dc68eb464d02bc6a8sewardj
14995448075345dc73986042f6dc68eb464d02bc6a8sewardjtypedef  IRExpr  IRAtom;
15095448075345dc73986042f6dc68eb464d02bc6a8sewardj
15195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): is this an atom which looks
15295448075345dc73986042f6dc68eb464d02bc6a8sewardj   like it's from original code? */
15395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isOriginalAtom ( MCEnv* mce, IRAtom* a1 )
154e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
15595448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (a1->tag == Iex_Const)
15695448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
15795448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp < mce->n_originalTmps)
15895448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
15995448075345dc73986042f6dc68eb464d02bc6a8sewardj   return False;
16095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
161e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
16295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): is this an atom which looks
16395448075345dc73986042f6dc68eb464d02bc6a8sewardj   like it's from shadow code? */
16495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isShadowAtom ( MCEnv* mce, IRAtom* a1 )
16595448075345dc73986042f6dc68eb464d02bc6a8sewardj{
16695448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (a1->tag == Iex_Const)
16795448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
16895448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp >= mce->n_originalTmps)
16995448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
17095448075345dc73986042f6dc68eb464d02bc6a8sewardj   return False;
17195448075345dc73986042f6dc68eb464d02bc6a8sewardj}
172e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
17395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): check that both args are atoms and
17495448075345dc73986042f6dc68eb464d02bc6a8sewardj   are identically-kinded. */
17595448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 )
17695448075345dc73986042f6dc68eb464d02bc6a8sewardj{
177bef552a3841d959ca18fac4e5ac6925ea29dfd32sewardj   if (a1->tag == Iex_Tmp && a2->tag == Iex_Tmp)
17895448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
179bef552a3841d959ca18fac4e5ac6925ea29dfd32sewardj   if (a1->tag == Iex_Const && a2->tag == Iex_Const)
18095448075345dc73986042f6dc68eb464d02bc6a8sewardj      return True;
18195448075345dc73986042f6dc68eb464d02bc6a8sewardj   return False;
18295448075345dc73986042f6dc68eb464d02bc6a8sewardj}
183e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
184e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
18595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
18695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Type management                                      ---*/
18795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
188e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
18995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Shadow state is always accessed using integer types.  This returns
19095448075345dc73986042f6dc68eb464d02bc6a8sewardj   an integer type with the same size (as per sizeofIRType) as the
19195448075345dc73986042f6dc68eb464d02bc6a8sewardj   given type.  The only valid shadow types are Bit, I8, I16, I32,
1923245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   I64, V128. */
193e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
19495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRType shadowType ( IRType ty )
19595448075345dc73986042f6dc68eb464d02bc6a8sewardj{
19695448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (ty) {
19795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I1:
19895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I8:
19995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I16:
20095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I32:
2016cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Ity_I64:
2026cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Ity_I128: return ty;
2033245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj      case Ity_F32:  return Ity_I32;
2043245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj      case Ity_F64:  return Ity_I64;
2053245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj      case Ity_V128: return Ity_V128;
20695448075345dc73986042f6dc68eb464d02bc6a8sewardj      default: ppIRType(ty);
20795448075345dc73986042f6dc68eb464d02bc6a8sewardj               VG_(tool_panic)("memcheck:shadowType");
208e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
20995448075345dc73986042f6dc68eb464d02bc6a8sewardj}
210e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
21195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Produce a 'defined' value of the given shadow type.  Should only be
21295448075345dc73986042f6dc68eb464d02bc6a8sewardj   supplied shadow types (Bit/I8/I16/I32/UI64). */
21395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRExpr* definedOfType ( IRType ty ) {
21495448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (ty) {
215170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I1:   return IRExpr_Const(IRConst_U1(False));
216170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I8:   return IRExpr_Const(IRConst_U8(0));
217170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I16:  return IRExpr_Const(IRConst_U16(0));
218170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I32:  return IRExpr_Const(IRConst_U32(0));
219170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I64:  return IRExpr_Const(IRConst_U64(0));
220170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000));
22195448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:      VG_(tool_panic)("memcheck:definedOfType");
22295448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
223e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
224e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
225e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
22695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
22795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Constructing IR fragments                            ---*/
22895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
229e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
23095448075345dc73986042f6dc68eb464d02bc6a8sewardj/* assign value to tmp */
23195448075345dc73986042f6dc68eb464d02bc6a8sewardj#define assign(_bb,_tmp,_expr)   \
23295448075345dc73986042f6dc68eb464d02bc6a8sewardj   addStmtToIRBB((_bb), IRStmt_Tmp((_tmp),(_expr)))
23395448075345dc73986042f6dc68eb464d02bc6a8sewardj
23495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* add stmt to a bb */
23595448075345dc73986042f6dc68eb464d02bc6a8sewardj#define stmt(_bb,_stmt)    \
23695448075345dc73986042f6dc68eb464d02bc6a8sewardj   addStmtToIRBB((_bb), (_stmt))
23795448075345dc73986042f6dc68eb464d02bc6a8sewardj
23895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* build various kinds of expressions */
23995448075345dc73986042f6dc68eb464d02bc6a8sewardj#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
24095448075345dc73986042f6dc68eb464d02bc6a8sewardj#define unop(_op, _arg)          IRExpr_Unop((_op),(_arg))
24195448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU8(_n)                 IRExpr_Const(IRConst_U8(_n))
24295448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU16(_n)                IRExpr_Const(IRConst_U16(_n))
24395448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU32(_n)                IRExpr_Const(IRConst_U32(_n))
24495448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU64(_n)                IRExpr_Const(IRConst_U64(_n))
245170ee210842367a5cc52390358ba560774f76329sewardj#define mkV128(_n)               IRExpr_Const(IRConst_V128(_n))
24695448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkexpr(_tmp)             IRExpr_Tmp((_tmp))
24795448075345dc73986042f6dc68eb464d02bc6a8sewardj
24895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* bind the given expression to a new temporary, and return the
24995448075345dc73986042f6dc68eb464d02bc6a8sewardj   temporary.  This effectively converts an arbitrary expression into
25095448075345dc73986042f6dc68eb464d02bc6a8sewardj   an atom. */
25195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) {
25295448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRTemp t = newIRTemp(mce->bb->tyenv, ty);
25395448075345dc73986042f6dc68eb464d02bc6a8sewardj   assign(mce->bb, t, e);
25495448075345dc73986042f6dc68eb464d02bc6a8sewardj   return mkexpr(t);
255e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
256e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
25795448075345dc73986042f6dc68eb464d02bc6a8sewardj
258e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*------------------------------------------------------------*/
25995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Constructing definedness primitive ops               ---*/
260e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*------------------------------------------------------------*/
261e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
26295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Defined-if-either-defined --------- */
26395448075345dc73986042f6dc68eb464d02bc6a8sewardj
26495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
26595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
26695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
26795448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I8, binop(Iop_And8, a1, a2));
268e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
269e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
27095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
27195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
27295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
27395448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I16, binop(Iop_And16, a1, a2));
27495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
275e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
27695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
27795448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
27895448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
27995448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I32, binop(Iop_And32, a1, a2));
280e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
281e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2827010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkDifD64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
2837010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isShadowAtom(mce,a1));
2847010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isShadowAtom(mce,a2));
2857010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   return assignNew(mce, Ity_I64, binop(Iop_And64, a1, a2));
2867010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj}
2877010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj
28820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkDifDV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
289170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isShadowAtom(mce,a1));
290170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isShadowAtom(mce,a2));
29120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   return assignNew(mce, Ity_V128, binop(Iop_AndV128, a1, a2));
292170ee210842367a5cc52390358ba560774f76329sewardj}
293170ee210842367a5cc52390358ba560774f76329sewardj
29495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Undefined-if-either-undefined --------- */
295e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
29695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
29795448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
29895448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
29995448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I8, binop(Iop_Or8, a1, a2));
300e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
301e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
30295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
30395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
30495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
30595448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I16, binop(Iop_Or16, a1, a2));
30695448075345dc73986042f6dc68eb464d02bc6a8sewardj}
307e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
30895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
30995448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
31095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
31195448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2));
312e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
313e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
31495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
31595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
31695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a2));
31795448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2));
31895448075345dc73986042f6dc68eb464d02bc6a8sewardj}
319e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
32020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
3213245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce,a1));
3223245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce,a2));
32320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   return assignNew(mce, Ity_V128, binop(Iop_OrV128, a1, a2));
3243245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj}
3253245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
326e50a1b14b5ec5a180d2797614de48b19129c9e4fsewardjstatic IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) {
32795448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (vty) {
328e50a1b14b5ec5a180d2797614de48b19129c9e4fsewardj      case Ity_I8:   return mkUifU8(mce, a1, a2);
329a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Ity_I16:  return mkUifU16(mce, a1, a2);
330a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Ity_I32:  return mkUifU32(mce, a1, a2);
331a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Ity_I64:  return mkUifU64(mce, a1, a2);
33220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Ity_V128: return mkUifUV128(mce, a1, a2);
33395448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
33495448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n");
33595448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("memcheck:mkUifU");
336e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
337e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
338e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
33995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- The Left-family of operations. --------- */
340e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
34195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) {
34295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
34395448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* It's safe to duplicate a1 since it's only an atom */
34495448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I8,
34595448075345dc73986042f6dc68eb464d02bc6a8sewardj                    binop(Iop_Or8, a1,
34695448075345dc73986042f6dc68eb464d02bc6a8sewardj                          assignNew(mce, Ity_I8,
34737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj                                         unop(Iop_Neg8, a1))));
348e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
349e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
35095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) {
35195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
35295448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* It's safe to duplicate a1 since it's only an atom */
35395448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I16,
35495448075345dc73986042f6dc68eb464d02bc6a8sewardj                    binop(Iop_Or16, a1,
35595448075345dc73986042f6dc68eb464d02bc6a8sewardj                          assignNew(mce, Ity_I16,
35637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj                                         unop(Iop_Neg16, a1))));
35795448075345dc73986042f6dc68eb464d02bc6a8sewardj}
358e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
35995448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) {
36095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,a1));
36195448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* It's safe to duplicate a1 since it's only an atom */
36295448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I32,
36395448075345dc73986042f6dc68eb464d02bc6a8sewardj                    binop(Iop_Or32, a1,
36495448075345dc73986042f6dc68eb464d02bc6a8sewardj                          assignNew(mce, Ity_I32,
36537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj                                         unop(Iop_Neg32, a1))));
36695448075345dc73986042f6dc68eb464d02bc6a8sewardj}
367e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
368681be302af5528c2cb415270da9fde2e7f347e69sewardjstatic IRAtom* mkLeft64 ( MCEnv* mce, IRAtom* a1 ) {
369681be302af5528c2cb415270da9fde2e7f347e69sewardj   tl_assert(isShadowAtom(mce,a1));
370681be302af5528c2cb415270da9fde2e7f347e69sewardj   /* It's safe to duplicate a1 since it's only an atom */
371681be302af5528c2cb415270da9fde2e7f347e69sewardj   return assignNew(mce, Ity_I64,
372681be302af5528c2cb415270da9fde2e7f347e69sewardj                    binop(Iop_Or64, a1,
373681be302af5528c2cb415270da9fde2e7f347e69sewardj                          assignNew(mce, Ity_I64,
37437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj                                         unop(Iop_Neg64, a1))));
375681be302af5528c2cb415270da9fde2e7f347e69sewardj}
376681be302af5528c2cb415270da9fde2e7f347e69sewardj
37795448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- 'Improvement' functions for AND/OR. --------- */
378e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
37995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* ImproveAND(data, vbits) = data OR vbits.  Defined (0) data 0s give
38095448075345dc73986042f6dc68eb464d02bc6a8sewardj   defined (0); all other -> undefined (1).
38195448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
38295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
38395448075345dc73986042f6dc68eb464d02bc6a8sewardj{
38495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
38595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
38695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
38795448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I8, binop(Iop_Or8, data, vbits));
388e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
389e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
39095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
391e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
39295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
39395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
39495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
39595448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I16, binop(Iop_Or16, data, vbits));
396e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
397e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
39895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
39995448075345dc73986042f6dc68eb464d02bc6a8sewardj{
40095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
40195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
40295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
40395448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(mce, Ity_I32, binop(Iop_Or32, data, vbits));
40495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
405e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
4067010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkImproveAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
4077010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj{
4087010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isOriginalAtom(mce, data));
4097010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isShadowAtom(mce, vbits));
4107010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(sameKindedAtoms(data, vbits));
4117010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   return assignNew(mce, Ity_I64, binop(Iop_Or64, data, vbits));
4127010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj}
4137010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj
41420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkImproveANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
415170ee210842367a5cc52390358ba560774f76329sewardj{
416170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isOriginalAtom(mce, data));
417170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isShadowAtom(mce, vbits));
418170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(sameKindedAtoms(data, vbits));
41920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   return assignNew(mce, Ity_V128, binop(Iop_OrV128, data, vbits));
420170ee210842367a5cc52390358ba560774f76329sewardj}
421170ee210842367a5cc52390358ba560774f76329sewardj
42295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* ImproveOR(data, vbits) = ~data OR vbits.  Defined (0) data 1s give
42395448075345dc73986042f6dc68eb464d02bc6a8sewardj   defined (0); all other -> undefined (1).
42495448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
42595448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
426e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
42795448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
42895448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
42995448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
43095448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(
43195448075345dc73986042f6dc68eb464d02bc6a8sewardj             mce, Ity_I8,
43295448075345dc73986042f6dc68eb464d02bc6a8sewardj             binop(Iop_Or8,
43395448075345dc73986042f6dc68eb464d02bc6a8sewardj                   assignNew(mce, Ity_I8, unop(Iop_Not8, data)),
43495448075345dc73986042f6dc68eb464d02bc6a8sewardj                   vbits) );
435e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
436e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
43795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
43895448075345dc73986042f6dc68eb464d02bc6a8sewardj{
43995448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
44095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
44195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
44295448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(
44395448075345dc73986042f6dc68eb464d02bc6a8sewardj             mce, Ity_I16,
44495448075345dc73986042f6dc68eb464d02bc6a8sewardj             binop(Iop_Or16,
44595448075345dc73986042f6dc68eb464d02bc6a8sewardj                   assignNew(mce, Ity_I16, unop(Iop_Not16, data)),
44695448075345dc73986042f6dc68eb464d02bc6a8sewardj                   vbits) );
44795448075345dc73986042f6dc68eb464d02bc6a8sewardj}
448e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
44995448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
450e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
45195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, data));
45295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vbits));
45395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(data, vbits));
45495448075345dc73986042f6dc68eb464d02bc6a8sewardj   return assignNew(
45595448075345dc73986042f6dc68eb464d02bc6a8sewardj             mce, Ity_I32,
45695448075345dc73986042f6dc68eb464d02bc6a8sewardj             binop(Iop_Or32,
45795448075345dc73986042f6dc68eb464d02bc6a8sewardj                   assignNew(mce, Ity_I32, unop(Iop_Not32, data)),
45895448075345dc73986042f6dc68eb464d02bc6a8sewardj                   vbits) );
459e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
460e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
4617010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkImproveOR64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
4627010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj{
4637010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isOriginalAtom(mce, data));
4647010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(isShadowAtom(mce, vbits));
4657010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   tl_assert(sameKindedAtoms(data, vbits));
4667010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj   return assignNew(
4677010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj             mce, Ity_I64,
4687010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj             binop(Iop_Or64,
4697010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj                   assignNew(mce, Ity_I64, unop(Iop_Not64, data)),
4707010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj                   vbits) );
4717010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj}
4727010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj
47320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkImproveORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
474170ee210842367a5cc52390358ba560774f76329sewardj{
475170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isOriginalAtom(mce, data));
476170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(isShadowAtom(mce, vbits));
477170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert(sameKindedAtoms(data, vbits));
478170ee210842367a5cc52390358ba560774f76329sewardj   return assignNew(
479170ee210842367a5cc52390358ba560774f76329sewardj             mce, Ity_V128,
48020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj             binop(Iop_OrV128,
48120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj                   assignNew(mce, Ity_V128, unop(Iop_NotV128, data)),
482170ee210842367a5cc52390358ba560774f76329sewardj                   vbits) );
483170ee210842367a5cc52390358ba560774f76329sewardj}
484170ee210842367a5cc52390358ba560774f76329sewardj
48595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Pessimising casts. --------- */
486e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
48795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits )
488e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
4897cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRType  ty;
4907cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRAtom* tmp1;
49195448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Note, dst_ty is a shadow type, not an original type. */
49295448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* First of all, collapse vbits down to a single bit. */
49395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,vbits));
4947cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   ty   = typeOfIRExpr(mce->bb->tyenv, vbits);
4957cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   tmp1 = NULL;
49695448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (ty) {
49795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I1:
49895448075345dc73986042f6dc68eb464d02bc6a8sewardj         tmp1 = vbits;
49995448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
50095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I8:
50137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj         tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ8, vbits));
50295448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
50395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I16:
50437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj         tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ16, vbits));
50595448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
50695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I32:
50737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj         tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ32, vbits));
50895448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
50995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I64:
51037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj         tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ64, vbits));
51195448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
51269a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Ity_I128: {
51369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         /* Gah.  Chop it in half, OR the halves together, and compare
51469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj            that with zero. */
51569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         IRAtom* tmp2 = assignNew(mce, Ity_I64, unop(Iop_128HIto64, vbits));
51669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         IRAtom* tmp3 = assignNew(mce, Ity_I64, unop(Iop_128to64, vbits));
51769a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         IRAtom* tmp4 = assignNew(mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3));
51869a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         tmp1         = assignNew(mce, Ity_I1,
51937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj                                       unop(Iop_CmpNEZ64, tmp4));
52069a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         break;
52169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      }
52295448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
52369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         ppIRType(ty);
52495448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("mkPCastTo(1)");
52595448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
52695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(tmp1);
52795448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Now widen up to the dst type. */
52895448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (dst_ty) {
52995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I1:
53095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return tmp1;
53195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I8:
53295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I8, unop(Iop_1Sto8, tmp1));
53395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I16:
53495448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1));
53595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I32:
53695448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1));
53795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ity_I64:
53895448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
539a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Ity_V128:
540a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         tmp1 = assignNew(mce, Ity_I64,  unop(Iop_1Sto64, tmp1));
54120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         tmp1 = assignNew(mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1));
542a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return tmp1;
54369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Ity_I128:
54469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         tmp1 = assignNew(mce, Ity_I64,  unop(Iop_1Sto64, tmp1));
54569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         tmp1 = assignNew(mce, Ity_I128, binop(Iop_64HLto128, tmp1, tmp1));
54669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         return tmp1;
54795448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
54895448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIRType(dst_ty);
54995448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("mkPCastTo(2)");
550e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
551e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
552e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
553d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj/* --------- Accurate interpretation of CmpEQ/CmpNE. --------- */
554d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj/*
555d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   Normally, we can do CmpEQ/CmpNE by doing UifU on the arguments, and
556d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   PCasting to Ity_U1.  However, sometimes it is necessary to be more
557d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   accurate.  The insight is that the result is defined if two
558d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   corresponding bits can be found, one from each argument, so that
559d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   both bits are defined but are different -- that makes EQ say "No"
560d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   and NE say "Yes".  Hence, we compute an improvement term and DifD
561d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   it onto the "normal" (UifU) result.
562d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
563d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   The result is:
564d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
565d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   PCastTo<1> (
566e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      -- naive version
567e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      PCastTo<sz>( UifU<sz>(vxx, vyy) )
568e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
569d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      `DifD<sz>`
570e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
571e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      -- improvement term
572e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      PCastTo<sz>( PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) ) )
573d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   )
574e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
575d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   where
576d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj     vec contains 0 (defined) bits where the corresponding arg bits
577e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     are defined but different, and 1 bits otherwise.
578e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
579e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     vec = Or<sz>( vxx,   // 0 iff bit defined
580e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj                   vyy,   // 0 iff bit defined
581e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj                   Not<sz>(Xor<sz>( xx, yy )) // 0 iff bits different
582e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj                 )
583e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
584e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     If any bit of vec is 0, the result is defined and so the
585e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     improvement term should produce 0...0, else it should produce
586e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     1...1.
587e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
588e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     Hence require for the improvement term:
589d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
590e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj        if vec == 1...1 then 1...1 else 0...0
591e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj     ->
592e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj        PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) )
593e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj
594e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj   This was extensively re-analysed and checked on 6 July 05.
595d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj*/
596d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardjstatic IRAtom* expensiveCmpEQorNE ( MCEnv*  mce,
597d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                                    IRType  ty,
598d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                                    IRAtom* vxx, IRAtom* vyy,
599d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                                    IRAtom* xx,  IRAtom* yy )
600d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj{
601e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj   IRAtom *naive, *vec, *improvement_term;
602e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj   IRAtom *improved, *final_cast, *top;
603e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj   IROp   opDIFD, opUIFU, opXOR, opNOT, opCMP, opOR;
604d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
605d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(isShadowAtom(mce,vxx));
606d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(isShadowAtom(mce,vyy));
607d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(isOriginalAtom(mce,xx));
608d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(isOriginalAtom(mce,yy));
609d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(sameKindedAtoms(vxx,xx));
610d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   tl_assert(sameKindedAtoms(vyy,yy));
611d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
612d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   switch (ty) {
613d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ity_I32:
614e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj         opOR   = Iop_Or32;
615d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opDIFD = Iop_And32;
616d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opUIFU = Iop_Or32;
617d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opNOT  = Iop_Not32;
618d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opXOR  = Iop_Xor32;
619d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opCMP  = Iop_CmpEQ32;
620d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         top    = mkU32(0xFFFFFFFF);
621d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         break;
622cd986336a55192fe237a72b323b378b674af38e0tom      case Ity_I64:
623e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj         opOR   = Iop_Or64;
624cd986336a55192fe237a72b323b378b674af38e0tom         opDIFD = Iop_And64;
625cd986336a55192fe237a72b323b378b674af38e0tom         opUIFU = Iop_Or64;
626cd986336a55192fe237a72b323b378b674af38e0tom         opNOT  = Iop_Not64;
627cd986336a55192fe237a72b323b378b674af38e0tom         opXOR  = Iop_Xor64;
628cd986336a55192fe237a72b323b378b674af38e0tom         opCMP  = Iop_CmpEQ64;
62937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj         top    = mkU64(0xFFFFFFFFFFFFFFFFULL);
630cd986336a55192fe237a72b323b378b674af38e0tom         break;
631d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      default:
632d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         VG_(tool_panic)("expensiveCmpEQorNE");
633d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   }
634d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
635d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   naive
636d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      = mkPCastTo(mce,ty, assignNew(mce, ty, binop(opUIFU, vxx, vyy)));
637d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
638d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   vec
639d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      = assignNew(
640d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj           mce,ty,
641e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj           binop( opOR,
642e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj                  assignNew(mce,ty, binop(opOR, vxx, vyy)),
643d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                  assignNew(
644d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                     mce,ty,
645d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                     unop( opNOT,
646d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                           assignNew(mce,ty, binop(opXOR, xx, yy))))));
647d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
648e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj   improvement_term
649d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      = mkPCastTo( mce,ty, assignNew(mce,Ity_I1, binop(opCMP, vec, top)));
650d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
651d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   improved
652e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      = assignNew( mce,ty, binop(opDIFD, naive, improvement_term) );
653d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
654d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   final_cast
655d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      = mkPCastTo( mce, Ity_I1, improved );
656d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
657d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   return final_cast;
658d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj}
659d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
660e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
66195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
66295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Emit a test and complaint if something is undefined. ---*/
66395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
66495448075345dc73986042f6dc68eb464d02bc6a8sewardj
66595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Set the annotations on a dirty helper to indicate that the stack
66695448075345dc73986042f6dc68eb464d02bc6a8sewardj   pointer and instruction pointers might be read.  This is the
66795448075345dc73986042f6dc68eb464d02bc6a8sewardj   behaviour of all 'emit-a-complaint' style functions we might
66895448075345dc73986042f6dc68eb464d02bc6a8sewardj   call. */
66995448075345dc73986042f6dc68eb464d02bc6a8sewardj
67095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic void setHelperAnns ( MCEnv* mce, IRDirty* di ) {
67195448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->nFxState = 2;
67295448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[0].fx     = Ifx_Read;
67395448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[0].offset = mce->layout->offset_SP;
67495448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[0].size   = mce->layout->sizeof_SP;
67595448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[1].fx     = Ifx_Read;
67695448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[1].offset = mce->layout->offset_IP;
67795448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->fxState[1].size   = mce->layout->sizeof_IP;
678e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
679e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
680e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
68195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Check the supplied **original** atom for undefinedness, and emit a
68295448075345dc73986042f6dc68eb464d02bc6a8sewardj   complaint if so.  Once that happens, mark it as defined.  This is
68395448075345dc73986042f6dc68eb464d02bc6a8sewardj   possible because the atom is either a tmp or literal.  If it's a
68495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tmp, it will be shadowed by a tmp, and so we can set the shadow to
68595448075345dc73986042f6dc68eb464d02bc6a8sewardj   be defined.  In fact as mentioned above, we will have to allocate a
68695448075345dc73986042f6dc68eb464d02bc6a8sewardj   new tmp to carry the new 'defined' shadow value, and update the
68795448075345dc73986042f6dc68eb464d02bc6a8sewardj   original->tmp mapping accordingly; we cannot simply assign a new
68895448075345dc73986042f6dc68eb464d02bc6a8sewardj   value to an existing shadow tmp as this breaks SSAness -- resulting
68995448075345dc73986042f6dc68eb464d02bc6a8sewardj   in the post-instrumentation sanity checker spluttering in disapproval.
69095448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
69195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic void complainIfUndefined ( MCEnv* mce, IRAtom* atom )
692e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
6937cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRAtom*  vatom;
6947cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRType   ty;
6957cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   Int      sz;
6967cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRDirty* di;
6977cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRAtom*  cond;
6987cf97ee841afd255879bff9ff791fbabb7f95cecsewardj
69995448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Since the original expression is atomic, there's no duplicated
70095448075345dc73986042f6dc68eb464d02bc6a8sewardj      work generated by making multiple V-expressions for it.  So we
70195448075345dc73986042f6dc68eb464d02bc6a8sewardj      don't really care about the possibility that someone else may
70295448075345dc73986042f6dc68eb464d02bc6a8sewardj      also create a V-interpretion for it. */
70395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, atom));
7047cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   vatom = expr2vbits( mce, atom );
70595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce, vatom));
70695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(atom, vatom));
707e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
7087cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   ty = typeOfIRExpr(mce->bb->tyenv, vatom);
709e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
71095448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* sz is only used for constructing the error message */
7117cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
712e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
7137cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   cond = mkPCastTo( mce, Ity_I1, vatom );
71495448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* cond will be 0 if all defined, and 1 if any not defined. */
715e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
71695448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (sz) {
71795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 0:
71895448075345dc73986042f6dc68eb464d02bc6a8sewardj         di = unsafeIRDirty_0_N( 0/*regparms*/,
71995448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 "MC_(helperc_value_check0_fail)",
72095448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 &MC_(helperc_value_check0_fail),
72195448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 mkIRExprVec_0()
72295448075345dc73986042f6dc68eb464d02bc6a8sewardj                               );
72395448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
72495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 1:
72595448075345dc73986042f6dc68eb464d02bc6a8sewardj         di = unsafeIRDirty_0_N( 0/*regparms*/,
72695448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 "MC_(helperc_value_check1_fail)",
72795448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 &MC_(helperc_value_check1_fail),
72895448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 mkIRExprVec_0()
72995448075345dc73986042f6dc68eb464d02bc6a8sewardj                               );
73095448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
73195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 4:
73295448075345dc73986042f6dc68eb464d02bc6a8sewardj         di = unsafeIRDirty_0_N( 0/*regparms*/,
73395448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 "MC_(helperc_value_check4_fail)",
73495448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 &MC_(helperc_value_check4_fail),
73595448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 mkIRExprVec_0()
73695448075345dc73986042f6dc68eb464d02bc6a8sewardj                               );
73795448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
73811bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj      case 8:
73911bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj         di = unsafeIRDirty_0_N( 0/*regparms*/,
74011bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj                                 "MC_(helperc_value_check8_fail)",
74111bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj                                 &MC_(helperc_value_check8_fail),
74211bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj                                 mkIRExprVec_0()
74311bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj                               );
74411bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj         break;
74595448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
74695448075345dc73986042f6dc68eb464d02bc6a8sewardj         di = unsafeIRDirty_0_N( 1/*regparms*/,
74795448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 "MC_(helperc_complain_undef)",
74895448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 &MC_(helperc_complain_undef),
74995448075345dc73986042f6dc68eb464d02bc6a8sewardj                                 mkIRExprVec_1( mkIRExpr_HWord( sz ))
75095448075345dc73986042f6dc68eb464d02bc6a8sewardj                               );
75195448075345dc73986042f6dc68eb464d02bc6a8sewardj         break;
75295448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
75395448075345dc73986042f6dc68eb464d02bc6a8sewardj   di->guard = cond;
75495448075345dc73986042f6dc68eb464d02bc6a8sewardj   setHelperAnns( mce, di );
75595448075345dc73986042f6dc68eb464d02bc6a8sewardj   stmt( mce->bb, IRStmt_Dirty(di));
75695448075345dc73986042f6dc68eb464d02bc6a8sewardj
75795448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Set the shadow tmp to be defined.  First, update the
75895448075345dc73986042f6dc68eb464d02bc6a8sewardj      orig->shadow tmp mapping to reflect the fact that this shadow is
75995448075345dc73986042f6dc68eb464d02bc6a8sewardj      getting a new value. */
760710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj   tl_assert(isIRAtom(vatom));
76195448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* sameKindedAtoms ... */
76295448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (vatom->tag == Iex_Tmp) {
76395448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(atom->tag == Iex_Tmp);
76495448075345dc73986042f6dc68eb464d02bc6a8sewardj      newShadowTmp(mce, atom->Iex.Tmp.tmp);
76595448075345dc73986042f6dc68eb464d02bc6a8sewardj      assign(mce->bb, findShadowTmp(mce, atom->Iex.Tmp.tmp),
76695448075345dc73986042f6dc68eb464d02bc6a8sewardj                      definedOfType(ty));
76795448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
768e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
769e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
770e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
77195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
77295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Shadowing PUTs/GETs, and indexed variants thereof    ---*/
77395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
77495448075345dc73986042f6dc68eb464d02bc6a8sewardj
77595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Examine the always-defined sections declared in layout to see if
77695448075345dc73986042f6dc68eb464d02bc6a8sewardj   the (offset,size) section is within one.  Note, is is an error to
77795448075345dc73986042f6dc68eb464d02bc6a8sewardj   partially fall into such a region: (offset,size) should either be
77895448075345dc73986042f6dc68eb464d02bc6a8sewardj   completely in such a region or completely not-in such a region.
77995448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
78095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size )
781e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
78295448075345dc73986042f6dc68eb464d02bc6a8sewardj   Int minoffD, maxoffD, i;
78395448075345dc73986042f6dc68eb464d02bc6a8sewardj   Int minoff = offset;
78495448075345dc73986042f6dc68eb464d02bc6a8sewardj   Int maxoff = minoff + size - 1;
78595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert((minoff & ~0xFFFF) == 0);
78695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert((maxoff & ~0xFFFF) == 0);
78795448075345dc73986042f6dc68eb464d02bc6a8sewardj
78895448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; i < mce->layout->n_alwaysDefd; i++) {
78995448075345dc73986042f6dc68eb464d02bc6a8sewardj      minoffD = mce->layout->alwaysDefd[i].offset;
79095448075345dc73986042f6dc68eb464d02bc6a8sewardj      maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1;
79195448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert((minoffD & ~0xFFFF) == 0);
79295448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert((maxoffD & ~0xFFFF) == 0);
79395448075345dc73986042f6dc68eb464d02bc6a8sewardj
79495448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (maxoff < minoffD || maxoffD < minoff)
79595448075345dc73986042f6dc68eb464d02bc6a8sewardj         continue; /* no overlap */
79695448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (minoff >= minoffD && maxoff <= maxoffD)
79795448075345dc73986042f6dc68eb464d02bc6a8sewardj         return True; /* completely contained in an always-defd section */
79895448075345dc73986042f6dc68eb464d02bc6a8sewardj
79995448075345dc73986042f6dc68eb464d02bc6a8sewardj      VG_(tool_panic)("memcheck:isAlwaysDefd:partial overlap");
80095448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
80195448075345dc73986042f6dc68eb464d02bc6a8sewardj   return False; /* could not find any containing section */
802e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
803e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
804e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
80595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Generate into bb suitable actions to shadow this Put.  If the state
80695448075345dc73986042f6dc68eb464d02bc6a8sewardj   slice is marked 'always defined', do nothing.  Otherwise, write the
80795448075345dc73986042f6dc68eb464d02bc6a8sewardj   supplied V bits to the shadow state.  We can pass in either an
80895448075345dc73986042f6dc68eb464d02bc6a8sewardj   original atom or a V-atom, but not both.  In the former case the
80995448075345dc73986042f6dc68eb464d02bc6a8sewardj   relevant V-bits are then generated from the original.
81095448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
811e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnstatic
81295448075345dc73986042f6dc68eb464d02bc6a8sewardjvoid do_shadow_PUT ( MCEnv* mce,  Int offset,
81395448075345dc73986042f6dc68eb464d02bc6a8sewardj                     IRAtom* atom, IRAtom* vatom )
814e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
8157cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRType ty;
81695448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (atom) {
81795448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(!vatom);
81895448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(isOriginalAtom(mce, atom));
81995448075345dc73986042f6dc68eb464d02bc6a8sewardj      vatom = expr2vbits( mce, atom );
82095448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
82195448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(vatom);
82295448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(isShadowAtom(mce, vatom));
823e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
82495448075345dc73986042f6dc68eb464d02bc6a8sewardj
8257cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   ty = typeOfIRExpr(mce->bb->tyenv, vatom);
82695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(ty != Ity_I1);
82795448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
82895448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* later: no ... */
82995448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* emit code to emit a complaint if any of the vbits are 1. */
83095448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* complainIfUndefined(mce, atom); */
83195448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
83295448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Do a plain shadow Put. */
83395448075345dc73986042f6dc68eb464d02bc6a8sewardj      stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) );
834e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
835e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
836e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
83795448075345dc73986042f6dc68eb464d02bc6a8sewardj
83895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the
83995448075345dc73986042f6dc68eb464d02bc6a8sewardj   given GETI (passed in in pieces).
84095448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
84195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
84295448075345dc73986042f6dc68eb464d02bc6a8sewardjvoid do_shadow_PUTI ( MCEnv* mce,
84395448075345dc73986042f6dc68eb464d02bc6a8sewardj                      IRArray* descr, IRAtom* ix, Int bias, IRAtom* atom )
844e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
8457cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRAtom* vatom;
8467cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRType  ty, tyS;
8477cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   Int     arrSize;;
8487cf97ee841afd255879bff9ff791fbabb7f95cecsewardj
84995448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,atom));
8507cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   vatom = expr2vbits( mce, atom );
85195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(atom, vatom));
8527cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   ty   = descr->elemTy;
8537cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   tyS  = shadowType(ty);
8547cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   arrSize = descr->nElems * sizeofIRType(ty);
85595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(ty != Ity_I1);
85695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,ix));
85795448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined(mce,ix);
85895448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (isAlwaysDefd(mce, descr->base, arrSize)) {
85995448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* later: no ... */
86095448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* emit code to emit a complaint if any of the vbits are 1. */
86195448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* complainIfUndefined(mce, atom); */
86295448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
86395448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Do a cloned version of the Put that refers to the shadow
86495448075345dc73986042f6dc68eb464d02bc6a8sewardj         area. */
86595448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRArray* new_descr
86695448075345dc73986042f6dc68eb464d02bc6a8sewardj         = mkIRArray( descr->base + mce->layout->total_sizeB,
86795448075345dc73986042f6dc68eb464d02bc6a8sewardj                      tyS, descr->nElems);
86895448075345dc73986042f6dc68eb464d02bc6a8sewardj      stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom ));
8698ec2cfcb9c1267fd7b20529f1b95973a9712b872sewardj   }
87095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
8718ec2cfcb9c1267fd7b20529f1b95973a9712b872sewardj
872e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
87395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the
87495448075345dc73986042f6dc68eb464d02bc6a8sewardj   given GET (passed in in pieces).
87595448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
87695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
87795448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty )
87895448075345dc73986042f6dc68eb464d02bc6a8sewardj{
87995448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRType tyS = shadowType(ty);
88095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(ty != Ity_I1);
88195448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
88295448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Always defined, return all zeroes of the relevant type */
88395448075345dc73986042f6dc68eb464d02bc6a8sewardj      return definedOfType(tyS);
88495448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
88595448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* return a cloned version of the Get that refers to the shadow
88695448075345dc73986042f6dc68eb464d02bc6a8sewardj         area. */
88795448075345dc73986042f6dc68eb464d02bc6a8sewardj      return IRExpr_Get( offset + mce->layout->total_sizeB, tyS );
88895448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
88995448075345dc73986042f6dc68eb464d02bc6a8sewardj}
890e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
891e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
89295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the
89395448075345dc73986042f6dc68eb464d02bc6a8sewardj   given GETI (passed in in pieces).
89495448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
89595448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
89695448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* shadow_GETI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias )
89795448075345dc73986042f6dc68eb464d02bc6a8sewardj{
89895448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRType ty   = descr->elemTy;
89995448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRType tyS  = shadowType(ty);
90095448075345dc73986042f6dc68eb464d02bc6a8sewardj   Int arrSize = descr->nElems * sizeofIRType(ty);
90195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(ty != Ity_I1);
90295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,ix));
90395448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined(mce,ix);
90495448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (isAlwaysDefd(mce, descr->base, arrSize)) {
90595448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Always defined, return all zeroes of the relevant type */
90695448075345dc73986042f6dc68eb464d02bc6a8sewardj      return definedOfType(tyS);
90795448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
90895448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* return a cloned version of the Get that refers to the shadow
90995448075345dc73986042f6dc68eb464d02bc6a8sewardj         area. */
91095448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRArray* new_descr
91195448075345dc73986042f6dc68eb464d02bc6a8sewardj         = mkIRArray( descr->base + mce->layout->total_sizeB,
91295448075345dc73986042f6dc68eb464d02bc6a8sewardj                      tyS, descr->nElems);
91395448075345dc73986042f6dc68eb464d02bc6a8sewardj      return IRExpr_GetI( new_descr, ix, bias );
91495448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
91595448075345dc73986042f6dc68eb464d02bc6a8sewardj}
916e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
917d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj
91895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
91995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generating approximations for unknown operations,    ---*/
92095448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- using lazy-propagate semantics                       ---*/
92195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
922d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj
92395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Lazy propagation of undefinedness from two values, resulting in the
92495448075345dc73986042f6dc68eb464d02bc6a8sewardj   specified shadow type.
92595448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
92695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
92795448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
92895448075345dc73986042f6dc68eb464d02bc6a8sewardj{
92995448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* at;
93037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   IRType t1 = typeOfIRExpr(mce->bb->tyenv, va1);
93137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   IRType t2 = typeOfIRExpr(mce->bb->tyenv, va2);
93295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,va1));
93395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,va2));
93437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj
93537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   /* The general case is inefficient because PCast is an expensive
93637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      operation.  Here are some special cases which use PCast only
93737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      once rather than twice. */
93837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj
93937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   /* I64 x I64 -> I64 */
94037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I64) {
94137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      if (0) VG_(printf)("mkLazy2: I64 x I64 -> I64\n");
94237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      at = mkUifU(mce, Ity_I64, va1, va2);
94337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      at = mkPCastTo(mce, Ity_I64, at);
94437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      return at;
94537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   }
94637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj
94737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   /* I64 x I64 -> I32 */
94837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I32) {
94937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      if (0) VG_(printf)("mkLazy2: I64 x I64 -> I32\n");
95037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      at = mkUifU(mce, Ity_I64, va1, va2);
95137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      at = mkPCastTo(mce, Ity_I32, at);
95237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      return at;
95337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   }
95437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj
95537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   if (0) {
95637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      VG_(printf)("mkLazy2 ");
95737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      ppIRType(t1);
95837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      VG_(printf)("_");
95937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      ppIRType(t2);
96037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      VG_(printf)("_");
96137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      ppIRType(finalVty);
96237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj      VG_(printf)("\n");
96337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   }
96437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj
96537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj   /* General case: force everything via 32-bit intermediaries. */
96695448075345dc73986042f6dc68eb464d02bc6a8sewardj   at = mkPCastTo(mce, Ity_I32, va1);
96795448075345dc73986042f6dc68eb464d02bc6a8sewardj   at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2));
96895448075345dc73986042f6dc68eb464d02bc6a8sewardj   at = mkPCastTo(mce, finalVty, at);
96995448075345dc73986042f6dc68eb464d02bc6a8sewardj   return at;
97095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
971d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj
972e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
97395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Do the lazy propagation game from a null-terminated vector of
97495448075345dc73986042f6dc68eb464d02bc6a8sewardj   atoms.  This is presumably the arguments to a helper call, so the
97595448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRCallee info is also supplied in order that we can know which
97695448075345dc73986042f6dc68eb464d02bc6a8sewardj   arguments should be ignored (via the .mcx_mask field).
97795448075345dc73986042f6dc68eb464d02bc6a8sewardj*/
97895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
97995448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* mkLazyN ( MCEnv* mce,
98095448075345dc73986042f6dc68eb464d02bc6a8sewardj                  IRAtom** exprvec, IRType finalVtype, IRCallee* cee )
98195448075345dc73986042f6dc68eb464d02bc6a8sewardj{
98295448075345dc73986042f6dc68eb464d02bc6a8sewardj   Int i;
98395448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* here;
98495448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* curr = definedOfType(Ity_I32);
98595448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; exprvec[i]; i++) {
98695448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(i < 32);
98795448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(isOriginalAtom(mce, exprvec[i]));
98895448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Only take notice of this arg if the callee's mc-exclusion
98995448075345dc73986042f6dc68eb464d02bc6a8sewardj         mask does not say it is to be excluded. */
99095448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (cee->mcx_mask & (1<<i)) {
99195448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* the arg is to be excluded from definedness checking.  Do
99295448075345dc73986042f6dc68eb464d02bc6a8sewardj            nothing. */
99395448075345dc73986042f6dc68eb464d02bc6a8sewardj         if (0) VG_(printf)("excluding %s(%d)\n", cee->name, i);
99495448075345dc73986042f6dc68eb464d02bc6a8sewardj      } else {
99595448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* calculate the arg's definedness, and pessimistically merge
99695448075345dc73986042f6dc68eb464d02bc6a8sewardj            it in. */
99795448075345dc73986042f6dc68eb464d02bc6a8sewardj         here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, exprvec[i]) );
99895448075345dc73986042f6dc68eb464d02bc6a8sewardj         curr = mkUifU32(mce, here, curr);
99995448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
100095448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
100195448075345dc73986042f6dc68eb464d02bc6a8sewardj   return mkPCastTo(mce, finalVtype, curr );
100295448075345dc73986042f6dc68eb464d02bc6a8sewardj}
1003e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1004e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
100595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
100695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generating expensive sequences for exact carry-chain ---*/
100795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- propagation in add/sub and related operations.       ---*/
100895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
1009e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
101095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
1011d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardjIRAtom* expensiveAddSub ( MCEnv*  mce,
1012d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          Bool    add,
1013d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          IRType  ty,
1014d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          IRAtom* qaa, IRAtom* qbb,
1015d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          IRAtom* aa,  IRAtom* bb )
101695448075345dc73986042f6dc68eb464d02bc6a8sewardj{
10177cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRAtom *a_min, *b_min, *a_max, *b_max;
1018d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   IROp   opAND, opOR, opXOR, opNOT, opADD, opSUB;
10197cf97ee841afd255879bff9ff791fbabb7f95cecsewardj
102095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,qaa));
102195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,qbb));
102295448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,aa));
102395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,bb));
102495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(qaa,aa));
102595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(qbb,bb));
102695448075345dc73986042f6dc68eb464d02bc6a8sewardj
1027d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   switch (ty) {
1028d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ity_I32:
1029d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opAND = Iop_And32;
1030d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opOR  = Iop_Or32;
1031d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opXOR = Iop_Xor32;
1032d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opNOT = Iop_Not32;
1033d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opADD = Iop_Add32;
1034d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         opSUB = Iop_Sub32;
1035d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         break;
1036d9774d73807c7292c72e1254119d6bd8ded81f15tom      case Ity_I64:
1037d9774d73807c7292c72e1254119d6bd8ded81f15tom         opAND = Iop_And64;
1038d9774d73807c7292c72e1254119d6bd8ded81f15tom         opOR  = Iop_Or64;
1039d9774d73807c7292c72e1254119d6bd8ded81f15tom         opXOR = Iop_Xor64;
1040d9774d73807c7292c72e1254119d6bd8ded81f15tom         opNOT = Iop_Not64;
1041d9774d73807c7292c72e1254119d6bd8ded81f15tom         opADD = Iop_Add64;
1042d9774d73807c7292c72e1254119d6bd8ded81f15tom         opSUB = Iop_Sub64;
1043d9774d73807c7292c72e1254119d6bd8ded81f15tom         break;
1044d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      default:
1045d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         VG_(tool_panic)("expensiveAddSub");
1046d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   }
104795448075345dc73986042f6dc68eb464d02bc6a8sewardj
104895448075345dc73986042f6dc68eb464d02bc6a8sewardj   // a_min = aa & ~qaa
104995448075345dc73986042f6dc68eb464d02bc6a8sewardj   a_min = assignNew(mce,ty,
105095448075345dc73986042f6dc68eb464d02bc6a8sewardj                     binop(opAND, aa,
105195448075345dc73986042f6dc68eb464d02bc6a8sewardj                                  assignNew(mce,ty, unop(opNOT, qaa))));
105295448075345dc73986042f6dc68eb464d02bc6a8sewardj
105395448075345dc73986042f6dc68eb464d02bc6a8sewardj   // b_min = bb & ~qbb
105495448075345dc73986042f6dc68eb464d02bc6a8sewardj   b_min = assignNew(mce,ty,
105595448075345dc73986042f6dc68eb464d02bc6a8sewardj                     binop(opAND, bb,
105695448075345dc73986042f6dc68eb464d02bc6a8sewardj                                  assignNew(mce,ty, unop(opNOT, qbb))));
105795448075345dc73986042f6dc68eb464d02bc6a8sewardj
105895448075345dc73986042f6dc68eb464d02bc6a8sewardj   // a_max = aa | qaa
105995448075345dc73986042f6dc68eb464d02bc6a8sewardj   a_max = assignNew(mce,ty, binop(opOR, aa, qaa));
106095448075345dc73986042f6dc68eb464d02bc6a8sewardj
106195448075345dc73986042f6dc68eb464d02bc6a8sewardj   // b_max = bb | qbb
106295448075345dc73986042f6dc68eb464d02bc6a8sewardj   b_max = assignNew(mce,ty, binop(opOR, bb, qbb));
106395448075345dc73986042f6dc68eb464d02bc6a8sewardj
1064d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   if (add) {
1065d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      // result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max))
1066d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      return
1067d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      assignNew(mce,ty,
1068d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         binop( opOR,
1069d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                assignNew(mce,ty, binop(opOR, qaa, qbb)),
1070d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                assignNew(mce,ty,
1071d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                   binop( opXOR,
1072d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          assignNew(mce,ty, binop(opADD, a_min, b_min)),
1073d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          assignNew(mce,ty, binop(opADD, a_max, b_max))
1074d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                   )
1075d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                )
1076d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         )
1077d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      );
1078d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   } else {
1079d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      // result = (qaa | qbb) | ((a_min - b_max) ^ (a_max + b_min))
1080d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      return
1081d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      assignNew(mce,ty,
1082d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         binop( opOR,
1083d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                assignNew(mce,ty, binop(opOR, qaa, qbb)),
1084d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                assignNew(mce,ty,
1085d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                   binop( opXOR,
1086d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          assignNew(mce,ty, binop(opSUB, a_min, b_max)),
1087d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                          assignNew(mce,ty, binop(opSUB, a_max, b_min))
1088d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                   )
108995448075345dc73986042f6dc68eb464d02bc6a8sewardj                )
1090d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         )
1091d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      );
1092d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   }
1093d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
109495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
1095e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1096e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
109795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
10983245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/*--- Helpers for dealing with vector primops.            ---*/
10993245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/*------------------------------------------------------------*/
11003245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
1101a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* Vector pessimisation -- pessimise within each lane individually. */
1102a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1103a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast8x16 ( MCEnv* mce, IRAtom* at )
1104a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1105a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ8x16, at));
1106a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1107a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1108a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast16x8 ( MCEnv* mce, IRAtom* at )
1109a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1110a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ16x8, at));
1111a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1112a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1113a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast32x4 ( MCEnv* mce, IRAtom* at )
1114a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1115a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ32x4, at));
1116a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1117a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1118a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast64x2 ( MCEnv* mce, IRAtom* at )
1119a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1120a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ64x2, at));
1121a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1122a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1123acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast32x2 ( MCEnv* mce, IRAtom* at )
1124acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1125acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ32x2, at));
1126acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1127acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1128acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast16x4 ( MCEnv* mce, IRAtom* at )
1129acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1130acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ16x4, at));
1131acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1132acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1133acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast8x8 ( MCEnv* mce, IRAtom* at )
1134acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1135acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ8x8, at));
1136acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1137acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1138a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
11393245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/* Here's a simple scheme capable of handling ops derived from SSE1
11403245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   code and while only generating ops that can be efficiently
11413245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   implemented in SSE1. */
11423245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11433245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/* All-lanes versions are straightforward:
11443245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
114520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   binary32Fx4(x,y)   ==> PCast32x4(UifUV128(x#,y#))
11463245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11473245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   unary32Fx4(x,y)    ==> PCast32x4(x#)
11483245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11493245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   Lowest-lane-only versions are more complex:
11503245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
115120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   binary32F0x4(x,y)  ==> SetV128lo32(
11523245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj                             x#,
115320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj                             PCast32(V128to32(UifUV128(x#,y#)))
11543245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj                          )
11553245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11563245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   This is perhaps not so obvious.  In particular, it's faster to
115720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   do a V128-bit UifU and then take the bottom 32 bits than the more
11583245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   obvious scheme of taking the bottom 32 bits of each operand
11593245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   and doing a 32-bit UifU.  Basically since UifU is fast and
11603245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   chopping lanes off vector values is slow.
11613245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11623245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   Finally:
11633245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
116420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   unary32F0x4(x)     ==> SetV128lo32(
11653245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj                             x#,
116620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj                             PCast32(V128to32(x#))
11673245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj                          )
11683245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11693245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   Where:
11703245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11713245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   PCast32(v#)   = 1Sto32(CmpNE32(v#,0))
11723245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   PCast32x4(v#) = CmpNEZ32x4(v#)
11733245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj*/
11743245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11753245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic
11763245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* binary32Fx4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
11773245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{
11783245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   IRAtom* at;
11793245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomX));
11803245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomY));
118120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatomX, vatomY);
1182a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = assignNew(mce, Ity_V128, mkPCast32x4(mce, at));
11833245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   return at;
11843245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj}
11853245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11863245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic
11873245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* unary32Fx4 ( MCEnv* mce, IRAtom* vatomX )
11883245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{
11893245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   IRAtom* at;
11903245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomX));
1191a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = assignNew(mce, Ity_V128, mkPCast32x4(mce, vatomX));
11923245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   return at;
11933245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj}
11943245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
11953245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic
11963245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* binary32F0x4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
11973245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{
11983245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   IRAtom* at;
11993245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomX));
12003245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomY));
120120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatomX, vatomY);
120220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_I32, unop(Iop_V128to32, at));
12033245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   at = mkPCastTo(mce, Ity_I32, at);
120420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
12053245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   return at;
12063245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj}
12073245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
12083245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic
12093245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* unary32F0x4 ( MCEnv* mce, IRAtom* vatomX )
12103245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{
12113245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   IRAtom* at;
12123245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   tl_assert(isShadowAtom(mce, vatomX));
121320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_I32, unop(Iop_V128to32, vatomX));
12143245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   at = mkPCastTo(mce, Ity_I32, at);
121520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
12163245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj   return at;
12173245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj}
12183245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
12190b07059814aee8563905f2caeef186a8c83072cfsewardj/* --- ... and ... 64Fx2 versions of the same ... --- */
12200b07059814aee8563905f2caeef186a8c83072cfsewardj
12210b07059814aee8563905f2caeef186a8c83072cfsewardjstatic
12220b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* binary64Fx2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
12230b07059814aee8563905f2caeef186a8c83072cfsewardj{
12240b07059814aee8563905f2caeef186a8c83072cfsewardj   IRAtom* at;
12250b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomX));
12260b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomY));
122720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatomX, vatomY);
1228a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = assignNew(mce, Ity_V128, mkPCast64x2(mce, at));
12290b07059814aee8563905f2caeef186a8c83072cfsewardj   return at;
12300b07059814aee8563905f2caeef186a8c83072cfsewardj}
12310b07059814aee8563905f2caeef186a8c83072cfsewardj
12320b07059814aee8563905f2caeef186a8c83072cfsewardjstatic
12330b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* unary64Fx2 ( MCEnv* mce, IRAtom* vatomX )
12340b07059814aee8563905f2caeef186a8c83072cfsewardj{
12350b07059814aee8563905f2caeef186a8c83072cfsewardj   IRAtom* at;
12360b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomX));
1237a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = assignNew(mce, Ity_V128, mkPCast64x2(mce, vatomX));
12380b07059814aee8563905f2caeef186a8c83072cfsewardj   return at;
12390b07059814aee8563905f2caeef186a8c83072cfsewardj}
12400b07059814aee8563905f2caeef186a8c83072cfsewardj
12410b07059814aee8563905f2caeef186a8c83072cfsewardjstatic
12420b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* binary64F0x2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY )
12430b07059814aee8563905f2caeef186a8c83072cfsewardj{
12440b07059814aee8563905f2caeef186a8c83072cfsewardj   IRAtom* at;
12450b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomX));
12460b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomY));
124720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatomX, vatomY);
124820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_I64, unop(Iop_V128to64, at));
12490b07059814aee8563905f2caeef186a8c83072cfsewardj   at = mkPCastTo(mce, Ity_I64, at);
125020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
12510b07059814aee8563905f2caeef186a8c83072cfsewardj   return at;
12520b07059814aee8563905f2caeef186a8c83072cfsewardj}
12530b07059814aee8563905f2caeef186a8c83072cfsewardj
12540b07059814aee8563905f2caeef186a8c83072cfsewardjstatic
12550b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* unary64F0x2 ( MCEnv* mce, IRAtom* vatomX )
12560b07059814aee8563905f2caeef186a8c83072cfsewardj{
12570b07059814aee8563905f2caeef186a8c83072cfsewardj   IRAtom* at;
12580b07059814aee8563905f2caeef186a8c83072cfsewardj   tl_assert(isShadowAtom(mce, vatomX));
125920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_I64, unop(Iop_V128to64, vatomX));
12600b07059814aee8563905f2caeef186a8c83072cfsewardj   at = mkPCastTo(mce, Ity_I64, at);
126120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
12620b07059814aee8563905f2caeef186a8c83072cfsewardj   return at;
12630b07059814aee8563905f2caeef186a8c83072cfsewardj}
12640b07059814aee8563905f2caeef186a8c83072cfsewardj
1265a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* --- --- Vector saturated narrowing --- --- */
1266a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1267a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* This is quite subtle.  What to do is simple:
1268a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1269a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   Let the original narrowing op be QNarrowW{S,U}xN.  Produce:
1270a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1271a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      the-narrowing-op( PCastWxN(vatom1), PCastWxN(vatom2))
1272a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1273a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   Why this is right is not so simple.  Consider a lane in the args,
1274a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   vatom1 or 2, doesn't matter.
1275a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1276a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   After the PCast, that lane is all 0s (defined) or all
1277a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   1s(undefined).
1278a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1279a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   Both signed and unsigned saturating narrowing of all 0s produces
1280a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   all 0s, which is what we want.
1281a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1282a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   The all-1s case is more complex.  Unsigned narrowing interprets an
1283a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   all-1s input as the largest unsigned integer, and so produces all
1284a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   1s as a result since that is the largest unsigned value at the
1285a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   smaller width.
1286a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1287a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   Signed narrowing interprets all 1s as -1.  Fortunately, -1 narrows
1288a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   to -1, so we still wind up with all 1s at the smaller width.
1289a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1290a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   So: In short, pessimise the args, then apply the original narrowing
1291a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   op.
1292a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj*/
1293a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic
129420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjIRAtom* vectorNarrowV128 ( MCEnv* mce, IROp narrow_op,
1295a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj                          IRAtom* vatom1, IRAtom* vatom2)
1296a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1297a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom *at1, *at2, *at3;
1298a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom* (*pcast)( MCEnv*, IRAtom* );
1299a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   switch (narrow_op) {
1300a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow32Sx4: pcast = mkPCast32x4; break;
1301a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow16Sx8: pcast = mkPCast16x8; break;
1302a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow16Ux8: pcast = mkPCast16x8; break;
130320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      default: VG_(tool_panic)("vectorNarrowV128");
1304a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   }
1305a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   tl_assert(isShadowAtom(mce,vatom1));
1306a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   tl_assert(isShadowAtom(mce,vatom2));
1307a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at1 = assignNew(mce, Ity_V128, pcast(mce, vatom1));
1308a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at2 = assignNew(mce, Ity_V128, pcast(mce, vatom2));
1309a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at3 = assignNew(mce, Ity_V128, binop(narrow_op, at1, at2));
1310a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return at3;
1311a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1312a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1313acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic
1314acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* vectorNarrow64 ( MCEnv* mce, IROp narrow_op,
1315acd2e910861cfc0f95229401922d38d7ce9c6259sewardj                         IRAtom* vatom1, IRAtom* vatom2)
1316acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1317acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   IRAtom *at1, *at2, *at3;
1318acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   IRAtom* (*pcast)( MCEnv*, IRAtom* );
1319acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   switch (narrow_op) {
1320acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow32Sx2: pcast = mkPCast32x2; break;
1321acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow16Sx4: pcast = mkPCast16x4; break;
1322acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow16Ux4: pcast = mkPCast16x4; break;
1323acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      default: VG_(tool_panic)("vectorNarrow64");
1324acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   }
1325acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   tl_assert(isShadowAtom(mce,vatom1));
1326acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   tl_assert(isShadowAtom(mce,vatom2));
1327acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at1 = assignNew(mce, Ity_I64, pcast(mce, vatom1));
1328acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at2 = assignNew(mce, Ity_I64, pcast(mce, vatom2));
1329acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at3 = assignNew(mce, Ity_I64, binop(narrow_op, at1, at2));
1330acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return at3;
1331acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1332acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1333a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1334a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* --- --- Vector integer arithmetic --- --- */
1335a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1336a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* Simple ... UifU the args and per-lane pessimise the results. */
1337acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
133820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj/* --- V128-bit versions --- */
1339acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1340a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic
1341a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary8Ix16 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1342a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1343a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom* at;
134420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatom1, vatom2);
1345a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = mkPCast8x16(mce, at);
1346a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return at;
1347a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1348a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1349a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic
1350a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary16Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1351a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1352a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom* at;
135320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatom1, vatom2);
1354a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = mkPCast16x8(mce, at);
1355a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return at;
1356a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1357a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1358a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic
1359a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary32Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1360a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1361a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom* at;
136220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatom1, vatom2);
1363a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = mkPCast32x4(mce, at);
1364a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return at;
1365a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
1366a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1367a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic
1368a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary64Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1369a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{
1370a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   IRAtom* at;
137120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj   at = mkUifUV128(mce, vatom1, vatom2);
1372a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   at = mkPCast64x2(mce, at);
1373a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj   return at;
1374a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj}
13753245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
1376acd2e910861cfc0f95229401922d38d7ce9c6259sewardj/* --- 64-bit versions --- */
1377acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1378acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic
1379acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary8Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1380acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1381acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   IRAtom* at;
1382acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkUifU64(mce, vatom1, vatom2);
1383acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkPCast8x8(mce, at);
1384acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return at;
1385acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1386acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1387acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic
1388acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary16Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1389acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1390acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   IRAtom* at;
1391acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkUifU64(mce, vatom1, vatom2);
1392acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkPCast16x4(mce, at);
1393acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return at;
1394acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1395acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1396acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic
1397acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary32Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 )
1398acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{
1399acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   IRAtom* at;
1400acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkUifU64(mce, vatom1, vatom2);
1401acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   at = mkPCast32x2(mce, at);
1402acd2e910861cfc0f95229401922d38d7ce9c6259sewardj   return at;
1403acd2e910861cfc0f95229401922d38d7ce9c6259sewardj}
1404acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
14053245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
14063245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/*------------------------------------------------------------*/
140795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generate shadow values from all kinds of IRExprs.    ---*/
140895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
1409e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
141095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
141195448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* expr2vbits_Binop ( MCEnv* mce,
141295448075345dc73986042f6dc68eb464d02bc6a8sewardj                           IROp op,
141395448075345dc73986042f6dc68eb464d02bc6a8sewardj                           IRAtom* atom1, IRAtom* atom2 )
141495448075345dc73986042f6dc68eb464d02bc6a8sewardj{
141595448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRType  and_or_ty;
141695448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* (*uifu)    (MCEnv*, IRAtom*, IRAtom*);
141795448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* (*difd)    (MCEnv*, IRAtom*, IRAtom*);
141895448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*);
141995448075345dc73986042f6dc68eb464d02bc6a8sewardj
142095448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* vatom1 = expr2vbits( mce, atom1 );
142195448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* vatom2 = expr2vbits( mce, atom2 );
142295448075345dc73986042f6dc68eb464d02bc6a8sewardj
142395448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,atom1));
142495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,atom2));
142595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,vatom1));
142695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,vatom2));
142795448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(atom1,vatom1));
142895448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(sameKindedAtoms(atom2,vatom2));
142995448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (op) {
143095448075345dc73986042f6dc68eb464d02bc6a8sewardj
1431acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      /* 64-bit SIMD */
1432acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1433acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_ShrN16x4:
1434acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_ShrN32x2:
1435acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_SarN16x4:
1436acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_SarN32x2:
1437acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_ShlN16x4:
1438acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_ShlN32x2:
1439acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         /* Same scheme as with all other shifts. */
1440acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         complainIfUndefined(mce, atom2);
1441acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return assignNew(mce, Ity_I64, binop(op, vatom1, atom2));
1442acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1443acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow32Sx2:
1444acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow16Sx4:
1445acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QNarrow16Ux4:
1446acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return vectorNarrow64(mce, op, vatom1, vatom2);
1447acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1448acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Min8Ux8:
1449acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Max8Ux8:
1450acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Avg8Ux8:
1451acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QSub8Sx8:
1452acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QSub8Ux8:
1453acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Sub8x8:
1454acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpGT8Sx8:
1455acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpEQ8x8:
1456acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QAdd8Sx8:
1457acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QAdd8Ux8:
1458acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Add8x8:
1459acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return binary8Ix8(mce, vatom1, vatom2);
1460acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1461acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Min16Sx4:
1462acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Max16Sx4:
1463acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Avg16Ux4:
1464acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QSub16Ux4:
1465acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QSub16Sx4:
1466acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Sub16x4:
1467acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Mul16x4:
1468acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_MulHi16Sx4:
1469acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_MulHi16Ux4:
1470acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpGT16Sx4:
1471acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpEQ16x4:
1472acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QAdd16Sx4:
1473acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_QAdd16Ux4:
1474acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Add16x4:
1475acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return binary16Ix4(mce, vatom1, vatom2);
1476acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1477acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Sub32x2:
1478acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpGT32Sx2:
1479acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_CmpEQ32x2:
1480acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_Add32x2:
1481acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return binary32Ix2(mce, vatom1, vatom2);
1482acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
1483acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      /* 64-bit data-steering */
1484acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveLO32x2:
1485acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveLO16x4:
1486acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveLO8x8:
1487acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveHI32x2:
1488acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveHI16x4:
1489acd2e910861cfc0f95229401922d38d7ce9c6259sewardj      case Iop_InterleaveHI8x8:
1490acd2e910861cfc0f95229401922d38d7ce9c6259sewardj         return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
1491acd2e910861cfc0f95229401922d38d7ce9c6259sewardj
149220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      /* V128-bit SIMD */
14930b07059814aee8563905f2caeef186a8c83072cfsewardj
1494a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShrN16x8:
1495a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShrN32x4:
1496a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShrN64x2:
1497a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_SarN16x8:
1498a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_SarN32x4:
1499a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShlN16x8:
1500a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShlN32x4:
1501a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_ShlN64x2:
1502a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         /* Same scheme as with all other shifts. */
1503a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         complainIfUndefined(mce, atom2);
1504a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return assignNew(mce, Ity_V128, binop(op, vatom1, atom2));
1505a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1506a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QSub8Ux16:
1507a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QSub8Sx16:
1508a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Sub8x16:
1509a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Min8Ux16:
1510a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Max8Ux16:
1511a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpGT8Sx16:
1512a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpEQ8x16:
1513a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Avg8Ux16:
1514a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QAdd8Ux16:
1515a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QAdd8Sx16:
1516a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Add8x16:
1517a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return binary8Ix16(mce, vatom1, vatom2);
1518a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1519a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QSub16Ux8:
1520a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QSub16Sx8:
1521a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Sub16x8:
1522a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Mul16x8:
1523a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_MulHi16Sx8:
1524a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_MulHi16Ux8:
1525a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Min16Sx8:
1526a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Max16Sx8:
1527a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpGT16Sx8:
1528a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpEQ16x8:
1529a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Avg16Ux8:
1530a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QAdd16Ux8:
1531a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QAdd16Sx8:
1532a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Add16x8:
1533a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return binary16Ix8(mce, vatom1, vatom2);
1534a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1535a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Sub32x4:
1536a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpGT32Sx4:
1537a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_CmpEQ32x4:
1538a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Add32x4:
1539a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return binary32Ix4(mce, vatom1, vatom2);
1540a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1541a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Sub64x2:
1542a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_Add64x2:
1543a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj         return binary64Ix2(mce, vatom1, vatom2);
1544a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
1545a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow32Sx4:
1546a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow16Sx8:
1547a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_QNarrow16Ux8:
154820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         return vectorNarrowV128(mce, op, vatom1, vatom2);
1549a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj
15500b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Sub64Fx2:
15510b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Mul64Fx2:
15520b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Min64Fx2:
15530b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Max64Fx2:
15540b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Div64Fx2:
15550b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpLT64Fx2:
15560b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpLE64Fx2:
15570b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpEQ64Fx2:
15580b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Add64Fx2:
15590b07059814aee8563905f2caeef186a8c83072cfsewardj         return binary64Fx2(mce, vatom1, vatom2);
15600b07059814aee8563905f2caeef186a8c83072cfsewardj
15610b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Sub64F0x2:
15620b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Mul64F0x2:
15630b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Min64F0x2:
15640b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Max64F0x2:
15650b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Div64F0x2:
15660b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpLT64F0x2:
15670b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpLE64F0x2:
15680b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_CmpEQ64F0x2:
15690b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Add64F0x2:
15700b07059814aee8563905f2caeef186a8c83072cfsewardj         return binary64F0x2(mce, vatom1, vatom2);
15710b07059814aee8563905f2caeef186a8c83072cfsewardj
1572170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Sub32Fx4:
1573170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Mul32Fx4:
1574170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Min32Fx4:
1575170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Max32Fx4:
1576170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Div32Fx4:
1577170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpLT32Fx4:
1578170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpLE32Fx4:
1579170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpEQ32Fx4:
15803245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj      case Iop_Add32Fx4:
15813245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj         return binary32Fx4(mce, vatom1, vatom2);
15823245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
1583170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Sub32F0x4:
1584170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Mul32F0x4:
1585170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Min32F0x4:
1586170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Max32F0x4:
1587170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Div32F0x4:
1588170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpLT32F0x4:
1589170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpLE32F0x4:
1590170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_CmpEQ32F0x4:
1591170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Add32F0x4:
1592170ee210842367a5cc52390358ba560774f76329sewardj         return binary32F0x4(mce, vatom1, vatom2);
1593170ee210842367a5cc52390358ba560774f76329sewardj
159420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      /* V128-bit data-steering */
159520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_SetV128lo32:
159620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_SetV128lo64:
159720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_64HLtoV128:
1598a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveLO64x2:
1599a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveLO32x4:
1600a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveLO16x8:
1601a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveLO8x16:
1602a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveHI64x2:
1603a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveHI32x4:
1604a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveHI16x8:
1605a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj      case Iop_InterleaveHI8x16:
1606170ee210842367a5cc52390358ba560774f76329sewardj         return assignNew(mce, Ity_V128, binop(op, vatom1, vatom2));
1607170ee210842367a5cc52390358ba560774f76329sewardj
160869a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      /* I128-bit data-steering */
160969a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Iop_64HLto128:
161069a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         return assignNew(mce, Ity_I128, binop(op, vatom1, vatom2));
161169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj
16123245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj      /* Scalar floating point */
16133245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj
161495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_RoundF64:
161595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_F64toI64:
1616e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      case Iop_I64toF64:
1617e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         /* First arg is I32 (rounding mode), second is F64 or I64
1618e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj            (data). */
161995448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I64, vatom1, vatom2);
162095448075345dc73986042f6dc68eb464d02bc6a8sewardj
162195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
162295448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* Takes two F64 args. */
162395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_F64toI32:
1624e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      case Iop_F64toF32:
162595448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* First arg is I32 (rounding mode), second is F64 (data). */
162695448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I32, vatom1, vatom2);
162795448075345dc73986042f6dc68eb464d02bc6a8sewardj
162895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_F64toI16:
162995448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* First arg is I32 (rounding mode), second is F64 (data). */
163095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I16, vatom1, vatom2);
163195448075345dc73986042f6dc68eb464d02bc6a8sewardj
163295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_ScaleF64:
163395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Yl2xF64:
163495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Yl2xp1F64:
163595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_PRemF64:
163696403eb283475bee96cce41daf4c0c54924daf2esewardj      case Iop_PRem1F64:
163795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_AtanF64:
163895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_AddF64:
163995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_DivF64:
164095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_SubF64:
164195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MulF64:
164295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I64, vatom1, vatom2);
164395448075345dc73986042f6dc68eb464d02bc6a8sewardj
164495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CmpF64:
164595448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I32, vatom1, vatom2);
164695448075345dc73986042f6dc68eb464d02bc6a8sewardj
164795448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* non-FP after here */
164895448075345dc73986042f6dc68eb464d02bc6a8sewardj
164995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_DivModU64to32:
165095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_DivModS64to32:
165195448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazy2(mce, Ity_I64, vatom1, vatom2);
165295448075345dc73986042f6dc68eb464d02bc6a8sewardj
165369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Iop_DivModU128to64:
165469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Iop_DivModS128to64:
165569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         return mkLazy2(mce, Ity_I128, vatom1, vatom2);
165669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj
165795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_16HLto32:
1658170ee210842367a5cc52390358ba560774f76329sewardj         return assignNew(mce, Ity_I32, binop(op, vatom1, vatom2));
165995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32HLto64:
1660170ee210842367a5cc52390358ba560774f76329sewardj         return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
166195448075345dc73986042f6dc68eb464d02bc6a8sewardj
16626cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Iop_MullS64:
16636cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Iop_MullU64: {
16646cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj         IRAtom* vLo64 = mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
16656cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj         IRAtom* vHi64 = mkPCastTo(mce, Ity_I64, vLo64);
16666cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj         return assignNew(mce, Ity_I128, binop(Iop_64HLto128, vHi64, vLo64));
16676cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      }
16686cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj
166995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullS32:
167095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullU32: {
167195448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
167295448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32);
167395448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32));
167495448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
1675e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
167695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullS16:
167795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullU16: {
167895448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2));
167995448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16);
168095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16));
168195448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
1682e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
168395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullS8:
168495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_MullU8: {
168595448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2));
168695448075345dc73986042f6dc68eb464d02bc6a8sewardj         IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8);
168795448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8));
168895448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
1689e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
16909e5910872335c1ff7cb9733480904aa84dfe16abcerion      case Iop_DivS32:
16919e5910872335c1ff7cb9733480904aa84dfe16abcerion      case Iop_DivU32:
16929e5910872335c1ff7cb9733480904aa84dfe16abcerion         return mkLazy2(mce, Ity_I32, vatom1, vatom2);
16939e5910872335c1ff7cb9733480904aa84dfe16abcerion
169495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Add32:
1695d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         if (mce->bogusLiterals)
1696d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            return expensiveAddSub(mce,True,Ity_I32,
1697d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                                   vatom1,vatom2, atom1,atom2);
1698d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         else
1699d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            goto cheap_AddSub32;
170095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Sub32:
1701d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         if (mce->bogusLiterals)
1702d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            return expensiveAddSub(mce,False,Ity_I32,
1703d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                                   vatom1,vatom2, atom1,atom2);
1704d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         else
1705d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            goto cheap_AddSub32;
1706d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
1707d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      cheap_AddSub32:
170895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Mul32:
1709463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj      case Iop_CmpORD32S:
1710463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj      case Iop_CmpORD32U:
171195448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
171295448075345dc73986042f6dc68eb464d02bc6a8sewardj
1713681be302af5528c2cb415270da9fde2e7f347e69sewardj      case Iop_Add64:
1714d9774d73807c7292c72e1254119d6bd8ded81f15tom         if (mce->bogusLiterals)
1715d9774d73807c7292c72e1254119d6bd8ded81f15tom            return expensiveAddSub(mce,True,Ity_I64,
1716d9774d73807c7292c72e1254119d6bd8ded81f15tom                                   vatom1,vatom2, atom1,atom2);
1717d9774d73807c7292c72e1254119d6bd8ded81f15tom         else
1718d9774d73807c7292c72e1254119d6bd8ded81f15tom            goto cheap_AddSub64;
1719681be302af5528c2cb415270da9fde2e7f347e69sewardj      case Iop_Sub64:
1720d9774d73807c7292c72e1254119d6bd8ded81f15tom         if (mce->bogusLiterals)
1721d9774d73807c7292c72e1254119d6bd8ded81f15tom            return expensiveAddSub(mce,False,Ity_I64,
1722d9774d73807c7292c72e1254119d6bd8ded81f15tom                                   vatom1,vatom2, atom1,atom2);
1723d9774d73807c7292c72e1254119d6bd8ded81f15tom         else
1724d9774d73807c7292c72e1254119d6bd8ded81f15tom            goto cheap_AddSub64;
1725d9774d73807c7292c72e1254119d6bd8ded81f15tom
1726d9774d73807c7292c72e1254119d6bd8ded81f15tom      cheap_AddSub64:
1727d9774d73807c7292c72e1254119d6bd8ded81f15tom      case Iop_Mul64:
1728681be302af5528c2cb415270da9fde2e7f347e69sewardj         return mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
1729681be302af5528c2cb415270da9fde2e7f347e69sewardj
173095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Mul16:
173195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Add16:
173295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Sub16:
173395448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLeft16(mce, mkUifU16(mce, vatom1,vatom2));
173495448075345dc73986042f6dc68eb464d02bc6a8sewardj
173595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Sub8:
173695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Add8:
173795448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLeft8(mce, mkUifU8(mce, vatom1,vatom2));
173895448075345dc73986042f6dc68eb464d02bc6a8sewardj
173969a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Iop_CmpEQ64:
1740e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      case Iop_CmpNE64:
174169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         if (mce->bogusLiterals)
174269a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj            return expensiveCmpEQorNE(mce,Ity_I64, vatom1,vatom2, atom1,atom2 );
174369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         else
174469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj            goto cheap_cmp64;
174569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      cheap_cmp64:
1746cd986336a55192fe237a72b323b378b674af38e0tom      case Iop_CmpLE64S: case Iop_CmpLE64U:
1747cd986336a55192fe237a72b323b378b674af38e0tom      case Iop_CmpLT64U: case Iop_CmpLT64S:
174869a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         return mkPCastTo(mce, Ity_I1, mkUifU64(mce, vatom1,vatom2));
174969a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj
1750d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Iop_CmpEQ32:
1751e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj      case Iop_CmpNE32:
1752d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         if (mce->bogusLiterals)
1753d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            return expensiveCmpEQorNE(mce,Ity_I32, vatom1,vatom2, atom1,atom2 );
1754d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         else
1755d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            goto cheap_cmp32;
1756d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      cheap_cmp32:
175795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CmpLE32S: case Iop_CmpLE32U:
175895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CmpLT32U: case Iop_CmpLT32S:
175995448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkPCastTo(mce, Ity_I1, mkUifU32(mce, vatom1,vatom2));
176095448075345dc73986042f6dc68eb464d02bc6a8sewardj
176195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CmpEQ16: case Iop_CmpNE16:
176295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkPCastTo(mce, Ity_I1, mkUifU16(mce, vatom1,vatom2));
176395448075345dc73986042f6dc68eb464d02bc6a8sewardj
176495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CmpEQ8: case Iop_CmpNE8:
176595448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkPCastTo(mce, Ity_I1, mkUifU8(mce, vatom1,vatom2));
176695448075345dc73986042f6dc68eb464d02bc6a8sewardj
176795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
176895448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* Complain if the shift amount is undefined.  Then simply
176995448075345dc73986042f6dc68eb464d02bc6a8sewardj            shift the first arg's V bits by the real shift amount. */
177095448075345dc73986042f6dc68eb464d02bc6a8sewardj         complainIfUndefined(mce, atom2);
177195448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I32, binop(op, vatom1, atom2));
177295448075345dc73986042f6dc68eb464d02bc6a8sewardj
1773db67f5fbbfcf585bf4ff553ab555b9e4ffc1d195sewardj      case Iop_Shl16: case Iop_Shr16: case Iop_Sar16:
177495448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* Same scheme as with 32-bit shifts. */
177595448075345dc73986042f6dc68eb464d02bc6a8sewardj         complainIfUndefined(mce, atom2);
177695448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I16, binop(op, vatom1, atom2));
177795448075345dc73986042f6dc68eb464d02bc6a8sewardj
177895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Shl8: case Iop_Shr8:
177995448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* Same scheme as with 32-bit shifts. */
178095448075345dc73986042f6dc68eb464d02bc6a8sewardj         complainIfUndefined(mce, atom2);
178195448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I8, binop(op, vatom1, atom2));
178295448075345dc73986042f6dc68eb464d02bc6a8sewardj
178369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj      case Iop_Shl64: case Iop_Shr64: case Iop_Sar64:
178495448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* Same scheme as with 32-bit shifts. */
178595448075345dc73986042f6dc68eb464d02bc6a8sewardj         complainIfUndefined(mce, atom2);
178695448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I64, binop(op, vatom1, atom2));
178795448075345dc73986042f6dc68eb464d02bc6a8sewardj
178820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_AndV128:
178920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         uifu = mkUifUV128; difd = mkDifDV128;
179020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         and_or_ty = Ity_V128; improve = mkImproveANDV128; goto do_And_Or;
17917010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj      case Iop_And64:
17927010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj         uifu = mkUifU64; difd = mkDifD64;
17937010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj         and_or_ty = Ity_I64; improve = mkImproveAND64; goto do_And_Or;
179495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_And32:
179595448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU32; difd = mkDifD32;
179695448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or;
179795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_And16:
179895448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU16; difd = mkDifD16;
179995448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or;
180095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_And8:
180195448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU8; difd = mkDifD8;
180295448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or;
180395448075345dc73986042f6dc68eb464d02bc6a8sewardj
180420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_OrV128:
180520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         uifu = mkUifUV128; difd = mkDifDV128;
180620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         and_or_ty = Ity_V128; improve = mkImproveORV128; goto do_And_Or;
18077010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj      case Iop_Or64:
18087010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj         uifu = mkUifU64; difd = mkDifD64;
18097010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj         and_or_ty = Ity_I64; improve = mkImproveOR64; goto do_And_Or;
181095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Or32:
181195448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU32; difd = mkDifD32;
181295448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or;
181395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Or16:
181495448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU16; difd = mkDifD16;
181595448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or;
181695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Or8:
181795448075345dc73986042f6dc68eb464d02bc6a8sewardj         uifu = mkUifU8; difd = mkDifD8;
181895448075345dc73986042f6dc68eb464d02bc6a8sewardj         and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or;
181995448075345dc73986042f6dc68eb464d02bc6a8sewardj
182095448075345dc73986042f6dc68eb464d02bc6a8sewardj      do_And_Or:
182195448075345dc73986042f6dc68eb464d02bc6a8sewardj         return
182295448075345dc73986042f6dc68eb464d02bc6a8sewardj         assignNew(
182395448075345dc73986042f6dc68eb464d02bc6a8sewardj            mce,
182495448075345dc73986042f6dc68eb464d02bc6a8sewardj            and_or_ty,
182595448075345dc73986042f6dc68eb464d02bc6a8sewardj            difd(mce, uifu(mce, vatom1, vatom2),
182695448075345dc73986042f6dc68eb464d02bc6a8sewardj                      difd(mce, improve(mce, atom1, vatom1),
182795448075345dc73986042f6dc68eb464d02bc6a8sewardj                                improve(mce, atom2, vatom2) ) ) );
182895448075345dc73986042f6dc68eb464d02bc6a8sewardj
182995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Xor8:
183095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkUifU8(mce, vatom1, vatom2);
183195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Xor16:
183295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkUifU16(mce, vatom1, vatom2);
183395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Xor32:
183495448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkUifU32(mce, vatom1, vatom2);
18357010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj      case Iop_Xor64:
18367010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj         return mkUifU64(mce, vatom1, vatom2);
183720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_XorV128:
183820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj         return mkUifUV128(mce, vatom1, vatom2);
1839e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
184095448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
184195448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIROp(op);
184295448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("memcheck:expr2vbits_Binop");
184395448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
184495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
1845e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1846e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
184795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
184895448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom )
184995448075345dc73986042f6dc68eb464d02bc6a8sewardj{
185095448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom* vatom = expr2vbits( mce, atom );
185195448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,atom));
185295448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (op) {
185395448075345dc73986042f6dc68eb464d02bc6a8sewardj
18540b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Sqrt64Fx2:
18550b07059814aee8563905f2caeef186a8c83072cfsewardj         return unary64Fx2(mce, vatom);
18560b07059814aee8563905f2caeef186a8c83072cfsewardj
18570b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_Sqrt64F0x2:
18580b07059814aee8563905f2caeef186a8c83072cfsewardj         return unary64F0x2(mce, vatom);
18590b07059814aee8563905f2caeef186a8c83072cfsewardj
1860170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Sqrt32Fx4:
1861170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_RSqrt32Fx4:
1862170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Recip32Fx4:
1863170ee210842367a5cc52390358ba560774f76329sewardj         return unary32Fx4(mce, vatom);
1864170ee210842367a5cc52390358ba560774f76329sewardj
1865170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Sqrt32F0x4:
1866170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_RSqrt32F0x4:
1867170ee210842367a5cc52390358ba560774f76329sewardj      case Iop_Recip32F0x4:
1868170ee210842367a5cc52390358ba560774f76329sewardj         return unary32F0x4(mce, vatom);
1869170ee210842367a5cc52390358ba560774f76329sewardj
187020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_32UtoV128:
187120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_64UtoV128:
1872170ee210842367a5cc52390358ba560774f76329sewardj         return assignNew(mce, Ity_V128, unop(op, vatom));
1873170ee210842367a5cc52390358ba560774f76329sewardj
187495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_F32toF64:
187595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_I32toF64:
187695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_NegF64:
187795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_SinF64:
187895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_CosF64:
187995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_TanF64:
188095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_SqrtF64:
188195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_AbsF64:
188295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_2xm1F64:
188339cc73532a985e3fecf9bf3822fffc6466b38d80sewardj      case Iop_Clz64:
188439cc73532a985e3fecf9bf3822fffc6466b38d80sewardj      case Iop_Ctz64:
188595448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkPCastTo(mce, Ity_I64, vatom);
188695448075345dc73986042f6dc68eb464d02bc6a8sewardj
188795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Clz32:
188895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Ctz32:
188995448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkPCastTo(mce, Ity_I32, vatom);
189095448075345dc73986042f6dc68eb464d02bc6a8sewardj
1891d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_1Uto64:
1892d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_8Uto64:
1893d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_8Sto64:
1894d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_16Uto64:
1895d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_16Sto64:
189695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32Sto64:
189795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32Uto64:
189820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_V128to64:
189920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_V128HIto64:
19006cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Iop_128HIto64:
19016cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      case Iop_128to64:
190295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I64, unop(op, vatom));
190395448075345dc73986042f6dc68eb464d02bc6a8sewardj
190495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_64to32:
190595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_64HIto32:
190695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_1Uto32:
1907463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj      case Iop_1Sto32:
190895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_8Uto32:
190995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_16Uto32:
191095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_16Sto32:
191195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_8Sto32:
191295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I32, unop(op, vatom));
191395448075345dc73986042f6dc68eb464d02bc6a8sewardj
191495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_8Sto16:
191595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_8Uto16:
191695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32to16:
191795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32HIto16:
1918d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_64to16:
191995448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I16, unop(op, vatom));
192095448075345dc73986042f6dc68eb464d02bc6a8sewardj
192195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_1Uto8:
192295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_16to8:
192395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32to8:
1924d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_64to8:
192595448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I8, unop(op, vatom));
192695448075345dc73986042f6dc68eb464d02bc6a8sewardj
192795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_32to1:
192895448075345dc73986042f6dc68eb464d02bc6a8sewardj         return assignNew(mce, Ity_I1, unop(Iop_32to1, vatom));
192995448075345dc73986042f6dc68eb464d02bc6a8sewardj
1930d9dbc19c507323f02079ea4ee3cca66149f7357csewardj      case Iop_64to1:
1931d9dbc19c507323f02079ea4ee3cca66149f7357csewardj         return assignNew(mce, Ity_I1, unop(Iop_64to1, vatom));
1932d9dbc19c507323f02079ea4ee3cca66149f7357csewardj
193395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_ReinterpF64asI64:
193495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_ReinterpI64asF64:
19350b07059814aee8563905f2caeef186a8c83072cfsewardj      case Iop_ReinterpI32asF32:
193620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      case Iop_NotV128:
19377010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj      case Iop_Not64:
193895448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Not32:
193995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Not16:
194095448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Not8:
194195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iop_Not1:
194295448075345dc73986042f6dc68eb464d02bc6a8sewardj         return vatom;
19437010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj
1944e53bd99542226fcc64fe51c1e4158248993fc852sewardj      /* Neg* really fall under the Add/Sub banner, and as such you
1945e53bd99542226fcc64fe51c1e4158248993fc852sewardj         might think would qualify for the 'expensive add/sub'
1946e53bd99542226fcc64fe51c1e4158248993fc852sewardj         treatment.  However, in this case since the implied literal
1947e53bd99542226fcc64fe51c1e4158248993fc852sewardj         is zero (0 - arg), we just do the cheap thing anyway. */
1948e53bd99542226fcc64fe51c1e4158248993fc852sewardj      case Iop_Neg8:
1949e53bd99542226fcc64fe51c1e4158248993fc852sewardj         return mkLeft8(mce, vatom);
1950e53bd99542226fcc64fe51c1e4158248993fc852sewardj      case Iop_Neg16:
1951e53bd99542226fcc64fe51c1e4158248993fc852sewardj         return mkLeft16(mce, vatom);
1952e53bd99542226fcc64fe51c1e4158248993fc852sewardj      case Iop_Neg32:
1953e53bd99542226fcc64fe51c1e4158248993fc852sewardj         return mkLeft32(mce, vatom);
1954e53bd99542226fcc64fe51c1e4158248993fc852sewardj
195595448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
195695448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIROp(op);
195795448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("memcheck:expr2vbits_Unop");
195895448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
195995448075345dc73986042f6dc68eb464d02bc6a8sewardj}
1960e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1961e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1962170ee210842367a5cc52390358ba560774f76329sewardj/* Worker function; do not call directly. */
196395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
19642e595858903b80f29f271dc94e32a9e052bb4c8asewardjIRAtom* expr2vbits_Load_WRK ( MCEnv* mce,
19652e595858903b80f29f271dc94e32a9e052bb4c8asewardj                              IREndness end, IRType ty,
19662e595858903b80f29f271dc94e32a9e052bb4c8asewardj                              IRAtom* addr, UInt bias )
196795448075345dc73986042f6dc68eb464d02bc6a8sewardj{
196895448075345dc73986042f6dc68eb464d02bc6a8sewardj   void*    helper;
196995448075345dc73986042f6dc68eb464d02bc6a8sewardj   Char*    hname;
197095448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRDirty* di;
197195448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRTemp   datavbits;
197295448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom*  addrAct;
197395448075345dc73986042f6dc68eb464d02bc6a8sewardj
197495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,addr));
19752e595858903b80f29f271dc94e32a9e052bb4c8asewardj   tl_assert(end == Iend_LE || end == Iend_BE);
197695448075345dc73986042f6dc68eb464d02bc6a8sewardj
197795448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* First, emit a definedness test for the address.  This also sets
197895448075345dc73986042f6dc68eb464d02bc6a8sewardj      the address (shadow) to 'defined' following the test. */
197995448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined( mce, addr );
198095448075345dc73986042f6dc68eb464d02bc6a8sewardj
198195448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Now cook up a call to the relevant helper function, to read the
198295448075345dc73986042f6dc68eb464d02bc6a8sewardj      data V bits from shadow memory. */
198395448075345dc73986042f6dc68eb464d02bc6a8sewardj   ty = shadowType(ty);
19842e595858903b80f29f271dc94e32a9e052bb4c8asewardj
19852e595858903b80f29f271dc94e32a9e052bb4c8asewardj   if (end == Iend_LE) {
19862e595858903b80f29f271dc94e32a9e052bb4c8asewardj      switch (ty) {
19872e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I64: helper = &MC_(helperc_LOADV8le);
19882e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_LOADV8le)";
19892e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
19902e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I32: helper = &MC_(helperc_LOADV4le);
19912e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_LOADV4le)";
19922e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
19932e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I16: helper = &MC_(helperc_LOADV2le);
19942e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_LOADV2le)";
19952e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
19968cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I8:  helper = &MC_(helperc_LOADV1);
19978cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_LOADV1)";
19982e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
19992e595858903b80f29f271dc94e32a9e052bb4c8asewardj         default:      ppIRType(ty);
20002e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       VG_(tool_panic)("memcheck:do_shadow_Load(LE)");
20012e595858903b80f29f271dc94e32a9e052bb4c8asewardj      }
20022e595858903b80f29f271dc94e32a9e052bb4c8asewardj   } else {
20038cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj      switch (ty) {
20048cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I64: helper = &MC_(helperc_LOADV8be);
20058cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_LOADV8be)";
20068cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
20078cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I32: helper = &MC_(helperc_LOADV4be);
20088cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_LOADV4be)";
20098cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
20108cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I16: helper = &MC_(helperc_LOADV2be);
20118cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_LOADV2be)";
20128cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
20138cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I8:  helper = &MC_(helperc_LOADV1);
20148cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_LOADV1)";
20158cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
20168cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         default:      ppIRType(ty);
20178cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       VG_(tool_panic)("memcheck:do_shadow_Load(BE)");
20188cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj      }
201995448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2020e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
202195448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Generate the actual address into addrAct. */
202295448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (bias == 0) {
202395448075345dc73986042f6dc68eb464d02bc6a8sewardj      addrAct = addr;
202495448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
20257cf97ee841afd255879bff9ff791fbabb7f95cecsewardj      IROp    mkAdd;
20267cf97ee841afd255879bff9ff791fbabb7f95cecsewardj      IRAtom* eBias;
202795448075345dc73986042f6dc68eb464d02bc6a8sewardj      IRType  tyAddr  = mce->hWordTy;
202895448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
20297cf97ee841afd255879bff9ff791fbabb7f95cecsewardj      mkAdd   = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
20307cf97ee841afd255879bff9ff791fbabb7f95cecsewardj      eBias   = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
203195448075345dc73986042f6dc68eb464d02bc6a8sewardj      addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
203295448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2033e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
203495448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* We need to have a place to park the V bits we're just about to
203595448075345dc73986042f6dc68eb464d02bc6a8sewardj      read. */
203695448075345dc73986042f6dc68eb464d02bc6a8sewardj   datavbits = newIRTemp(mce->bb->tyenv, ty);
203795448075345dc73986042f6dc68eb464d02bc6a8sewardj   di = unsafeIRDirty_1_N( datavbits,
203895448075345dc73986042f6dc68eb464d02bc6a8sewardj                           1/*regparms*/, hname, helper,
203995448075345dc73986042f6dc68eb464d02bc6a8sewardj                           mkIRExprVec_1( addrAct ));
204095448075345dc73986042f6dc68eb464d02bc6a8sewardj   setHelperAnns( mce, di );
204195448075345dc73986042f6dc68eb464d02bc6a8sewardj   stmt( mce->bb, IRStmt_Dirty(di) );
2042e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
204395448075345dc73986042f6dc68eb464d02bc6a8sewardj   return mkexpr(datavbits);
204495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2045e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2046e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
204795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
20482e595858903b80f29f271dc94e32a9e052bb4c8asewardjIRAtom* expr2vbits_Load ( MCEnv* mce,
20492e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          IREndness end, IRType ty,
20502e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          IRAtom* addr, UInt bias )
2051170ee210842367a5cc52390358ba560774f76329sewardj{
2052170ee210842367a5cc52390358ba560774f76329sewardj   IRAtom *v64hi, *v64lo;
20532e595858903b80f29f271dc94e32a9e052bb4c8asewardj   tl_assert(end == Iend_LE || end == Iend_BE);
2054170ee210842367a5cc52390358ba560774f76329sewardj   switch (shadowType(ty)) {
2055170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I8:
2056170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I16:
2057170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I32:
2058170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_I64:
20592e595858903b80f29f271dc94e32a9e052bb4c8asewardj         return expr2vbits_Load_WRK(mce, end, ty, addr, bias);
2060170ee210842367a5cc52390358ba560774f76329sewardj      case Ity_V128:
20612e595858903b80f29f271dc94e32a9e052bb4c8asewardj         if (end == Iend_LE) {
20622e595858903b80f29f271dc94e32a9e052bb4c8asewardj            v64lo = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias);
20632e595858903b80f29f271dc94e32a9e052bb4c8asewardj            v64hi = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias+8);
20642e595858903b80f29f271dc94e32a9e052bb4c8asewardj         } else {
20652e595858903b80f29f271dc94e32a9e052bb4c8asewardj            v64hi = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias);
20662e595858903b80f29f271dc94e32a9e052bb4c8asewardj            v64lo = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias+8);
20672e595858903b80f29f271dc94e32a9e052bb4c8asewardj         }
2068170ee210842367a5cc52390358ba560774f76329sewardj         return assignNew( mce,
2069170ee210842367a5cc52390358ba560774f76329sewardj                           Ity_V128,
207020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj                           binop(Iop_64HLtoV128, v64hi, v64lo));
2071170ee210842367a5cc52390358ba560774f76329sewardj      default:
20722e595858903b80f29f271dc94e32a9e052bb4c8asewardj         VG_(tool_panic)("expr2vbits_Load");
2073170ee210842367a5cc52390358ba560774f76329sewardj   }
2074170ee210842367a5cc52390358ba560774f76329sewardj}
2075170ee210842367a5cc52390358ba560774f76329sewardj
2076170ee210842367a5cc52390358ba560774f76329sewardj
2077170ee210842367a5cc52390358ba560774f76329sewardjstatic
207895448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* expr2vbits_Mux0X ( MCEnv* mce,
207995448075345dc73986042f6dc68eb464d02bc6a8sewardj                           IRAtom* cond, IRAtom* expr0, IRAtom* exprX )
208095448075345dc73986042f6dc68eb464d02bc6a8sewardj{
208195448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRAtom *vbitsC, *vbits0, *vbitsX;
208295448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRType ty;
208395448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Given Mux0X(cond,expr0,exprX), generate
208495448075345dc73986042f6dc68eb464d02bc6a8sewardj         Mux0X(cond,expr0#,exprX#) `UifU` PCast(cond#)
208595448075345dc73986042f6dc68eb464d02bc6a8sewardj      That is, steer the V bits like the originals, but trash the
208695448075345dc73986042f6dc68eb464d02bc6a8sewardj      result if the steering value is undefined.  This gives
208795448075345dc73986042f6dc68eb464d02bc6a8sewardj      lazy propagation. */
208895448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, cond));
208995448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, expr0));
209095448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce, exprX));
209195448075345dc73986042f6dc68eb464d02bc6a8sewardj
209295448075345dc73986042f6dc68eb464d02bc6a8sewardj   vbitsC = expr2vbits(mce, cond);
209395448075345dc73986042f6dc68eb464d02bc6a8sewardj   vbits0 = expr2vbits(mce, expr0);
209495448075345dc73986042f6dc68eb464d02bc6a8sewardj   vbitsX = expr2vbits(mce, exprX);
209595448075345dc73986042f6dc68eb464d02bc6a8sewardj   ty = typeOfIRExpr(mce->bb->tyenv, vbits0);
209695448075345dc73986042f6dc68eb464d02bc6a8sewardj
209795448075345dc73986042f6dc68eb464d02bc6a8sewardj   return
209895448075345dc73986042f6dc68eb464d02bc6a8sewardj      mkUifU(mce, ty, assignNew(mce, ty, IRExpr_Mux0X(cond, vbits0, vbitsX)),
209995448075345dc73986042f6dc68eb464d02bc6a8sewardj                      mkPCastTo(mce, ty, vbitsC) );
210095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
210195448075345dc73986042f6dc68eb464d02bc6a8sewardj
210295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- This is the main expression-handling function. --------- */
2103e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
210495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
210595448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* expr2vbits ( MCEnv* mce, IRExpr* e )
210695448075345dc73986042f6dc68eb464d02bc6a8sewardj{
210795448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (e->tag) {
2108e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
210995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Get:
211095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty );
2111e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
211295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_GetI:
211395448075345dc73986042f6dc68eb464d02bc6a8sewardj         return shadow_GETI( mce, e->Iex.GetI.descr,
211495448075345dc73986042f6dc68eb464d02bc6a8sewardj                                  e->Iex.GetI.ix, e->Iex.GetI.bias );
2115e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
211695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Tmp:
211795448075345dc73986042f6dc68eb464d02bc6a8sewardj         return IRExpr_Tmp( findShadowTmp(mce, e->Iex.Tmp.tmp) );
2118e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
211995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Const:
212095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)));
2121e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
212295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Binop:
212395448075345dc73986042f6dc68eb464d02bc6a8sewardj         return expr2vbits_Binop(
212495448075345dc73986042f6dc68eb464d02bc6a8sewardj                   mce,
212595448075345dc73986042f6dc68eb464d02bc6a8sewardj                   e->Iex.Binop.op,
212695448075345dc73986042f6dc68eb464d02bc6a8sewardj                   e->Iex.Binop.arg1, e->Iex.Binop.arg2
212795448075345dc73986042f6dc68eb464d02bc6a8sewardj                );
2128e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
212995448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Unop:
213095448075345dc73986042f6dc68eb464d02bc6a8sewardj         return expr2vbits_Unop( mce, e->Iex.Unop.op, e->Iex.Unop.arg );
213196b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes
21322e595858903b80f29f271dc94e32a9e052bb4c8asewardj      case Iex_Load:
21332e595858903b80f29f271dc94e32a9e052bb4c8asewardj         return expr2vbits_Load( mce, e->Iex.Load.end,
21342e595858903b80f29f271dc94e32a9e052bb4c8asewardj                                      e->Iex.Load.ty,
21352e595858903b80f29f271dc94e32a9e052bb4c8asewardj                                      e->Iex.Load.addr, 0/*addr bias*/ );
213696b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes
213795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_CCall:
213895448075345dc73986042f6dc68eb464d02bc6a8sewardj         return mkLazyN( mce, e->Iex.CCall.args,
213995448075345dc73986042f6dc68eb464d02bc6a8sewardj                              e->Iex.CCall.retty,
214095448075345dc73986042f6dc68eb464d02bc6a8sewardj                              e->Iex.CCall.cee );
214196b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes
214295448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Iex_Mux0X:
214395448075345dc73986042f6dc68eb464d02bc6a8sewardj         return expr2vbits_Mux0X( mce, e->Iex.Mux0X.cond, e->Iex.Mux0X.expr0,
214495448075345dc73986042f6dc68eb464d02bc6a8sewardj                                       e->Iex.Mux0X.exprX);
214596b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes
214695448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
214795448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n");
214895448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIRExpr(e);
214995448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n");
215095448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("memcheck: expr2vbits");
215195448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
215295448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2153b6d9b5426120bb87736591d22376e94355130bfbdaywalker
215495448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
215595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generate shadow stmts from all kinds of IRStmts.     ---*/
215695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
2157b11168575af550e72048e09e1f372eeb13a32be6sewardj
215895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Widen a value to the host word size. */
2159e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
216095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
216195448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* zwidenToHostWord ( MCEnv* mce, IRAtom* vatom )
216295448075345dc73986042f6dc68eb464d02bc6a8sewardj{
21637cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   IRType ty, tyH;
21647cf97ee841afd255879bff9ff791fbabb7f95cecsewardj
216595448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* vatom is vbits-value and as such can only have a shadow type. */
216695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,vatom));
216795448075345dc73986042f6dc68eb464d02bc6a8sewardj
21687cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   ty  = typeOfIRExpr(mce->bb->tyenv, vatom);
21697cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   tyH = mce->hWordTy;
217095448075345dc73986042f6dc68eb464d02bc6a8sewardj
217195448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (tyH == Ity_I32) {
217295448075345dc73986042f6dc68eb464d02bc6a8sewardj      switch (ty) {
217395448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ity_I32: return vatom;
217495448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ity_I16: return assignNew(mce, tyH, unop(Iop_16Uto32, vatom));
217595448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ity_I8:  return assignNew(mce, tyH, unop(Iop_8Uto32, vatom));
217695448075345dc73986042f6dc68eb464d02bc6a8sewardj         default:      goto unhandled;
217795448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
21786cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   } else
21796cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   if (tyH == Ity_I64) {
21806cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      switch (ty) {
21816cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj         case Ity_I32: return assignNew(mce, tyH, unop(Iop_32Uto64, vatom));
218269a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         case Ity_I16: return assignNew(mce, tyH, unop(Iop_32Uto64,
218369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj                              assignNew(mce, Ity_I32, unop(Iop_16Uto32, vatom))));
218469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj         case Ity_I8:  return assignNew(mce, tyH, unop(Iop_32Uto64,
218569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj                              assignNew(mce, Ity_I32, unop(Iop_8Uto32, vatom))));
21866cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj         default:      goto unhandled;
21876cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj      }
218895448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
218995448075345dc73986042f6dc68eb464d02bc6a8sewardj      goto unhandled;
219095448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
219195448075345dc73986042f6dc68eb464d02bc6a8sewardj  unhandled:
219295448075345dc73986042f6dc68eb464d02bc6a8sewardj   VG_(printf)("\nty = "); ppIRType(ty); VG_(printf)("\n");
219395448075345dc73986042f6dc68eb464d02bc6a8sewardj   VG_(tool_panic)("zwidenToHostWord");
219495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2195901a4a946376b70c7c87f750dc3eef44e78032besewardj
21963d7c9c8c2e4882c787a9b63befe095785f3d5d07sewardj
219795448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Generate a shadow store.  addr is always the original address atom.
219895448075345dc73986042f6dc68eb464d02bc6a8sewardj   You can pass in either originals or V-bits for the data atom, but
219995448075345dc73986042f6dc68eb464d02bc6a8sewardj   obviously not both.  */
2200e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
220195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
22022e595858903b80f29f271dc94e32a9e052bb4c8asewardjvoid do_shadow_Store ( MCEnv* mce,
22032e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       IREndness end,
22042e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       IRAtom* addr, UInt bias,
22052e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       IRAtom* data, IRAtom* vdata )
220695448075345dc73986042f6dc68eb464d02bc6a8sewardj{
2207170ee210842367a5cc52390358ba560774f76329sewardj   IROp     mkAdd;
2208170ee210842367a5cc52390358ba560774f76329sewardj   IRType   ty, tyAddr;
2209170ee210842367a5cc52390358ba560774f76329sewardj   IRDirty  *di, *diLo64, *diHi64;
2210170ee210842367a5cc52390358ba560774f76329sewardj   IRAtom   *addrAct, *addrLo64, *addrHi64;
2211170ee210842367a5cc52390358ba560774f76329sewardj   IRAtom   *vdataLo64, *vdataHi64;
22122e595858903b80f29f271dc94e32a9e052bb4c8asewardj   IRAtom   *eBias, *eBiasLo64, *eBiasHi64;
221395448075345dc73986042f6dc68eb464d02bc6a8sewardj   void*    helper = NULL;
221495448075345dc73986042f6dc68eb464d02bc6a8sewardj   Char*    hname = NULL;
2215170ee210842367a5cc52390358ba560774f76329sewardj
2216170ee210842367a5cc52390358ba560774f76329sewardj   tyAddr = mce->hWordTy;
2217170ee210842367a5cc52390358ba560774f76329sewardj   mkAdd  = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
2218170ee210842367a5cc52390358ba560774f76329sewardj   tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
22192e595858903b80f29f271dc94e32a9e052bb4c8asewardj   tl_assert( end == Iend_LE || end == Iend_BE );
2220170ee210842367a5cc52390358ba560774f76329sewardj
2221170ee210842367a5cc52390358ba560774f76329sewardj   di = diLo64 = diHi64 = NULL;
22222e595858903b80f29f271dc94e32a9e052bb4c8asewardj   eBias = eBiasLo64 = eBiasHi64 = NULL;
2223170ee210842367a5cc52390358ba560774f76329sewardj   addrAct = addrLo64 = addrHi64 = NULL;
2224170ee210842367a5cc52390358ba560774f76329sewardj   vdataLo64 = vdataHi64 = NULL;
222595448075345dc73986042f6dc68eb464d02bc6a8sewardj
222695448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (data) {
222795448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(!vdata);
222895448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(isOriginalAtom(mce, data));
222995448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(bias == 0);
223095448075345dc73986042f6dc68eb464d02bc6a8sewardj      vdata = expr2vbits( mce, data );
223195448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
223295448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(vdata);
223395448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2234e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
223595448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isOriginalAtom(mce,addr));
223695448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(isShadowAtom(mce,vdata));
223795448075345dc73986042f6dc68eb464d02bc6a8sewardj
223895448075345dc73986042f6dc68eb464d02bc6a8sewardj   ty = typeOfIRExpr(mce->bb->tyenv, vdata);
223995448075345dc73986042f6dc68eb464d02bc6a8sewardj
224095448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* First, emit a definedness test for the address.  This also sets
224195448075345dc73986042f6dc68eb464d02bc6a8sewardj      the address (shadow) to 'defined' following the test. */
224295448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined( mce, addr );
224395448075345dc73986042f6dc68eb464d02bc6a8sewardj
2244170ee210842367a5cc52390358ba560774f76329sewardj   /* Now decide which helper function to call to write the data V
2245170ee210842367a5cc52390358ba560774f76329sewardj      bits into shadow memory. */
22462e595858903b80f29f271dc94e32a9e052bb4c8asewardj   if (end == Iend_LE) {
22472e595858903b80f29f271dc94e32a9e052bb4c8asewardj      switch (ty) {
22482e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_V128: /* we'll use the helper twice */
22492e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I64: helper = &MC_(helperc_STOREV8le);
22502e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_STOREV8le)";
22512e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
22522e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I32: helper = &MC_(helperc_STOREV4le);
22532e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_STOREV4le)";
22542e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
22552e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ity_I16: helper = &MC_(helperc_STOREV2le);
22562e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       hname = "MC_(helperc_STOREV2le)";
22572e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
22588cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I8:  helper = &MC_(helperc_STOREV1);
22598cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_STOREV1)";
22602e595858903b80f29f271dc94e32a9e052bb4c8asewardj                       break;
22612e595858903b80f29f271dc94e32a9e052bb4c8asewardj         default:      VG_(tool_panic)("memcheck:do_shadow_Store(LE)");
22622e595858903b80f29f271dc94e32a9e052bb4c8asewardj      }
22632e595858903b80f29f271dc94e32a9e052bb4c8asewardj   } else {
22648cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj      switch (ty) {
22658cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_V128: /* we'll use the helper twice */
22668cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I64: helper = &MC_(helperc_STOREV8be);
22678cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_STOREV8be)";
22688cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
22698cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I32: helper = &MC_(helperc_STOREV4be);
22708cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_STOREV4be)";
22718cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
22728cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I16: helper = &MC_(helperc_STOREV2be);
22738cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_STOREV2be)";
22748cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
22758cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         case Ity_I8:  helper = &MC_(helperc_STOREV1);
22768cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       hname = "MC_(helperc_STOREV1)";
22778cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj                       break;
22788cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj         default:      VG_(tool_panic)("memcheck:do_shadow_Store(BE)");
22798cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj      }
228095448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
228195448075345dc73986042f6dc68eb464d02bc6a8sewardj
2282170ee210842367a5cc52390358ba560774f76329sewardj   if (ty == Ity_V128) {
2283170ee210842367a5cc52390358ba560774f76329sewardj
228420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      /* V128-bit case */
2285170ee210842367a5cc52390358ba560774f76329sewardj      /* See comment in next clause re 64-bit regparms */
22862e595858903b80f29f271dc94e32a9e052bb4c8asewardj      /* also, need to be careful about endianness */
22872e595858903b80f29f271dc94e32a9e052bb4c8asewardj
22882e595858903b80f29f271dc94e32a9e052bb4c8asewardj      Int offLo64, offHi64;
22892e595858903b80f29f271dc94e32a9e052bb4c8asewardj      if (end == Iend_LE) {
22902e595858903b80f29f271dc94e32a9e052bb4c8asewardj         offLo64 = 0;
22912e595858903b80f29f271dc94e32a9e052bb4c8asewardj         offHi64 = 8;
22922e595858903b80f29f271dc94e32a9e052bb4c8asewardj      } else {
22932e595858903b80f29f271dc94e32a9e052bb4c8asewardj         offLo64 = 8;
22942e595858903b80f29f271dc94e32a9e052bb4c8asewardj         offHi64 = 0;
22952e595858903b80f29f271dc94e32a9e052bb4c8asewardj      }
22962e595858903b80f29f271dc94e32a9e052bb4c8asewardj
22972e595858903b80f29f271dc94e32a9e052bb4c8asewardj      eBiasLo64 = tyAddr==Ity_I32 ? mkU32(bias+offLo64) : mkU64(bias+offLo64);
22982e595858903b80f29f271dc94e32a9e052bb4c8asewardj      addrLo64  = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasLo64) );
229920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      vdataLo64 = assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata));
2300170ee210842367a5cc52390358ba560774f76329sewardj      diLo64    = unsafeIRDirty_0_N(
2301170ee210842367a5cc52390358ba560774f76329sewardj                     1/*regparms*/, hname, helper,
2302170ee210842367a5cc52390358ba560774f76329sewardj                     mkIRExprVec_2( addrLo64, vdataLo64 ));
2303170ee210842367a5cc52390358ba560774f76329sewardj
23042e595858903b80f29f271dc94e32a9e052bb4c8asewardj      eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64);
23052e595858903b80f29f271dc94e32a9e052bb4c8asewardj      addrHi64  = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasHi64) );
230620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj      vdataHi64 = assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata));
2307170ee210842367a5cc52390358ba560774f76329sewardj      diHi64    = unsafeIRDirty_0_N(
2308170ee210842367a5cc52390358ba560774f76329sewardj                     1/*regparms*/, hname, helper,
2309170ee210842367a5cc52390358ba560774f76329sewardj                     mkIRExprVec_2( addrHi64, vdataHi64 ));
2310170ee210842367a5cc52390358ba560774f76329sewardj
2311170ee210842367a5cc52390358ba560774f76329sewardj      setHelperAnns( mce, diLo64 );
2312170ee210842367a5cc52390358ba560774f76329sewardj      setHelperAnns( mce, diHi64 );
2313170ee210842367a5cc52390358ba560774f76329sewardj      stmt( mce->bb, IRStmt_Dirty(diLo64) );
2314170ee210842367a5cc52390358ba560774f76329sewardj      stmt( mce->bb, IRStmt_Dirty(diHi64) );
2315e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
231695448075345dc73986042f6dc68eb464d02bc6a8sewardj   } else {
2317170ee210842367a5cc52390358ba560774f76329sewardj
2318170ee210842367a5cc52390358ba560774f76329sewardj      /* 8/16/32/64-bit cases */
2319170ee210842367a5cc52390358ba560774f76329sewardj      /* Generate the actual address into addrAct. */
2320170ee210842367a5cc52390358ba560774f76329sewardj      if (bias == 0) {
2321170ee210842367a5cc52390358ba560774f76329sewardj         addrAct = addr;
2322170ee210842367a5cc52390358ba560774f76329sewardj      } else {
2323170ee210842367a5cc52390358ba560774f76329sewardj         eBias   = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
2324170ee210842367a5cc52390358ba560774f76329sewardj         addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
2325170ee210842367a5cc52390358ba560774f76329sewardj      }
2326170ee210842367a5cc52390358ba560774f76329sewardj
2327170ee210842367a5cc52390358ba560774f76329sewardj      if (ty == Ity_I64) {
2328170ee210842367a5cc52390358ba560774f76329sewardj         /* We can't do this with regparm 2 on 32-bit platforms, since
2329170ee210842367a5cc52390358ba560774f76329sewardj            the back ends aren't clever enough to handle 64-bit
2330170ee210842367a5cc52390358ba560774f76329sewardj            regparm args.  Therefore be different. */
2331170ee210842367a5cc52390358ba560774f76329sewardj         di = unsafeIRDirty_0_N(
2332170ee210842367a5cc52390358ba560774f76329sewardj                 1/*regparms*/, hname, helper,
2333170ee210842367a5cc52390358ba560774f76329sewardj                 mkIRExprVec_2( addrAct, vdata ));
2334170ee210842367a5cc52390358ba560774f76329sewardj      } else {
2335170ee210842367a5cc52390358ba560774f76329sewardj         di = unsafeIRDirty_0_N(
2336170ee210842367a5cc52390358ba560774f76329sewardj                 2/*regparms*/, hname, helper,
2337170ee210842367a5cc52390358ba560774f76329sewardj                 mkIRExprVec_2( addrAct,
2338170ee210842367a5cc52390358ba560774f76329sewardj                                zwidenToHostWord( mce, vdata )));
2339170ee210842367a5cc52390358ba560774f76329sewardj      }
2340170ee210842367a5cc52390358ba560774f76329sewardj      setHelperAnns( mce, di );
2341170ee210842367a5cc52390358ba560774f76329sewardj      stmt( mce->bb, IRStmt_Dirty(di) );
234295448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2343170ee210842367a5cc52390358ba560774f76329sewardj
2344e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
2345e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2346e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
234795448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Do lazy pessimistic propagation through a dirty helper call, by
234895448075345dc73986042f6dc68eb464d02bc6a8sewardj   looking at the annotations on it.  This is the most complex part of
234995448075345dc73986042f6dc68eb464d02bc6a8sewardj   Memcheck. */
2350e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
235195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRType szToITy ( Int n )
235295448075345dc73986042f6dc68eb464d02bc6a8sewardj{
235395448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (n) {
235495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 1: return Ity_I8;
235595448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 2: return Ity_I16;
235695448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 4: return Ity_I32;
235795448075345dc73986042f6dc68eb464d02bc6a8sewardj      case 8: return Ity_I64;
235895448075345dc73986042f6dc68eb464d02bc6a8sewardj      default: VG_(tool_panic)("szToITy(memcheck)");
235995448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
236095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2361e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
236295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic
236395448075345dc73986042f6dc68eb464d02bc6a8sewardjvoid do_shadow_Dirty ( MCEnv* mce, IRDirty* d )
236495448075345dc73986042f6dc68eb464d02bc6a8sewardj{
23652e595858903b80f29f271dc94e32a9e052bb4c8asewardj   Int       i, n, offset, toDo, gSz, gOff;
23662e595858903b80f29f271dc94e32a9e052bb4c8asewardj   IRAtom    *src, *here, *curr;
23672e595858903b80f29f271dc94e32a9e052bb4c8asewardj   IRType    tyAddr, tySrc, tyDst;
23682e595858903b80f29f271dc94e32a9e052bb4c8asewardj   IRTemp    dst;
23692e595858903b80f29f271dc94e32a9e052bb4c8asewardj   IREndness end;
23702e595858903b80f29f271dc94e32a9e052bb4c8asewardj
23712e595858903b80f29f271dc94e32a9e052bb4c8asewardj   /* What's the native endianness?  We need to know this. */
23726e340c7a2c09971ac5ead854c40bbc0491b67636sewardj#  if defined(VG_BIGENDIAN)
23732e595858903b80f29f271dc94e32a9e052bb4c8asewardj   end = Iend_BE;
23746e340c7a2c09971ac5ead854c40bbc0491b67636sewardj#  elif defined(VG_LITTLEENDIAN)
23752e595858903b80f29f271dc94e32a9e052bb4c8asewardj   end = Iend_LE;
23762e595858903b80f29f271dc94e32a9e052bb4c8asewardj#  else
23772e595858903b80f29f271dc94e32a9e052bb4c8asewardj#    error "Unknown endianness"
23782e595858903b80f29f271dc94e32a9e052bb4c8asewardj#  endif
237995448075345dc73986042f6dc68eb464d02bc6a8sewardj
238095448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* First check the guard. */
238195448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined(mce, d->guard);
238295448075345dc73986042f6dc68eb464d02bc6a8sewardj
238395448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Now round up all inputs and PCast over them. */
23847cf97ee841afd255879bff9ff791fbabb7f95cecsewardj   curr = definedOfType(Ity_I32);
238595448075345dc73986042f6dc68eb464d02bc6a8sewardj
238695448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Inputs: unmasked args */
238795448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; d->args[i]; i++) {
238895448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (d->cee->mcx_mask & (1<<i)) {
238995448075345dc73986042f6dc68eb464d02bc6a8sewardj         /* ignore this arg */
239095448075345dc73986042f6dc68eb464d02bc6a8sewardj      } else {
239195448075345dc73986042f6dc68eb464d02bc6a8sewardj         here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, d->args[i]) );
239295448075345dc73986042f6dc68eb464d02bc6a8sewardj         curr = mkUifU32(mce, here, curr);
239395448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
239495448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2395e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
239695448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Inputs: guest state that we read. */
239795448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; i < d->nFxState; i++) {
239895448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(d->fxState[i].fx != Ifx_None);
239995448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (d->fxState[i].fx == Ifx_Write)
240095448075345dc73986042f6dc68eb464d02bc6a8sewardj         continue;
2401a72032508d826f53df7e1211327f5321d9fba56fsewardj
2402a72032508d826f53df7e1211327f5321d9fba56fsewardj      /* Ignore any sections marked as 'always defined'. */
2403a72032508d826f53df7e1211327f5321d9fba56fsewardj      if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) {
2404e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         if (0)
2405a72032508d826f53df7e1211327f5321d9fba56fsewardj         VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n",
2406a72032508d826f53df7e1211327f5321d9fba56fsewardj                     d->fxState[i].offset, d->fxState[i].size );
2407a72032508d826f53df7e1211327f5321d9fba56fsewardj         continue;
2408a72032508d826f53df7e1211327f5321d9fba56fsewardj      }
2409a72032508d826f53df7e1211327f5321d9fba56fsewardj
241095448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* This state element is read or modified.  So we need to
2411e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         consider it.  If larger than 8 bytes, deal with it in 8-byte
2412e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         chunks. */
2413e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      gSz  = d->fxState[i].size;
2414e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      gOff = d->fxState[i].offset;
2415e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      tl_assert(gSz > 0);
2416e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      while (True) {
2417e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         if (gSz == 0) break;
2418e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         n = gSz <= 8 ? gSz : 8;
2419e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         /* update 'curr' with UifU of the state slice
2420e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj            gOff .. gOff+n-1 */
2421e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         tySrc = szToITy( n );
2422e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         src   = assignNew( mce, tySrc,
2423e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj                            shadow_GET(mce, gOff, tySrc ) );
2424e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         here = mkPCastTo( mce, Ity_I32, src );
2425e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         curr = mkUifU32(mce, here, curr);
2426e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         gSz -= n;
2427e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         gOff += n;
2428e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      }
2429e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj
243095448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2431e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
243295448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Inputs: memory.  First set up some info needed regardless of
243395448075345dc73986042f6dc68eb464d02bc6a8sewardj      whether we're doing reads or writes. */
243495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tyAddr = Ity_INVALID;
243595448075345dc73986042f6dc68eb464d02bc6a8sewardj
243695448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (d->mFx != Ifx_None) {
243795448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* Because we may do multiple shadow loads/stores from the same
243895448075345dc73986042f6dc68eb464d02bc6a8sewardj         base address, it's best to do a single test of its
243995448075345dc73986042f6dc68eb464d02bc6a8sewardj         definedness right now.  Post-instrumentation optimisation
244095448075345dc73986042f6dc68eb464d02bc6a8sewardj         should remove all but this test. */
244195448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(d->mAddr);
244295448075345dc73986042f6dc68eb464d02bc6a8sewardj      complainIfUndefined(mce, d->mAddr);
244395448075345dc73986042f6dc68eb464d02bc6a8sewardj
244495448075345dc73986042f6dc68eb464d02bc6a8sewardj      tyAddr = typeOfIRExpr(mce->bb->tyenv, d->mAddr);
244595448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
244695448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(tyAddr == mce->hWordTy); /* not really right */
244795448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2448e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
244995448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Deal with memory inputs (reads or modifies) */
245095448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) {
245195448075345dc73986042f6dc68eb464d02bc6a8sewardj      offset = 0;
245295448075345dc73986042f6dc68eb464d02bc6a8sewardj      toDo   = d->mSize;
24532e595858903b80f29f271dc94e32a9e052bb4c8asewardj      /* chew off 32-bit chunks.  We don't care about the endianness
24542e595858903b80f29f271dc94e32a9e052bb4c8asewardj         since it's all going to be condensed down to a single bit,
24552e595858903b80f29f271dc94e32a9e052bb4c8asewardj         but nevertheless choose an endianness which is hopefully
24562e595858903b80f29f271dc94e32a9e052bb4c8asewardj         native to the platform. */
245795448075345dc73986042f6dc68eb464d02bc6a8sewardj      while (toDo >= 4) {
245895448075345dc73986042f6dc68eb464d02bc6a8sewardj         here = mkPCastTo(
245995448075345dc73986042f6dc68eb464d02bc6a8sewardj                   mce, Ity_I32,
24602e595858903b80f29f271dc94e32a9e052bb4c8asewardj                   expr2vbits_Load ( mce, end, Ity_I32,
246195448075345dc73986042f6dc68eb464d02bc6a8sewardj                                     d->mAddr, d->mSize - toDo )
246295448075345dc73986042f6dc68eb464d02bc6a8sewardj                );
246395448075345dc73986042f6dc68eb464d02bc6a8sewardj         curr = mkUifU32(mce, here, curr);
246495448075345dc73986042f6dc68eb464d02bc6a8sewardj         toDo -= 4;
246595448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
246695448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* chew off 16-bit chunks */
246795448075345dc73986042f6dc68eb464d02bc6a8sewardj      while (toDo >= 2) {
246895448075345dc73986042f6dc68eb464d02bc6a8sewardj         here = mkPCastTo(
246995448075345dc73986042f6dc68eb464d02bc6a8sewardj                   mce, Ity_I32,
24702e595858903b80f29f271dc94e32a9e052bb4c8asewardj                   expr2vbits_Load ( mce, end, Ity_I16,
247195448075345dc73986042f6dc68eb464d02bc6a8sewardj                                     d->mAddr, d->mSize - toDo )
247295448075345dc73986042f6dc68eb464d02bc6a8sewardj                );
247395448075345dc73986042f6dc68eb464d02bc6a8sewardj         curr = mkUifU32(mce, here, curr);
247495448075345dc73986042f6dc68eb464d02bc6a8sewardj         toDo -= 2;
247595448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
247695448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(toDo == 0); /* also need to handle 1-byte excess */
247795448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2478e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
247995448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Whew!  So curr is a 32-bit V-value summarising pessimistically
248095448075345dc73986042f6dc68eb464d02bc6a8sewardj      all the inputs to the helper.  Now we need to re-distribute the
248195448075345dc73986042f6dc68eb464d02bc6a8sewardj      results to all destinations. */
2482e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
248395448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Outputs: the destination temporary, if there is one. */
248495448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (d->tmp != IRTemp_INVALID) {
248595448075345dc73986042f6dc68eb464d02bc6a8sewardj      dst   = findShadowTmp(mce, d->tmp);
248695448075345dc73986042f6dc68eb464d02bc6a8sewardj      tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp);
248795448075345dc73986042f6dc68eb464d02bc6a8sewardj      assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) );
248895448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2489e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
249095448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Outputs: guest state that we write or modify. */
249195448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; i < d->nFxState; i++) {
249295448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(d->fxState[i].fx != Ifx_None);
249395448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (d->fxState[i].fx == Ifx_Read)
249495448075345dc73986042f6dc68eb464d02bc6a8sewardj         continue;
2495a72032508d826f53df7e1211327f5321d9fba56fsewardj      /* Ignore any sections marked as 'always defined'. */
2496a72032508d826f53df7e1211327f5321d9fba56fsewardj      if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size ))
2497a72032508d826f53df7e1211327f5321d9fba56fsewardj         continue;
2498e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      /* This state element is written or modified.  So we need to
2499e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         consider it.  If larger than 8 bytes, deal with it in 8-byte
2500e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         chunks. */
2501e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      gSz  = d->fxState[i].size;
2502e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      gOff = d->fxState[i].offset;
2503e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      tl_assert(gSz > 0);
2504e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      while (True) {
2505e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         if (gSz == 0) break;
2506e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         n = gSz <= 8 ? gSz : 8;
2507e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         /* Write suitably-casted 'curr' to the state slice
2508e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj            gOff .. gOff+n-1 */
2509e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         tyDst = szToITy( n );
2510e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         do_shadow_PUT( mce, gOff,
2511e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj                             NULL, /* original atom */
2512e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj                             mkPCastTo( mce, tyDst, curr ) );
2513e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         gSz -= n;
2514e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj         gOff += n;
2515e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj      }
251695448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2517e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
25182e595858903b80f29f271dc94e32a9e052bb4c8asewardj   /* Outputs: memory that we write or modify.  Same comments about
25192e595858903b80f29f271dc94e32a9e052bb4c8asewardj      endianness as above apply. */
252095448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) {
252195448075345dc73986042f6dc68eb464d02bc6a8sewardj      offset = 0;
252295448075345dc73986042f6dc68eb464d02bc6a8sewardj      toDo   = d->mSize;
252395448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* chew off 32-bit chunks */
252495448075345dc73986042f6dc68eb464d02bc6a8sewardj      while (toDo >= 4) {
25252e595858903b80f29f271dc94e32a9e052bb4c8asewardj         do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo,
25262e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          NULL, /* original data */
25272e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          mkPCastTo( mce, Ity_I32, curr ) );
252895448075345dc73986042f6dc68eb464d02bc6a8sewardj         toDo -= 4;
252995448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
253095448075345dc73986042f6dc68eb464d02bc6a8sewardj      /* chew off 16-bit chunks */
253195448075345dc73986042f6dc68eb464d02bc6a8sewardj      while (toDo >= 2) {
25322e595858903b80f29f271dc94e32a9e052bb4c8asewardj         do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo,
25332e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          NULL, /* original data */
25342e595858903b80f29f271dc94e32a9e052bb4c8asewardj                          mkPCastTo( mce, Ity_I16, curr ) );
253595448075345dc73986042f6dc68eb464d02bc6a8sewardj         toDo -= 2;
2536e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      }
253795448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(toDo == 0); /* also need to handle 1-byte excess */
2538e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
2539e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
254095448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2541e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2542826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj/* We have an ABI hint telling us that [base .. base+len-1] is to
2543826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   become undefined ("writable").  Generate code to call a helper to
2544826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   notify the A/V bit machinery of this fact.
2545826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj
2546826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   We call
2547826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len );
2548826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj*/
2549826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardjstatic
2550826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardjvoid do_AbiHint ( MCEnv* mce, IRExpr* base, Int len )
2551826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj{
2552826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   IRDirty* di;
2553826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   di = unsafeIRDirty_0_N(
2554826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj           0/*regparms*/,
2555826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj           "MC_(helperc_MAKE_STACK_UNINIT)",
2556826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj           &MC_(helperc_MAKE_STACK_UNINIT),
2557826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj           mkIRExprVec_2( base, mkIRExpr_HWord( (UInt)len) )
2558826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj        );
2559826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj   stmt( mce->bb, IRStmt_Dirty(di) );
2560826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj}
2561826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj
2562e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
256395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
256495448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Memcheck main                                        ---*/
256595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/
2566e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
256795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isBogusAtom ( IRAtom* at )
2568e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
256995448075345dc73986042f6dc68eb464d02bc6a8sewardj   ULong n = 0;
257095448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRConst* con;
2571710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj   tl_assert(isIRAtom(at));
257295448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (at->tag == Iex_Tmp)
257395448075345dc73986042f6dc68eb464d02bc6a8sewardj      return False;
257495448075345dc73986042f6dc68eb464d02bc6a8sewardj   tl_assert(at->tag == Iex_Const);
257595448075345dc73986042f6dc68eb464d02bc6a8sewardj   con = at->Iex.Const.con;
257695448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (con->tag) {
2577d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_U1:   return False;
2578d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_U8:   n = (ULong)con->Ico.U8; break;
2579d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_U16:  n = (ULong)con->Ico.U16; break;
2580d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_U32:  n = (ULong)con->Ico.U32; break;
2581d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_U64:  n = (ULong)con->Ico.U64; break;
2582d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_F64:  return False;
2583d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_F64i: return False;
2584d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ico_V128: return False;
258595448075345dc73986042f6dc68eb464d02bc6a8sewardj      default: ppIRExpr(at); tl_assert(0);
258695448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
258795448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* VG_(printf)("%llx\n", n); */
258896a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj   return (/*32*/    n == 0xFEFEFEFFULL
258996a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj           /*32*/ || n == 0x80808080ULL
2590d9774d73807c7292c72e1254119d6bd8ded81f15tom           /*64*/ || n == 0xFFFFFFFFFEFEFEFFULL
259196a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj           /*64*/ || n == 0xFEFEFEFEFEFEFEFFULL
2592d9774d73807c7292c72e1254119d6bd8ded81f15tom           /*64*/ || n == 0x0000000000008080ULL
259396a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj           /*64*/ || n == 0x8080808080808080ULL
259496a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj	   /*64*/ || n == 0x0101010101010101ULL
259596a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj          );
259695448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2597e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
259895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st )
259995448075345dc73986042f6dc68eb464d02bc6a8sewardj{
2600d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   Int      i;
2601d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   IRExpr*  e;
2602d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   IRDirty* d;
260395448075345dc73986042f6dc68eb464d02bc6a8sewardj   switch (st->tag) {
260495448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ist_Tmp:
260595448075345dc73986042f6dc68eb464d02bc6a8sewardj         e = st->Ist.Tmp.data;
260695448075345dc73986042f6dc68eb464d02bc6a8sewardj         switch (e->tag) {
260795448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_Get:
260895448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_Tmp:
260995448075345dc73986042f6dc68eb464d02bc6a8sewardj               return False;
2610d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            case Iex_Const:
2611d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj               return isBogusAtom(e);
261295448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_Unop:
261395448075345dc73986042f6dc68eb464d02bc6a8sewardj               return isBogusAtom(e->Iex.Unop.arg);
2614d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            case Iex_GetI:
2615d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj               return isBogusAtom(e->Iex.GetI.ix);
261695448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_Binop:
261795448075345dc73986042f6dc68eb464d02bc6a8sewardj               return isBogusAtom(e->Iex.Binop.arg1)
261895448075345dc73986042f6dc68eb464d02bc6a8sewardj                      || isBogusAtom(e->Iex.Binop.arg2);
261995448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_Mux0X:
262095448075345dc73986042f6dc68eb464d02bc6a8sewardj               return isBogusAtom(e->Iex.Mux0X.cond)
262195448075345dc73986042f6dc68eb464d02bc6a8sewardj                      || isBogusAtom(e->Iex.Mux0X.expr0)
262295448075345dc73986042f6dc68eb464d02bc6a8sewardj                      || isBogusAtom(e->Iex.Mux0X.exprX);
26232e595858903b80f29f271dc94e32a9e052bb4c8asewardj            case Iex_Load:
26242e595858903b80f29f271dc94e32a9e052bb4c8asewardj               return isBogusAtom(e->Iex.Load.addr);
262595448075345dc73986042f6dc68eb464d02bc6a8sewardj            case Iex_CCall:
262695448075345dc73986042f6dc68eb464d02bc6a8sewardj               for (i = 0; e->Iex.CCall.args[i]; i++)
262795448075345dc73986042f6dc68eb464d02bc6a8sewardj                  if (isBogusAtom(e->Iex.CCall.args[i]))
262895448075345dc73986042f6dc68eb464d02bc6a8sewardj                     return True;
262995448075345dc73986042f6dc68eb464d02bc6a8sewardj               return False;
263095448075345dc73986042f6dc68eb464d02bc6a8sewardj            default:
263195448075345dc73986042f6dc68eb464d02bc6a8sewardj               goto unhandled;
263295448075345dc73986042f6dc68eb464d02bc6a8sewardj         }
2633d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ist_Dirty:
2634d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         d = st->Ist.Dirty.details;
2635d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         for (i = 0; d->args[i]; i++)
2636d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            if (isBogusAtom(d->args[i]))
2637d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj               return True;
2638d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         if (d->guard && isBogusAtom(d->guard))
2639d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            return True;
2640d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         if (d->mAddr && isBogusAtom(d->mAddr))
2641d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            return True;
2642d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         return False;
264395448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ist_Put:
264495448075345dc73986042f6dc68eb464d02bc6a8sewardj         return isBogusAtom(st->Ist.Put.data);
2645d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj      case Ist_PutI:
2646d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         return isBogusAtom(st->Ist.PutI.ix)
2647d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj                || isBogusAtom(st->Ist.PutI.data);
26482e595858903b80f29f271dc94e32a9e052bb4c8asewardj      case Ist_Store:
26492e595858903b80f29f271dc94e32a9e052bb4c8asewardj         return isBogusAtom(st->Ist.Store.addr)
26502e595858903b80f29f271dc94e32a9e052bb4c8asewardj                || isBogusAtom(st->Ist.Store.data);
265195448075345dc73986042f6dc68eb464d02bc6a8sewardj      case Ist_Exit:
2652d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj         return isBogusAtom(st->Ist.Exit.guard);
2653826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj      case Ist_AbiHint:
2654826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj         return isBogusAtom(st->Ist.AbiHint.base);
265521dc345ce861ac5a5686391b77659934c1d49a3esewardj      case Ist_NoOp:
265629faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj      case Ist_IMark:
2657bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj      case Ist_MFence:
2658bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj         return False;
265995448075345dc73986042f6dc68eb464d02bc6a8sewardj      default:
266095448075345dc73986042f6dc68eb464d02bc6a8sewardj      unhandled:
266195448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIRStmt(st);
266295448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(tool_panic)("hasBogusLiterals");
266395448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
266495448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2665e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2666e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
266751d827bcd88ce045a383ea1ca81768757df2d1fanjnIRBB* MC_(instrument) ( IRBB* bb_in, VexGuestLayout* layout,
2668d54babf82db303dfe43082bfe1af75d7b58b3267sewardj                        IRType gWordTy, IRType hWordTy )
266995448075345dc73986042f6dc68eb464d02bc6a8sewardj{
2670151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   Bool    verboze = False; //True;
2671151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   Bool    bogus;
2672d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   Int     i, j, first_stmt;
267395448075345dc73986042f6dc68eb464d02bc6a8sewardj   IRStmt* st;
2674d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   MCEnv   mce;
2675d54babf82db303dfe43082bfe1af75d7b58b3267sewardj   IRBB*   bb;
2676d54babf82db303dfe43082bfe1af75d7b58b3267sewardj
2677d54babf82db303dfe43082bfe1af75d7b58b3267sewardj   if (gWordTy != hWordTy) {
2678d54babf82db303dfe43082bfe1af75d7b58b3267sewardj      /* We don't currently support this case. */
2679d54babf82db303dfe43082bfe1af75d7b58b3267sewardj      VG_(tool_panic)("host/guest word size mismatch");
2680d54babf82db303dfe43082bfe1af75d7b58b3267sewardj   }
268195448075345dc73986042f6dc68eb464d02bc6a8sewardj
26826cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   /* Check we're not completely nuts */
26836cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(UWord) == sizeof(void*));
26846cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(Word)  == sizeof(void*));
26856cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(ULong) == 8);
26866cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(Long)  == 8);
26876cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(UInt)  == 4);
26886cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj   tl_assert(sizeof(Int)   == 4);
26896cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj
269095448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Set up BB */
2691d54babf82db303dfe43082bfe1af75d7b58b3267sewardj   bb           = emptyIRBB();
269295448075345dc73986042f6dc68eb464d02bc6a8sewardj   bb->tyenv    = dopyIRTypeEnv(bb_in->tyenv);
269395448075345dc73986042f6dc68eb464d02bc6a8sewardj   bb->next     = dopyIRExpr(bb_in->next);
269495448075345dc73986042f6dc68eb464d02bc6a8sewardj   bb->jumpkind = bb_in->jumpkind;
269595448075345dc73986042f6dc68eb464d02bc6a8sewardj
269695448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Set up the running environment.  Only .bb is modified as we go
269795448075345dc73986042f6dc68eb464d02bc6a8sewardj      along. */
269895448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce.bb             = bb;
269995448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce.layout         = layout;
270095448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce.n_originalTmps = bb->tyenv->types_used;
270195448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce.hWordTy        = hWordTy;
2702d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj   mce.bogusLiterals  = False;
270395448075345dc73986042f6dc68eb464d02bc6a8sewardj   mce.tmpMap         = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
270495448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; i < mce.n_originalTmps; i++)
270595448075345dc73986042f6dc68eb464d02bc6a8sewardj      mce.tmpMap[i] = IRTemp_INVALID;
270695448075345dc73986042f6dc68eb464d02bc6a8sewardj
2707151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   /* Make a preliminary inspection of the statements, to see if there
2708151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      are any dodgy-looking literals.  If there are, we generate
2709151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      extra-detailed (hence extra-expensive) instrumentation in
2710151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      places.  Scan the whole bb even if dodgyness is found earlier,
2711151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      so that the flatness assertion is applied to all stmts. */
2712151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
2713151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   bogus = False;
271495448075345dc73986042f6dc68eb464d02bc6a8sewardj
271595448075345dc73986042f6dc68eb464d02bc6a8sewardj   for (i = 0; i <  bb_in->stmts_used; i++) {
2716151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
271795448075345dc73986042f6dc68eb464d02bc6a8sewardj      st = bb_in->stmts[i];
271821dc345ce861ac5a5686391b77659934c1d49a3esewardj      tl_assert(st);
271995448075345dc73986042f6dc68eb464d02bc6a8sewardj      tl_assert(isFlatIRStmt(st));
272095448075345dc73986042f6dc68eb464d02bc6a8sewardj
2721151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      if (!bogus) {
2722151b90d888b37cc8694684433cbed2ddc5fcd205sewardj         bogus = checkForBogusLiterals(st);
2723151b90d888b37cc8694684433cbed2ddc5fcd205sewardj         if (0 && bogus) {
272495448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("bogus: ");
272595448075345dc73986042f6dc68eb464d02bc6a8sewardj            ppIRStmt(st);
272695448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("\n");
272795448075345dc73986042f6dc68eb464d02bc6a8sewardj         }
272895448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
2729d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj
2730151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   }
2731151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
2732151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   mce.bogusLiterals = bogus;
2733151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
2734151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   /* Iterate over the stmts to generate instrumentation. */
2735151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
2736151b90d888b37cc8694684433cbed2ddc5fcd205sewardj   for (i = 0; i <  bb_in->stmts_used; i++) {
2737151b90d888b37cc8694684433cbed2ddc5fcd205sewardj
2738151b90d888b37cc8694684433cbed2ddc5fcd205sewardj      st = bb_in->stmts[i];
273995448075345dc73986042f6dc68eb464d02bc6a8sewardj      first_stmt = bb->stmts_used;
2740e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
274195448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (verboze) {
274295448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIRStmt(st);
274395448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n\n");
274495448075345dc73986042f6dc68eb464d02bc6a8sewardj      }
2745e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
274629faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj      /* Generate instrumentation code for each stmt ... */
274729faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj
274895448075345dc73986042f6dc68eb464d02bc6a8sewardj      switch (st->tag) {
2749e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
275095448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ist_Tmp:
275195448075345dc73986042f6dc68eb464d02bc6a8sewardj            assign( bb, findShadowTmp(&mce, st->Ist.Tmp.tmp),
275295448075345dc73986042f6dc68eb464d02bc6a8sewardj                        expr2vbits( &mce, st->Ist.Tmp.data) );
2753e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2754e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
275595448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ist_Put:
275695448075345dc73986042f6dc68eb464d02bc6a8sewardj            do_shadow_PUT( &mce,
275795448075345dc73986042f6dc68eb464d02bc6a8sewardj                           st->Ist.Put.offset,
275895448075345dc73986042f6dc68eb464d02bc6a8sewardj                           st->Ist.Put.data,
275995448075345dc73986042f6dc68eb464d02bc6a8sewardj                           NULL /* shadow atom */ );
2760e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2761e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
276295448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ist_PutI:
276395448075345dc73986042f6dc68eb464d02bc6a8sewardj            do_shadow_PUTI( &mce,
276495448075345dc73986042f6dc68eb464d02bc6a8sewardj                            st->Ist.PutI.descr,
276595448075345dc73986042f6dc68eb464d02bc6a8sewardj                            st->Ist.PutI.ix,
276695448075345dc73986042f6dc68eb464d02bc6a8sewardj                            st->Ist.PutI.bias,
276795448075345dc73986042f6dc68eb464d02bc6a8sewardj                            st->Ist.PutI.data );
2768e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2769e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
27702e595858903b80f29f271dc94e32a9e052bb4c8asewardj         case Ist_Store:
27712e595858903b80f29f271dc94e32a9e052bb4c8asewardj            do_shadow_Store( &mce, st->Ist.Store.end,
27722e595858903b80f29f271dc94e32a9e052bb4c8asewardj                                   st->Ist.Store.addr, 0/* addr bias */,
27732e595858903b80f29f271dc94e32a9e052bb4c8asewardj                                   st->Ist.Store.data,
27742e595858903b80f29f271dc94e32a9e052bb4c8asewardj                                   NULL /* shadow data */ );
2775e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2776e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
277795448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ist_Exit:
2778d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj            complainIfUndefined( &mce, st->Ist.Exit.guard );
2779e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2780e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
278121dc345ce861ac5a5686391b77659934c1d49a3esewardj         case Ist_NoOp:
278229faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj         case Ist_IMark:
2783bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj         case Ist_MFence:
2784bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj            break;
2785bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj
278695448075345dc73986042f6dc68eb464d02bc6a8sewardj         case Ist_Dirty:
278795448075345dc73986042f6dc68eb464d02bc6a8sewardj            do_shadow_Dirty( &mce, st->Ist.Dirty.details );
2788e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            break;
2789e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2790826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj         case Ist_AbiHint:
2791826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj            do_AbiHint( &mce, st->Ist.AbiHint.base, st->Ist.AbiHint.len );
2792826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj            break;
2793826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj
2794e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         default:
279595448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("\n");
279695448075345dc73986042f6dc68eb464d02bc6a8sewardj            ppIRStmt(st);
279795448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("\n");
279895448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(tool_panic)("memcheck: unhandled IRStmt");
279995448075345dc73986042f6dc68eb464d02bc6a8sewardj
280095448075345dc73986042f6dc68eb464d02bc6a8sewardj      } /* switch (st->tag) */
280195448075345dc73986042f6dc68eb464d02bc6a8sewardj
280295448075345dc73986042f6dc68eb464d02bc6a8sewardj      if (verboze) {
280395448075345dc73986042f6dc68eb464d02bc6a8sewardj         for (j = first_stmt; j < bb->stmts_used; j++) {
280495448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("   ");
280595448075345dc73986042f6dc68eb464d02bc6a8sewardj            ppIRStmt(bb->stmts[j]);
280695448075345dc73986042f6dc68eb464d02bc6a8sewardj            VG_(printf)("\n");
280795448075345dc73986042f6dc68eb464d02bc6a8sewardj         }
280895448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n");
2809e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      }
281095448075345dc73986042f6dc68eb464d02bc6a8sewardj
281129faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj      /* ... and finally copy the stmt itself to the output. */
281295448075345dc73986042f6dc68eb464d02bc6a8sewardj      addStmtToIRBB(bb, st);
281395448075345dc73986042f6dc68eb464d02bc6a8sewardj
2814e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
2815e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
281695448075345dc73986042f6dc68eb464d02bc6a8sewardj   /* Now we need to complain if the jump target is undefined. */
281795448075345dc73986042f6dc68eb464d02bc6a8sewardj   first_stmt = bb->stmts_used;
2818e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
281995448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (verboze) {
282095448075345dc73986042f6dc68eb464d02bc6a8sewardj      VG_(printf)("bb->next = ");
282195448075345dc73986042f6dc68eb464d02bc6a8sewardj      ppIRExpr(bb->next);
282295448075345dc73986042f6dc68eb464d02bc6a8sewardj      VG_(printf)("\n\n");
282395448075345dc73986042f6dc68eb464d02bc6a8sewardj   }
2824e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
282595448075345dc73986042f6dc68eb464d02bc6a8sewardj   complainIfUndefined( &mce, bb->next );
2826e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
282795448075345dc73986042f6dc68eb464d02bc6a8sewardj   if (verboze) {
282895448075345dc73986042f6dc68eb464d02bc6a8sewardj      for (j = first_stmt; j < bb->stmts_used; j++) {
282995448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("   ");
283095448075345dc73986042f6dc68eb464d02bc6a8sewardj         ppIRStmt(bb->stmts[j]);
283195448075345dc73986042f6dc68eb464d02bc6a8sewardj         VG_(printf)("\n");
2832e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      }
283395448075345dc73986042f6dc68eb464d02bc6a8sewardj      VG_(printf)("\n");
2834e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
2835e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
283695448075345dc73986042f6dc68eb464d02bc6a8sewardj   return bb;
283795448075345dc73986042f6dc68eb464d02bc6a8sewardj}
2838e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
2839e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/
2840cac76cb18577b9c51d331f56e8ea241f6effaf31njn/*--- end                                           mc_translate.c ---*/
2841e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/
2842