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