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 11b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2000-2015 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" 336643e96a72e8530a7c8830c02ffb2fb4aee74c88philippe#include "pub_tool_poolalloc.h" // For mc_include.h 341d0825ff46d57f0ce83c3fa88538a42f67022eeenjn#include "pub_tool_hashtable.h" // For mc_include.h 35132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_tool_libcassert.h" 3636a20fa5f779a0a6fb7b4a90dcaa6376481f1faanjn#include "pub_tool_libcprint.h" 37c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_tool_tooliface.h" 3853ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj#include "pub_tool_machine.h" // VG_(fnptr_to_fnentry) 3981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj#include "pub_tool_xarray.h" 4081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj#include "pub_tool_mallocfree.h" 4181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj#include "pub_tool_libcbase.h" 42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include "mc_include.h" 447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 467ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj/* FIXMEs JRS 2011-June-16. 477ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj 487ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj Check the interpretation for vector narrowing and widening ops, 497ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj particularly the saturating ones. I suspect they are either overly 507ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj pessimistic and/or wrong. 51bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 52bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj Iop_QandSQsh64x2 and friends (vector-by-vector bidirectional 53bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj saturating shifts): the interpretation is overly pessimistic. 54bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj See comments on the relevant cases below for details. 55bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 56bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj Iop_Sh64Sx2 and friends (vector-by-vector bidirectional shifts, 57bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj both rounding and non-rounding variants): ditto 587ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj*/ 597ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj 60992dff97aa9c074f86f831a76367fb55e0541da2sewardj/* This file implements the Memcheck instrumentation, and in 61992dff97aa9c074f86f831a76367fb55e0541da2sewardj particular contains the core of its undefined value detection 62992dff97aa9c074f86f831a76367fb55e0541da2sewardj machinery. For a comprehensive background of the terminology, 63992dff97aa9c074f86f831a76367fb55e0541da2sewardj algorithms and rationale used herein, read: 64992dff97aa9c074f86f831a76367fb55e0541da2sewardj 65992dff97aa9c074f86f831a76367fb55e0541da2sewardj Using Valgrind to detect undefined value errors with 66992dff97aa9c074f86f831a76367fb55e0541da2sewardj bit-precision 67992dff97aa9c074f86f831a76367fb55e0541da2sewardj 68992dff97aa9c074f86f831a76367fb55e0541da2sewardj Julian Seward and Nicholas Nethercote 69992dff97aa9c074f86f831a76367fb55e0541da2sewardj 70992dff97aa9c074f86f831a76367fb55e0541da2sewardj 2005 USENIX Annual Technical Conference (General Track), 71992dff97aa9c074f86f831a76367fb55e0541da2sewardj Anaheim, CA, USA, April 10-15, 2005. 726665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 736665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn ---- 746665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 756665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn Here is as good a place as any to record exactly when V bits are and 766665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn should be checked, why, and what function is responsible. 776665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 786665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 796665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn Memcheck complains when an undefined value is used: 806665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 816665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1. In the condition of a conditional branch. Because it could cause 826665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn incorrect control flow, and thus cause incorrect externally-visible 836665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn behaviour. [mc_translate.c:complainIfUndefined] 846665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 856665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 2. As an argument to a system call, or as the value that specifies 866665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn the system call number. Because it could cause an incorrect 876665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn externally-visible side effect. [mc_translate.c:mc_pre_reg_read] 886665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 896665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 3. As the address in a load or store. Because it could cause an 906665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn incorrect value to be used later, which could cause externally-visible 916665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn behaviour (eg. via incorrect control flow or an incorrect system call 926665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn argument) [complainIfUndefined] 936665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 946665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 4. As the target address of a branch. Because it could cause incorrect 956665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn control flow. [complainIfUndefined] 966665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 976665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 5. As an argument to setenv, unsetenv, or putenv. Because it could put 986665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn an incorrect value into the external environment. 996665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn [mc_replace_strmem.c:VG_WRAP_FUNCTION_ZU(*, *env)] 1006665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1016665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 6. As the index in a GETI or PUTI operation. I'm not sure why... (njn). 1026665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn [complainIfUndefined] 1036665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1046665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 7. As an argument to the VALGRIND_CHECK_MEM_IS_DEFINED and 1056665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn VALGRIND_CHECK_VALUE_IS_DEFINED client requests. Because the user 1066665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn requested it. [in memcheck.h] 1076665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1086665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1096665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn Memcheck also complains, but should not, when an undefined value is used: 1106665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1116665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 8. As the shift value in certain SIMD shift operations (but not in the 1126665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn standard integer shift operations). This inconsistency is due to 1136665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn historical reasons.) [complainIfUndefined] 1146665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1156665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1166665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn Memcheck does not complain, but should, when an undefined value is used: 1176665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1186665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 9. As an input to a client request. Because the client request may 1196665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn affect the visible behaviour -- see bug #144362 for an example 1206665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn involving the malloc replacements in vg_replace_malloc.c and 1216665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn VALGRIND_NON_SIMD_CALL* requests, where an uninitialised argument 1226665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn isn't identified. That bug report also has some info on how to solve 1236665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn the problem. [valgrind.h:VALGRIND_DO_CLIENT_REQUEST] 1246665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1256665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn 1266665ea2a7d2b734965d491bc6bc2e35c1a4a6f8anjn In practice, 1 and 2 account for the vast majority of cases. 127992dff97aa9c074f86f831a76367fb55e0541da2sewardj*/ 128992dff97aa9c074f86f831a76367fb55e0541da2sewardj 129b9e6d244e474c971ea88181de1f83a30057db9dasewardj/* Generation of addr-definedness, addr-validity and 130b9e6d244e474c971ea88181de1f83a30057db9dasewardj guard-definedness checks pertaining to loads and stores (Iex_Load, 131b9e6d244e474c971ea88181de1f83a30057db9dasewardj Ist_Store, IRLoadG, IRStoreG, LLSC, CAS and Dirty memory 132b9e6d244e474c971ea88181de1f83a30057db9dasewardj loads/stores) was re-checked 11 May 2013. */ 133b9e6d244e474c971ea88181de1f83a30057db9dasewardj 13495448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 13595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Forward decls ---*/ 13695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 13795448075345dc73986042f6dc68eb464d02bc6a8sewardj 13895448075345dc73986042f6dc68eb464d02bc6a8sewardjstruct _MCEnv; 13995448075345dc73986042f6dc68eb464d02bc6a8sewardj 1407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRType shadowTypeV ( IRType ty ); 14195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e ); 142afa617b9d5792ae31fc201b3549da3e3288bb37dsewardjstatic IRTemp findShadowTmpB ( struct _MCEnv* mce, IRTemp orig ); 14395448075345dc73986042f6dc68eb464d02bc6a8sewardj 144b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjstatic IRExpr *i128_const_zero(void); 14595448075345dc73986042f6dc68eb464d02bc6a8sewardj 14695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 14795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Memcheck running state, and tmp management. ---*/ 14895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 149e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* Carries info about a particular tmp. The tmp's number is not 1511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj recorded, as this is implied by (equal to) its index in the tmpMap 1521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj in MCEnv. The tmp's type is also not recorded, as this is present 1531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj in MCEnv.sb->tyenv. 1541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj When .kind is Orig, .shadowV and .shadowB may give the identities 1561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj of the temps currently holding the associated definedness (shadowV) 1571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj and origin (shadowB) values, or these may be IRTemp_INVALID if code 1581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj to compute such values has not yet been emitted. 1591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj When .kind is VSh or BSh then the tmp is holds a V- or B- value, 1611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj and so .shadowV and .shadowB must be IRTemp_INVALID, since it is 1621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj illogical for a shadow tmp itself to be shadowed. 1631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj*/ 1641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjtypedef 1651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj enum { Orig=1, VSh=2, BSh=3 } 1661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempKind; 1671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjtypedef 1691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj struct { 1701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempKind kind; 1711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp shadowV; 1721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp shadowB; 1731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 1741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt; 1751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 17795448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Carries around state during memcheck instrumentation. */ 17895448075345dc73986042f6dc68eb464d02bc6a8sewardjtypedef 17995448075345dc73986042f6dc68eb464d02bc6a8sewardj struct _MCEnv { 1800b9d74abd0a663b530d290b2b788ddeda46e5400sewardj /* MODIFIED: the superblock being constructed. IRStmts are 1810b9d74abd0a663b530d290b2b788ddeda46e5400sewardj added. */ 1821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRSB* sb; 1837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Bool trace; 18495448075345dc73986042f6dc68eb464d02bc6a8sewardj 1851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the 1861c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj current kind and possibly shadow temps for each temp in the 1871c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRSB being constructed. Note that it does not contain the 1881c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj type of each tmp. If you want to know the type, look at the 1891c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj relevant entry in sb->tyenv. It follows that at all times 1901c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj during the instrumentation process, the valid indices for 1911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tmpMap and sb->tyenv are identical, being 0 .. N-1 where N is 1921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj total number of Orig, V- and B- temps allocated so far. 1931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj The reason for this strange split (types in one place, all 1951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj other info in another) is that we need the types to be 1961c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj attached to sb so as to make it possible to do 1971c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj "typeOfIRExpr(mce->bb->tyenv, ...)" at various places in the 1981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj instrumentation process. */ 1991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj XArray* /* of TempMapEnt */ tmpMap; 20095448075345dc73986042f6dc68eb464d02bc6a8sewardj 201d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj /* MODIFIED: indicates whether "bogus" literals have so far been 202d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj found. Starts off False, and may change to True. */ 20354eac25a54a255d5deaa228547d2ef145590929bsewardj Bool bogusLiterals; 20454eac25a54a255d5deaa228547d2ef145590929bsewardj 20554eac25a54a255d5deaa228547d2ef145590929bsewardj /* READONLY: indicates whether we should use expensive 20654eac25a54a255d5deaa228547d2ef145590929bsewardj interpretations of integer adds, since unfortunately LLVM 20754eac25a54a255d5deaa228547d2ef145590929bsewardj uses them to do ORs in some circumstances. Defaulted to True 20854eac25a54a255d5deaa228547d2ef145590929bsewardj on MacOS and False everywhere else. */ 20954eac25a54a255d5deaa228547d2ef145590929bsewardj Bool useLLVMworkarounds; 210d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 21195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* READONLY: the guest layout. This indicates which parts of 21295448075345dc73986042f6dc68eb464d02bc6a8sewardj the guest state should be regarded as 'always defined'. */ 2133c0c94777f547bcb5eadbe8cb4328debf0f51875florian const VexGuestLayout* layout; 214634ba77657e28bd4568744eb1dcc0b2cb7108e5esewardj 21595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* READONLY: the host word type. Needed for constructing 21695448075345dc73986042f6dc68eb464d02bc6a8sewardj arguments of type 'HWord' to be passed to helper functions. 21795448075345dc73986042f6dc68eb464d02bc6a8sewardj Ity_I32 or Ity_I64 only. */ 21895448075345dc73986042f6dc68eb464d02bc6a8sewardj IRType hWordTy; 219e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 22095448075345dc73986042f6dc68eb464d02bc6a8sewardj MCEnv; 22195448075345dc73986042f6dc68eb464d02bc6a8sewardj 22295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on 22395448075345dc73986042f6dc68eb464d02bc6a8sewardj demand), as they are encountered. This is for two reasons. 22495448075345dc73986042f6dc68eb464d02bc6a8sewardj 22595448075345dc73986042f6dc68eb464d02bc6a8sewardj (1) (less important reason): Many original tmps are unused due to 22695448075345dc73986042f6dc68eb464d02bc6a8sewardj initial IR optimisation, and we do not want to spaces in tables 22795448075345dc73986042f6dc68eb464d02bc6a8sewardj tracking them. 22895448075345dc73986042f6dc68eb464d02bc6a8sewardj 22995448075345dc73986042f6dc68eb464d02bc6a8sewardj Shadow IRTemps are therefore allocated on demand. mce.tmpMap is a 23095448075345dc73986042f6dc68eb464d02bc6a8sewardj table indexed [0 .. n_types-1], which gives the current shadow for 23195448075345dc73986042f6dc68eb464d02bc6a8sewardj each original tmp, or INVALID_IRTEMP if none is so far assigned. 23295448075345dc73986042f6dc68eb464d02bc6a8sewardj It is necessary to support making multiple assignments to a shadow 23395448075345dc73986042f6dc68eb464d02bc6a8sewardj -- specifically, after testing a shadow for definedness, it needs 23495448075345dc73986042f6dc68eb464d02bc6a8sewardj to be made defined. But IR's SSA property disallows this. 23595448075345dc73986042f6dc68eb464d02bc6a8sewardj 23695448075345dc73986042f6dc68eb464d02bc6a8sewardj (2) (more important reason): Therefore, when a shadow needs to get 23795448075345dc73986042f6dc68eb464d02bc6a8sewardj a new value, a new temporary is created, the value is assigned to 23895448075345dc73986042f6dc68eb464d02bc6a8sewardj that, and the tmpMap is updated to reflect the new binding. 23995448075345dc73986042f6dc68eb464d02bc6a8sewardj 24095448075345dc73986042f6dc68eb464d02bc6a8sewardj A corollary is that if the tmpMap maps a given tmp to 241f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj IRTemp_INVALID and we are hoping to read that shadow tmp, it means 24295448075345dc73986042f6dc68eb464d02bc6a8sewardj there's a read-before-write error in the original tmps. The IR 24395448075345dc73986042f6dc68eb464d02bc6a8sewardj sanity checker should catch all such anomalies, however. 24495448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 245e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* Create a new IRTemp of type 'ty' and kind 'kind', and add it to 2471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj both the table in mce->sb and to our auxiliary mapping. Note that 2481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj newTemp may cause mce->tmpMap to resize, hence previous results 2491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj from VG_(indexXA)(mce->tmpMap) are invalidated. */ 2501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic IRTemp newTemp ( MCEnv* mce, IRType ty, TempKind kind ) 2511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 2521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Word newIx; 2531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt ent; 2541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp tmp = newIRTemp(mce->sb->tyenv, ty); 2551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.kind = kind; 2561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.shadowV = IRTemp_INVALID; 2571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.shadowB = IRTemp_INVALID; 2581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj newIx = VG_(addToXA)( mce->tmpMap, &ent ); 2591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(newIx == (Word)tmp); 2601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return tmp; 2611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj} 2621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 2631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 26495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Find the tmp currently shadowing the given original tmp. If none 26595448075345dc73986042f6dc68eb464d02bc6a8sewardj so far exists, allocate one. */ 2667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRTemp findShadowTmpV ( MCEnv* mce, IRTemp orig ) 267e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt* ent; 2691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* VG_(indexXA) range-checks 'orig', hence no need to check 2701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj here. */ 2711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 2721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 2731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (ent->shadowV == IRTemp_INVALID) { 2741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp tmpV 2751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh ); 2761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* newTemp may cause mce->tmpMap to resize, hence previous results 2771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj from VG_(indexXA) are invalid. */ 2781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 2791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 2801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->shadowV == IRTemp_INVALID); 2811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent->shadowV = tmpV; 282e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 2831c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return ent->shadowV; 284e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 285e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 28695448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Allocate a new shadow for the given original tmp. This means any 28795448075345dc73986042f6dc68eb464d02bc6a8sewardj previous shadow is abandoned. This is needed because it is 28895448075345dc73986042f6dc68eb464d02bc6a8sewardj necessary to give a new value to a shadow once it has been tested 28995448075345dc73986042f6dc68eb464d02bc6a8sewardj for undefinedness, but unfortunately IR's SSA property disallows 29095448075345dc73986042f6dc68eb464d02bc6a8sewardj this. Instead we must abandon the old shadow, allocate a new one 2911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj and use that instead. 2921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 2931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj This is the same as findShadowTmpV, except we don't bother to see 2941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if a shadow temp already existed -- we simply allocate a new one 2951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj regardless. */ 2967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void newShadowTmpV ( MCEnv* mce, IRTemp orig ) 297e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt* ent; 2991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* VG_(indexXA) range-checks 'orig', hence no need to check 3001c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj here. */ 3011c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 3021c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 3031c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (1) { 3041c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp tmpV 3051c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh ); 3061c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* newTemp may cause mce->tmpMap to resize, hence previous results 3071c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj from VG_(indexXA) are invalid. */ 3081c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 3091c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 3101c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent->shadowV = tmpV; 3111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 312e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 313e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 314e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 31595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 31695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- IRAtoms -- a subset of IRExprs ---*/ 31795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 31895448075345dc73986042f6dc68eb464d02bc6a8sewardj 31995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* An atom is either an IRExpr_Const or an IRExpr_Tmp, as defined by 320710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj isIRAtom() in libvex_ir.h. Because this instrumenter expects flat 32195448075345dc73986042f6dc68eb464d02bc6a8sewardj input, most of this code deals in atoms. Usefully, a value atom 32295448075345dc73986042f6dc68eb464d02bc6a8sewardj always has a V-value which is also an atom: constants are shadowed 32395448075345dc73986042f6dc68eb464d02bc6a8sewardj by constants, and temps are shadowed by the corresponding shadow 32495448075345dc73986042f6dc68eb464d02bc6a8sewardj temporary. */ 32595448075345dc73986042f6dc68eb464d02bc6a8sewardj 32695448075345dc73986042f6dc68eb464d02bc6a8sewardjtypedef IRExpr IRAtom; 32795448075345dc73986042f6dc68eb464d02bc6a8sewardj 32895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): is this an atom which looks 32995448075345dc73986042f6dc68eb464d02bc6a8sewardj like it's from original code? */ 33095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isOriginalAtom ( MCEnv* mce, IRAtom* a1 ) 331e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 33295448075345dc73986042f6dc68eb464d02bc6a8sewardj if (a1->tag == Iex_Const) 33395448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; 3341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (a1->tag == Iex_RdTmp) { 3351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp ); 3361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return ent->kind == Orig; 3371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 33895448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 33995448075345dc73986042f6dc68eb464d02bc6a8sewardj} 340e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 34195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): is this an atom which looks 34295448075345dc73986042f6dc68eb464d02bc6a8sewardj like it's from shadow code? */ 34395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isShadowAtom ( MCEnv* mce, IRAtom* a1 ) 34495448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 34595448075345dc73986042f6dc68eb464d02bc6a8sewardj if (a1->tag == Iex_Const) 34695448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; 3471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (a1->tag == Iex_RdTmp) { 3481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp ); 3491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return ent->kind == VSh || ent->kind == BSh; 3501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 35195448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 35295448075345dc73986042f6dc68eb464d02bc6a8sewardj} 353e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 35495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* (used for sanity checks only): check that both args are atoms and 35595448075345dc73986042f6dc68eb464d02bc6a8sewardj are identically-kinded. */ 35695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 ) 35795448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 3580b9d74abd0a663b530d290b2b788ddeda46e5400sewardj if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp) 35995448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; 360bef552a3841d959ca18fac4e5ac6925ea29dfd32sewardj if (a1->tag == Iex_Const && a2->tag == Iex_Const) 36195448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; 36295448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 36395448075345dc73986042f6dc68eb464d02bc6a8sewardj} 364e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 365e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 36695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 36795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Type management ---*/ 36895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 369e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 37095448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Shadow state is always accessed using integer types. This returns 37195448075345dc73986042f6dc68eb464d02bc6a8sewardj an integer type with the same size (as per sizeofIRType) as the 37295448075345dc73986042f6dc68eb464d02bc6a8sewardj given type. The only valid shadow types are Bit, I8, I16, I32, 37345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj I64, I128, V128, V256. */ 374e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 3757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRType shadowTypeV ( IRType ty ) 37695448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 37795448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (ty) { 37895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I1: 37995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I8: 38095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I16: 38195448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I32: 3826cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Ity_I64: 3836cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Ity_I128: return ty; 3841f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj case Ity_F16: return Ity_I16; 3853245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj case Ity_F32: return Ity_I32; 386b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Ity_D32: return Ity_I32; 3873245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj case Ity_F64: return Ity_I64; 388b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Ity_D64: return Ity_I64; 389b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Ity_F128: return Ity_I128; 390b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Ity_D128: return Ity_I128; 3913245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj case Ity_V128: return Ity_V128; 39245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case Ity_V256: return Ity_V256; 39395448075345dc73986042f6dc68eb464d02bc6a8sewardj default: ppIRType(ty); 3947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(tool_panic)("memcheck:shadowTypeV"); 395e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 39695448075345dc73986042f6dc68eb464d02bc6a8sewardj} 397e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 39895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Produce a 'defined' value of the given shadow type. Should only be 39995448075345dc73986042f6dc68eb464d02bc6a8sewardj supplied shadow types (Bit/I8/I16/I32/UI64). */ 40095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRExpr* definedOfType ( IRType ty ) { 40195448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (ty) { 402170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I1: return IRExpr_Const(IRConst_U1(False)); 403170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I8: return IRExpr_Const(IRConst_U8(0)); 404170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I16: return IRExpr_Const(IRConst_U16(0)); 405170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I32: return IRExpr_Const(IRConst_U32(0)); 406170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I64: return IRExpr_Const(IRConst_U64(0)); 407b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Ity_I128: return i128_const_zero(); 408170ee210842367a5cc52390358ba560774f76329sewardj case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000)); 4091eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Ity_V256: return IRExpr_Const(IRConst_V256(0x00000000)); 410f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj default: VG_(tool_panic)("memcheck:definedOfType"); 41195448075345dc73986042f6dc68eb464d02bc6a8sewardj } 412e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 413e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 414e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 41595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 41695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Constructing IR fragments ---*/ 41795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 418e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 41995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* add stmt to a bb */ 4207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic inline void stmt ( HChar cat, MCEnv* mce, IRStmt* st ) { 4217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (mce->trace) { 4227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)(" %c: ", cat); 4237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ppIRStmt(st); 4247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("\n"); 4257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 4261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj addStmtToIRSB(mce->sb, st); 4277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 4287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 4297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* assign value to tmp */ 4307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic inline 4317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid assign ( HChar cat, MCEnv* mce, IRTemp tmp, IRExpr* expr ) { 4321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj stmt(cat, mce, IRStmt_WrTmp(tmp,expr)); 4337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 43495448075345dc73986042f6dc68eb464d02bc6a8sewardj 43595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* build various kinds of expressions */ 43657f92b0326e164124201034afc0c51dcd8db6d07sewardj#define triop(_op, _arg1, _arg2, _arg3) \ 43757f92b0326e164124201034afc0c51dcd8db6d07sewardj IRExpr_Triop((_op),(_arg1),(_arg2),(_arg3)) 43895448075345dc73986042f6dc68eb464d02bc6a8sewardj#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2)) 43995448075345dc73986042f6dc68eb464d02bc6a8sewardj#define unop(_op, _arg) IRExpr_Unop((_op),(_arg)) 440cc9616506450cb02944b62dc07774c29462bfefcsewardj#define mkU1(_n) IRExpr_Const(IRConst_U1(_n)) 44195448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 44295448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU16(_n) IRExpr_Const(IRConst_U16(_n)) 44395448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 44495448075345dc73986042f6dc68eb464d02bc6a8sewardj#define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) 445170ee210842367a5cc52390358ba560774f76329sewardj#define mkV128(_n) IRExpr_Const(IRConst_V128(_n)) 4460b9d74abd0a663b530d290b2b788ddeda46e5400sewardj#define mkexpr(_tmp) IRExpr_RdTmp((_tmp)) 44795448075345dc73986042f6dc68eb464d02bc6a8sewardj 4487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Bind the given expression to a new temporary, and return the 44995448075345dc73986042f6dc68eb464d02bc6a8sewardj temporary. This effectively converts an arbitrary expression into 4507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj an atom. 4517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 4527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'ty' is the type of 'e' and hence the type that the new temporary 4531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj needs to be. But passing it in is redundant, since we can deduce 4541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj the type merely by inspecting 'e'. So at least use that fact to 4551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj assert that the two types agree. */ 4561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic IRAtom* assignNew ( HChar cat, MCEnv* mce, IRType ty, IRExpr* e ) 4571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 4581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempKind k; 4591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp t; 4601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType tyE = typeOfIRExpr(mce->sb->tyenv, e); 461b0ccb4d09a74c94a712b2edf9894b408f270493asewardj 4627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(tyE == ty); /* so 'ty' is redundant (!) */ 4631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj switch (cat) { 4641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case 'V': k = VSh; break; 4651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case 'B': k = BSh; break; 4661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case 'C': k = Orig; break; 4671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* happens when we are making up new "orig" 4681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expressions, for IRCAS handling */ 4691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj default: tl_assert(0); 4701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 4711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj t = newTemp(mce, ty, k); 4727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign(cat, mce, t, e); 47395448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkexpr(t); 474e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 475e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 47695448075345dc73986042f6dc68eb464d02bc6a8sewardj 477e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*------------------------------------------------------------*/ 478b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/*--- Helper functions for 128-bit ops ---*/ 479b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/*------------------------------------------------------------*/ 48045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 481b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjstatic IRExpr *i128_const_zero(void) 482b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj{ 48345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj IRAtom* z64 = IRExpr_Const(IRConst_U64(0)); 48445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj return binop(Iop_64HLto128, z64, z64); 485b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj} 486b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 48745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj/* There are no I128-bit loads and/or stores [as generated by any 48845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj current front ends]. So we do not need to worry about that in 48945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj expr2vbits_Load */ 49045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 491b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 492b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/*------------------------------------------------------------*/ 49395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Constructing definedness primitive ops ---*/ 494e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*------------------------------------------------------------*/ 495e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 49695448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Defined-if-either-defined --------- */ 49795448075345dc73986042f6dc68eb464d02bc6a8sewardj 49895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 49995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 50095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, binop(Iop_And8, a1, a2)); 502e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 503e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 50495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 50595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 50695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, binop(Iop_And16, a1, a2)); 50895448075345dc73986042f6dc68eb464d02bc6a8sewardj} 509e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 51095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 51195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 51295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, binop(Iop_And32, a1, a2)); 514e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 515e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 5167010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkDifD64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 5177010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isShadowAtom(mce,a1)); 5187010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isShadowAtom(mce,a2)); 5197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(Iop_And64, a1, a2)); 5207010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj} 5217010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj 52220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkDifDV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 523170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isShadowAtom(mce,a1)); 524170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isShadowAtom(mce,a2)); 5257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(Iop_AndV128, a1, a2)); 526170ee210842367a5cc52390358ba560774f76329sewardj} 527170ee210842367a5cc52390358ba560774f76329sewardj 528350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkDifDV256 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 529350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce,a1)); 530350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce,a2)); 531350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, binop(Iop_AndV256, a1, a2)); 532350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 533350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 53495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Undefined-if-either-undefined --------- */ 535e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 53695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 53795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 53895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, binop(Iop_Or8, a1, a2)); 540e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 541e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 54295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 54395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 54495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, binop(Iop_Or16, a1, a2)); 54695448075345dc73986042f6dc68eb464d02bc6a8sewardj} 547e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 54895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 54995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 55095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, binop(Iop_Or32, a1, a2)); 552e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 553e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 55495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 55595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 55695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a2)); 5577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(Iop_Or64, a1, a2)); 55895448075345dc73986042f6dc68eb464d02bc6a8sewardj} 559e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 560b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjstatic IRAtom* mkUifU128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 561b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj IRAtom *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6; 562b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tl_assert(isShadowAtom(mce,a1)); 563b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tl_assert(isShadowAtom(mce,a2)); 564b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, a1)); 565b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp2 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, a1)); 566b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp3 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, a2)); 567b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp4 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, a2)); 568b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp5 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp1, tmp3)); 569b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tmp6 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp2, tmp4)); 570b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 571b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, tmp6, tmp5)); 572b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj} 573b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 57420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 5753245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce,a1)); 5763245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce,a2)); 5777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(Iop_OrV128, a1, a2)); 5783245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj} 5793245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 580350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkUifUV256 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { 581350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce,a1)); 582350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce,a2)); 583350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, binop(Iop_OrV256, a1, a2)); 584350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 585350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 586e50a1b14b5ec5a180d2797614de48b19129c9e4fsewardjstatic IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) { 58795448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (vty) { 588e50a1b14b5ec5a180d2797614de48b19129c9e4fsewardj case Ity_I8: return mkUifU8(mce, a1, a2); 589a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Ity_I16: return mkUifU16(mce, a1, a2); 590a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Ity_I32: return mkUifU32(mce, a1, a2); 591a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Ity_I64: return mkUifU64(mce, a1, a2); 592b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Ity_I128: return mkUifU128(mce, a1, a2); 59320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Ity_V128: return mkUifUV128(mce, a1, a2); 594a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Ity_V256: return mkUifUV256(mce, a1, a2); 59595448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 59695448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n"); 59795448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck:mkUifU"); 598e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 599e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 600e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 60195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- The Left-family of operations. --------- */ 602e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 60395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) { 60495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 6057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, unop(Iop_Left8, a1)); 606e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 607e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 60895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) { 60995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 6107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, unop(Iop_Left16, a1)); 61195448075345dc73986042f6dc68eb464d02bc6a8sewardj} 612e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 61395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) { 61495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,a1)); 6157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, unop(Iop_Left32, a1)); 61695448075345dc73986042f6dc68eb464d02bc6a8sewardj} 617e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 618681be302af5528c2cb415270da9fde2e7f347e69sewardjstatic IRAtom* mkLeft64 ( MCEnv* mce, IRAtom* a1 ) { 619681be302af5528c2cb415270da9fde2e7f347e69sewardj tl_assert(isShadowAtom(mce,a1)); 6207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_Left64, a1)); 621681be302af5528c2cb415270da9fde2e7f347e69sewardj} 622681be302af5528c2cb415270da9fde2e7f347e69sewardj 62395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- 'Improvement' functions for AND/OR. --------- */ 624e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 62595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* ImproveAND(data, vbits) = data OR vbits. Defined (0) data 0s give 62695448075345dc73986042f6dc68eb464d02bc6a8sewardj defined (0); all other -> undefined (1). 62795448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 62895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 62995448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 63095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 63195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 63295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 6337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, binop(Iop_Or8, data, vbits)); 634e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 635e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 63695448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 637e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 63895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 63995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 64095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 6417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, binop(Iop_Or16, data, vbits)); 642e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 643e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 64495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 64595448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 64695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 64795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 64895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 6497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, binop(Iop_Or32, data, vbits)); 65095448075345dc73986042f6dc68eb464d02bc6a8sewardj} 651e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 6527010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkImproveAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 6537010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj{ 6547010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isOriginalAtom(mce, data)); 6557010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isShadowAtom(mce, vbits)); 6567010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(sameKindedAtoms(data, vbits)); 6577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(Iop_Or64, data, vbits)); 6587010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj} 6597010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj 66020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkImproveANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 661170ee210842367a5cc52390358ba560774f76329sewardj{ 662170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isOriginalAtom(mce, data)); 663170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isShadowAtom(mce, vbits)); 664170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(sameKindedAtoms(data, vbits)); 6657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(Iop_OrV128, data, vbits)); 666170ee210842367a5cc52390358ba560774f76329sewardj} 667170ee210842367a5cc52390358ba560774f76329sewardj 668350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkImproveANDV256 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 669350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 670350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isOriginalAtom(mce, data)); 671350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vbits)); 672350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(sameKindedAtoms(data, vbits)); 673350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, binop(Iop_OrV256, data, vbits)); 674350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 675350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 67695448075345dc73986042f6dc68eb464d02bc6a8sewardj/* ImproveOR(data, vbits) = ~data OR vbits. Defined (0) data 1s give 67795448075345dc73986042f6dc68eb464d02bc6a8sewardj defined (0); all other -> undefined (1). 67895448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 67995448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 680e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 68195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 68295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 68395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 68495448075345dc73986042f6dc68eb464d02bc6a8sewardj return assignNew( 6857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, Ity_I8, 68695448075345dc73986042f6dc68eb464d02bc6a8sewardj binop(Iop_Or8, 6877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I8, unop(Iop_Not8, data)), 68895448075345dc73986042f6dc68eb464d02bc6a8sewardj vbits) ); 689e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 690e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 69195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 69295448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 69395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 69495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 69595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 69695448075345dc73986042f6dc68eb464d02bc6a8sewardj return assignNew( 6977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, Ity_I16, 69895448075345dc73986042f6dc68eb464d02bc6a8sewardj binop(Iop_Or16, 6997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I16, unop(Iop_Not16, data)), 70095448075345dc73986042f6dc68eb464d02bc6a8sewardj vbits) ); 70195448075345dc73986042f6dc68eb464d02bc6a8sewardj} 702e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 70395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkImproveOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 704e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 70595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 70695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vbits)); 70795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(data, vbits)); 70895448075345dc73986042f6dc68eb464d02bc6a8sewardj return assignNew( 7097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, Ity_I32, 71095448075345dc73986042f6dc68eb464d02bc6a8sewardj binop(Iop_Or32, 7117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I32, unop(Iop_Not32, data)), 71295448075345dc73986042f6dc68eb464d02bc6a8sewardj vbits) ); 713e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 714e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 7157010f6eec42f5ace7c02c582e12d8150c2a2c964sewardjstatic IRAtom* mkImproveOR64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 7167010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj{ 7177010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isOriginalAtom(mce, data)); 7187010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(isShadowAtom(mce, vbits)); 7197010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj tl_assert(sameKindedAtoms(data, vbits)); 7207010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj return assignNew( 7217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, Ity_I64, 7227010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj binop(Iop_Or64, 7237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I64, unop(Iop_Not64, data)), 7247010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj vbits) ); 7257010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj} 7267010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj 72720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardjstatic IRAtom* mkImproveORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 728170ee210842367a5cc52390358ba560774f76329sewardj{ 729170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isOriginalAtom(mce, data)); 730170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(isShadowAtom(mce, vbits)); 731170ee210842367a5cc52390358ba560774f76329sewardj tl_assert(sameKindedAtoms(data, vbits)); 732170ee210842367a5cc52390358ba560774f76329sewardj return assignNew( 7337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, Ity_V128, 73420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj binop(Iop_OrV128, 7357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_V128, unop(Iop_NotV128, data)), 736170ee210842367a5cc52390358ba560774f76329sewardj vbits) ); 737170ee210842367a5cc52390358ba560774f76329sewardj} 738170ee210842367a5cc52390358ba560774f76329sewardj 739350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkImproveORV256 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) 740350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 741350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isOriginalAtom(mce, data)); 742350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vbits)); 743350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(sameKindedAtoms(data, vbits)); 744350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew( 745350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 'V', mce, Ity_V256, 746350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_OrV256, 747350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj assignNew('V', mce, Ity_V256, unop(Iop_NotV256, data)), 748350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj vbits) ); 749350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 750350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 75195448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- Pessimising casts. --------- */ 752e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 753b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* The function returns an expression of type DST_TY. If any of the VBITS 754b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is undefined (value == 1) the resulting expression has all bits set to 755b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1. Otherwise, all bits are 0. */ 756b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 75795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) 758e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 7594cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj IRType src_ty; 7607cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom* tmp1; 7612eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 76295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Note, dst_ty is a shadow type, not an original type. */ 76395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,vbits)); 7641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj src_ty = typeOfIRExpr(mce->sb->tyenv, vbits); 7654cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 7664cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj /* Fast-track some common cases */ 7674cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj if (src_ty == Ity_I32 && dst_ty == Ity_I32) 7687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits)); 7694cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 7704cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj if (src_ty == Ity_I64 && dst_ty == Ity_I64) 7717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits)); 7724cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 7734cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj if (src_ty == Ity_I32 && dst_ty == Ity_I64) { 7742eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* PCast the arg, then clone it. */ 7757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* tmp = assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits)); 7767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp)); 7774cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj } 7784cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 7791eb272f53fadb410dd27fb38fb1be75af84868d0sewardj if (src_ty == Ity_I32 && dst_ty == Ity_V128) { 7801eb272f53fadb410dd27fb38fb1be75af84868d0sewardj /* PCast the arg, then clone it 4 times. */ 7811eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* tmp = assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits)); 7821eb272f53fadb410dd27fb38fb1be75af84868d0sewardj tmp = assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp)); 7831eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, tmp, tmp)); 7841eb272f53fadb410dd27fb38fb1be75af84868d0sewardj } 7851eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 7861eb272f53fadb410dd27fb38fb1be75af84868d0sewardj if (src_ty == Ity_I32 && dst_ty == Ity_V256) { 7871eb272f53fadb410dd27fb38fb1be75af84868d0sewardj /* PCast the arg, then clone it 8 times. */ 7881eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* tmp = assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits)); 7891eb272f53fadb410dd27fb38fb1be75af84868d0sewardj tmp = assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp)); 7901eb272f53fadb410dd27fb38fb1be75af84868d0sewardj tmp = assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, tmp, tmp)); 7911eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return assignNew('V', mce, Ity_V256, binop(Iop_V128HLtoV256, tmp, tmp)); 7921eb272f53fadb410dd27fb38fb1be75af84868d0sewardj } 7931eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 7942eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (src_ty == Ity_I64 && dst_ty == Ity_I32) { 7952eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* PCast the arg. This gives all 0s or all 1s. Then throw away 7962eecb74d4a8816485c97ae8e535ce25511460bc8sewardj the top half. */ 7972eecb74d4a8816485c97ae8e535ce25511460bc8sewardj IRAtom* tmp = assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits)); 7982eecb74d4a8816485c97ae8e535ce25511460bc8sewardj return assignNew('V', mce, Ity_I32, unop(Iop_64to32, tmp)); 7992eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 8002eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 801bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj if (src_ty == Ity_V128 && dst_ty == Ity_I64) { 802bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* Use InterleaveHI64x2 to copy the top half of the vector into 803bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj the bottom half. Then we can UifU it with the original, throw 804bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj away the upper half of the result, and PCast-I64-to-I64 805bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj the lower half. */ 806bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates vbits[127:64] : vbits[127:64] 807bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* hi64hi64 808bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_V128, 809bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binop(Iop_InterleaveHI64x2, vbits, vbits)); 810bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates 811bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // UifU(vbits[127:64],vbits[127:64]) : UifU(vbits[127:64],vbits[63:0]) 812bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // == vbits[127:64] : UifU(vbits[127:64],vbits[63:0]) 813bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* lohi64 814bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = mkUifUV128(mce, hi64hi64, vbits); 815bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates UifU(vbits[127:64],vbits[63:0]) 816bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* lo64 817bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, lohi64)); 818bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates 819bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // PCast-to-I64( UifU(vbits[127:64], vbits[63:0] ) 820bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // == PCast-to-I64( vbits[127:0] ) 821bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* res 822bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, lo64)); 823bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return res; 824bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 825bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 8264cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj /* Else do it the slow way .. */ 8272eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* First of all, collapse vbits down to a single bit. */ 8284cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj tmp1 = NULL; 8294cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj switch (src_ty) { 83095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I1: 83195448075345dc73986042f6dc68eb464d02bc6a8sewardj tmp1 = vbits; 83295448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 83395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I8: 8347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ8, vbits)); 83595448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 83695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I16: 8377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ16, vbits)); 83895448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 83995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I32: 8407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ32, vbits)); 84195448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 84295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I64: 8437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ64, vbits)); 84495448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 84569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Ity_I128: { 84669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj /* Gah. Chop it in half, OR the halves together, and compare 84769a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj that with zero. */ 8487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* tmp2 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, vbits)); 8497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* tmp3 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, vbits)); 8507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* tmp4 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3)); 8517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I1, 85237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj unop(Iop_CmpNEZ64, tmp4)); 85369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj break; 85469a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj } 85595448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 8564cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj ppIRType(src_ty); 85795448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("mkPCastTo(1)"); 85895448075345dc73986042f6dc68eb464d02bc6a8sewardj } 85995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(tmp1); 86095448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Now widen up to the dst type. */ 86195448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (dst_ty) { 86295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I1: 86395448075345dc73986042f6dc68eb464d02bc6a8sewardj return tmp1; 86495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I8: 8657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, unop(Iop_1Sto8, tmp1)); 86695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I16: 8677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, unop(Iop_1Sto16, tmp1)); 86895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I32: 8697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, unop(Iop_1Sto32, tmp1)); 87095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ity_I64: 8717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1)); 872a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Ity_V128: 8737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1)); 8747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1)); 875a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return tmp1; 87669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Ity_I128: 8777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1)); 8787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tmp1 = assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, tmp1, tmp1)); 87969a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj return tmp1; 880a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Ity_V256: 881a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1)); 882a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj tmp1 = assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, 883a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj tmp1, tmp1)); 884a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj tmp1 = assignNew('V', mce, Ity_V256, binop(Iop_V128HLtoV256, 885a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj tmp1, tmp1)); 886a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return tmp1; 88795448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 88895448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIRType(dst_ty); 88995448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("mkPCastTo(2)"); 890e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 891e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 892e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 893bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj/* This is a minor variant. It takes an arg of some type and returns 894bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj a value of the same type. The result consists entirely of Defined 895bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj (zero) bits except its least significant bit, which is a PCast of 896bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj the entire argument down to a single bit. */ 897bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardjstatic IRAtom* mkPCastXXtoXXlsb ( MCEnv* mce, IRAtom* varg, IRType ty ) 898bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj{ 899bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj if (ty == Ity_V128) { 900bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* --- Case for V128 --- */ 901bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* varg128 = varg; 902bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // generates: PCast-to-I64(varg128) 903bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* pcdTo64 = mkPCastTo(mce, Ity_I64, varg128); 904bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Now introduce zeros (defined bits) in the top 63 places 905bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // generates: Def--(63)--Def PCast-to-I1(varg128) 906bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* d63pc 907bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_I64, binop(Iop_And64, pcdTo64, mkU64(1))); 908bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // generates: Def--(64)--Def 909bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* d64 910bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = definedOfType(Ity_I64); 911bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // generates: Def--(127)--Def PCast-to-I1(varg128) 912bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* res 913bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, d64, d63pc)); 914bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return res; 915bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 916bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj if (ty == Ity_I64) { 917bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* --- Case for I64 --- */ 918bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // PCast to 64 919bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* pcd = mkPCastTo(mce, Ity_I64, varg); 920bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Zero (Def) out the top 63 bits 921bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* res 922bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_I64, binop(Iop_And64, pcd, mkU64(1))); 923bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return res; 924bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 925bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /*NOTREACHED*/ 926bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj tl_assert(0); 927bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj} 928bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 929d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj/* --------- Accurate interpretation of CmpEQ/CmpNE. --------- */ 930d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj/* 931d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj Normally, we can do CmpEQ/CmpNE by doing UifU on the arguments, and 932d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj PCasting to Ity_U1. However, sometimes it is necessary to be more 933d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj accurate. The insight is that the result is defined if two 934d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj corresponding bits can be found, one from each argument, so that 935d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj both bits are defined but are different -- that makes EQ say "No" 936d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj and NE say "Yes". Hence, we compute an improvement term and DifD 937d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj it onto the "normal" (UifU) result. 938d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 939d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj The result is: 940d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 941d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj PCastTo<1> ( 942e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj -- naive version 943e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj PCastTo<sz>( UifU<sz>(vxx, vyy) ) 944e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 945d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj `DifD<sz>` 946e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 947e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj -- improvement term 948e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj PCastTo<sz>( PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) ) ) 949d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 950e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 951d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj where 952d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj vec contains 0 (defined) bits where the corresponding arg bits 953e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj are defined but different, and 1 bits otherwise. 954e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 955e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj vec = Or<sz>( vxx, // 0 iff bit defined 956e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj vyy, // 0 iff bit defined 957e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj Not<sz>(Xor<sz>( xx, yy )) // 0 iff bits different 958e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj ) 959e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 960e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj If any bit of vec is 0, the result is defined and so the 961e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj improvement term should produce 0...0, else it should produce 962e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 1...1. 963e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 964e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj Hence require for the improvement term: 965d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 966e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj if vec == 1...1 then 1...1 else 0...0 967e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj -> 968e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj PCast<sz>( CmpEQ<sz> ( vec, 1...1 ) ) 969e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj 970e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj This was extensively re-analysed and checked on 6 July 05. 971d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj*/ 972d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardjstatic IRAtom* expensiveCmpEQorNE ( MCEnv* mce, 973d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRType ty, 974d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRAtom* vxx, IRAtom* vyy, 975d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRAtom* xx, IRAtom* yy ) 976d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj{ 977e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj IRAtom *naive, *vec, *improvement_term; 978e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj IRAtom *improved, *final_cast, *top; 979e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj IROp opDIFD, opUIFU, opXOR, opNOT, opCMP, opOR; 980d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 981d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(isShadowAtom(mce,vxx)); 982d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(isShadowAtom(mce,vyy)); 983d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(isOriginalAtom(mce,xx)); 984d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(isOriginalAtom(mce,yy)); 985d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(sameKindedAtoms(vxx,xx)); 986d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj tl_assert(sameKindedAtoms(vyy,yy)); 987d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 988d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj switch (ty) { 9894cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Ity_I16: 9904cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opOR = Iop_Or16; 9914cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opDIFD = Iop_And16; 9924cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opUIFU = Iop_Or16; 9934cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opNOT = Iop_Not16; 9944cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opXOR = Iop_Xor16; 9954cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj opCMP = Iop_CmpEQ16; 9964cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj top = mkU16(0xFFFF); 9974cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj break; 998d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ity_I32: 999e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj opOR = Iop_Or32; 1000d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opDIFD = Iop_And32; 1001d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opUIFU = Iop_Or32; 1002d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opNOT = Iop_Not32; 1003d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opXOR = Iop_Xor32; 1004d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opCMP = Iop_CmpEQ32; 1005d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj top = mkU32(0xFFFFFFFF); 1006d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj break; 1007cd986336a55192fe237a72b323b378b674af38e0tom case Ity_I64: 1008e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj opOR = Iop_Or64; 1009cd986336a55192fe237a72b323b378b674af38e0tom opDIFD = Iop_And64; 1010cd986336a55192fe237a72b323b378b674af38e0tom opUIFU = Iop_Or64; 1011cd986336a55192fe237a72b323b378b674af38e0tom opNOT = Iop_Not64; 1012cd986336a55192fe237a72b323b378b674af38e0tom opXOR = Iop_Xor64; 1013cd986336a55192fe237a72b323b378b674af38e0tom opCMP = Iop_CmpEQ64; 101437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj top = mkU64(0xFFFFFFFFFFFFFFFFULL); 1015cd986336a55192fe237a72b323b378b674af38e0tom break; 1016d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj default: 1017d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj VG_(tool_panic)("expensiveCmpEQorNE"); 1018d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj } 1019d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1020d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj naive 10217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = mkPCastTo(mce,ty, 10227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, ty, binop(opUIFU, vxx, vyy))); 1023d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1024d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj vec 1025d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj = assignNew( 10267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce,ty, 1027e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj binop( opOR, 10287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opOR, vxx, vyy)), 1029d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj assignNew( 10307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce,ty, 1031d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj unop( opNOT, 10327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opXOR, xx, yy)))))); 1033d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1034e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj improvement_term 10357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = mkPCastTo( mce,ty, 10367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,Ity_I1, binop(opCMP, vec, top))); 1037d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1038d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj improved 10397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = assignNew( 'V', mce,ty, binop(opDIFD, naive, improvement_term) ); 1040d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1041d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj final_cast 1042d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj = mkPCastTo( mce, Ity_I1, improved ); 1043d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1044d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return final_cast; 1045d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj} 1046d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 1047e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1048992dff97aa9c074f86f831a76367fb55e0541da2sewardj/* --------- Semi-accurate interpretation of CmpORD. --------- */ 1049992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1050992dff97aa9c074f86f831a76367fb55e0541da2sewardj/* CmpORD32{S,U} does PowerPC-style 3-way comparisons: 1051992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1052992dff97aa9c074f86f831a76367fb55e0541da2sewardj CmpORD32S(x,y) = 1<<3 if x <s y 1053992dff97aa9c074f86f831a76367fb55e0541da2sewardj = 1<<2 if x >s y 1054992dff97aa9c074f86f831a76367fb55e0541da2sewardj = 1<<1 if x == y 1055992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1056992dff97aa9c074f86f831a76367fb55e0541da2sewardj and similarly the unsigned variant. The default interpretation is: 1057992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1058992dff97aa9c074f86f831a76367fb55e0541da2sewardj CmpORD32{S,U}#(x,y,x#,y#) = PCast(x# `UifU` y#) 10591bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj & (7<<1) 1060992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1061992dff97aa9c074f86f831a76367fb55e0541da2sewardj The "& (7<<1)" reflects the fact that all result bits except 3,2,1 1062992dff97aa9c074f86f831a76367fb55e0541da2sewardj are zero and therefore defined (viz, zero). 1063a9e62a9997a442eecd38f81479c15792bca201easewardj 1064a9e62a9997a442eecd38f81479c15792bca201easewardj Also deal with a special case better: 1065a9e62a9997a442eecd38f81479c15792bca201easewardj 1066a9e62a9997a442eecd38f81479c15792bca201easewardj CmpORD32S(x,0) 1067a9e62a9997a442eecd38f81479c15792bca201easewardj 1068a9e62a9997a442eecd38f81479c15792bca201easewardj Here, bit 3 (LT) of the result is a copy of the top bit of x and 1069a9e62a9997a442eecd38f81479c15792bca201easewardj will be defined even if the rest of x isn't. In which case we do: 1070a9e62a9997a442eecd38f81479c15792bca201easewardj 1071a9e62a9997a442eecd38f81479c15792bca201easewardj CmpORD32S#(x,x#,0,{impliedly 0}#) 10721bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj = PCast(x#) & (3<<1) -- standard interp for GT#,EQ# 10731bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj | (x# >>u 31) << 3 -- LT# = x#[31] 1074a9e62a9997a442eecd38f81479c15792bca201easewardj 10751bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj Analogous handling for CmpORD64{S,U}. 1076992dff97aa9c074f86f831a76367fb55e0541da2sewardj*/ 1077a9e62a9997a442eecd38f81479c15792bca201easewardjstatic Bool isZeroU32 ( IRAtom* e ) 1078a9e62a9997a442eecd38f81479c15792bca201easewardj{ 1079a9e62a9997a442eecd38f81479c15792bca201easewardj return 1080a9e62a9997a442eecd38f81479c15792bca201easewardj toBool( e->tag == Iex_Const 1081a9e62a9997a442eecd38f81479c15792bca201easewardj && e->Iex.Const.con->tag == Ico_U32 1082a9e62a9997a442eecd38f81479c15792bca201easewardj && e->Iex.Const.con->Ico.U32 == 0 ); 1083a9e62a9997a442eecd38f81479c15792bca201easewardj} 1084a9e62a9997a442eecd38f81479c15792bca201easewardj 10851bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardjstatic Bool isZeroU64 ( IRAtom* e ) 1086992dff97aa9c074f86f831a76367fb55e0541da2sewardj{ 10871bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj return 10881bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj toBool( e->tag == Iex_Const 10891bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj && e->Iex.Const.con->tag == Ico_U64 10901bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj && e->Iex.Const.con->Ico.U64 == 0 ); 10911bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj} 10921bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj 10931bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardjstatic IRAtom* doCmpORD ( MCEnv* mce, 10941bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IROp cmp_op, 10951bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IRAtom* xxhash, IRAtom* yyhash, 10961bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IRAtom* xx, IRAtom* yy ) 10971bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj{ 10981bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj Bool m64 = cmp_op == Iop_CmpORD64S || cmp_op == Iop_CmpORD64U; 10991bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj Bool syned = cmp_op == Iop_CmpORD64S || cmp_op == Iop_CmpORD32S; 11001bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IROp opOR = m64 ? Iop_Or64 : Iop_Or32; 11011bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IROp opAND = m64 ? Iop_And64 : Iop_And32; 11021bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IROp opSHL = m64 ? Iop_Shl64 : Iop_Shl32; 11031bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IROp opSHR = m64 ? Iop_Shr64 : Iop_Shr32; 11041bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IRType ty = m64 ? Ity_I64 : Ity_I32; 11051bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj Int width = m64 ? 64 : 32; 11061bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj 11071bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj Bool (*isZero)(IRAtom*) = m64 ? isZeroU64 : isZeroU32; 11081bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj 11091bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IRAtom* threeLeft1 = NULL; 11101bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj IRAtom* sevenLeft1 = NULL; 11111bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj 1112992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(isShadowAtom(mce,xxhash)); 1113992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(isShadowAtom(mce,yyhash)); 1114992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(isOriginalAtom(mce,xx)); 1115992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(isOriginalAtom(mce,yy)); 1116992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(sameKindedAtoms(xxhash,xx)); 1117992dff97aa9c074f86f831a76367fb55e0541da2sewardj tl_assert(sameKindedAtoms(yyhash,yy)); 11181bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj tl_assert(cmp_op == Iop_CmpORD32S || cmp_op == Iop_CmpORD32U 11191bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj || cmp_op == Iop_CmpORD64S || cmp_op == Iop_CmpORD64U); 1120992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1121a9e62a9997a442eecd38f81479c15792bca201easewardj if (0) { 1122a9e62a9997a442eecd38f81479c15792bca201easewardj ppIROp(cmp_op); VG_(printf)(" "); 1123a9e62a9997a442eecd38f81479c15792bca201easewardj ppIRExpr(xx); VG_(printf)(" "); ppIRExpr( yy ); VG_(printf)("\n"); 1124a9e62a9997a442eecd38f81479c15792bca201easewardj } 1125a9e62a9997a442eecd38f81479c15792bca201easewardj 11261bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj if (syned && isZero(yy)) { 1127a9e62a9997a442eecd38f81479c15792bca201easewardj /* fancy interpretation */ 1128a9e62a9997a442eecd38f81479c15792bca201easewardj /* if yy is zero, then it must be fully defined (zero#). */ 11291bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj tl_assert(isZero(yyhash)); 11301bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj threeLeft1 = m64 ? mkU64(3<<1) : mkU32(3<<1); 1131a9e62a9997a442eecd38f81479c15792bca201easewardj return 1132a9e62a9997a442eecd38f81479c15792bca201easewardj binop( 11331bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj opOR, 1134a9e62a9997a442eecd38f81479c15792bca201easewardj assignNew( 11357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce,ty, 1136a9e62a9997a442eecd38f81479c15792bca201easewardj binop( 11371bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj opAND, 11381bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj mkPCastTo(mce,ty, xxhash), 11391bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj threeLeft1 1140a9e62a9997a442eecd38f81479c15792bca201easewardj )), 1141a9e62a9997a442eecd38f81479c15792bca201easewardj assignNew( 11427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce,ty, 1143a9e62a9997a442eecd38f81479c15792bca201easewardj binop( 11441bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj opSHL, 1145a9e62a9997a442eecd38f81479c15792bca201easewardj assignNew( 11467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce,ty, 11471bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj binop(opSHR, xxhash, mkU8(width-1))), 1148a9e62a9997a442eecd38f81479c15792bca201easewardj mkU8(3) 1149a9e62a9997a442eecd38f81479c15792bca201easewardj )) 1150a9e62a9997a442eecd38f81479c15792bca201easewardj ); 1151a9e62a9997a442eecd38f81479c15792bca201easewardj } else { 1152a9e62a9997a442eecd38f81479c15792bca201easewardj /* standard interpretation */ 11531bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj sevenLeft1 = m64 ? mkU64(7<<1) : mkU32(7<<1); 1154a9e62a9997a442eecd38f81479c15792bca201easewardj return 1155a9e62a9997a442eecd38f81479c15792bca201easewardj binop( 11561bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj opAND, 11571bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj mkPCastTo( mce,ty, 11581bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj mkUifU(mce,ty, xxhash,yyhash)), 11591bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj sevenLeft1 1160a9e62a9997a442eecd38f81479c15792bca201easewardj ); 1161a9e62a9997a442eecd38f81479c15792bca201easewardj } 1162992dff97aa9c074f86f831a76367fb55e0541da2sewardj} 1163992dff97aa9c074f86f831a76367fb55e0541da2sewardj 1164992dff97aa9c074f86f831a76367fb55e0541da2sewardj 116595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 116695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Emit a test and complaint if something is undefined. ---*/ 116795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 116895448075345dc73986042f6dc68eb464d02bc6a8sewardj 11697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRAtom* schemeE ( MCEnv* mce, IRExpr* e ); /* fwds */ 11707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 11717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 117295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Set the annotations on a dirty helper to indicate that the stack 117395448075345dc73986042f6dc68eb464d02bc6a8sewardj pointer and instruction pointers might be read. This is the 117495448075345dc73986042f6dc68eb464d02bc6a8sewardj behaviour of all 'emit-a-complaint' style functions we might 117595448075345dc73986042f6dc68eb464d02bc6a8sewardj call. */ 117695448075345dc73986042f6dc68eb464d02bc6a8sewardj 117795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic void setHelperAnns ( MCEnv* mce, IRDirty* di ) { 117895448075345dc73986042f6dc68eb464d02bc6a8sewardj di->nFxState = 2; 11792eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[0].fx = Ifx_Read; 11802eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[0].offset = mce->layout->offset_SP; 11812eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[0].size = mce->layout->sizeof_SP; 11822eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[0].nRepeats = 0; 11832eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[0].repeatLen = 0; 11842eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[1].fx = Ifx_Read; 11852eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[1].offset = mce->layout->offset_IP; 11862eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[1].size = mce->layout->sizeof_IP; 11872eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[1].nRepeats = 0; 11882eecb74d4a8816485c97ae8e535ce25511460bc8sewardj di->fxState[1].repeatLen = 0; 1189e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1190e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1191e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1192cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Check the supplied *original* |atom| for undefinedness, and emit a 119395448075345dc73986042f6dc68eb464d02bc6a8sewardj complaint if so. Once that happens, mark it as defined. This is 119495448075345dc73986042f6dc68eb464d02bc6a8sewardj possible because the atom is either a tmp or literal. If it's a 119595448075345dc73986042f6dc68eb464d02bc6a8sewardj tmp, it will be shadowed by a tmp, and so we can set the shadow to 119695448075345dc73986042f6dc68eb464d02bc6a8sewardj be defined. In fact as mentioned above, we will have to allocate a 119795448075345dc73986042f6dc68eb464d02bc6a8sewardj new tmp to carry the new 'defined' shadow value, and update the 119895448075345dc73986042f6dc68eb464d02bc6a8sewardj original->tmp mapping accordingly; we cannot simply assign a new 1199cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj value to an existing shadow tmp as this breaks SSAness. 1200cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 1201b9e6d244e474c971ea88181de1f83a30057db9dasewardj The checks are performed, any resulting complaint emitted, and 1202b9e6d244e474c971ea88181de1f83a30057db9dasewardj |atom|'s shadow temp set to 'defined', ONLY in the case that 1203b9e6d244e474c971ea88181de1f83a30057db9dasewardj |guard| evaluates to True at run-time. If it evaluates to False 1204b9e6d244e474c971ea88181de1f83a30057db9dasewardj then no action is performed. If |guard| is NULL (the usual case) 1205b9e6d244e474c971ea88181de1f83a30057db9dasewardj then it is assumed to be always-true, and hence these actions are 1206b9e6d244e474c971ea88181de1f83a30057db9dasewardj performed unconditionally. 1207b9e6d244e474c971ea88181de1f83a30057db9dasewardj 1208b9e6d244e474c971ea88181de1f83a30057db9dasewardj This routine does not generate code to check the definedness of 1209b9e6d244e474c971ea88181de1f83a30057db9dasewardj |guard|. The caller is assumed to have taken care of that already. 121095448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 1211b9e6d244e474c971ea88181de1f83a30057db9dasewardjstatic void complainIfUndefined ( MCEnv* mce, IRAtom* atom, IRExpr *guard ) 1212e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 12137cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom* vatom; 12147cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRType ty; 12157cf97ee841afd255879bff9ff791fbabb7f95cecsewardj Int sz; 12167cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRDirty* di; 12177cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom* cond; 12187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* origin; 12197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void* fn; 12206bd9dc18c043927c1196caba20a327238a179c42florian const HChar* nm; 12217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRExpr** args; 12227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Int nargs; 12237cf97ee841afd255879bff9ff791fbabb7f95cecsewardj 12241d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // Don't do V bit tests if we're not reporting undefined value errors. 12257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) == 1) 12261d0825ff46d57f0ce83c3fa88538a42f67022eeenjn return; 12271d0825ff46d57f0ce83c3fa88538a42f67022eeenjn 1228b9e6d244e474c971ea88181de1f83a30057db9dasewardj if (guard) 1229b9e6d244e474c971ea88181de1f83a30057db9dasewardj tl_assert(isOriginalAtom(mce, guard)); 1230b9e6d244e474c971ea88181de1f83a30057db9dasewardj 123195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Since the original expression is atomic, there's no duplicated 123295448075345dc73986042f6dc68eb464d02bc6a8sewardj work generated by making multiple V-expressions for it. So we 123395448075345dc73986042f6dc68eb464d02bc6a8sewardj don't really care about the possibility that someone else may 123495448075345dc73986042f6dc68eb464d02bc6a8sewardj also create a V-interpretion for it. */ 123595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, atom)); 12367cf97ee841afd255879bff9ff791fbabb7f95cecsewardj vatom = expr2vbits( mce, atom ); 123795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vatom)); 123895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(atom, vatom)); 1239e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 12401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ty = typeOfIRExpr(mce->sb->tyenv, vatom); 1241e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 124295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* sz is only used for constructing the error message */ 12437cf97ee841afd255879bff9ff791fbabb7f95cecsewardj sz = ty==Ity_I1 ? 0 : sizeofIRType(ty); 1244e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 12457cf97ee841afd255879bff9ff791fbabb7f95cecsewardj cond = mkPCastTo( mce, Ity_I1, vatom ); 124695448075345dc73986042f6dc68eb464d02bc6a8sewardj /* cond will be 0 if all defined, and 1 if any not defined. */ 1247e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 12487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Get the origin info for the value we are about to check. At 12497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj least, if we are doing origin tracking. If not, use a dummy 12507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj zero origin. */ 12517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) == 3) { 12527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj origin = schemeE( mce, atom ); 12537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (mce->hWordTy == Ity_I64) { 12547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj origin = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, origin) ); 12557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 12567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 12577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj origin = NULL; 12587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 12597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 12607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = NULL; 12617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = NULL; 12627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = NULL; 12637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = -1; 12647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 126595448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (sz) { 126695448075345dc73986042f6dc68eb464d02bc6a8sewardj case 0: 12677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (origin) { 12687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check0_fail_w_o); 12697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check0_fail_w_o)"; 12707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_1(origin); 12717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 1; 12727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 12737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check0_fail_no_o); 12747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check0_fail_no_o)"; 12757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_0(); 12767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 0; 12777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 127895448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 127995448075345dc73986042f6dc68eb464d02bc6a8sewardj case 1: 12807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (origin) { 12817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check1_fail_w_o); 12827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check1_fail_w_o)"; 12837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_1(origin); 12847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 1; 12857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 12867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check1_fail_no_o); 12877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check1_fail_no_o)"; 12887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_0(); 12897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 0; 12907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 129195448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 129295448075345dc73986042f6dc68eb464d02bc6a8sewardj case 4: 12937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (origin) { 12947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check4_fail_w_o); 12957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check4_fail_w_o)"; 12967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_1(origin); 12977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 1; 12987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 12997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check4_fail_no_o); 13007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check4_fail_no_o)"; 13017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_0(); 13027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 0; 13037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 130495448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 130511bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj case 8: 13067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (origin) { 13077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check8_fail_w_o); 13087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check8_fail_w_o)"; 13097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_1(origin); 13107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 1; 13117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 13127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_check8_fail_no_o); 13137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_check8_fail_no_o)"; 13147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_0(); 13157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 0; 13167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 131711bcc4ec8e861aea0dc36b32f6fcc9300dddd577sewardj break; 13184c245e595b9f6300d3120408ca873f7115d9cc7dnjn case 2: 13194c245e595b9f6300d3120408ca873f7115d9cc7dnjn case 16: 13207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (origin) { 13217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_checkN_fail_w_o); 13227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_checkN_fail_w_o)"; 13237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_2( mkIRExpr_HWord( sz ), origin); 13247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 2; 13257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 13267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj fn = &MC_(helperc_value_checkN_fail_no_o); 13277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nm = "MC_(helperc_value_checkN_fail_no_o)"; 13287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj args = mkIRExprVec_1( mkIRExpr_HWord( sz ) ); 13297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nargs = 1; 13307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 133195448075345dc73986042f6dc68eb464d02bc6a8sewardj break; 13324c245e595b9f6300d3120408ca873f7115d9cc7dnjn default: 13334c245e595b9f6300d3120408ca873f7115d9cc7dnjn VG_(tool_panic)("unexpected szB"); 133495448075345dc73986042f6dc68eb464d02bc6a8sewardj } 13357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 13367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(fn); 13377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(nm); 13387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(args); 13397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(nargs >= 0 && nargs <= 2); 13407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert( (MC_(clo_mc_level) == 3 && origin != NULL) 13417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || (MC_(clo_mc_level) == 2 && origin == NULL) ); 13427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 13437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj di = unsafeIRDirty_0_N( nargs/*regparms*/, nm, 13447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(fnptr_to_fnentry)( fn ), args ); 1345b9e6d244e474c971ea88181de1f83a30057db9dasewardj di->guard = cond; // and cond is PCast-to-1(atom#) 1346b9e6d244e474c971ea88181de1f83a30057db9dasewardj 1347b9e6d244e474c971ea88181de1f83a30057db9dasewardj /* If the complaint is to be issued under a guard condition, AND 1348b9e6d244e474c971ea88181de1f83a30057db9dasewardj that into the guard condition for the helper call. */ 1349b9e6d244e474c971ea88181de1f83a30057db9dasewardj if (guard) { 1350b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRAtom *g1 = assignNew('V', mce, Ity_I32, unop(Iop_1Uto32, di->guard)); 1351b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRAtom *g2 = assignNew('V', mce, Ity_I32, unop(Iop_1Uto32, guard)); 1352b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRAtom *e = assignNew('V', mce, Ity_I32, binop(Iop_And32, g1, g2)); 1353b9e6d244e474c971ea88181de1f83a30057db9dasewardj di->guard = assignNew('V', mce, Ity_I1, unop(Iop_32to1, e)); 1354b9e6d244e474c971ea88181de1f83a30057db9dasewardj } 1355434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 135695448075345dc73986042f6dc68eb464d02bc6a8sewardj setHelperAnns( mce, di ); 13577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(di)); 135895448075345dc73986042f6dc68eb464d02bc6a8sewardj 1359b9e6d244e474c971ea88181de1f83a30057db9dasewardj /* If |atom| is shadowed by an IRTemp, set the shadow tmp to be 1360b9e6d244e474c971ea88181de1f83a30057db9dasewardj defined -- but only in the case where the guard evaluates to 1361b9e6d244e474c971ea88181de1f83a30057db9dasewardj True at run-time. Do the update by setting the orig->shadow 1362b9e6d244e474c971ea88181de1f83a30057db9dasewardj mapping for tmp to reflect the fact that this shadow is getting 1363b9e6d244e474c971ea88181de1f83a30057db9dasewardj a new value. */ 1364710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj tl_assert(isIRAtom(vatom)); 136595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* sameKindedAtoms ... */ 13660b9d74abd0a663b530d290b2b788ddeda46e5400sewardj if (vatom->tag == Iex_RdTmp) { 13670b9d74abd0a663b530d290b2b788ddeda46e5400sewardj tl_assert(atom->tag == Iex_RdTmp); 1368b9e6d244e474c971ea88181de1f83a30057db9dasewardj if (guard == NULL) { 1369b9e6d244e474c971ea88181de1f83a30057db9dasewardj // guard is 'always True', hence update unconditionally 1370b9e6d244e474c971ea88181de1f83a30057db9dasewardj newShadowTmpV(mce, atom->Iex.RdTmp.tmp); 1371b9e6d244e474c971ea88181de1f83a30057db9dasewardj assign('V', mce, findShadowTmpV(mce, atom->Iex.RdTmp.tmp), 1372b9e6d244e474c971ea88181de1f83a30057db9dasewardj definedOfType(ty)); 1373b9e6d244e474c971ea88181de1f83a30057db9dasewardj } else { 1374b9e6d244e474c971ea88181de1f83a30057db9dasewardj // update the temp only conditionally. Do this by copying 1375b9e6d244e474c971ea88181de1f83a30057db9dasewardj // its old value when the guard is False. 1376b9e6d244e474c971ea88181de1f83a30057db9dasewardj // The old value .. 1377b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRTemp old_tmpV = findShadowTmpV(mce, atom->Iex.RdTmp.tmp); 1378b9e6d244e474c971ea88181de1f83a30057db9dasewardj newShadowTmpV(mce, atom->Iex.RdTmp.tmp); 1379b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRAtom* new_tmpV 1380b9e6d244e474c971ea88181de1f83a30057db9dasewardj = assignNew('V', mce, shadowTypeV(ty), 1381b9e6d244e474c971ea88181de1f83a30057db9dasewardj IRExpr_ITE(guard, definedOfType(ty), 1382b9e6d244e474c971ea88181de1f83a30057db9dasewardj mkexpr(old_tmpV))); 1383b9e6d244e474c971ea88181de1f83a30057db9dasewardj assign('V', mce, findShadowTmpV(mce, atom->Iex.RdTmp.tmp), new_tmpV); 1384b9e6d244e474c971ea88181de1f83a30057db9dasewardj } 138595448075345dc73986042f6dc68eb464d02bc6a8sewardj } 1386e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1387e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1388e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 138995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 139095448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Shadowing PUTs/GETs, and indexed variants thereof ---*/ 139195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 139295448075345dc73986042f6dc68eb464d02bc6a8sewardj 139395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Examine the always-defined sections declared in layout to see if 139495448075345dc73986042f6dc68eb464d02bc6a8sewardj the (offset,size) section is within one. Note, is is an error to 139595448075345dc73986042f6dc68eb464d02bc6a8sewardj partially fall into such a region: (offset,size) should either be 139695448075345dc73986042f6dc68eb464d02bc6a8sewardj completely in such a region or completely not-in such a region. 139795448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 139895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size ) 1399e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 140095448075345dc73986042f6dc68eb464d02bc6a8sewardj Int minoffD, maxoffD, i; 140195448075345dc73986042f6dc68eb464d02bc6a8sewardj Int minoff = offset; 140295448075345dc73986042f6dc68eb464d02bc6a8sewardj Int maxoff = minoff + size - 1; 140395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert((minoff & ~0xFFFF) == 0); 140495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert((maxoff & ~0xFFFF) == 0); 140595448075345dc73986042f6dc68eb464d02bc6a8sewardj 140695448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; i < mce->layout->n_alwaysDefd; i++) { 140795448075345dc73986042f6dc68eb464d02bc6a8sewardj minoffD = mce->layout->alwaysDefd[i].offset; 140895448075345dc73986042f6dc68eb464d02bc6a8sewardj maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1; 140995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert((minoffD & ~0xFFFF) == 0); 141095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert((maxoffD & ~0xFFFF) == 0); 141195448075345dc73986042f6dc68eb464d02bc6a8sewardj 141295448075345dc73986042f6dc68eb464d02bc6a8sewardj if (maxoff < minoffD || maxoffD < minoff) 141395448075345dc73986042f6dc68eb464d02bc6a8sewardj continue; /* no overlap */ 141495448075345dc73986042f6dc68eb464d02bc6a8sewardj if (minoff >= minoffD && maxoff <= maxoffD) 141595448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; /* completely contained in an always-defd section */ 141695448075345dc73986042f6dc68eb464d02bc6a8sewardj 141795448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck:isAlwaysDefd:partial overlap"); 141895448075345dc73986042f6dc68eb464d02bc6a8sewardj } 141995448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; /* could not find any containing section */ 1420e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1421e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1422e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 142395448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Generate into bb suitable actions to shadow this Put. If the state 142495448075345dc73986042f6dc68eb464d02bc6a8sewardj slice is marked 'always defined', do nothing. Otherwise, write the 142595448075345dc73986042f6dc68eb464d02bc6a8sewardj supplied V bits to the shadow state. We can pass in either an 142695448075345dc73986042f6dc68eb464d02bc6a8sewardj original atom or a V-atom, but not both. In the former case the 142795448075345dc73986042f6dc68eb464d02bc6a8sewardj relevant V-bits are then generated from the original. 1428434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian We assume here, that the definedness of GUARD has already been checked. 142995448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 1430e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnstatic 143195448075345dc73986042f6dc68eb464d02bc6a8sewardjvoid do_shadow_PUT ( MCEnv* mce, Int offset, 1432434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRAtom* atom, IRAtom* vatom, IRExpr *guard ) 1433e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 14347cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRType ty; 14351d0825ff46d57f0ce83c3fa88538a42f67022eeenjn 14361d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // Don't do shadow PUTs if we're not doing undefined value checking. 14371d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // Their absence lets Vex's optimiser remove all the shadow computation 14381d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // that they depend on, which includes GETs of the shadow registers. 14397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) == 1) 14401d0825ff46d57f0ce83c3fa88538a42f67022eeenjn return; 14411d0825ff46d57f0ce83c3fa88538a42f67022eeenjn 144295448075345dc73986042f6dc68eb464d02bc6a8sewardj if (atom) { 144395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(!vatom); 144495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, atom)); 144595448075345dc73986042f6dc68eb464d02bc6a8sewardj vatom = expr2vbits( mce, atom ); 144695448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 144795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(vatom); 144895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce, vatom)); 1449e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 145095448075345dc73986042f6dc68eb464d02bc6a8sewardj 14511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ty = typeOfIRExpr(mce->sb->tyenv, vatom); 145295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(ty != Ity_I1); 1453b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tl_assert(ty != Ity_I128); 145495448075345dc73986042f6dc68eb464d02bc6a8sewardj if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { 145595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* later: no ... */ 145695448075345dc73986042f6dc68eb464d02bc6a8sewardj /* emit code to emit a complaint if any of the vbits are 1. */ 145795448075345dc73986042f6dc68eb464d02bc6a8sewardj /* complainIfUndefined(mce, atom); */ 145895448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 145995448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Do a plain shadow Put. */ 1460434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian if (guard) { 1461434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian /* If the guard expression evaluates to false we simply Put the value 1462434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian that is already stored in the guest state slot */ 1463434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRAtom *cond, *iffalse; 1464434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 1465cc9616506450cb02944b62dc07774c29462bfefcsewardj cond = assignNew('V', mce, Ity_I1, guard); 1466434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian iffalse = assignNew('V', mce, ty, 1467434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRExpr_Get(offset + mce->layout->total_sizeB, ty)); 14685686b2d7e97a6f65e436531dac999a52a3d3dac9florian vatom = assignNew('V', mce, ty, IRExpr_ITE(cond, vatom, iffalse)); 1469434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian } 1470434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian stmt( 'V', mce, IRStmt_Put( offset + mce->layout->total_sizeB, vatom )); 1471e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 1472e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1473e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 147495448075345dc73986042f6dc68eb464d02bc6a8sewardj 147595448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the 147695448075345dc73986042f6dc68eb464d02bc6a8sewardj given GETI (passed in in pieces). 147795448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 147895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 1479d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florianvoid do_shadow_PUTI ( MCEnv* mce, IRPutI *puti) 1480e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 14817cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom* vatom; 14827cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRType ty, tyS; 14837cf97ee841afd255879bff9ff791fbabb7f95cecsewardj Int arrSize;; 1484d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian IRRegArray* descr = puti->descr; 1485d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian IRAtom* ix = puti->ix; 1486d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian Int bias = puti->bias; 1487d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian IRAtom* atom = puti->data; 14887cf97ee841afd255879bff9ff791fbabb7f95cecsewardj 14891d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // Don't do shadow PUTIs if we're not doing undefined value checking. 14901d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // Their absence lets Vex's optimiser remove all the shadow computation 14911d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // that they depend on, which includes GETIs of the shadow registers. 14927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) == 1) 14931d0825ff46d57f0ce83c3fa88538a42f67022eeenjn return; 14941d0825ff46d57f0ce83c3fa88538a42f67022eeenjn 149595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,atom)); 14967cf97ee841afd255879bff9ff791fbabb7f95cecsewardj vatom = expr2vbits( mce, atom ); 149795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(atom, vatom)); 14987cf97ee841afd255879bff9ff791fbabb7f95cecsewardj ty = descr->elemTy; 14997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tyS = shadowTypeV(ty); 15007cf97ee841afd255879bff9ff791fbabb7f95cecsewardj arrSize = descr->nElems * sizeofIRType(ty); 150195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(ty != Ity_I1); 150295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,ix)); 1503b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, ix, NULL); 150495448075345dc73986042f6dc68eb464d02bc6a8sewardj if (isAlwaysDefd(mce, descr->base, arrSize)) { 150595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* later: no ... */ 150695448075345dc73986042f6dc68eb464d02bc6a8sewardj /* emit code to emit a complaint if any of the vbits are 1. */ 150795448075345dc73986042f6dc68eb464d02bc6a8sewardj /* complainIfUndefined(mce, atom); */ 150895448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 150995448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Do a cloned version of the Put that refers to the shadow 151095448075345dc73986042f6dc68eb464d02bc6a8sewardj area. */ 15110b9d74abd0a663b530d290b2b788ddeda46e5400sewardj IRRegArray* new_descr 15120b9d74abd0a663b530d290b2b788ddeda46e5400sewardj = mkIRRegArray( descr->base + mce->layout->total_sizeB, 15130b9d74abd0a663b530d290b2b788ddeda46e5400sewardj tyS, descr->nElems); 1514d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian stmt( 'V', mce, IRStmt_PutI( mkIRPutI(new_descr, ix, bias, vatom) )); 15158ec2cfcb9c1267fd7b20529f1b95973a9712b872sewardj } 151695448075345dc73986042f6dc68eb464d02bc6a8sewardj} 15178ec2cfcb9c1267fd7b20529f1b95973a9712b872sewardj 1518e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 151995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the 152095448075345dc73986042f6dc68eb464d02bc6a8sewardj given GET (passed in in pieces). 152195448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 152295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 152395448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty ) 152495448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 15257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRType tyS = shadowTypeV(ty); 152695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(ty != Ity_I1); 1527b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj tl_assert(ty != Ity_I128); 152895448075345dc73986042f6dc68eb464d02bc6a8sewardj if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { 152995448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Always defined, return all zeroes of the relevant type */ 153095448075345dc73986042f6dc68eb464d02bc6a8sewardj return definedOfType(tyS); 153195448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 153295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* return a cloned version of the Get that refers to the shadow 153395448075345dc73986042f6dc68eb464d02bc6a8sewardj area. */ 15347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* FIXME: this isn't an atom! */ 153595448075345dc73986042f6dc68eb464d02bc6a8sewardj return IRExpr_Get( offset + mce->layout->total_sizeB, tyS ); 153695448075345dc73986042f6dc68eb464d02bc6a8sewardj } 153795448075345dc73986042f6dc68eb464d02bc6a8sewardj} 1538e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1539e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 154095448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Return an expression which contains the V bits corresponding to the 154195448075345dc73986042f6dc68eb464d02bc6a8sewardj given GETI (passed in in pieces). 154295448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 154395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 15440b9d74abd0a663b530d290b2b788ddeda46e5400sewardjIRExpr* shadow_GETI ( MCEnv* mce, 15450b9d74abd0a663b530d290b2b788ddeda46e5400sewardj IRRegArray* descr, IRAtom* ix, Int bias ) 154695448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 154795448075345dc73986042f6dc68eb464d02bc6a8sewardj IRType ty = descr->elemTy; 15487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRType tyS = shadowTypeV(ty); 154995448075345dc73986042f6dc68eb464d02bc6a8sewardj Int arrSize = descr->nElems * sizeofIRType(ty); 155095448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(ty != Ity_I1); 155195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,ix)); 1552b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, ix, NULL); 155395448075345dc73986042f6dc68eb464d02bc6a8sewardj if (isAlwaysDefd(mce, descr->base, arrSize)) { 155495448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Always defined, return all zeroes of the relevant type */ 155595448075345dc73986042f6dc68eb464d02bc6a8sewardj return definedOfType(tyS); 155695448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 155795448075345dc73986042f6dc68eb464d02bc6a8sewardj /* return a cloned version of the Get that refers to the shadow 155895448075345dc73986042f6dc68eb464d02bc6a8sewardj area. */ 15590b9d74abd0a663b530d290b2b788ddeda46e5400sewardj IRRegArray* new_descr 15600b9d74abd0a663b530d290b2b788ddeda46e5400sewardj = mkIRRegArray( descr->base + mce->layout->total_sizeB, 15610b9d74abd0a663b530d290b2b788ddeda46e5400sewardj tyS, descr->nElems); 156295448075345dc73986042f6dc68eb464d02bc6a8sewardj return IRExpr_GetI( new_descr, ix, bias ); 156395448075345dc73986042f6dc68eb464d02bc6a8sewardj } 156495448075345dc73986042f6dc68eb464d02bc6a8sewardj} 1565e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1566d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj 156795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 156895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generating approximations for unknown operations, ---*/ 156995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- using lazy-propagate semantics ---*/ 157095448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 1571d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj 157295448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Lazy propagation of undefinedness from two values, resulting in the 157395448075345dc73986042f6dc68eb464d02bc6a8sewardj specified shadow type. 157495448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 157595448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 157695448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 ) 157795448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 157895448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* at; 15791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1); 15801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2); 158195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,va1)); 158295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,va2)); 158337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj 158437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj /* The general case is inefficient because PCast is an expensive 158537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj operation. Here are some special cases which use PCast only 158637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj once rather than twice. */ 158737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj 158837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj /* I64 x I64 -> I64 */ 158937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I64) { 159037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj if (0) VG_(printf)("mkLazy2: I64 x I64 -> I64\n"); 159137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj at = mkUifU(mce, Ity_I64, va1, va2); 159237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj at = mkPCastTo(mce, Ity_I64, at); 159337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj return at; 159437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj } 159537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj 159637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj /* I64 x I64 -> I32 */ 159737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj if (t1 == Ity_I64 && t2 == Ity_I64 && finalVty == Ity_I32) { 159837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj if (0) VG_(printf)("mkLazy2: I64 x I64 -> I32\n"); 159937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj at = mkUifU(mce, Ity_I64, va1, va2); 160037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj at = mkPCastTo(mce, Ity_I32, at); 160137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj return at; 160237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj } 160337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj 160437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj if (0) { 160537c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj VG_(printf)("mkLazy2 "); 160637c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj ppIRType(t1); 160737c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj VG_(printf)("_"); 160837c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj ppIRType(t2); 160937c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj VG_(printf)("_"); 161037c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj ppIRType(finalVty); 161137c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj VG_(printf)("\n"); 161237c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj } 161337c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj 161437c31ccc12f6b479b06fbe94f8f74814fb553c28sewardj /* General case: force everything via 32-bit intermediaries. */ 161595448075345dc73986042f6dc68eb464d02bc6a8sewardj at = mkPCastTo(mce, Ity_I32, va1); 161695448075345dc73986042f6dc68eb464d02bc6a8sewardj at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2)); 161795448075345dc73986042f6dc68eb464d02bc6a8sewardj at = mkPCastTo(mce, finalVty, at); 161895448075345dc73986042f6dc68eb464d02bc6a8sewardj return at; 161995448075345dc73986042f6dc68eb464d02bc6a8sewardj} 1620d077f533d5422966ab9f013ccbeb0c8ecc8506ffsewardj 1621e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1622ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj/* 3-arg version of the above. */ 1623ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardjstatic 1624ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardjIRAtom* mkLazy3 ( MCEnv* mce, IRType finalVty, 1625ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* va1, IRAtom* va2, IRAtom* va3 ) 1626ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj{ 1627ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* at; 16281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1); 16291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2); 16301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3); 1631ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,va1)); 1632ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,va2)); 1633ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,va3)); 1634ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1635ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* The general case is inefficient because PCast is an expensive 1636ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj operation. Here are some special cases which use PCast only 1637ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj twice rather than three times. */ 1638ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1639ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* I32 x I64 x I64 -> I64 */ 1640ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* Standard FP idiom: rm x FParg1 x FParg2 -> FPresult */ 1641ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64 1642ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj && finalVty == Ity_I64) { 1643ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj if (0) VG_(printf)("mkLazy3: I32 x I64 x I64 -> I64\n"); 1644ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* Widen 1st arg to I64. Since 1st arg is typically a rounding 1645ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj mode indication which is fully defined, this should get 1646ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj folded out later. */ 1647ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkPCastTo(mce, Ity_I64, va1); 1648ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* Now fold in 2nd and 3rd args. */ 1649ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkUifU(mce, Ity_I64, at, va2); 1650ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkUifU(mce, Ity_I64, at, va3); 1651ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* and PCast once again. */ 1652ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkPCastTo(mce, Ity_I64, at); 1653ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj return at; 1654ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj } 1655ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1656fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* I32 x I8 x I64 -> I64 */ 1657fb583cbc61a1d82a4a970887a6d54737038b71b6carll if (t1 == Ity_I32 && t2 == Ity_I8 && t3 == Ity_I64 1658fb583cbc61a1d82a4a970887a6d54737038b71b6carll && finalVty == Ity_I64) { 1659fb583cbc61a1d82a4a970887a6d54737038b71b6carll if (0) VG_(printf)("mkLazy3: I32 x I8 x I64 -> I64\n"); 1660fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* Widen 1st and 2nd args to I64. Since 1st arg is typically a 1661fb583cbc61a1d82a4a970887a6d54737038b71b6carll * rounding mode indication which is fully defined, this should 1662fb583cbc61a1d82a4a970887a6d54737038b71b6carll * get folded out later. 1663fb583cbc61a1d82a4a970887a6d54737038b71b6carll */ 1664fb583cbc61a1d82a4a970887a6d54737038b71b6carll IRAtom* at1 = mkPCastTo(mce, Ity_I64, va1); 1665fb583cbc61a1d82a4a970887a6d54737038b71b6carll IRAtom* at2 = mkPCastTo(mce, Ity_I64, va2); 1666fb583cbc61a1d82a4a970887a6d54737038b71b6carll at = mkUifU(mce, Ity_I64, at1, at2); // UifU(PCast(va1), PCast(va2)) 1667fb583cbc61a1d82a4a970887a6d54737038b71b6carll at = mkUifU(mce, Ity_I64, at, va3); 1668fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* and PCast once again. */ 1669fb583cbc61a1d82a4a970887a6d54737038b71b6carll at = mkPCastTo(mce, Ity_I64, at); 1670fb583cbc61a1d82a4a970887a6d54737038b71b6carll return at; 1671fb583cbc61a1d82a4a970887a6d54737038b71b6carll } 1672fb583cbc61a1d82a4a970887a6d54737038b71b6carll 1673453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj /* I32 x I64 x I64 -> I32 */ 1674453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64 1675453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj && finalVty == Ity_I32) { 167659570ffbe31930ab4d678754daaeec0715117a3dsewardj if (0) VG_(printf)("mkLazy3: I32 x I64 x I64 -> I32\n"); 1677453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj at = mkPCastTo(mce, Ity_I64, va1); 1678453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj at = mkUifU(mce, Ity_I64, at, va2); 1679453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj at = mkUifU(mce, Ity_I64, at, va3); 1680453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj at = mkPCastTo(mce, Ity_I32, at); 1681453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj return at; 1682453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj } 1683453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj 168459570ffbe31930ab4d678754daaeec0715117a3dsewardj /* I32 x I32 x I32 -> I32 */ 168559570ffbe31930ab4d678754daaeec0715117a3dsewardj /* 32-bit FP idiom, as (eg) happens on ARM */ 168659570ffbe31930ab4d678754daaeec0715117a3dsewardj if (t1 == Ity_I32 && t2 == Ity_I32 && t3 == Ity_I32 168759570ffbe31930ab4d678754daaeec0715117a3dsewardj && finalVty == Ity_I32) { 168859570ffbe31930ab4d678754daaeec0715117a3dsewardj if (0) VG_(printf)("mkLazy3: I32 x I32 x I32 -> I32\n"); 168959570ffbe31930ab4d678754daaeec0715117a3dsewardj at = va1; 169059570ffbe31930ab4d678754daaeec0715117a3dsewardj at = mkUifU(mce, Ity_I32, at, va2); 169159570ffbe31930ab4d678754daaeec0715117a3dsewardj at = mkUifU(mce, Ity_I32, at, va3); 169259570ffbe31930ab4d678754daaeec0715117a3dsewardj at = mkPCastTo(mce, Ity_I32, at); 169359570ffbe31930ab4d678754daaeec0715117a3dsewardj return at; 169459570ffbe31930ab4d678754daaeec0715117a3dsewardj } 169559570ffbe31930ab4d678754daaeec0715117a3dsewardj 1696b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32 x I128 x I128 -> I128 */ 1697b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Standard FP idiom: rm x FParg1 x FParg2 -> FPresult */ 1698b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (t1 == Ity_I32 && t2 == Ity_I128 && t3 == Ity_I128 1699b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj && finalVty == Ity_I128) { 1700b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (0) VG_(printf)("mkLazy3: I32 x I128 x I128 -> I128\n"); 1701b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Widen 1st arg to I128. Since 1st arg is typically a rounding 1702b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj mode indication which is fully defined, this should get 1703b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj folded out later. */ 1704b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkPCastTo(mce, Ity_I128, va1); 1705b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Now fold in 2nd and 3rd args. */ 1706b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkUifU(mce, Ity_I128, at, va2); 1707b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkUifU(mce, Ity_I128, at, va3); 1708b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* and PCast once again. */ 1709b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkPCastTo(mce, Ity_I128, at); 1710b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return at; 1711b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 1712fb583cbc61a1d82a4a970887a6d54737038b71b6carll 1713fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* I32 x I8 x I128 -> I128 */ 1714fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* Standard FP idiom: rm x FParg1 x FParg2 -> FPresult */ 1715fb583cbc61a1d82a4a970887a6d54737038b71b6carll if (t1 == Ity_I32 && t2 == Ity_I8 && t3 == Ity_I128 1716fb583cbc61a1d82a4a970887a6d54737038b71b6carll && finalVty == Ity_I128) { 1717fb583cbc61a1d82a4a970887a6d54737038b71b6carll if (0) VG_(printf)("mkLazy3: I32 x I8 x I128 -> I128\n"); 1718a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj /* Use I64 as an intermediate type, which means PCasting all 3 1719a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj args to I64 to start with. 1st arg is typically a rounding 1720a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj mode indication which is fully defined, so we hope that it 1721a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj will get folded out later. */ 1722fb583cbc61a1d82a4a970887a6d54737038b71b6carll IRAtom* at1 = mkPCastTo(mce, Ity_I64, va1); 1723fb583cbc61a1d82a4a970887a6d54737038b71b6carll IRAtom* at2 = mkPCastTo(mce, Ity_I64, va2); 1724a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj IRAtom* at3 = mkPCastTo(mce, Ity_I64, va3); 1725a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj /* Now UifU all three together. */ 1726fb583cbc61a1d82a4a970887a6d54737038b71b6carll at = mkUifU(mce, Ity_I64, at1, at2); // UifU(PCast(va1), PCast(va2)) 1727a28c43c3aac5a8b1c5cdf4e47acab1b1f79de778sewardj at = mkUifU(mce, Ity_I64, at, at3); // ... `UifU` PCast(va3) 1728fb583cbc61a1d82a4a970887a6d54737038b71b6carll /* and PCast once again. */ 1729fb583cbc61a1d82a4a970887a6d54737038b71b6carll at = mkPCastTo(mce, Ity_I128, at); 1730fb583cbc61a1d82a4a970887a6d54737038b71b6carll return at; 1731fb583cbc61a1d82a4a970887a6d54737038b71b6carll } 1732453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj if (1) { 1733453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj VG_(printf)("mkLazy3: "); 1734ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ppIRType(t1); 1735453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj VG_(printf)(" x "); 1736ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ppIRType(t2); 1737453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj VG_(printf)(" x "); 1738ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ppIRType(t3); 1739453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj VG_(printf)(" -> "); 1740ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ppIRType(finalVty); 1741ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj VG_(printf)("\n"); 1742ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj } 1743ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1744453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj tl_assert(0); 1745ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj /* General case: force everything via 32-bit intermediaries. */ 1746453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj /* 1747ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkPCastTo(mce, Ity_I32, va1); 1748ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2)); 1749ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va3)); 1750ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj at = mkPCastTo(mce, finalVty, at); 1751ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj return at; 1752453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj */ 1753ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj} 1754ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1755ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 1756e91cea71129edc807428c8228d0d9f5b13894a5asewardj/* 4-arg version of the above. */ 1757e91cea71129edc807428c8228d0d9f5b13894a5asewardjstatic 1758e91cea71129edc807428c8228d0d9f5b13894a5asewardjIRAtom* mkLazy4 ( MCEnv* mce, IRType finalVty, 1759e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 ) 1760e91cea71129edc807428c8228d0d9f5b13894a5asewardj{ 1761e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* at; 17621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1); 17631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2); 17641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3); 17651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType t4 = typeOfIRExpr(mce->sb->tyenv, va4); 1766e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,va1)); 1767e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,va2)); 1768e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,va3)); 1769e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,va4)); 1770e91cea71129edc807428c8228d0d9f5b13894a5asewardj 1771e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* The general case is inefficient because PCast is an expensive 1772e91cea71129edc807428c8228d0d9f5b13894a5asewardj operation. Here are some special cases which use PCast only 1773e91cea71129edc807428c8228d0d9f5b13894a5asewardj twice rather than three times. */ 1774e91cea71129edc807428c8228d0d9f5b13894a5asewardj 1775e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* I32 x I64 x I64 x I64 -> I64 */ 1776e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* Standard FP idiom: rm x FParg1 x FParg2 x FParg3 -> FPresult */ 1777e91cea71129edc807428c8228d0d9f5b13894a5asewardj if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64 && t4 == Ity_I64 1778e91cea71129edc807428c8228d0d9f5b13894a5asewardj && finalVty == Ity_I64) { 1779e91cea71129edc807428c8228d0d9f5b13894a5asewardj if (0) VG_(printf)("mkLazy4: I32 x I64 x I64 x I64 -> I64\n"); 1780e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* Widen 1st arg to I64. Since 1st arg is typically a rounding 1781e91cea71129edc807428c8228d0d9f5b13894a5asewardj mode indication which is fully defined, this should get 1782e91cea71129edc807428c8228d0d9f5b13894a5asewardj folded out later. */ 1783e91cea71129edc807428c8228d0d9f5b13894a5asewardj at = mkPCastTo(mce, Ity_I64, va1); 1784e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* Now fold in 2nd, 3rd, 4th args. */ 1785e91cea71129edc807428c8228d0d9f5b13894a5asewardj at = mkUifU(mce, Ity_I64, at, va2); 1786e91cea71129edc807428c8228d0d9f5b13894a5asewardj at = mkUifU(mce, Ity_I64, at, va3); 1787e91cea71129edc807428c8228d0d9f5b13894a5asewardj at = mkUifU(mce, Ity_I64, at, va4); 1788e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* and PCast once again. */ 1789e91cea71129edc807428c8228d0d9f5b13894a5asewardj at = mkPCastTo(mce, Ity_I64, at); 1790e91cea71129edc807428c8228d0d9f5b13894a5asewardj return at; 1791e91cea71129edc807428c8228d0d9f5b13894a5asewardj } 1792b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32 x I32 x I32 x I32 -> I32 */ 1793b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Standard FP idiom: rm x FParg1 x FParg2 x FParg3 -> FPresult */ 1794b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (t1 == Ity_I32 && t2 == Ity_I32 && t3 == Ity_I32 && t4 == Ity_I32 1795b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj && finalVty == Ity_I32) { 1796b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (0) VG_(printf)("mkLazy4: I32 x I32 x I32 x I32 -> I32\n"); 1797b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = va1; 1798b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Now fold in 2nd, 3rd, 4th args. */ 1799b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkUifU(mce, Ity_I32, at, va2); 1800b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkUifU(mce, Ity_I32, at, va3); 1801b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkUifU(mce, Ity_I32, at, va4); 1802b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj at = mkPCastTo(mce, Ity_I32, at); 1803b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return at; 1804b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 1805e91cea71129edc807428c8228d0d9f5b13894a5asewardj 1806e91cea71129edc807428c8228d0d9f5b13894a5asewardj if (1) { 1807453e8f85186bf9f35c870059d5f4decf65f9e0aasewardj VG_(printf)("mkLazy4: "); 1808e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIRType(t1); 1809e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(printf)(" x "); 1810e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIRType(t2); 1811e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(printf)(" x "); 1812e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIRType(t3); 1813e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(printf)(" x "); 1814e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIRType(t4); 1815e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(printf)(" -> "); 1816e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIRType(finalVty); 1817e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(printf)("\n"); 1818e91cea71129edc807428c8228d0d9f5b13894a5asewardj } 1819e91cea71129edc807428c8228d0d9f5b13894a5asewardj 1820e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(0); 1821e91cea71129edc807428c8228d0d9f5b13894a5asewardj} 1822e91cea71129edc807428c8228d0d9f5b13894a5asewardj 1823e91cea71129edc807428c8228d0d9f5b13894a5asewardj 182495448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Do the lazy propagation game from a null-terminated vector of 182595448075345dc73986042f6dc68eb464d02bc6a8sewardj atoms. This is presumably the arguments to a helper call, so the 182695448075345dc73986042f6dc68eb464d02bc6a8sewardj IRCallee info is also supplied in order that we can know which 182795448075345dc73986042f6dc68eb464d02bc6a8sewardj arguments should be ignored (via the .mcx_mask field). 182895448075345dc73986042f6dc68eb464d02bc6a8sewardj*/ 182995448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 183095448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* mkLazyN ( MCEnv* mce, 183195448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom** exprvec, IRType finalVtype, IRCallee* cee ) 183295448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 18334cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj Int i; 183495448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* here; 18354cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj IRAtom* curr; 18364cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj IRType mergeTy; 18379943003f546be63b208d02ab57fd31b1c00b8abasewardj Bool mergeTy64 = True; 18384cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 18394cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj /* Decide on the type of the merge intermediary. If all relevant 18404cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj args are I64, then it's I64. In all other circumstances, use 18414cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj I32. */ 18424cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj for (i = 0; exprvec[i]; i++) { 18434cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj tl_assert(i < 32); 18444cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj tl_assert(isOriginalAtom(mce, exprvec[i])); 18454cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj if (cee->mcx_mask & (1<<i)) 18464cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj continue; 18471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (typeOfIRExpr(mce->sb->tyenv, exprvec[i]) != Ity_I64) 18484cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj mergeTy64 = False; 18494cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj } 18504cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 18514cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj mergeTy = mergeTy64 ? Ity_I64 : Ity_I32; 18524cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj curr = definedOfType(mergeTy); 18534cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj 185495448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; exprvec[i]; i++) { 185595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(i < 32); 185695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, exprvec[i])); 185795448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Only take notice of this arg if the callee's mc-exclusion 185895448075345dc73986042f6dc68eb464d02bc6a8sewardj mask does not say it is to be excluded. */ 185995448075345dc73986042f6dc68eb464d02bc6a8sewardj if (cee->mcx_mask & (1<<i)) { 186095448075345dc73986042f6dc68eb464d02bc6a8sewardj /* the arg is to be excluded from definedness checking. Do 186195448075345dc73986042f6dc68eb464d02bc6a8sewardj nothing. */ 186295448075345dc73986042f6dc68eb464d02bc6a8sewardj if (0) VG_(printf)("excluding %s(%d)\n", cee->name, i); 186395448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 186495448075345dc73986042f6dc68eb464d02bc6a8sewardj /* calculate the arg's definedness, and pessimistically merge 186595448075345dc73986042f6dc68eb464d02bc6a8sewardj it in. */ 18664cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj here = mkPCastTo( mce, mergeTy, expr2vbits(mce, exprvec[i]) ); 18674cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj curr = mergeTy64 18684cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj ? mkUifU64(mce, here, curr) 18694cc684b9b2bc521d3a6f1f415dbe8d77f91401fdsewardj : mkUifU32(mce, here, curr); 187095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 187195448075345dc73986042f6dc68eb464d02bc6a8sewardj } 187295448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, finalVtype, curr ); 187395448075345dc73986042f6dc68eb464d02bc6a8sewardj} 1874e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1875e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 187695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 187795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generating expensive sequences for exact carry-chain ---*/ 187895448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- propagation in add/sub and related operations. ---*/ 187995448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 1880e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 188195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 1882d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardjIRAtom* expensiveAddSub ( MCEnv* mce, 1883d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj Bool add, 1884d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRType ty, 1885d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRAtom* qaa, IRAtom* qbb, 1886d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRAtom* aa, IRAtom* bb ) 188795448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 18887cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom *a_min, *b_min, *a_max, *b_max; 1889d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IROp opAND, opOR, opXOR, opNOT, opADD, opSUB; 18907cf97ee841afd255879bff9ff791fbabb7f95cecsewardj 189195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,qaa)); 189295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,qbb)); 189395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,aa)); 189495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,bb)); 189595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(qaa,aa)); 189695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(qbb,bb)); 189795448075345dc73986042f6dc68eb464d02bc6a8sewardj 1898d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj switch (ty) { 1899d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ity_I32: 1900d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opAND = Iop_And32; 1901d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opOR = Iop_Or32; 1902d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opXOR = Iop_Xor32; 1903d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opNOT = Iop_Not32; 1904d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opADD = Iop_Add32; 1905d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj opSUB = Iop_Sub32; 1906d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj break; 1907d9774d73807c7292c72e1254119d6bd8ded81f15tom case Ity_I64: 1908d9774d73807c7292c72e1254119d6bd8ded81f15tom opAND = Iop_And64; 1909d9774d73807c7292c72e1254119d6bd8ded81f15tom opOR = Iop_Or64; 1910d9774d73807c7292c72e1254119d6bd8ded81f15tom opXOR = Iop_Xor64; 1911d9774d73807c7292c72e1254119d6bd8ded81f15tom opNOT = Iop_Not64; 1912d9774d73807c7292c72e1254119d6bd8ded81f15tom opADD = Iop_Add64; 1913d9774d73807c7292c72e1254119d6bd8ded81f15tom opSUB = Iop_Sub64; 1914d9774d73807c7292c72e1254119d6bd8ded81f15tom break; 1915d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj default: 1916d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj VG_(tool_panic)("expensiveAddSub"); 1917d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj } 191895448075345dc73986042f6dc68eb464d02bc6a8sewardj 191995448075345dc73986042f6dc68eb464d02bc6a8sewardj // a_min = aa & ~qaa 19207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj a_min = assignNew('V', mce,ty, 192195448075345dc73986042f6dc68eb464d02bc6a8sewardj binop(opAND, aa, 19227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, unop(opNOT, qaa)))); 192395448075345dc73986042f6dc68eb464d02bc6a8sewardj 192495448075345dc73986042f6dc68eb464d02bc6a8sewardj // b_min = bb & ~qbb 19257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj b_min = assignNew('V', mce,ty, 192695448075345dc73986042f6dc68eb464d02bc6a8sewardj binop(opAND, bb, 19277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, unop(opNOT, qbb)))); 192895448075345dc73986042f6dc68eb464d02bc6a8sewardj 192995448075345dc73986042f6dc68eb464d02bc6a8sewardj // a_max = aa | qaa 19307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj a_max = assignNew('V', mce,ty, binop(opOR, aa, qaa)); 193195448075345dc73986042f6dc68eb464d02bc6a8sewardj 193295448075345dc73986042f6dc68eb464d02bc6a8sewardj // b_max = bb | qbb 19337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj b_max = assignNew('V', mce,ty, binop(opOR, bb, qbb)); 193495448075345dc73986042f6dc68eb464d02bc6a8sewardj 1935d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj if (add) { 1936d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj // result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max)) 1937d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return 19387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, 1939d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj binop( opOR, 19407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opOR, qaa, qbb)), 19417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, 1942d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj binop( opXOR, 19437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opADD, a_min, b_min)), 19447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opADD, a_max, b_max)) 1945d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 1946d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 1947d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 1948d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ); 1949d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj } else { 1950d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj // result = (qaa | qbb) | ((a_min - b_max) ^ (a_max + b_min)) 1951d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return 19527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, 1953d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj binop( opOR, 19547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opOR, qaa, qbb)), 19557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, 1956d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj binop( opXOR, 19577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opSUB, a_min, b_max)), 19587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce,ty, binop(opSUB, a_max, b_min)) 1959d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 196095448075345dc73986042f6dc68eb464d02bc6a8sewardj ) 1961d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ) 1962d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj ); 1963d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj } 1964d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 196595448075345dc73986042f6dc68eb464d02bc6a8sewardj} 1966e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 1967e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 19684cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardjstatic 19694cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardjIRAtom* expensiveCountTrailingZeroes ( MCEnv* mce, IROp czop, 19704cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj IRAtom* atom, IRAtom* vatom ) 19714cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj{ 19724cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj IRType ty; 19734cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj IROp xorOp, subOp, andOp; 19744cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj IRExpr *one; 19754cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj IRAtom *improver, *improved; 19764cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj tl_assert(isShadowAtom(mce,vatom)); 19774cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj tl_assert(isOriginalAtom(mce,atom)); 19784cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj tl_assert(sameKindedAtoms(atom,vatom)); 19794cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 19804cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj switch (czop) { 19814cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_Ctz32: 19824cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj ty = Ity_I32; 19834cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj xorOp = Iop_Xor32; 19844cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj subOp = Iop_Sub32; 19854cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj andOp = Iop_And32; 19864cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj one = mkU32(1); 19874cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj break; 19884cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_Ctz64: 19894cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj ty = Ity_I64; 19904cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj xorOp = Iop_Xor64; 19914cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj subOp = Iop_Sub64; 19924cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj andOp = Iop_And64; 19934cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj one = mkU64(1); 19944cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj break; 19954cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj default: 19964cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj ppIROp(czop); 19974cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj VG_(tool_panic)("memcheck:expensiveCountTrailingZeroes"); 19984cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj } 19994cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 20004cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // improver = atom ^ (atom - 1) 20014cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // 20024cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // That is, improver has its low ctz(atom) bits equal to one; 20034cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // higher bits (if any) equal to zero. 20044cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj improver = assignNew('V', mce,ty, 20054cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj binop(xorOp, 20064cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj atom, 20074cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj assignNew('V', mce, ty, 20084cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj binop(subOp, atom, one)))); 20094cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 20104cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // improved = vatom & improver 20114cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // 20124cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // That is, treat any V bits above the first ctz(atom) bits as 20134cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // "defined". 20144cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj improved = assignNew('V', mce, ty, 20154cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj binop(andOp, vatom, improver)); 20164cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 20174cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj // Return pessimizing cast of improved. 20184cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj return mkPCastTo(mce, ty, improved); 20194cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj} 20204cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 20214cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 202295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 2023aaddbc281556387b2a16009e058f785fb4d5c576sewardj/*--- Scalar shifts. ---*/ 2024aaddbc281556387b2a16009e058f785fb4d5c576sewardj/*------------------------------------------------------------*/ 2025aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2026aaddbc281556387b2a16009e058f785fb4d5c576sewardj/* Produce an interpretation for (aa << bb) (or >>s, >>u). The basic 2027aaddbc281556387b2a16009e058f785fb4d5c576sewardj idea is to shift the definedness bits by the original shift amount. 2028aaddbc281556387b2a16009e058f785fb4d5c576sewardj This introduces 0s ("defined") in new positions for left shifts and 2029aaddbc281556387b2a16009e058f785fb4d5c576sewardj unsigned right shifts, and copies the top definedness bit for 2030aaddbc281556387b2a16009e058f785fb4d5c576sewardj signed right shifts. So, conveniently, applying the original shift 2031aaddbc281556387b2a16009e058f785fb4d5c576sewardj operator to the definedness bits for the left arg is exactly the 2032aaddbc281556387b2a16009e058f785fb4d5c576sewardj right thing to do: 2033aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2034aaddbc281556387b2a16009e058f785fb4d5c576sewardj (qaa << bb) 2035aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2036aaddbc281556387b2a16009e058f785fb4d5c576sewardj However if the shift amount is undefined then the whole result 2037aaddbc281556387b2a16009e058f785fb4d5c576sewardj is undefined. Hence need: 2038aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2039aaddbc281556387b2a16009e058f785fb4d5c576sewardj (qaa << bb) `UifU` PCast(qbb) 2040aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2041aaddbc281556387b2a16009e058f785fb4d5c576sewardj If the shift amount bb is a literal than qbb will say 'all defined' 2042aaddbc281556387b2a16009e058f785fb4d5c576sewardj and the UifU and PCast will get folded out by post-instrumentation 2043aaddbc281556387b2a16009e058f785fb4d5c576sewardj optimisation. 2044aaddbc281556387b2a16009e058f785fb4d5c576sewardj*/ 2045aaddbc281556387b2a16009e058f785fb4d5c576sewardjstatic IRAtom* scalarShift ( MCEnv* mce, 2046aaddbc281556387b2a16009e058f785fb4d5c576sewardj IRType ty, 2047aaddbc281556387b2a16009e058f785fb4d5c576sewardj IROp original_op, 2048aaddbc281556387b2a16009e058f785fb4d5c576sewardj IRAtom* qaa, IRAtom* qbb, 2049aaddbc281556387b2a16009e058f785fb4d5c576sewardj IRAtom* aa, IRAtom* bb ) 2050aaddbc281556387b2a16009e058f785fb4d5c576sewardj{ 2051aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(isShadowAtom(mce,qaa)); 2052aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(isShadowAtom(mce,qbb)); 2053aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(isOriginalAtom(mce,aa)); 2054aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(isOriginalAtom(mce,bb)); 2055aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(sameKindedAtoms(qaa,aa)); 2056aaddbc281556387b2a16009e058f785fb4d5c576sewardj tl_assert(sameKindedAtoms(qbb,bb)); 2057aaddbc281556387b2a16009e058f785fb4d5c576sewardj return 2058aaddbc281556387b2a16009e058f785fb4d5c576sewardj assignNew( 20597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, ty, 2060aaddbc281556387b2a16009e058f785fb4d5c576sewardj mkUifU( mce, ty, 20617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, ty, binop(original_op, qaa, bb)), 2062aaddbc281556387b2a16009e058f785fb4d5c576sewardj mkPCastTo(mce, ty, qbb) 2063aaddbc281556387b2a16009e058f785fb4d5c576sewardj ) 2064aaddbc281556387b2a16009e058f785fb4d5c576sewardj ); 2065aaddbc281556387b2a16009e058f785fb4d5c576sewardj} 2066aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2067aaddbc281556387b2a16009e058f785fb4d5c576sewardj 2068aaddbc281556387b2a16009e058f785fb4d5c576sewardj/*------------------------------------------------------------*/ 2069aaddbc281556387b2a16009e058f785fb4d5c576sewardj/*--- Helpers for dealing with vector primops. ---*/ 20703245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/*------------------------------------------------------------*/ 20713245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 2072a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* Vector pessimisation -- pessimise within each lane individually. */ 2073a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2074a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast8x16 ( MCEnv* mce, IRAtom* at ) 2075a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 20767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ8x16, at)); 2077a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2078a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2079a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast16x8 ( MCEnv* mce, IRAtom* at ) 2080a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 20817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ16x8, at)); 2082a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2083a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2084a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast32x4 ( MCEnv* mce, IRAtom* at ) 2085a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 20867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ32x4, at)); 2087a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2088a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2089a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic IRAtom* mkPCast64x2 ( MCEnv* mce, IRAtom* at ) 2090a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 20917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ64x2, at)); 2092a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2093a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2094350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkPCast64x4 ( MCEnv* mce, IRAtom* at ) 2095350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2096350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, unop(Iop_CmpNEZ64x4, at)); 2097350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2098350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2099350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic IRAtom* mkPCast32x8 ( MCEnv* mce, IRAtom* at ) 2100350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2101350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, unop(Iop_CmpNEZ32x8, at)); 2102350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2103350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2104acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast32x2 ( MCEnv* mce, IRAtom* at ) 2105acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 21067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ32x2, at)); 2107acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2108acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2109a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic IRAtom* mkPCast16x16 ( MCEnv* mce, IRAtom* at ) 2110a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2111a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return assignNew('V', mce, Ity_V256, unop(Iop_CmpNEZ16x16, at)); 2112a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2113a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2114acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast16x4 ( MCEnv* mce, IRAtom* at ) 2115acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 21167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ16x4, at)); 2117acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2118acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2119a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic IRAtom* mkPCast8x32 ( MCEnv* mce, IRAtom* at ) 2120a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2121a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return assignNew('V', mce, Ity_V256, unop(Iop_CmpNEZ8x32, at)); 2122a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2123a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2124acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic IRAtom* mkPCast8x8 ( MCEnv* mce, IRAtom* at ) 2125acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 21267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ8x8, at)); 2127acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2128acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2129c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjstatic IRAtom* mkPCast16x2 ( MCEnv* mce, IRAtom* at ) 2130c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj{ 2131c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return assignNew('V', mce, Ity_I32, unop(Iop_CmpNEZ16x2, at)); 2132c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj} 2133c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2134c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjstatic IRAtom* mkPCast8x4 ( MCEnv* mce, IRAtom* at ) 2135c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj{ 2136c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return assignNew('V', mce, Ity_I32, unop(Iop_CmpNEZ8x4, at)); 2137c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj} 2138c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2139a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 21403245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/* Here's a simple scheme capable of handling ops derived from SSE1 21413245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj code and while only generating ops that can be efficiently 21423245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj implemented in SSE1. */ 21433245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21443245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/* All-lanes versions are straightforward: 21453245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 214620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj binary32Fx4(x,y) ==> PCast32x4(UifUV128(x#,y#)) 21473245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21483245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj unary32Fx4(x,y) ==> PCast32x4(x#) 21493245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21503245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj Lowest-lane-only versions are more complex: 21513245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 215220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj binary32F0x4(x,y) ==> SetV128lo32( 21533245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj x#, 215420d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj PCast32(V128to32(UifUV128(x#,y#))) 21553245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj ) 21563245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21573245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj This is perhaps not so obvious. In particular, it's faster to 215820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj do a V128-bit UifU and then take the bottom 32 bits than the more 21593245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj obvious scheme of taking the bottom 32 bits of each operand 21603245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj and doing a 32-bit UifU. Basically since UifU is fast and 21613245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj chopping lanes off vector values is slow. 21623245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21633245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj Finally: 21643245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 216520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj unary32F0x4(x) ==> SetV128lo32( 21663245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj x#, 216720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj PCast32(V128to32(x#)) 21683245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj ) 21693245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21703245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj Where: 21713245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21723245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj PCast32(v#) = 1Sto32(CmpNE32(v#,0)) 21733245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj PCast32x4(v#) = CmpNEZ32x4(v#) 21743245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj*/ 21753245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21763245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic 21773245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* binary32Fx4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 21783245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{ 21793245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj IRAtom* at; 21803245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomX)); 21813245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomY)); 218220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatomX, vatomY); 21837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, mkPCast32x4(mce, at)); 21843245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj return at; 21853245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj} 21863245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21873245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic 21883245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* unary32Fx4 ( MCEnv* mce, IRAtom* vatomX ) 21893245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{ 21903245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj IRAtom* at; 21913245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomX)); 21927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, mkPCast32x4(mce, vatomX)); 21933245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj return at; 21943245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj} 21953245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 21963245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic 21973245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* binary32F0x4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 21983245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{ 21993245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj IRAtom* at; 22003245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomX)); 22013245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomY)); 220220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatomX, vatomY); 22037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_I32, unop(Iop_V128to32, at)); 22043245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj at = mkPCastTo(mce, Ity_I32, at); 22057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at)); 22063245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj return at; 22073245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj} 22083245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 22093245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjstatic 22103245c919d273a73ce23632d6a3ab4fc027fefcd9sewardjIRAtom* unary32F0x4 ( MCEnv* mce, IRAtom* vatomX ) 22113245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj{ 22123245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj IRAtom* at; 22133245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj tl_assert(isShadowAtom(mce, vatomX)); 22147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_I32, unop(Iop_V128to32, vatomX)); 22153245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj at = mkPCastTo(mce, Ity_I32, at); 22167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at)); 22173245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj return at; 22183245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj} 22193245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 22200b07059814aee8563905f2caeef186a8c83072cfsewardj/* --- ... and ... 64Fx2 versions of the same ... --- */ 22210b07059814aee8563905f2caeef186a8c83072cfsewardj 22220b07059814aee8563905f2caeef186a8c83072cfsewardjstatic 22230b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* binary64Fx2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 22240b07059814aee8563905f2caeef186a8c83072cfsewardj{ 22250b07059814aee8563905f2caeef186a8c83072cfsewardj IRAtom* at; 22260b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomX)); 22270b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomY)); 222820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatomX, vatomY); 22297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, mkPCast64x2(mce, at)); 22300b07059814aee8563905f2caeef186a8c83072cfsewardj return at; 22310b07059814aee8563905f2caeef186a8c83072cfsewardj} 22320b07059814aee8563905f2caeef186a8c83072cfsewardj 22330b07059814aee8563905f2caeef186a8c83072cfsewardjstatic 22340b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* unary64Fx2 ( MCEnv* mce, IRAtom* vatomX ) 22350b07059814aee8563905f2caeef186a8c83072cfsewardj{ 22360b07059814aee8563905f2caeef186a8c83072cfsewardj IRAtom* at; 22370b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomX)); 22387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, mkPCast64x2(mce, vatomX)); 22390b07059814aee8563905f2caeef186a8c83072cfsewardj return at; 22400b07059814aee8563905f2caeef186a8c83072cfsewardj} 22410b07059814aee8563905f2caeef186a8c83072cfsewardj 22420b07059814aee8563905f2caeef186a8c83072cfsewardjstatic 22430b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* binary64F0x2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 22440b07059814aee8563905f2caeef186a8c83072cfsewardj{ 22450b07059814aee8563905f2caeef186a8c83072cfsewardj IRAtom* at; 22460b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomX)); 22470b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomY)); 224820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatomX, vatomY); 22497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, at)); 22500b07059814aee8563905f2caeef186a8c83072cfsewardj at = mkPCastTo(mce, Ity_I64, at); 22517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at)); 22520b07059814aee8563905f2caeef186a8c83072cfsewardj return at; 22530b07059814aee8563905f2caeef186a8c83072cfsewardj} 22540b07059814aee8563905f2caeef186a8c83072cfsewardj 22550b07059814aee8563905f2caeef186a8c83072cfsewardjstatic 22560b07059814aee8563905f2caeef186a8c83072cfsewardjIRAtom* unary64F0x2 ( MCEnv* mce, IRAtom* vatomX ) 22570b07059814aee8563905f2caeef186a8c83072cfsewardj{ 22580b07059814aee8563905f2caeef186a8c83072cfsewardj IRAtom* at; 22590b07059814aee8563905f2caeef186a8c83072cfsewardj tl_assert(isShadowAtom(mce, vatomX)); 22607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vatomX)); 22610b07059814aee8563905f2caeef186a8c83072cfsewardj at = mkPCastTo(mce, Ity_I64, at); 22627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at)); 22630b07059814aee8563905f2caeef186a8c83072cfsewardj return at; 22640b07059814aee8563905f2caeef186a8c83072cfsewardj} 22650b07059814aee8563905f2caeef186a8c83072cfsewardj 226657f92b0326e164124201034afc0c51dcd8db6d07sewardj/* --- --- ... and ... 32Fx2 versions of the same --- --- */ 226757f92b0326e164124201034afc0c51dcd8db6d07sewardj 226857f92b0326e164124201034afc0c51dcd8db6d07sewardjstatic 226957f92b0326e164124201034afc0c51dcd8db6d07sewardjIRAtom* binary32Fx2 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 227057f92b0326e164124201034afc0c51dcd8db6d07sewardj{ 227157f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom* at; 227257f92b0326e164124201034afc0c51dcd8db6d07sewardj tl_assert(isShadowAtom(mce, vatomX)); 227357f92b0326e164124201034afc0c51dcd8db6d07sewardj tl_assert(isShadowAtom(mce, vatomY)); 227457f92b0326e164124201034afc0c51dcd8db6d07sewardj at = mkUifU64(mce, vatomX, vatomY); 227557f92b0326e164124201034afc0c51dcd8db6d07sewardj at = assignNew('V', mce, Ity_I64, mkPCast32x2(mce, at)); 227657f92b0326e164124201034afc0c51dcd8db6d07sewardj return at; 227757f92b0326e164124201034afc0c51dcd8db6d07sewardj} 227857f92b0326e164124201034afc0c51dcd8db6d07sewardj 227957f92b0326e164124201034afc0c51dcd8db6d07sewardjstatic 228057f92b0326e164124201034afc0c51dcd8db6d07sewardjIRAtom* unary32Fx2 ( MCEnv* mce, IRAtom* vatomX ) 228157f92b0326e164124201034afc0c51dcd8db6d07sewardj{ 228257f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom* at; 228357f92b0326e164124201034afc0c51dcd8db6d07sewardj tl_assert(isShadowAtom(mce, vatomX)); 228457f92b0326e164124201034afc0c51dcd8db6d07sewardj at = assignNew('V', mce, Ity_I64, mkPCast32x2(mce, vatomX)); 228557f92b0326e164124201034afc0c51dcd8db6d07sewardj return at; 228657f92b0326e164124201034afc0c51dcd8db6d07sewardj} 228757f92b0326e164124201034afc0c51dcd8db6d07sewardj 2288350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj/* --- ... and ... 64Fx4 versions of the same ... --- */ 2289350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2290350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic 2291350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjIRAtom* binary64Fx4 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 2292350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2293350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj IRAtom* at; 2294350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomX)); 2295350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomY)); 2296350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = mkUifUV256(mce, vatomX, vatomY); 2297350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = assignNew('V', mce, Ity_V256, mkPCast64x4(mce, at)); 2298350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return at; 2299350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2300350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2301350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic 2302350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjIRAtom* unary64Fx4 ( MCEnv* mce, IRAtom* vatomX ) 2303350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2304350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj IRAtom* at; 2305350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomX)); 2306350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = assignNew('V', mce, Ity_V256, mkPCast64x4(mce, vatomX)); 2307350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return at; 2308350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2309350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2310350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj/* --- ... and ... 32Fx8 versions of the same ... --- */ 2311350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2312350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic 2313350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjIRAtom* binary32Fx8 ( MCEnv* mce, IRAtom* vatomX, IRAtom* vatomY ) 2314350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2315350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj IRAtom* at; 2316350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomX)); 2317350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomY)); 2318350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = mkUifUV256(mce, vatomX, vatomY); 2319350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = assignNew('V', mce, Ity_V256, mkPCast32x8(mce, at)); 2320350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return at; 2321350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2322350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2323350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjstatic 2324350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardjIRAtom* unary32Fx8 ( MCEnv* mce, IRAtom* vatomX ) 2325350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj{ 2326350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj IRAtom* at; 2327350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj tl_assert(isShadowAtom(mce, vatomX)); 2328350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj at = assignNew('V', mce, Ity_V256, mkPCast32x8(mce, vatomX)); 2329350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return at; 2330350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj} 2331350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 23321eb272f53fadb410dd27fb38fb1be75af84868d0sewardj/* --- 64Fx2 binary FP ops, with rounding mode --- */ 23331eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23341eb272f53fadb410dd27fb38fb1be75af84868d0sewardjstatic 23351eb272f53fadb410dd27fb38fb1be75af84868d0sewardjIRAtom* binary64Fx2_w_rm ( MCEnv* mce, IRAtom* vRM, 23361eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* vatomX, IRAtom* vatomY ) 23371eb272f53fadb410dd27fb38fb1be75af84868d0sewardj{ 23381eb272f53fadb410dd27fb38fb1be75af84868d0sewardj /* This is the same as binary64Fx2, except that we subsequently 23391eb272f53fadb410dd27fb38fb1be75af84868d0sewardj pessimise vRM (definedness of the rounding mode), widen to 128 23401eb272f53fadb410dd27fb38fb1be75af84868d0sewardj bits and UifU it into the result. As with the scalar cases, if 23411eb272f53fadb410dd27fb38fb1be75af84868d0sewardj the RM is a constant then it is defined and so this extra bit 23421eb272f53fadb410dd27fb38fb1be75af84868d0sewardj will get constant-folded out later. */ 23431eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // "do" the vector args 23441eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t1 = binary64Fx2(mce, vatomX, vatomY); 23451eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // PCast the RM, and widen it to 128 bits 23461eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t2 = mkPCastTo(mce, Ity_V128, vRM); 23471eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // Roll it into the result 23481eb272f53fadb410dd27fb38fb1be75af84868d0sewardj t1 = mkUifUV128(mce, t1, t2); 23491eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return t1; 23501eb272f53fadb410dd27fb38fb1be75af84868d0sewardj} 23511eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23521eb272f53fadb410dd27fb38fb1be75af84868d0sewardj/* --- ... and ... 32Fx4 versions of the same --- */ 23531eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23541eb272f53fadb410dd27fb38fb1be75af84868d0sewardjstatic 23551eb272f53fadb410dd27fb38fb1be75af84868d0sewardjIRAtom* binary32Fx4_w_rm ( MCEnv* mce, IRAtom* vRM, 23561eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* vatomX, IRAtom* vatomY ) 23571eb272f53fadb410dd27fb38fb1be75af84868d0sewardj{ 23581eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t1 = binary32Fx4(mce, vatomX, vatomY); 23591eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // PCast the RM, and widen it to 128 bits 23601eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t2 = mkPCastTo(mce, Ity_V128, vRM); 23611eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // Roll it into the result 23621eb272f53fadb410dd27fb38fb1be75af84868d0sewardj t1 = mkUifUV128(mce, t1, t2); 23631eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return t1; 23641eb272f53fadb410dd27fb38fb1be75af84868d0sewardj} 23651eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23661eb272f53fadb410dd27fb38fb1be75af84868d0sewardj/* --- ... and ... 64Fx4 versions of the same --- */ 23671eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23681eb272f53fadb410dd27fb38fb1be75af84868d0sewardjstatic 23691eb272f53fadb410dd27fb38fb1be75af84868d0sewardjIRAtom* binary64Fx4_w_rm ( MCEnv* mce, IRAtom* vRM, 23701eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* vatomX, IRAtom* vatomY ) 23711eb272f53fadb410dd27fb38fb1be75af84868d0sewardj{ 23721eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t1 = binary64Fx4(mce, vatomX, vatomY); 23731eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // PCast the RM, and widen it to 256 bits 23741eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t2 = mkPCastTo(mce, Ity_V256, vRM); 23751eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // Roll it into the result 23761eb272f53fadb410dd27fb38fb1be75af84868d0sewardj t1 = mkUifUV256(mce, t1, t2); 23771eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return t1; 23781eb272f53fadb410dd27fb38fb1be75af84868d0sewardj} 23791eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23801eb272f53fadb410dd27fb38fb1be75af84868d0sewardj/* --- ... and ... 32Fx8 versions of the same --- */ 23811eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23821eb272f53fadb410dd27fb38fb1be75af84868d0sewardjstatic 23831eb272f53fadb410dd27fb38fb1be75af84868d0sewardjIRAtom* binary32Fx8_w_rm ( MCEnv* mce, IRAtom* vRM, 23841eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* vatomX, IRAtom* vatomY ) 23851eb272f53fadb410dd27fb38fb1be75af84868d0sewardj{ 23861eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t1 = binary32Fx8(mce, vatomX, vatomY); 23871eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // PCast the RM, and widen it to 256 bits 23881eb272f53fadb410dd27fb38fb1be75af84868d0sewardj IRAtom* t2 = mkPCastTo(mce, Ity_V256, vRM); 23891eb272f53fadb410dd27fb38fb1be75af84868d0sewardj // Roll it into the result 23901eb272f53fadb410dd27fb38fb1be75af84868d0sewardj t1 = mkUifUV256(mce, t1, t2); 23911eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return t1; 23921eb272f53fadb410dd27fb38fb1be75af84868d0sewardj} 23931eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 23947222f649c0dab0f50f5a60f841accc64a127856esewardj/* --- 64Fx2 unary FP ops, with rounding mode --- */ 23957222f649c0dab0f50f5a60f841accc64a127856esewardj 23967222f649c0dab0f50f5a60f841accc64a127856esewardjstatic 23977222f649c0dab0f50f5a60f841accc64a127856esewardjIRAtom* unary64Fx2_w_rm ( MCEnv* mce, IRAtom* vRM, IRAtom* vatomX ) 23987222f649c0dab0f50f5a60f841accc64a127856esewardj{ 23997222f649c0dab0f50f5a60f841accc64a127856esewardj /* Same scheme as binary64Fx2_w_rm. */ 24007222f649c0dab0f50f5a60f841accc64a127856esewardj // "do" the vector arg 24017222f649c0dab0f50f5a60f841accc64a127856esewardj IRAtom* t1 = unary64Fx2(mce, vatomX); 24027222f649c0dab0f50f5a60f841accc64a127856esewardj // PCast the RM, and widen it to 128 bits 24037222f649c0dab0f50f5a60f841accc64a127856esewardj IRAtom* t2 = mkPCastTo(mce, Ity_V128, vRM); 24047222f649c0dab0f50f5a60f841accc64a127856esewardj // Roll it into the result 24057222f649c0dab0f50f5a60f841accc64a127856esewardj t1 = mkUifUV128(mce, t1, t2); 24067222f649c0dab0f50f5a60f841accc64a127856esewardj return t1; 24077222f649c0dab0f50f5a60f841accc64a127856esewardj} 24087222f649c0dab0f50f5a60f841accc64a127856esewardj 24097222f649c0dab0f50f5a60f841accc64a127856esewardj/* --- ... and ... 32Fx4 versions of the same --- */ 24107222f649c0dab0f50f5a60f841accc64a127856esewardj 24117222f649c0dab0f50f5a60f841accc64a127856esewardjstatic 24127222f649c0dab0f50f5a60f841accc64a127856esewardjIRAtom* unary32Fx4_w_rm ( MCEnv* mce, IRAtom* vRM, IRAtom* vatomX ) 24137222f649c0dab0f50f5a60f841accc64a127856esewardj{ 24147222f649c0dab0f50f5a60f841accc64a127856esewardj /* Same scheme as unary32Fx4_w_rm. */ 24157222f649c0dab0f50f5a60f841accc64a127856esewardj IRAtom* t1 = unary32Fx4(mce, vatomX); 24167222f649c0dab0f50f5a60f841accc64a127856esewardj // PCast the RM, and widen it to 128 bits 24177222f649c0dab0f50f5a60f841accc64a127856esewardj IRAtom* t2 = mkPCastTo(mce, Ity_V128, vRM); 24187222f649c0dab0f50f5a60f841accc64a127856esewardj // Roll it into the result 24197222f649c0dab0f50f5a60f841accc64a127856esewardj t1 = mkUifUV128(mce, t1, t2); 24207222f649c0dab0f50f5a60f841accc64a127856esewardj return t1; 24217222f649c0dab0f50f5a60f841accc64a127856esewardj} 24227222f649c0dab0f50f5a60f841accc64a127856esewardj 24231eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 2424a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* --- --- Vector saturated narrowing --- --- */ 2425a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2426b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj/* We used to do something very clever here, but on closer inspection 2427b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj (2011-Jun-15), and in particular bug #279698, it turns out to be 2428b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj wrong. Part of the problem came from the fact that for a long 2429b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj time, the IR primops to do with saturated narrowing were 2430b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj underspecified and managed to confuse multiple cases which needed 2431b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj to be separate: the op names had a signedness qualifier, but in 2432b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj fact the source and destination signednesses needed to be specified 2433b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj independently, so the op names really need two independent 2434b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj signedness specifiers. 2435b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2436b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj As of 2011-Jun-15 (ish) the underspecification was sorted out 2437b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj properly. The incorrect instrumentation remained, though. That 2438b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj has now (2011-Oct-22) been fixed. 2439b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2440b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj What we now do is simple: 2441b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2442b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj Let the original narrowing op be QNarrowBinXtoYxZ, where Z is a 2443b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj number of lanes, X is the source lane width and signedness, and Y 2444b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj is the destination lane width and signedness. In all cases the 2445b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj destination lane width is half the source lane width, so the names 2446b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj have a bit of redundancy, but are at least easy to read. 2447b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2448b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj For example, Iop_QNarrowBin32Sto16Ux8 narrows 8 lanes of signed 32s 2449b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj to unsigned 16s. 2450b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2451b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj Let Vanilla(OP) be a function that takes OP, one of these 2452b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj saturating narrowing ops, and produces the same "shaped" narrowing 2453b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj op which is not saturating, but merely dumps the most significant 2454b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj bits. "same shape" means that the lane numbers and widths are the 2455b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj same as with OP. 2456b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2457b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj For example, Vanilla(Iop_QNarrowBin32Sto16Ux8) 2458b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj = Iop_NarrowBin32to16x8, 2459b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj that is, narrow 8 lanes of 32 bits to 8 lanes of 16 bits, by 2460b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj dumping the top half of each lane. 2461b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2462b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj So, with that in place, the scheme is simple, and it is simple to 2463b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj pessimise each lane individually and then apply Vanilla(OP) so as 2464b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj to get the result in the right "shape". If the original OP is 2465b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj QNarrowBinXtoYxZ then we produce 2466b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2467b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj Vanilla(OP)( PCast-X-to-X-x-Z(vatom1), PCast-X-to-X-x-Z(vatom2) ) 2468b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2469b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj or for the case when OP is unary (Iop_QNarrowUn*) 2470b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2471b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj Vanilla(OP)( PCast-X-to-X-x-Z(vatom) ) 2472a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj*/ 2473a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic 2474b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardjIROp vanillaNarrowingOpOfShape ( IROp qnarrowOp ) 2475b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj{ 2476b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj switch (qnarrowOp) { 2477b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj /* Binary: (128, 128) -> 128 */ 2478b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin16Sto8Ux16: 2479b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin16Sto8Sx16: 2480b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin16Uto8Ux16: 24816277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Sto32Sx4: 24826277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Uto32Ux4: 2483b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowBin16to8x16; 2484b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin32Sto16Ux8: 2485b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin32Sto16Sx8: 2486b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin32Uto16Ux8: 2487b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowBin32to16x8; 2488b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj /* Binary: (64, 64) -> 64 */ 2489b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin32Sto16Sx4: 2490b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowBin32to16x4; 2491b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin16Sto8Ux8: 2492b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowBin16Sto8Sx8: 2493b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowBin16to8x8; 2494b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj /* Unary: 128 -> 64 */ 2495b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn64Uto32Ux2: 2496b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn64Sto32Sx2: 2497b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn64Sto32Ux2: 2498b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowUn64to32x2; 2499b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn32Uto16Ux4: 2500b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn32Sto16Sx4: 2501b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn32Sto16Ux4: 2502b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowUn32to16x4; 2503b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn16Uto8Ux8: 2504b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn16Sto8Sx8: 2505b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_QNarrowUn16Sto8Ux8: 2506b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return Iop_NarrowUn16to8x8; 2507b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj default: 2508b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj ppIROp(qnarrowOp); 2509b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj VG_(tool_panic)("vanillaNarrowOpOfShape"); 2510b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj } 2511b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj} 2512b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj 2513b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardjstatic 25147ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardjIRAtom* vectorNarrowBinV128 ( MCEnv* mce, IROp narrow_op, 25157ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj IRAtom* vatom1, IRAtom* vatom2) 2516a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 2517a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom *at1, *at2, *at3; 2518a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom* (*pcast)( MCEnv*, IRAtom* ); 2519a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj switch (narrow_op) { 25206277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Sto32Sx4: pcast = mkPCast32x4; break; 25216277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Uto32Ux4: pcast = mkPCast32x4; break; 25227ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Sx8: pcast = mkPCast32x4; break; 25237ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Uto16Ux8: pcast = mkPCast32x4; break; 25247ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Ux8: pcast = mkPCast32x4; break; 25257ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Sx16: pcast = mkPCast16x8; break; 25267ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Uto8Ux16: pcast = mkPCast16x8; break; 25277ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Ux16: pcast = mkPCast16x8; break; 25287ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj default: VG_(tool_panic)("vectorNarrowBinV128"); 2529a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj } 2530b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj IROp vanilla_narrow = vanillaNarrowingOpOfShape(narrow_op); 2531a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj tl_assert(isShadowAtom(mce,vatom1)); 2532a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj tl_assert(isShadowAtom(mce,vatom2)); 25337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at1 = assignNew('V', mce, Ity_V128, pcast(mce, vatom1)); 25347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at2 = assignNew('V', mce, Ity_V128, pcast(mce, vatom2)); 2535b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj at3 = assignNew('V', mce, Ity_V128, binop(vanilla_narrow, at1, at2)); 2536a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return at3; 2537a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2538a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2539acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic 25407ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardjIRAtom* vectorNarrowBin64 ( MCEnv* mce, IROp narrow_op, 25417ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj IRAtom* vatom1, IRAtom* vatom2) 2542acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 2543acd2e910861cfc0f95229401922d38d7ce9c6259sewardj IRAtom *at1, *at2, *at3; 2544acd2e910861cfc0f95229401922d38d7ce9c6259sewardj IRAtom* (*pcast)( MCEnv*, IRAtom* ); 2545acd2e910861cfc0f95229401922d38d7ce9c6259sewardj switch (narrow_op) { 25467ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Sx4: pcast = mkPCast32x2; break; 25477ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Sx8: pcast = mkPCast16x4; break; 25487ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Ux8: pcast = mkPCast16x4; break; 25497ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj default: VG_(tool_panic)("vectorNarrowBin64"); 2550acd2e910861cfc0f95229401922d38d7ce9c6259sewardj } 2551b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj IROp vanilla_narrow = vanillaNarrowingOpOfShape(narrow_op); 2552acd2e910861cfc0f95229401922d38d7ce9c6259sewardj tl_assert(isShadowAtom(mce,vatom1)); 2553acd2e910861cfc0f95229401922d38d7ce9c6259sewardj tl_assert(isShadowAtom(mce,vatom2)); 25547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at1 = assignNew('V', mce, Ity_I64, pcast(mce, vatom1)); 25557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at2 = assignNew('V', mce, Ity_I64, pcast(mce, vatom2)); 2556b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj at3 = assignNew('V', mce, Ity_I64, binop(vanilla_narrow, at1, at2)); 2557acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return at3; 2558acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2559acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 256057f92b0326e164124201034afc0c51dcd8db6d07sewardjstatic 2561b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardjIRAtom* vectorNarrowUnV128 ( MCEnv* mce, IROp narrow_op, 25627ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj IRAtom* vatom1) 256357f92b0326e164124201034afc0c51dcd8db6d07sewardj{ 256457f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom *at1, *at2; 256557f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom* (*pcast)( MCEnv*, IRAtom* ); 2566b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj tl_assert(isShadowAtom(mce,vatom1)); 2567b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj /* For vanilla narrowing (non-saturating), we can just apply 2568b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj the op directly to the V bits. */ 2569b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj switch (narrow_op) { 2570b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_NarrowUn16to8x8: 2571b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_NarrowUn32to16x4: 2572b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj case Iop_NarrowUn64to32x2: 2573b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj at1 = assignNew('V', mce, Ity_I64, unop(narrow_op, vatom1)); 2574b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj return at1; 2575b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj default: 2576b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj break; /* Do Plan B */ 2577b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj } 2578b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj /* Plan B: for ops that involve a saturation operation on the args, 2579b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj we must PCast before the vanilla narrow. */ 2580b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj switch (narrow_op) { 25817ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Sto8Sx8: pcast = mkPCast16x8; break; 25827ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Sto8Ux8: pcast = mkPCast16x8; break; 25837ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Uto8Ux8: pcast = mkPCast16x8; break; 25847ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Sto16Sx4: pcast = mkPCast32x4; break; 25857ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Sto16Ux4: pcast = mkPCast32x4; break; 25867ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Uto16Ux4: pcast = mkPCast32x4; break; 25877ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Sto32Sx2: pcast = mkPCast64x2; break; 25887ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Sto32Ux2: pcast = mkPCast64x2; break; 25897ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Uto32Ux2: pcast = mkPCast64x2; break; 25907ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj default: VG_(tool_panic)("vectorNarrowUnV128"); 259157f92b0326e164124201034afc0c51dcd8db6d07sewardj } 2592b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj IROp vanilla_narrow = vanillaNarrowingOpOfShape(narrow_op); 259357f92b0326e164124201034afc0c51dcd8db6d07sewardj at1 = assignNew('V', mce, Ity_V128, pcast(mce, vatom1)); 2594b5a2923ecd25ae8ef4dc412e6af8de28c0b69b23sewardj at2 = assignNew('V', mce, Ity_I64, unop(vanilla_narrow, at1)); 259557f92b0326e164124201034afc0c51dcd8db6d07sewardj return at2; 259657f92b0326e164124201034afc0c51dcd8db6d07sewardj} 259757f92b0326e164124201034afc0c51dcd8db6d07sewardj 259857f92b0326e164124201034afc0c51dcd8db6d07sewardjstatic 25997ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardjIRAtom* vectorWidenI64 ( MCEnv* mce, IROp longen_op, 26007ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj IRAtom* vatom1) 260157f92b0326e164124201034afc0c51dcd8db6d07sewardj{ 260257f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom *at1, *at2; 260357f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom* (*pcast)( MCEnv*, IRAtom* ); 260457f92b0326e164124201034afc0c51dcd8db6d07sewardj switch (longen_op) { 26057ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen8Uto16x8: pcast = mkPCast16x8; break; 26067ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen8Sto16x8: pcast = mkPCast16x8; break; 26077ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen16Uto32x4: pcast = mkPCast32x4; break; 26087ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen16Sto32x4: pcast = mkPCast32x4; break; 26097ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen32Uto64x2: pcast = mkPCast64x2; break; 26107ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen32Sto64x2: pcast = mkPCast64x2; break; 26117ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj default: VG_(tool_panic)("vectorWidenI64"); 261257f92b0326e164124201034afc0c51dcd8db6d07sewardj } 261357f92b0326e164124201034afc0c51dcd8db6d07sewardj tl_assert(isShadowAtom(mce,vatom1)); 261457f92b0326e164124201034afc0c51dcd8db6d07sewardj at1 = assignNew('V', mce, Ity_V128, unop(longen_op, vatom1)); 261557f92b0326e164124201034afc0c51dcd8db6d07sewardj at2 = assignNew('V', mce, Ity_V128, pcast(mce, at1)); 261657f92b0326e164124201034afc0c51dcd8db6d07sewardj return at2; 261757f92b0326e164124201034afc0c51dcd8db6d07sewardj} 261857f92b0326e164124201034afc0c51dcd8db6d07sewardj 2619a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2620a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* --- --- Vector integer arithmetic --- --- */ 2621a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2622a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj/* Simple ... UifU the args and per-lane pessimise the results. */ 2623acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2624a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj/* --- V256-bit versions --- */ 2625a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2626a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic 2627a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjIRAtom* binary8Ix32 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2628a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2629a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj IRAtom* at; 2630a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkUifUV256(mce, vatom1, vatom2); 2631a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkPCast8x32(mce, at); 2632a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return at; 2633a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2634a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2635a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic 2636a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjIRAtom* binary16Ix16 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2637a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2638a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj IRAtom* at; 2639a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkUifUV256(mce, vatom1, vatom2); 2640a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkPCast16x16(mce, at); 2641a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return at; 2642a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2643a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2644a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic 2645a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjIRAtom* binary32Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2646a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2647a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj IRAtom* at; 2648a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkUifUV256(mce, vatom1, vatom2); 2649a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkPCast32x8(mce, at); 2650a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return at; 2651a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2652a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 2653a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjstatic 2654a2f309566f7bdd7ac8e2347ef50e873894f95498sewardjIRAtom* binary64Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2655a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj{ 2656a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj IRAtom* at; 2657a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkUifUV256(mce, vatom1, vatom2); 2658a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj at = mkPCast64x4(mce, at); 2659a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return at; 2660a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj} 2661a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 266220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj/* --- V128-bit versions --- */ 2663acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2664a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic 2665a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary8Ix16 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2666a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 2667a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom* at; 266820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatom1, vatom2); 2669a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj at = mkPCast8x16(mce, at); 2670a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return at; 2671a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2672a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2673a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic 2674a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary16Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2675a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 2676a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom* at; 267720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatom1, vatom2); 2678a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj at = mkPCast16x8(mce, at); 2679a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return at; 2680a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2681a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2682a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic 2683a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary32Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2684a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 2685a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom* at; 268620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatom1, vatom2); 2687a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj at = mkPCast32x4(mce, at); 2688a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return at; 2689a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 2690a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 2691a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjstatic 2692a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardjIRAtom* binary64Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2693a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj{ 2694a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj IRAtom* at; 269520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj at = mkUifUV128(mce, vatom1, vatom2); 2696a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj at = mkPCast64x2(mce, at); 2697a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return at; 2698a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj} 26993245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 2700acd2e910861cfc0f95229401922d38d7ce9c6259sewardj/* --- 64-bit versions --- */ 2701acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2702acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic 2703acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary8Ix8 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2704acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 2705acd2e910861cfc0f95229401922d38d7ce9c6259sewardj IRAtom* at; 2706acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkUifU64(mce, vatom1, vatom2); 2707acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkPCast8x8(mce, at); 2708acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return at; 2709acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2710acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2711acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic 2712acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary16Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2713acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 2714acd2e910861cfc0f95229401922d38d7ce9c6259sewardj IRAtom* at; 2715acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkUifU64(mce, vatom1, vatom2); 2716acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkPCast16x4(mce, at); 2717acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return at; 2718acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2719acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2720acd2e910861cfc0f95229401922d38d7ce9c6259sewardjstatic 2721acd2e910861cfc0f95229401922d38d7ce9c6259sewardjIRAtom* binary32Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2722acd2e910861cfc0f95229401922d38d7ce9c6259sewardj{ 2723acd2e910861cfc0f95229401922d38d7ce9c6259sewardj IRAtom* at; 2724acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkUifU64(mce, vatom1, vatom2); 2725acd2e910861cfc0f95229401922d38d7ce9c6259sewardj at = mkPCast32x2(mce, at); 2726acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return at; 2727acd2e910861cfc0f95229401922d38d7ce9c6259sewardj} 2728acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 272957f92b0326e164124201034afc0c51dcd8db6d07sewardjstatic 273057f92b0326e164124201034afc0c51dcd8db6d07sewardjIRAtom* binary64Ix1 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 273157f92b0326e164124201034afc0c51dcd8db6d07sewardj{ 273257f92b0326e164124201034afc0c51dcd8db6d07sewardj IRAtom* at; 273357f92b0326e164124201034afc0c51dcd8db6d07sewardj at = mkUifU64(mce, vatom1, vatom2); 273457f92b0326e164124201034afc0c51dcd8db6d07sewardj at = mkPCastTo(mce, Ity_I64, at); 273557f92b0326e164124201034afc0c51dcd8db6d07sewardj return at; 273657f92b0326e164124201034afc0c51dcd8db6d07sewardj} 273757f92b0326e164124201034afc0c51dcd8db6d07sewardj 2738c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj/* --- 32-bit versions --- */ 2739c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2740c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjstatic 2741c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjIRAtom* binary8Ix4 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2742c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj{ 2743c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj IRAtom* at; 2744c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj at = mkUifU32(mce, vatom1, vatom2); 2745c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj at = mkPCast8x4(mce, at); 2746c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return at; 2747c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj} 2748c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2749c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjstatic 2750c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardjIRAtom* binary16Ix2 ( MCEnv* mce, IRAtom* vatom1, IRAtom* vatom2 ) 2751c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj{ 2752c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj IRAtom* at; 2753c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj at = mkUifU32(mce, vatom1, vatom2); 2754c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj at = mkPCast16x2(mce, at); 2755c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return at; 2756c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj} 2757c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 27583245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 27593245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj/*------------------------------------------------------------*/ 276095448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generate shadow values from all kinds of IRExprs. ---*/ 276195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 2762e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 276395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 2764e91cea71129edc807428c8228d0d9f5b13894a5asewardjIRAtom* expr2vbits_Qop ( MCEnv* mce, 2765e91cea71129edc807428c8228d0d9f5b13894a5asewardj IROp op, 2766e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* atom1, IRAtom* atom2, 2767e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* atom3, IRAtom* atom4 ) 2768e91cea71129edc807428c8228d0d9f5b13894a5asewardj{ 2769e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* vatom1 = expr2vbits( mce, atom1 ); 2770e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* vatom2 = expr2vbits( mce, atom2 ); 2771e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* vatom3 = expr2vbits( mce, atom3 ); 2772e91cea71129edc807428c8228d0d9f5b13894a5asewardj IRAtom* vatom4 = expr2vbits( mce, atom4 ); 2773e91cea71129edc807428c8228d0d9f5b13894a5asewardj 2774e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isOriginalAtom(mce,atom1)); 2775e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isOriginalAtom(mce,atom2)); 2776e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isOriginalAtom(mce,atom3)); 2777e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isOriginalAtom(mce,atom4)); 2778e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,vatom1)); 2779e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,vatom2)); 2780e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,vatom3)); 2781e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(isShadowAtom(mce,vatom4)); 2782e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(sameKindedAtoms(atom1,vatom1)); 2783e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(sameKindedAtoms(atom2,vatom2)); 2784e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(sameKindedAtoms(atom3,vatom3)); 2785e91cea71129edc807428c8228d0d9f5b13894a5asewardj tl_assert(sameKindedAtoms(atom4,vatom4)); 2786e91cea71129edc807428c8228d0d9f5b13894a5asewardj switch (op) { 2787e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iop_MAddF64: 2788e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iop_MAddF64r32: 2789e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iop_MSubF64: 2790e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iop_MSubF64r32: 2791e91cea71129edc807428c8228d0d9f5b13894a5asewardj /* I32(rm) x F64 x F64 x F64 -> F64 */ 2792e91cea71129edc807428c8228d0d9f5b13894a5asewardj return mkLazy4(mce, Ity_I64, vatom1, vatom2, vatom3, vatom4); 2793b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 2794b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_MAddF32: 2795b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_MSubF32: 2796b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32(rm) x F32 x F32 x F32 -> F32 */ 2797b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy4(mce, Ity_I32, vatom1, vatom2, vatom3, vatom4); 2798b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 2799350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj /* V256-bit data-steering */ 2800350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_64x4toV256: 2801350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, 2802350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj IRExpr_Qop(op, vatom1, vatom2, vatom3, vatom4)); 2803350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 2804e91cea71129edc807428c8228d0d9f5b13894a5asewardj default: 2805e91cea71129edc807428c8228d0d9f5b13894a5asewardj ppIROp(op); 2806e91cea71129edc807428c8228d0d9f5b13894a5asewardj VG_(tool_panic)("memcheck:expr2vbits_Qop"); 2807e91cea71129edc807428c8228d0d9f5b13894a5asewardj } 2808e91cea71129edc807428c8228d0d9f5b13894a5asewardj} 2809e91cea71129edc807428c8228d0d9f5b13894a5asewardj 2810e91cea71129edc807428c8228d0d9f5b13894a5asewardj 2811e91cea71129edc807428c8228d0d9f5b13894a5asewardjstatic 2812ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardjIRAtom* expr2vbits_Triop ( MCEnv* mce, 2813ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IROp op, 2814ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* atom1, IRAtom* atom2, IRAtom* atom3 ) 2815ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj{ 2816ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* vatom1 = expr2vbits( mce, atom1 ); 2817ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* vatom2 = expr2vbits( mce, atom2 ); 2818ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj IRAtom* vatom3 = expr2vbits( mce, atom3 ); 2819ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 2820ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isOriginalAtom(mce,atom1)); 2821ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isOriginalAtom(mce,atom2)); 2822ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isOriginalAtom(mce,atom3)); 2823ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,vatom1)); 2824ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,vatom2)); 2825ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(isShadowAtom(mce,vatom3)); 2826ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(sameKindedAtoms(atom1,vatom1)); 2827ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(sameKindedAtoms(atom2,vatom2)); 2828ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj tl_assert(sameKindedAtoms(atom3,vatom3)); 2829ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj switch (op) { 2830b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_AddF128: 2831b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_AddD128: 2832b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_SubF128: 2833b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_SubD128: 2834b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_MulF128: 2835b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_MulD128: 2836b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_DivF128: 2837b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_DivD128: 283818c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_QuantizeD128: 283918c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj /* I32(rm) x F128/D128 x F128/D128 -> F128/D128 */ 2840b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy3(mce, Ity_I128, vatom1, vatom2, vatom3); 2841ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_AddF64: 2842b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_AddD64: 2843ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_AddF64r32: 2844ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_SubF64: 2845b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_SubD64: 2846ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_SubF64r32: 2847ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_MulF64: 2848b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_MulD64: 2849ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_MulF64r32: 2850ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_DivF64: 2851b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_DivD64: 2852ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_DivF64r32: 285322ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_ScaleF64: 285422ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_Yl2xF64: 285522ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_Yl2xp1F64: 285622ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_AtanF64: 2857d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj case Iop_PRemF64: 2858d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj case Iop_PRem1F64: 285918c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_QuantizeD64: 286018c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj /* I32(rm) x F64/D64 x F64/D64 -> F64/D64 */ 2861ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj return mkLazy3(mce, Ity_I64, vatom1, vatom2, vatom3); 2862d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj case Iop_PRemC3210F64: 2863d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj case Iop_PRem1C3210F64: 2864d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj /* I32(rm) x F64 x F64 -> I32 */ 2865d6075ebbdce70888ee82eaff9c1b53f04cbeb9f0sewardj return mkLazy3(mce, Ity_I32, vatom1, vatom2, vatom3); 286659570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_AddF32: 286759570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_SubF32: 286859570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_MulF32: 286959570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_DivF32: 287059570ffbe31930ab4d678754daaeec0715117a3dsewardj /* I32(rm) x F32 x F32 -> I32 */ 287159570ffbe31930ab4d678754daaeec0715117a3dsewardj return mkLazy3(mce, Ity_I32, vatom1, vatom2, vatom3); 287218c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_SignificanceRoundD64: 2873733b4db9e2385911103f8b10ec2a5a72f9329941florian /* IRRoundingMode(I32) x I8 x D64 -> D64 */ 287418c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj return mkLazy3(mce, Ity_I64, vatom1, vatom2, vatom3); 287518c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_SignificanceRoundD128: 2876733b4db9e2385911103f8b10ec2a5a72f9329941florian /* IRRoundingMode(I32) x I8 x D128 -> D128 */ 287718c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj return mkLazy3(mce, Ity_I128, vatom1, vatom2, vatom3); 28787b7b1cbe53ee541a803e1e00b58d58fcee65aa97sewardj case Iop_SliceV128: 28797b7b1cbe53ee541a803e1e00b58d58fcee65aa97sewardj /* (V128, V128, I8) -> V128 */ 2880b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom3, NULL); 288157f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_V128, triop(op, vatom1, vatom2, atom3)); 28827b7b1cbe53ee541a803e1e00b58d58fcee65aa97sewardj case Iop_Slice64: 28837b7b1cbe53ee541a803e1e00b58d58fcee65aa97sewardj /* (I64, I64, I8) -> I64 */ 2884b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom3, NULL); 288557f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I64, triop(op, vatom1, vatom2, atom3)); 288657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_SetElem8x8: 288757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_SetElem16x4: 288857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_SetElem32x2: 2889b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 289057f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I64, triop(op, vatom1, atom2, vatom3)); 289124e40de8f2127d70117ed9af3bc4474cbc29cb8acarll /* BCDIops */ 289224e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_BCDAdd: 289324e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_BCDSub: 289424e40de8f2127d70117ed9af3bc4474cbc29cb8acarll complainIfUndefined(mce, atom3, NULL); 289524e40de8f2127d70117ed9af3bc4474cbc29cb8acarll return assignNew('V', mce, Ity_V128, triop(op, vatom1, vatom2, atom3)); 289624e40de8f2127d70117ed9af3bc4474cbc29cb8acarll 28971eb272f53fadb410dd27fb38fb1be75af84868d0sewardj /* Vector FP with rounding mode as the first arg */ 28981eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Add64Fx2: 28991eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Sub64Fx2: 29001eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Mul64Fx2: 29011eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Div64Fx2: 29021eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return binary64Fx2_w_rm(mce, vatom1, vatom2, vatom3); 29031eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 29041eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Add32Fx4: 29051eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Sub32Fx4: 29061eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Mul32Fx4: 29071eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Div32Fx4: 29081eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return binary32Fx4_w_rm(mce, vatom1, vatom2, vatom3); 29091eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 29101eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Add64Fx4: 29111eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Sub64Fx4: 29121eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Mul64Fx4: 29131eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Div64Fx4: 29141eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return binary64Fx4_w_rm(mce, vatom1, vatom2, vatom3); 29151eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 29161eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Add32Fx8: 29171eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Sub32Fx8: 29181eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Mul32Fx8: 29191eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Iop_Div32Fx8: 29201eb272f53fadb410dd27fb38fb1be75af84868d0sewardj return binary32Fx8_w_rm(mce, vatom1, vatom2, vatom3); 29211eb272f53fadb410dd27fb38fb1be75af84868d0sewardj 2922ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj default: 2923ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ppIROp(op); 2924ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj VG_(tool_panic)("memcheck:expr2vbits_Triop"); 2925ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj } 2926ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj} 2927ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 2928ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 2929ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardjstatic 293095448075345dc73986042f6dc68eb464d02bc6a8sewardjIRAtom* expr2vbits_Binop ( MCEnv* mce, 293195448075345dc73986042f6dc68eb464d02bc6a8sewardj IROp op, 293295448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* atom1, IRAtom* atom2 ) 293395448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 293495448075345dc73986042f6dc68eb464d02bc6a8sewardj IRType and_or_ty; 293595448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*); 293695448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*); 293795448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*); 293895448075345dc73986042f6dc68eb464d02bc6a8sewardj 293995448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vatom1 = expr2vbits( mce, atom1 ); 294095448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vatom2 = expr2vbits( mce, atom2 ); 294195448075345dc73986042f6dc68eb464d02bc6a8sewardj 294295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,atom1)); 294395448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,atom2)); 294495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,vatom1)); 294595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,vatom2)); 294695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(atom1,vatom1)); 294795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(sameKindedAtoms(atom2,vatom2)); 294895448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (op) { 294995448075345dc73986042f6dc68eb464d02bc6a8sewardj 2950c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj /* 32-bit SIMD */ 2951c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2952c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_Add16x2: 2953c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HAdd16Ux2: 2954c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HAdd16Sx2: 2955c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_Sub16x2: 2956c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HSub16Ux2: 2957c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HSub16Sx2: 2958c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QAdd16Sx2: 2959c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QSub16Sx2: 29609fb31093cfbaeba9ebb965b318d07fb344120666sewardj case Iop_QSub16Ux2: 29617a3706554059125b018dcd12267db8d9c3e9176fsewardj case Iop_QAdd16Ux2: 2962c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return binary16Ix2(mce, vatom1, vatom2); 2963c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2964c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_Add8x4: 2965c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HAdd8Ux4: 2966c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HAdd8Sx4: 2967c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_Sub8x4: 2968c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HSub8Ux4: 2969c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_HSub8Sx4: 2970c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QSub8Ux4: 2971c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QAdd8Ux4: 2972c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QSub8Sx4: 2973c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj case Iop_QAdd8Sx4: 2974c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj return binary8Ix4(mce, vatom1, vatom2); 2975c678b85d7eb4e40d1ccb247a8d879ebde0a09affsewardj 2976acd2e910861cfc0f95229401922d38d7ce9c6259sewardj /* 64-bit SIMD */ 2977acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 297857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_ShrN8x8: 2979acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_ShrN16x4: 2980acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_ShrN32x2: 298103809aeba113248d22eb6161bb7b7606aad56844sewardj case Iop_SarN8x8: 2982acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_SarN16x4: 2983acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_SarN32x2: 2984acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_ShlN16x4: 2985acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_ShlN32x2: 2986114a917710310985f421b0c4748d9788164fdfc3sewardj case Iop_ShlN8x8: 2987acd2e910861cfc0f95229401922d38d7ce9c6259sewardj /* Same scheme as with all other shifts. */ 2988b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 29897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)); 2990acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 29917ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Sx4: 29927ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Sx8: 29937ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Ux8: 29947ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorNarrowBin64(mce, op, vatom1, vatom2); 2995acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 2996acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Min8Ux8: 299757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Min8Sx8: 2998acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Max8Ux8: 299957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Max8Sx8: 3000acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Avg8Ux8: 3001acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QSub8Sx8: 3002acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QSub8Ux8: 3003acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Sub8x8: 3004acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpGT8Sx8: 300557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpGT8Ux8: 3006acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpEQ8x8: 3007acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QAdd8Sx8: 3008acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QAdd8Ux8: 300957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal8x8: 301057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl8x8: 3011acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Add8x8: 301257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mul8x8: 301357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PolynomialMul8x8: 3014acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return binary8Ix8(mce, vatom1, vatom2); 3015acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 3016acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Min16Sx4: 301757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Min16Ux4: 3018acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Max16Sx4: 301957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Max16Ux4: 3020acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Avg16Ux4: 3021acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QSub16Ux4: 3022acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QSub16Sx4: 3023acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Sub16x4: 3024acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Mul16x4: 3025acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_MulHi16Sx4: 3026acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_MulHi16Ux4: 3027acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpGT16Sx4: 302857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpGT16Ux4: 3029acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpEQ16x4: 3030acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QAdd16Sx4: 3031acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_QAdd16Ux4: 303257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal16x4: 303357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl16x4: 3034acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Add16x4: 303557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QDMulHi16Sx4: 303657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QRDMulHi16Sx4: 3037acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return binary16Ix4(mce, vatom1, vatom2); 3038acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 3039acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Sub32x2: 3040114a917710310985f421b0c4748d9788164fdfc3sewardj case Iop_Mul32x2: 304157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Max32Sx2: 304257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Max32Ux2: 304357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Min32Sx2: 304457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Min32Ux2: 3045acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpGT32Sx2: 304657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpGT32Ux2: 3047acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_CmpEQ32x2: 3048acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_Add32x2: 304957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd32Ux2: 305057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd32Sx2: 305157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub32Ux2: 305257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub32Sx2: 305357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal32x2: 305457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl32x2: 305557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QDMulHi32Sx2: 305657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QRDMulHi32Sx2: 3057acd2e910861cfc0f95229401922d38d7ce9c6259sewardj return binary32Ix2(mce, vatom1, vatom2); 3058acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 305957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub64Ux1: 306057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub64Sx1: 306157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd64Ux1: 306257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd64Sx1: 306357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal64x1: 306457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl64x1: 306557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal64x1: 306657f92b0326e164124201034afc0c51dcd8db6d07sewardj return binary64Ix1(mce, vatom1, vatom2); 306757f92b0326e164124201034afc0c51dcd8db6d07sewardj 3068e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU8x8: 3069e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU8x8: 3070e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS8x8: 3071b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 307257f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x8(mce, vatom1); 307357f92b0326e164124201034afc0c51dcd8db6d07sewardj 3074e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU16x4: 3075e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU16x4: 3076e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS16x4: 3077b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 307857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x4(mce, vatom1); 307957f92b0326e164124201034afc0c51dcd8db6d07sewardj 3080e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU32x2: 3081e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU32x2: 3082e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS32x2: 3083b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 308457f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, vatom1); 308557f92b0326e164124201034afc0c51dcd8db6d07sewardj 3086e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU64x1: 3087e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU64x1: 3088e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS64x1: 3089b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 309057f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, vatom1); 309157f92b0326e164124201034afc0c51dcd8db6d07sewardj 309257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax32Sx2: 309357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax32Ux2: 309457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin32Sx2: 309557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin32Ux2: 309657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax32Fx2: 309757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin32Fx2: 3098350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I64, 3099350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_PwMax32Ux2, 3100350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast32x2(mce, vatom1), 3101350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast32x2(mce, vatom2))); 310257f92b0326e164124201034afc0c51dcd8db6d07sewardj 310357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax16Sx4: 310457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax16Ux4: 310557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin16Sx4: 310657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin16Ux4: 3107350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I64, 3108350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_PwMax16Ux4, 3109350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast16x4(mce, vatom1), 3110350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast16x4(mce, vatom2))); 311157f92b0326e164124201034afc0c51dcd8db6d07sewardj 311257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax8Sx8: 311357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMax8Ux8: 311457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin8Sx8: 311557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwMin8Ux8: 3116350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I64, 3117350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_PwMax8Ux8, 3118350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast8x8(mce, vatom1), 3119350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast8x8(mce, vatom2))); 312057f92b0326e164124201034afc0c51dcd8db6d07sewardj 312157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd32x2: 312257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd32Fx2: 312357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, 3124350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj assignNew('V', mce, Ity_I64, 3125350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_PwAdd32x2, 3126350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast32x2(mce, vatom1), 3127350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast32x2(mce, vatom2)))); 312857f92b0326e164124201034afc0c51dcd8db6d07sewardj 312957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd16x4: 313057f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x4(mce, 3131350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj assignNew('V', mce, Ity_I64, 3132350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(op, mkPCast16x4(mce, vatom1), 3133350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast16x4(mce, vatom2)))); 313457f92b0326e164124201034afc0c51dcd8db6d07sewardj 313557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd8x8: 313657f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x8(mce, 3137350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj assignNew('V', mce, Ity_I64, 3138350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(op, mkPCast8x8(mce, vatom1), 3139350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast8x8(mce, vatom2)))); 314057f92b0326e164124201034afc0c51dcd8db6d07sewardj 314157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shl8x8: 314257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shr8x8: 314357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sar8x8: 314457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal8x8: 314557f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkUifU64(mce, 314657f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)), 314757f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast8x8(mce,vatom2) 314857f92b0326e164124201034afc0c51dcd8db6d07sewardj ); 314957f92b0326e164124201034afc0c51dcd8db6d07sewardj 315057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shl16x4: 315157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shr16x4: 315257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sar16x4: 315357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal16x4: 315457f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkUifU64(mce, 315557f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)), 315657f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast16x4(mce,vatom2) 315757f92b0326e164124201034afc0c51dcd8db6d07sewardj ); 315857f92b0326e164124201034afc0c51dcd8db6d07sewardj 315957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shl32x2: 316057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shr32x2: 316157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sar32x2: 316257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal32x2: 316357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkUifU64(mce, 316457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)), 316557f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast32x2(mce,vatom2) 316657f92b0326e164124201034afc0c51dcd8db6d07sewardj ); 316757f92b0326e164124201034afc0c51dcd8db6d07sewardj 3168acd2e910861cfc0f95229401922d38d7ce9c6259sewardj /* 64-bit data-steering */ 3169acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveLO32x2: 3170acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveLO16x4: 3171acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveLO8x8: 3172acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveHI32x2: 3173acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveHI16x4: 3174acd2e910861cfc0f95229401922d38d7ce9c6259sewardj case Iop_InterleaveHI8x8: 317557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatOddLanes8x8: 317657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatEvenLanes8x8: 3177114a917710310985f421b0c4748d9788164fdfc3sewardj case Iop_CatOddLanes16x4: 3178114a917710310985f421b0c4748d9788164fdfc3sewardj case Iop_CatEvenLanes16x4: 317957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveOddLanes8x8: 318057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveEvenLanes8x8: 318157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveOddLanes16x4: 318257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveEvenLanes16x4: 31837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(op, vatom1, vatom2)); 3184acd2e910861cfc0f95229401922d38d7ce9c6259sewardj 318557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem8x8: 3186b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 318757f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I8, binop(op, vatom1, atom2)); 318857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem16x4: 3189b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 319057f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I16, binop(op, vatom1, atom2)); 319157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem32x2: 3192b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 319357f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I32, binop(op, vatom1, atom2)); 319457f92b0326e164124201034afc0c51dcd8db6d07sewardj 3195114a917710310985f421b0c4748d9788164fdfc3sewardj /* Perm8x8: rearrange values in left arg using steering values 3196114a917710310985f421b0c4748d9788164fdfc3sewardj from right arg. So rearrange the vbits in the same way but 3197114a917710310985f421b0c4748d9788164fdfc3sewardj pessimise wrt steering values. */ 3198114a917710310985f421b0c4748d9788164fdfc3sewardj case Iop_Perm8x8: 3199114a917710310985f421b0c4748d9788164fdfc3sewardj return mkUifU64( 3200114a917710310985f421b0c4748d9788164fdfc3sewardj mce, 32017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)), 3202114a917710310985f421b0c4748d9788164fdfc3sewardj mkPCast8x8(mce, vatom2) 3203114a917710310985f421b0c4748d9788164fdfc3sewardj ); 3204114a917710310985f421b0c4748d9788164fdfc3sewardj 320520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj /* V128-bit SIMD */ 32060b07059814aee8563905f2caeef186a8c83072cfsewardj 32077222f649c0dab0f50f5a60f841accc64a127856esewardj case Iop_Sqrt32Fx4: 32087222f649c0dab0f50f5a60f841accc64a127856esewardj return unary32Fx4_w_rm(mce, vatom1, vatom2); 32097222f649c0dab0f50f5a60f841accc64a127856esewardj case Iop_Sqrt64Fx2: 32107222f649c0dab0f50f5a60f841accc64a127856esewardj return unary64Fx2_w_rm(mce, vatom1, vatom2); 32117222f649c0dab0f50f5a60f841accc64a127856esewardj 321257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_ShrN8x16: 3213a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShrN16x8: 3214a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShrN32x4: 3215a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShrN64x2: 321657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_SarN8x16: 3217a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_SarN16x8: 3218a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_SarN32x4: 321957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_SarN64x2: 322057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_ShlN8x16: 3221a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShlN16x8: 3222a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShlN32x4: 3223a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_ShlN64x2: 3224620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj /* Same scheme as with all other shifts. Note: 22 Oct 05: 3225620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj this is wrong now, scalar shifts are done properly lazily. 3226620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj Vector shifts should be fixed too. */ 3227b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 32287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)); 3229a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 3230cbf8be74534db8c0a875185cb583502f0c113744sewardj /* V x V shifts/rotates are done using the standard lazy scheme. */ 3231bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* For the non-rounding variants of bi-di vector x vector 3232bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj shifts (the Iop_Sh.. ops, that is) we use the lazy scheme. 3233bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj But note that this is overly pessimistic, because in fact only 3234bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj the bottom 8 bits of each lane of the second argument are taken 3235bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj into account when shifting. So really we ought to ignore 3236bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj undefinedness in bits 8 and above of each lane in the 3237bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj second argument. */ 323843d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shl8x16: 323943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shr8x16: 324043d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Sar8x16: 324157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal8x16: 3242cbf8be74534db8c0a875185cb583502f0c113744sewardj case Iop_Rol8x16: 3243bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh8Sx16: 3244bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh8Ux16: 324543d607580781d902dd06b2c1175da5416f07581asewardj return mkUifUV128(mce, 32467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 324743d607580781d902dd06b2c1175da5416f07581asewardj mkPCast8x16(mce,vatom2) 324843d607580781d902dd06b2c1175da5416f07581asewardj ); 324943d607580781d902dd06b2c1175da5416f07581asewardj 325043d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shl16x8: 325143d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shr16x8: 325243d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Sar16x8: 325357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal16x8: 3254cbf8be74534db8c0a875185cb583502f0c113744sewardj case Iop_Rol16x8: 3255bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh16Sx8: 3256bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh16Ux8: 325743d607580781d902dd06b2c1175da5416f07581asewardj return mkUifUV128(mce, 32587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 325943d607580781d902dd06b2c1175da5416f07581asewardj mkPCast16x8(mce,vatom2) 326043d607580781d902dd06b2c1175da5416f07581asewardj ); 326143d607580781d902dd06b2c1175da5416f07581asewardj 326243d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shl32x4: 326343d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Shr32x4: 326443d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Sar32x4: 326557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal32x4: 3266cbf8be74534db8c0a875185cb583502f0c113744sewardj case Iop_Rol32x4: 3267bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh32Sx4: 3268bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh32Ux4: 326943d607580781d902dd06b2c1175da5416f07581asewardj return mkUifUV128(mce, 32707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 327143d607580781d902dd06b2c1175da5416f07581asewardj mkPCast32x4(mce,vatom2) 327243d607580781d902dd06b2c1175da5416f07581asewardj ); 327343d607580781d902dd06b2c1175da5416f07581asewardj 327457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shl64x2: 327557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Shr64x2: 327657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sar64x2: 327757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sal64x2: 3278147865ccf6e5711cd910f2b1532da59ad1d78bb9sewardj case Iop_Rol64x2: 3279bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh64Sx2: 3280bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Sh64Ux2: 328157f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkUifUV128(mce, 328257f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 328357f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast64x2(mce,vatom2) 328457f92b0326e164124201034afc0c51dcd8db6d07sewardj ); 328557f92b0326e164124201034afc0c51dcd8db6d07sewardj 3286bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* For the rounding variants of bi-di vector x vector shifts, the 3287bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj rounding adjustment can cause undefinedness to propagate through 3288bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj the entire lane, in the worst case. Too complex to handle 3289bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj properly .. just UifU the arguments and then PCast them. 3290bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj Suboptimal but safe. */ 3291bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh8Sx16: 3292bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh8Ux16: 3293bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return binary8Ix16(mce, vatom1, vatom2); 3294bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh16Sx8: 3295bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh16Ux8: 3296bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return binary16Ix8(mce, vatom1, vatom2); 3297bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh32Sx4: 3298bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh32Ux4: 3299bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return binary32Ix4(mce, vatom1, vatom2); 3300bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh64Sx2: 3301bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Rsh64Ux2: 3302bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return binary64Ix2(mce, vatom1, vatom2); 3303bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 330457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_F32ToFixed32Ux4_RZ: 330557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_F32ToFixed32Sx4_RZ: 330657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Fixed32UToF32x4_RN: 330757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Fixed32SToF32x4_RN: 3308b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 330957f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, vatom1); 331057f92b0326e164124201034afc0c51dcd8db6d07sewardj 331157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_F32ToFixed32Ux2_RZ: 331257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_F32ToFixed32Sx2_RZ: 331357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Fixed32UToF32x2_RN: 331457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Fixed32SToF32x2_RN: 3315b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 331657f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, vatom1); 331757f92b0326e164124201034afc0c51dcd8db6d07sewardj 3318a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QSub8Ux16: 3319a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QSub8Sx16: 3320a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Sub8x16: 3321a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Min8Ux16: 332243d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Min8Sx16: 3323a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Max8Ux16: 332443d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Max8Sx16: 3325a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpGT8Sx16: 332643d607580781d902dd06b2c1175da5416f07581asewardj case Iop_CmpGT8Ux16: 3327a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpEQ8x16: 3328a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Avg8Ux16: 332943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Avg8Sx16: 3330a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QAdd8Ux16: 3331a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QAdd8Sx16: 3332bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtUSsatSS8x16: 3333bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtSUsatUU8x16: 333457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal8x16: 333557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl8x16: 3336a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Add8x16: 333757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mul8x16: 333857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PolynomialMul8x16: 333924e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_PolynomialMulAdd8x16: 3340a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return binary8Ix16(mce, vatom1, vatom2); 3341a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 3342a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QSub16Ux8: 3343a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QSub16Sx8: 3344a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Sub16x8: 3345a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Mul16x8: 3346a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_MulHi16Sx8: 3347a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_MulHi16Ux8: 3348a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Min16Sx8: 334943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Min16Ux8: 3350a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Max16Sx8: 335143d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Max16Ux8: 3352a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpGT16Sx8: 335343d607580781d902dd06b2c1175da5416f07581asewardj case Iop_CmpGT16Ux8: 3354a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpEQ16x8: 3355a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Avg16Ux8: 335643d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Avg16Sx8: 3357a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QAdd16Ux8: 3358a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_QAdd16Sx8: 3359bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtUSsatSS16x8: 3360bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtSUsatUU16x8: 336157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal16x8: 336257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl16x8: 3363a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Add16x8: 336457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QDMulHi16Sx8: 336557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QRDMulHi16Sx8: 336624e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_PolynomialMulAdd16x8: 3367a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return binary16Ix8(mce, vatom1, vatom2); 3368a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 3369a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Sub32x4: 3370a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpGT32Sx4: 337143d607580781d902dd06b2c1175da5416f07581asewardj case Iop_CmpGT32Ux4: 3372a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_CmpEQ32x4: 337343d607580781d902dd06b2c1175da5416f07581asewardj case Iop_QAdd32Sx4: 337443d607580781d902dd06b2c1175da5416f07581asewardj case Iop_QAdd32Ux4: 337543d607580781d902dd06b2c1175da5416f07581asewardj case Iop_QSub32Sx4: 337643d607580781d902dd06b2c1175da5416f07581asewardj case Iop_QSub32Ux4: 3377bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtUSsatSS32x4: 3378bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtSUsatUU32x4: 337957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal32x4: 338057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl32x4: 338143d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Avg32Ux4: 338243d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Avg32Sx4: 3383a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Add32x4: 338443d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Max32Ux4: 338543d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Max32Sx4: 338643d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Min32Ux4: 338743d607580781d902dd06b2c1175da5416f07581asewardj case Iop_Min32Sx4: 3388b823b8531aedef4c8abff2544ea12aa0795e914dsewardj case Iop_Mul32x4: 338957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QDMulHi32Sx4: 339057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QRDMulHi32Sx4: 339124e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_PolynomialMulAdd32x4: 3392a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj return binary32Ix4(mce, vatom1, vatom2); 3393a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 3394a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Sub64x2: 3395a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_Add64x2: 33966277067119ad816282b8e57727295b3adee14075carll case Iop_Max64Sx2: 33976277067119ad816282b8e57727295b3adee14075carll case Iop_Max64Ux2: 33986277067119ad816282b8e57727295b3adee14075carll case Iop_Min64Sx2: 33996277067119ad816282b8e57727295b3adee14075carll case Iop_Min64Ux2: 34009a2afe98c754faafb035b165bf844733dd896731sewardj case Iop_CmpEQ64x2: 3401b823b8531aedef4c8abff2544ea12aa0795e914dsewardj case Iop_CmpGT64Sx2: 34026277067119ad816282b8e57727295b3adee14075carll case Iop_CmpGT64Ux2: 340357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSal64x2: 340457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QShl64x2: 340557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd64Ux2: 340657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QAdd64Sx2: 340757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub64Ux2: 340857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_QSub64Sx2: 3409bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtUSsatSS64x2: 3410bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QAddExtSUsatUU64x2: 341124e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_PolynomialMulAdd64x2: 341224e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_CipherV128: 341324e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_CipherLV128: 341424e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_NCipherV128: 341524e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_NCipherLV128: 341624e40de8f2127d70117ed9af3bc4474cbc29cb8acarll return binary64Ix2(mce, vatom1, vatom2); 3417a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 34186277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Sto32Sx4: 34196277067119ad816282b8e57727295b3adee14075carll case Iop_QNarrowBin64Uto32Ux4: 34207ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Sx8: 34217ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Uto16Ux8: 34227ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin32Sto16Ux8: 34237ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Sx16: 34247ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Uto8Ux16: 34257ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowBin16Sto8Ux16: 34267ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorNarrowBinV128(mce, op, vatom1, vatom2); 3427a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj 34280b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Min64Fx2: 34290b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Max64Fx2: 34300b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpLT64Fx2: 34310b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpLE64Fx2: 34320b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpEQ64Fx2: 3433545663e151401958e8f5d0bf21843bcff3e62f1csewardj case Iop_CmpUN64Fx2: 3434143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RecipStep64Fx2: 3435143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RSqrtStep64Fx2: 34360b07059814aee8563905f2caeef186a8c83072cfsewardj return binary64Fx2(mce, vatom1, vatom2); 34370b07059814aee8563905f2caeef186a8c83072cfsewardj 34380b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Sub64F0x2: 34390b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Mul64F0x2: 34400b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Min64F0x2: 34410b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Max64F0x2: 34420b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Div64F0x2: 34430b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpLT64F0x2: 34440b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpLE64F0x2: 34450b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_CmpEQ64F0x2: 3446545663e151401958e8f5d0bf21843bcff3e62f1csewardj case Iop_CmpUN64F0x2: 34470b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Add64F0x2: 34480b07059814aee8563905f2caeef186a8c83072cfsewardj return binary64F0x2(mce, vatom1, vatom2); 34490b07059814aee8563905f2caeef186a8c83072cfsewardj 3450170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Min32Fx4: 3451170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Max32Fx4: 3452170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpLT32Fx4: 3453170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpLE32Fx4: 3454170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpEQ32Fx4: 3455545663e151401958e8f5d0bf21843bcff3e62f1csewardj case Iop_CmpUN32Fx4: 3456e78ba2a7c5a7d33f461626a0f84c3faaf2e43950cerion case Iop_CmpGT32Fx4: 3457e78ba2a7c5a7d33f461626a0f84c3faaf2e43950cerion case Iop_CmpGE32Fx4: 3458ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipStep32Fx4: 3459ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtStep32Fx4: 34603245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj return binary32Fx4(mce, vatom1, vatom2); 34613245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 346257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Sub32Fx2: 346357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mul32Fx2: 346457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Min32Fx2: 346557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Max32Fx2: 346657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpEQ32Fx2: 346757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpGT32Fx2: 346857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpGE32Fx2: 346957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Add32Fx2: 3470ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipStep32Fx2: 3471ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtStep32Fx2: 347257f92b0326e164124201034afc0c51dcd8db6d07sewardj return binary32Fx2(mce, vatom1, vatom2); 347357f92b0326e164124201034afc0c51dcd8db6d07sewardj 3474170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Sub32F0x4: 3475170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Mul32F0x4: 3476170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Min32F0x4: 3477170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Max32F0x4: 3478170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Div32F0x4: 3479170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpLT32F0x4: 3480170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpLE32F0x4: 3481170ee210842367a5cc52390358ba560774f76329sewardj case Iop_CmpEQ32F0x4: 3482545663e151401958e8f5d0bf21843bcff3e62f1csewardj case Iop_CmpUN32F0x4: 3483170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Add32F0x4: 3484170ee210842367a5cc52390358ba560774f76329sewardj return binary32F0x4(mce, vatom1, vatom2); 3485170ee210842367a5cc52390358ba560774f76329sewardj 3486e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU8x16: 3487e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU8x16: 3488e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS8x16: 3489b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 349057f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x16(mce, vatom1); 349157f92b0326e164124201034afc0c51dcd8db6d07sewardj 3492e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU16x8: 3493e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU16x8: 3494e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS16x8: 3495b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 349657f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x8(mce, vatom1); 349757f92b0326e164124201034afc0c51dcd8db6d07sewardj 3498e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU32x4: 3499e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU32x4: 3500e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS32x4: 3501b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 350257f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, vatom1); 350357f92b0326e164124201034afc0c51dcd8db6d07sewardj 3504e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSU64x2: 3505e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatUU64x2: 3506e541e222ef15d58e1a61f97fcf729468628efa54sewardj case Iop_QShlNsatSS64x2: 3507b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 350857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, vatom1); 350957f92b0326e164124201034afc0c51dcd8db6d07sewardj 3510bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* Q-and-Qshift-by-imm-and-narrow of the form (V128, I8) -> V128. 3511bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj To make this simpler, do the following: 3512bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj * complain if the shift amount (the I8) is undefined 3513bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj * pcast each lane at the wide width 3514bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj * truncate each lane to half width 3515bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj * pcast the resulting 64-bit value to a single bit and use 3516bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj that as the least significant bit of the upper half of the 3517bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj result. */ 3518bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow64Uto32Ux2: 3519bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow64Sto32Sx2: 3520bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow64Sto32Ux2: 3521bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow64Uto32Ux2: 3522bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow64Sto32Sx2: 3523bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow64Sto32Ux2: 3524bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow32Uto16Ux4: 3525bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow32Sto16Sx4: 3526bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow32Sto16Ux4: 3527bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow32Uto16Ux4: 3528bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow32Sto16Sx4: 3529bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow32Sto16Ux4: 3530bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow16Uto8Ux8: 3531bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow16Sto8Sx8: 3532bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow16Sto8Ux8: 3533bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow16Uto8Ux8: 3534bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow16Sto8Sx8: 3535bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow16Sto8Ux8: 3536bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj { 3537bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* (*fnPessim) (MCEnv*, IRAtom*) = NULL; 3538bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IROp opNarrow = Iop_INVALID; 3539bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj switch (op) { 3540bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow64Uto32Ux2: 3541bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow64Sto32Sx2: 3542bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow64Sto32Ux2: 3543bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow64Uto32Ux2: 3544bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow64Sto32Sx2: 3545bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow64Sto32Ux2: 3546bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj fnPessim = mkPCast64x2; 3547bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj opNarrow = Iop_NarrowUn64to32x2; 3548bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 3549bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow32Uto16Ux4: 3550bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow32Sto16Sx4: 3551bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow32Sto16Ux4: 3552bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow32Uto16Ux4: 3553bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow32Sto16Sx4: 3554bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow32Sto16Ux4: 3555bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj fnPessim = mkPCast32x4; 3556bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj opNarrow = Iop_NarrowUn32to16x4; 3557bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 3558bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQShrNnarrow16Uto8Ux8: 3559bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow16Sto8Sx8: 3560bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQSarNnarrow16Sto8Ux8: 3561bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRShrNnarrow16Uto8Ux8: 3562bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow16Sto8Sx8: 3563bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandQRSarNnarrow16Sto8Ux8: 3564bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj fnPessim = mkPCast16x8; 3565bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj opNarrow = Iop_NarrowUn16to8x8; 3566bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 3567bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj default: 3568bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj tl_assert(0); 3569bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 3570bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj complainIfUndefined(mce, atom2, NULL); 3571bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Pessimised shift result 3572bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* shV 3573bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = fnPessim(mce, vatom1); 3574bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Narrowed, pessimised shift result 3575bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* shVnarrowed 3576bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj = assignNew('V', mce, Ity_I64, unop(opNarrow, shV)); 3577bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates: Def--(63)--Def PCast-to-I1(narrowed) 3578bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* qV = mkPCastXXtoXXlsb(mce, shVnarrowed, Ity_I64); 3579bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // and assemble the result 3580bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return assignNew('V', mce, Ity_V128, 3581bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binop(Iop_64HLtoV128, qV, shVnarrowed)); 3582bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 3583bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 358457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull32Sx2: 358557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull32Ux2: 35864d6ce849ad8534867072dbc7ed31464019e23396sewardj case Iop_QDMull32Sx2: 35877ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorWidenI64(mce, Iop_Widen32Sto64x2, 35887ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj mkUifU64(mce, vatom1, vatom2)); 358957f92b0326e164124201034afc0c51dcd8db6d07sewardj 359057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull16Sx4: 359157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull16Ux4: 35924d6ce849ad8534867072dbc7ed31464019e23396sewardj case Iop_QDMull16Sx4: 35937ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorWidenI64(mce, Iop_Widen16Sto32x4, 35947ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj mkUifU64(mce, vatom1, vatom2)); 359557f92b0326e164124201034afc0c51dcd8db6d07sewardj 359657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull8Sx8: 359757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Mull8Ux8: 359857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PolynomialMull8x8: 35997ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorWidenI64(mce, Iop_Widen8Sto16x8, 36007ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj mkUifU64(mce, vatom1, vatom2)); 360157f92b0326e164124201034afc0c51dcd8db6d07sewardj 360257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd32x4: 360357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, 360457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, binop(op, mkPCast32x4(mce, vatom1), 360557f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast32x4(mce, vatom2)))); 360657f92b0326e164124201034afc0c51dcd8db6d07sewardj 360757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd16x8: 360857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x8(mce, 360957f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, binop(op, mkPCast16x8(mce, vatom1), 361057f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast16x8(mce, vatom2)))); 361157f92b0326e164124201034afc0c51dcd8db6d07sewardj 361257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAdd8x16: 361357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x16(mce, 361457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, binop(op, mkPCast8x16(mce, vatom1), 361557f92b0326e164124201034afc0c51dcd8db6d07sewardj mkPCast8x16(mce, vatom2)))); 361657f92b0326e164124201034afc0c51dcd8db6d07sewardj 361720d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj /* V128-bit data-steering */ 361820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_SetV128lo32: 361920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_SetV128lo64: 362020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_64HLtoV128: 3621a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveLO64x2: 3622a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveLO32x4: 3623a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveLO16x8: 3624a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveLO8x16: 3625a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveHI64x2: 3626a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveHI32x4: 3627a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveHI16x8: 3628a1d9330a6d80e3c1ab69d7f0d0ad6c45b8a5cd38sewardj case Iop_InterleaveHI8x16: 362957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatOddLanes8x16: 363057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatOddLanes16x8: 363157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatOddLanes32x4: 363257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatEvenLanes8x16: 363357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatEvenLanes16x8: 363457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CatEvenLanes32x4: 363557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveOddLanes8x16: 363657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveOddLanes16x8: 363757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveOddLanes32x4: 363857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveEvenLanes8x16: 363957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveEvenLanes16x8: 364057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_InterleaveEvenLanes32x4: 36417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(op, vatom1, vatom2)); 364257f92b0326e164124201034afc0c51dcd8db6d07sewardj 364357f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem8x16: 3644b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 364557f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I8, binop(op, vatom1, atom2)); 364657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem16x8: 3647b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 364857f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I16, binop(op, vatom1, atom2)); 364957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem32x4: 3650b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 365157f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I32, binop(op, vatom1, atom2)); 365257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_GetElem64x2: 3653b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 365457f92b0326e164124201034afc0c51dcd8db6d07sewardj return assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)); 365557f92b0326e164124201034afc0c51dcd8db6d07sewardj 3656620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj /* Perm8x16: rearrange values in left arg using steering values 3657620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj from right arg. So rearrange the vbits in the same way but 3658350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj pessimise wrt steering values. Perm32x4 ditto. */ 3659620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj case Iop_Perm8x16: 3660620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj return mkUifUV128( 3661620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj mce, 36627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 3663620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj mkPCast8x16(mce, vatom2) 3664620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj ); 3665350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Perm32x4: 3666350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return mkUifUV128( 3667350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mce, 3668350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)), 3669350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj mkPCast32x4(mce, vatom2) 3670350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj ); 3671170ee210842367a5cc52390358ba560774f76329sewardj 367243d607580781d902dd06b2c1175da5416f07581asewardj /* These two take the lower half of each 16-bit lane, sign/zero 367343d607580781d902dd06b2c1175da5416f07581asewardj extend it to 32, and multiply together, producing a 32x4 367443d607580781d902dd06b2c1175da5416f07581asewardj result (and implicitly ignoring half the operand bits). So 367543d607580781d902dd06b2c1175da5416f07581asewardj treat it as a bunch of independent 16x8 operations, but then 367643d607580781d902dd06b2c1175da5416f07581asewardj do 32-bit shifts left-right to copy the lower half results 367743d607580781d902dd06b2c1175da5416f07581asewardj (which are all 0s or all 1s due to PCasting in binary16Ix8) 367843d607580781d902dd06b2c1175da5416f07581asewardj into the upper half of each result lane. */ 367943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_MullEven16Ux8: 368043d607580781d902dd06b2c1175da5416f07581asewardj case Iop_MullEven16Sx8: { 368143d607580781d902dd06b2c1175da5416f07581asewardj IRAtom* at; 368243d607580781d902dd06b2c1175da5416f07581asewardj at = binary16Ix8(mce,vatom1,vatom2); 36837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_ShlN32x4, at, mkU8(16))); 36847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SarN32x4, at, mkU8(16))); 368543d607580781d902dd06b2c1175da5416f07581asewardj return at; 368643d607580781d902dd06b2c1175da5416f07581asewardj } 368743d607580781d902dd06b2c1175da5416f07581asewardj 368843d607580781d902dd06b2c1175da5416f07581asewardj /* Same deal as Iop_MullEven16{S,U}x8 */ 368943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_MullEven8Ux16: 369043d607580781d902dd06b2c1175da5416f07581asewardj case Iop_MullEven8Sx16: { 369143d607580781d902dd06b2c1175da5416f07581asewardj IRAtom* at; 369243d607580781d902dd06b2c1175da5416f07581asewardj at = binary8Ix16(mce,vatom1,vatom2); 36937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_ShlN16x8, at, mkU8(8))); 36947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj at = assignNew('V', mce, Ity_V128, binop(Iop_SarN16x8, at, mkU8(8))); 369543d607580781d902dd06b2c1175da5416f07581asewardj return at; 369643d607580781d902dd06b2c1175da5416f07581asewardj } 369743d607580781d902dd06b2c1175da5416f07581asewardj 36986277067119ad816282b8e57727295b3adee14075carll /* Same deal as Iop_MullEven16{S,U}x8 */ 36996277067119ad816282b8e57727295b3adee14075carll case Iop_MullEven32Ux4: 37006277067119ad816282b8e57727295b3adee14075carll case Iop_MullEven32Sx4: { 37016277067119ad816282b8e57727295b3adee14075carll IRAtom* at; 37026277067119ad816282b8e57727295b3adee14075carll at = binary32Ix4(mce,vatom1,vatom2); 37036277067119ad816282b8e57727295b3adee14075carll at = assignNew('V', mce, Ity_V128, binop(Iop_ShlN64x2, at, mkU8(32))); 37046277067119ad816282b8e57727295b3adee14075carll at = assignNew('V', mce, Ity_V128, binop(Iop_SarN64x2, at, mkU8(32))); 37056277067119ad816282b8e57727295b3adee14075carll return at; 37066277067119ad816282b8e57727295b3adee14075carll } 37076277067119ad816282b8e57727295b3adee14075carll 370843d607580781d902dd06b2c1175da5416f07581asewardj /* narrow 2xV128 into 1xV128, hi half from left arg, in a 2 x 370943d607580781d902dd06b2c1175da5416f07581asewardj 32x4 -> 16x8 laneage, discarding the upper half of each lane. 371043d607580781d902dd06b2c1175da5416f07581asewardj Simply apply same op to the V bits, since this really no more 371143d607580781d902dd06b2c1175da5416f07581asewardj than a data steering operation. */ 37127ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_NarrowBin32to16x8: 37137ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_NarrowBin16to8x16: 3714dfbf294f08ac004a60cb3b528d544cb7d0404eb0carll case Iop_NarrowBin64to32x4: 37157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, 37167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj binop(op, vatom1, vatom2)); 371743d607580781d902dd06b2c1175da5416f07581asewardj 371843d607580781d902dd06b2c1175da5416f07581asewardj case Iop_ShrV128: 371943d607580781d902dd06b2c1175da5416f07581asewardj case Iop_ShlV128: 372043d607580781d902dd06b2c1175da5416f07581asewardj /* Same scheme as with all other shifts. Note: 10 Nov 05: 372143d607580781d902dd06b2c1175da5416f07581asewardj this is wrong now, scalar shifts are done properly lazily. 372243d607580781d902dd06b2c1175da5416f07581asewardj Vector shifts should be fixed too. */ 3723b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 37247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)); 372543d607580781d902dd06b2c1175da5416f07581asewardj 372624e40de8f2127d70117ed9af3bc4474cbc29cb8acarll /* SHA Iops */ 372724e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_SHA256: 372824e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_SHA512: 372924e40de8f2127d70117ed9af3bc4474cbc29cb8acarll complainIfUndefined(mce, atom2, NULL); 373024e40de8f2127d70117ed9af3bc4474cbc29cb8acarll return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)); 373124e40de8f2127d70117ed9af3bc4474cbc29cb8acarll 373269a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj /* I128-bit data-steering */ 373369a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Iop_64HLto128: 37347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I128, binop(op, vatom1, vatom2)); 373569a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj 3736350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj /* V256-bit SIMD */ 3737350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 3738350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Max64Fx4: 3739350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Min64Fx4: 3740350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return binary64Fx4(mce, vatom1, vatom2); 3741350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 3742350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Max32Fx8: 3743350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Min32Fx8: 3744350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return binary32Fx8(mce, vatom1, vatom2); 3745350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 3746350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj /* V256-bit data-steering */ 3747350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_V128HLtoV256: 3748350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_V256, binop(op, vatom1, vatom2)); 3749350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 37503245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj /* Scalar floating point */ 37513245c919d273a73ce23632d6a3ab4fc027fefcd9sewardj 3752b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F32toI64S: 37531b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_F32toI64U: 3754b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32(rm) x F32 -> I64 */ 3755b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 3756b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 3757b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_I64StoF32: 3758b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32(rm) x I64 -> F32 */ 3759b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3760b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 3761ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_RoundF64toInt: 3762ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_RoundF64toF32: 376306f96d01b9471616c142af3b9f4298cb265973cdsewardj case Iop_F64toI64S: 3764a201c45bddd4b13c00c171d707ad58b102569f41sewardj case Iop_F64toI64U: 376506f96d01b9471616c142af3b9f4298cb265973cdsewardj case Iop_I64StoF64: 3766f34eb496099507090f26dcf94bb780da8b3894e5sewardj case Iop_I64UtoF64: 376722ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_SinF64: 376822ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_CosF64: 376922ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_TanF64: 377022ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_2xm1F64: 377122ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj case Iop_SqrtF64: 3772143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RecpExpF64: 377322ac5f4e9561d5349d6864c42e7dddafb95e59a6sewardj /* I32(rm) x I64/F64 -> I64/F64 */ 377495448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 377595448075345dc73986042f6dc68eb464d02bc6a8sewardj 3776ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_ShlD64: 3777ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_ShrD64: 377818c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_RoundD64toInt: 3779054684ff9ed37d70584d6a954df3382edd8b9729florian /* I32(rm) x D64 -> D64 */ 3780ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 3781ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj 3782ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_ShlD128: 3783ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_ShrD128: 378418c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_RoundD128toInt: 3785054684ff9ed37d70584d6a954df3382edd8b9729florian /* I32(rm) x D128 -> D128 */ 3786ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj return mkLazy2(mce, Ity_I128, vatom1, vatom2); 3787ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj 378872e4640ec92ff566dbba01f69197865016cfeb84florian case Iop_RoundF128toInt: 378972e4640ec92ff566dbba01f69197865016cfeb84florian /* I32(rm) x F128 -> F128 */ 379072e4640ec92ff566dbba01f69197865016cfeb84florian return mkLazy2(mce, Ity_I128, vatom1, vatom2); 379172e4640ec92ff566dbba01f69197865016cfeb84florian 3792ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_D64toI64S: 379353eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_D64toI64U: 3794ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_I64StoD64: 379553eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I64UtoD64: 3796054684ff9ed37d70584d6a954df3382edd8b9729florian /* I32(rm) x I64/D64 -> D64/I64 */ 3797ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 3798ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj 3799ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F32toD32: 3800ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F64toD32: 3801ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F128toD32: 3802ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D32toF32: 3803ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D64toF32: 3804ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D128toF32: 3805ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian /* I32(rm) x F32/F64/F128/D32/D64/D128 -> D32/F32 */ 3806ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3807ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian 3808ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F32toD64: 380939b08d85652c321c2779a0256027d66144847c3cflorian case Iop_F64toD64: 3810ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F128toD64: 3811ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D32toF64: 381239b08d85652c321c2779a0256027d66144847c3cflorian case Iop_D64toF64: 381339b08d85652c321c2779a0256027d66144847c3cflorian case Iop_D128toF64: 3814ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian /* I32(rm) x F32/F64/F128/D32/D64/D128 -> D64/F64 */ 381539b08d85652c321c2779a0256027d66144847c3cflorian return mkLazy2(mce, Ity_I64, vatom1, vatom2); 381639b08d85652c321c2779a0256027d66144847c3cflorian 3817ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F32toD128: 3818ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_F64toD128: 381939b08d85652c321c2779a0256027d66144847c3cflorian case Iop_F128toD128: 3820ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D32toF128: 3821ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian case Iop_D64toF128: 382239b08d85652c321c2779a0256027d66144847c3cflorian case Iop_D128toF128: 3823ba5693c7155e28fc5d2cbe1be751a77fb2097d02florian /* I32(rm) x F32/F64/F128/D32/D64/D128 -> D128/F128 */ 382439b08d85652c321c2779a0256027d66144847c3cflorian return mkLazy2(mce, Ity_I128, vatom1, vatom2); 382539b08d85652c321c2779a0256027d66144847c3cflorian 3826d376a769d87c219f48bf180546af80bd6a9476f4sewardj case Iop_RoundF32toInt: 3827aec1be3a7092715756648cf7e62466af5eab73c2sewardj case Iop_SqrtF32: 3828143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RecpExpF32: 3829aec1be3a7092715756648cf7e62466af5eab73c2sewardj /* I32(rm) x I32/F32 -> I32/F32 */ 3830aec1be3a7092715756648cf7e62466af5eab73c2sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3831aec1be3a7092715756648cf7e62466af5eab73c2sewardj 3832b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_SqrtF128: 3833b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* I32(rm) x F128 -> F128 */ 3834b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I128, vatom1, vatom2); 3835b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 3836b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_I32StoF32: 38371b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_I32UtoF32: 3838b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F32toI32S: 38391b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_F32toI32U: 3840b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* First arg is I32 (rounding mode), second is F32/I32 (data). */ 3841b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3842b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 38431f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj case Iop_F64toF16: 38441f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj case Iop_F32toF16: 38451f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj /* First arg is I32 (rounding mode), second is F64/F32 (data). */ 38461f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj return mkLazy2(mce, Ity_I16, vatom1, vatom2); 38471f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj 3848b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128toI32S: /* IRRoundingMode(I32) x F128 -> signed I32 */ 38491b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_F128toI32U: /* IRRoundingMode(I32) x F128 -> unsigned I32 */ 3850b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128toF32: /* IRRoundingMode(I32) x F128 -> F32 */ 3851733b4db9e2385911103f8b10ec2a5a72f9329941florian case Iop_D128toI32S: /* IRRoundingMode(I32) x D128 -> signed I32 */ 3852733b4db9e2385911103f8b10ec2a5a72f9329941florian case Iop_D128toI32U: /* IRRoundingMode(I32) x D128 -> unsigned I32 */ 3853b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3854b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 3855b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128toI64S: /* IRRoundingMode(I32) x F128 -> signed I64 */ 38561b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_F128toI64U: /* IRRoundingMode(I32) x F128 -> unsigned I64 */ 3857b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128toF64: /* IRRoundingMode(I32) x F128 -> F64 */ 3858733b4db9e2385911103f8b10ec2a5a72f9329941florian case Iop_D128toD64: /* IRRoundingMode(I64) x D128 -> D64 */ 3859733b4db9e2385911103f8b10ec2a5a72f9329941florian case Iop_D128toI64S: /* IRRoundingMode(I64) x D128 -> signed I64 */ 3860733b4db9e2385911103f8b10ec2a5a72f9329941florian case Iop_D128toI64U: /* IRRoundingMode(I32) x D128 -> unsigned I64 */ 3861b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 3862b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 3863b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F64HLtoF128: 3864b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_D64HLtoD128: 3865350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I128, 3866350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_64HLto128, vatom1, vatom2)); 3867b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 386859570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_F64toI32U: 386906f96d01b9471616c142af3b9f4298cb265973cdsewardj case Iop_F64toI32S: 3870e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj case Iop_F64toF32: 3871f34eb496099507090f26dcf94bb780da8b3894e5sewardj case Iop_I64UtoF32: 387253eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_D64toI32U: 387353eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_D64toI32S: 387453eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian /* First arg is I32 (rounding mode), second is F64/D64 (data). */ 387595448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 387695448075345dc73986042f6dc68eb464d02bc6a8sewardj 3877ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_D64toD32: 3878054684ff9ed37d70584d6a954df3382edd8b9729florian /* First arg is I32 (rounding mode), second is D64 (data). */ 3879f4bed371e207f1bb0e52b796ac5f81d93a88245fflorian return mkLazy2(mce, Ity_I32, vatom1, vatom2); 3880ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj 388106f96d01b9471616c142af3b9f4298cb265973cdsewardj case Iop_F64toI16S: 388295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* First arg is I32 (rounding mode), second is F64 (data). */ 388395448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazy2(mce, Ity_I16, vatom1, vatom2); 388495448075345dc73986042f6dc68eb464d02bc6a8sewardj 388518c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_InsertExpD64: 388618c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj /* I64 x I64 -> D64 */ 388718c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 388818c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj 388918c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_InsertExpD128: 389018c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj /* I64 x I128 -> D128 */ 389118c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj return mkLazy2(mce, Ity_I128, vatom1, vatom2); 389218c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj 3893b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_CmpF32: 389495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_CmpF64: 3895b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_CmpF128: 389618c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_CmpD64: 389718c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_CmpD128: 389829a36b99ad14c9c5a9aa5e89ff3e0d8274fc0339florian case Iop_CmpExpD64: 389929a36b99ad14c9c5a9aa5e89ff3e0d8274fc0339florian case Iop_CmpExpD128: 390095448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazy2(mce, Ity_I32, vatom1, vatom2); 390195448075345dc73986042f6dc68eb464d02bc6a8sewardj 390295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* non-FP after here */ 390395448075345dc73986042f6dc68eb464d02bc6a8sewardj 390495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_DivModU64to32: 390595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_DivModS64to32: 390695448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 390795448075345dc73986042f6dc68eb464d02bc6a8sewardj 390869a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Iop_DivModU128to64: 390969a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Iop_DivModS128to64: 391069a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj return mkLazy2(mce, Ity_I128, vatom1, vatom2); 391169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj 3912537ed2d090e7472a6cb2ee80239d4780551a5f19florian case Iop_8HLto16: 3913537ed2d090e7472a6cb2ee80239d4780551a5f19florian return assignNew('V', mce, Ity_I16, binop(op, vatom1, vatom2)); 391495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_16HLto32: 39157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, binop(op, vatom1, vatom2)); 391695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32HLto64: 39177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, binop(op, vatom1, vatom2)); 391895448075345dc73986042f6dc68eb464d02bc6a8sewardj 3919b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_DivModS64to64: 39206cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Iop_MullS64: 39216cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Iop_MullU64: { 39226cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj IRAtom* vLo64 = mkLeft64(mce, mkUifU64(mce, vatom1,vatom2)); 39236cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj IRAtom* vHi64 = mkPCastTo(mce, Ity_I64, vLo64); 3924350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I128, 3925350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_64HLto128, vHi64, vLo64)); 39266cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj } 39276cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj 392895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullS32: 392995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullU32: { 393095448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); 393195448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32); 3932350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I64, 3933350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_32HLto64, vHi32, vLo32)); 393495448075345dc73986042f6dc68eb464d02bc6a8sewardj } 3935e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 393695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullS16: 393795448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullU16: { 393895448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); 393995448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16); 3940350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return assignNew('V', mce, Ity_I32, 3941350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj binop(Iop_16HLto32, vHi16, vLo16)); 394295448075345dc73986042f6dc68eb464d02bc6a8sewardj } 3943e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 394495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullS8: 394595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_MullU8: { 394695448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); 394795448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8); 39487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8)); 394995448075345dc73986042f6dc68eb464d02bc6a8sewardj } 3950e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 39515af0506e418c4b28e7538f8ad7991bb02a206fa7sewardj case Iop_Sad8Ux4: /* maybe we could do better? ftm, do mkLazy2. */ 39529e5910872335c1ff7cb9733480904aa84dfe16abcerion case Iop_DivS32: 39539e5910872335c1ff7cb9733480904aa84dfe16abcerion case Iop_DivU32: 3954a201c45bddd4b13c00c171d707ad58b102569f41sewardj case Iop_DivU32E: 3955169ac048e00bacd4dd5e16843404be9a958832basewardj case Iop_DivS32E: 39562157b2c139946c0b70c0e5e2ae2a38de57a43954sewardj case Iop_QAdd32S: /* could probably do better */ 39572157b2c139946c0b70c0e5e2ae2a38de57a43954sewardj case Iop_QSub32S: /* could probably do better */ 39589e5910872335c1ff7cb9733480904aa84dfe16abcerion return mkLazy2(mce, Ity_I32, vatom1, vatom2); 39599e5910872335c1ff7cb9733480904aa84dfe16abcerion 3960b00944a4fc5320f4f9313d2090c32f6d36fd0d10sewardj case Iop_DivS64: 3961b00944a4fc5320f4f9313d2090c32f6d36fd0d10sewardj case Iop_DivU64: 3962a201c45bddd4b13c00c171d707ad58b102569f41sewardj case Iop_DivS64E: 3963169ac048e00bacd4dd5e16843404be9a958832basewardj case Iop_DivU64E: 3964b00944a4fc5320f4f9313d2090c32f6d36fd0d10sewardj return mkLazy2(mce, Ity_I64, vatom1, vatom2); 3965b00944a4fc5320f4f9313d2090c32f6d36fd0d10sewardj 396695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Add32: 396754eac25a54a255d5deaa228547d2ef145590929bsewardj if (mce->bogusLiterals || mce->useLLVMworkarounds) 3968d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return expensiveAddSub(mce,True,Ity_I32, 3969d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj vatom1,vatom2, atom1,atom2); 3970d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj else 3971d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj goto cheap_AddSub32; 397295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Sub32: 3973d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj if (mce->bogusLiterals) 3974d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return expensiveAddSub(mce,False,Ity_I32, 3975d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj vatom1,vatom2, atom1,atom2); 3976d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj else 3977d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj goto cheap_AddSub32; 3978d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj 3979d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj cheap_AddSub32: 398095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Mul32: 3981992dff97aa9c074f86f831a76367fb55e0541da2sewardj return mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); 3982992dff97aa9c074f86f831a76367fb55e0541da2sewardj 3983463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj case Iop_CmpORD32S: 3984463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj case Iop_CmpORD32U: 39851bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj case Iop_CmpORD64S: 39861bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj case Iop_CmpORD64U: 39871bc8210aff6581dd3b48b72b6c27fdbbc6669e70sewardj return doCmpORD(mce, op, vatom1,vatom2, atom1,atom2); 398895448075345dc73986042f6dc68eb464d02bc6a8sewardj 3989681be302af5528c2cb415270da9fde2e7f347e69sewardj case Iop_Add64: 399054eac25a54a255d5deaa228547d2ef145590929bsewardj if (mce->bogusLiterals || mce->useLLVMworkarounds) 3991d9774d73807c7292c72e1254119d6bd8ded81f15tom return expensiveAddSub(mce,True,Ity_I64, 3992d9774d73807c7292c72e1254119d6bd8ded81f15tom vatom1,vatom2, atom1,atom2); 3993d9774d73807c7292c72e1254119d6bd8ded81f15tom else 3994d9774d73807c7292c72e1254119d6bd8ded81f15tom goto cheap_AddSub64; 3995681be302af5528c2cb415270da9fde2e7f347e69sewardj case Iop_Sub64: 3996d9774d73807c7292c72e1254119d6bd8ded81f15tom if (mce->bogusLiterals) 3997d9774d73807c7292c72e1254119d6bd8ded81f15tom return expensiveAddSub(mce,False,Ity_I64, 3998d9774d73807c7292c72e1254119d6bd8ded81f15tom vatom1,vatom2, atom1,atom2); 3999d9774d73807c7292c72e1254119d6bd8ded81f15tom else 4000d9774d73807c7292c72e1254119d6bd8ded81f15tom goto cheap_AddSub64; 4001d9774d73807c7292c72e1254119d6bd8ded81f15tom 4002d9774d73807c7292c72e1254119d6bd8ded81f15tom cheap_AddSub64: 4003d9774d73807c7292c72e1254119d6bd8ded81f15tom case Iop_Mul64: 4004681be302af5528c2cb415270da9fde2e7f347e69sewardj return mkLeft64(mce, mkUifU64(mce, vatom1,vatom2)); 4005681be302af5528c2cb415270da9fde2e7f347e69sewardj 400695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Mul16: 400795448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Add16: 400895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Sub16: 400995448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); 401095448075345dc73986042f6dc68eb464d02bc6a8sewardj 4011537ed2d090e7472a6cb2ee80239d4780551a5f19florian case Iop_Mul8: 401295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Sub8: 401395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Add8: 401495448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); 401595448075345dc73986042f6dc68eb464d02bc6a8sewardj 401669a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj case Iop_CmpEQ64: 4017e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj case Iop_CmpNE64: 401869a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj if (mce->bogusLiterals) 40194cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj goto expensive_cmp64; 402069a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj else 402169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj goto cheap_cmp64; 40224cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 40234cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj expensive_cmp64: 40244cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_ExpCmpNE64: 40254cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj return expensiveCmpEQorNE(mce,Ity_I64, vatom1,vatom2, atom1,atom2 ); 40264cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 402769a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj cheap_cmp64: 4028cd986336a55192fe237a72b323b378b674af38e0tom case Iop_CmpLE64S: case Iop_CmpLE64U: 4029cd986336a55192fe237a72b323b378b674af38e0tom case Iop_CmpLT64U: case Iop_CmpLT64S: 403069a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj return mkPCastTo(mce, Ity_I1, mkUifU64(mce, vatom1,vatom2)); 403169a1332a98a195be9300c5c5b5e5add32bae5aa6sewardj 4032d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Iop_CmpEQ32: 4033e6f8af482ef8992e0e1b2eba49cfa907a93f9b66sewardj case Iop_CmpNE32: 4034d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj if (mce->bogusLiterals) 40354cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj goto expensive_cmp32; 4036d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj else 4037d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj goto cheap_cmp32; 40384cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 40394cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj expensive_cmp32: 40404cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_ExpCmpNE32: 40414cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj return expensiveCmpEQorNE(mce,Ity_I32, vatom1,vatom2, atom1,atom2 ); 40424cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 4043d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj cheap_cmp32: 404495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_CmpLE32S: case Iop_CmpLE32U: 404595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_CmpLT32U: case Iop_CmpLT32S: 404695448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, Ity_I1, mkUifU32(mce, vatom1,vatom2)); 404795448075345dc73986042f6dc68eb464d02bc6a8sewardj 404895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_CmpEQ16: case Iop_CmpNE16: 404995448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, Ity_I1, mkUifU16(mce, vatom1,vatom2)); 405095448075345dc73986042f6dc68eb464d02bc6a8sewardj 40514cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_ExpCmpNE16: 40524cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj return expensiveCmpEQorNE(mce,Ity_I16, vatom1,vatom2, atom1,atom2 ); 40534cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 405495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_CmpEQ8: case Iop_CmpNE8: 405595448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, Ity_I1, mkUifU8(mce, vatom1,vatom2)); 405695448075345dc73986042f6dc68eb464d02bc6a8sewardj 4057afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ8: case Iop_CasCmpNE8: 4058afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ16: case Iop_CasCmpNE16: 4059afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ32: case Iop_CasCmpNE32: 4060afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ64: case Iop_CasCmpNE64: 4061afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* Just say these all produce a defined result, regardless 4062afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj of their arguments. See COMMENT_ON_CasCmpEQ in this file. */ 4063afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj return assignNew('V', mce, Ity_I1, definedOfType(Ity_I1)); 4064afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 4065aaddbc281556387b2a16009e058f785fb4d5c576sewardj case Iop_Shl64: case Iop_Shr64: case Iop_Sar64: 4066aaddbc281556387b2a16009e058f785fb4d5c576sewardj return scalarShift( mce, Ity_I64, op, vatom1,vatom2, atom1,atom2 ); 4067aaddbc281556387b2a16009e058f785fb4d5c576sewardj 406895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Shl32: case Iop_Shr32: case Iop_Sar32: 4069aaddbc281556387b2a16009e058f785fb4d5c576sewardj return scalarShift( mce, Ity_I32, op, vatom1,vatom2, atom1,atom2 ); 407095448075345dc73986042f6dc68eb464d02bc6a8sewardj 4071db67f5fbbfcf585bf4ff553ab555b9e4ffc1d195sewardj case Iop_Shl16: case Iop_Shr16: case Iop_Sar16: 4072aaddbc281556387b2a16009e058f785fb4d5c576sewardj return scalarShift( mce, Ity_I16, op, vatom1,vatom2, atom1,atom2 ); 407395448075345dc73986042f6dc68eb464d02bc6a8sewardj 4074537ed2d090e7472a6cb2ee80239d4780551a5f19florian case Iop_Shl8: case Iop_Shr8: case Iop_Sar8: 4075aaddbc281556387b2a16009e058f785fb4d5c576sewardj return scalarShift( mce, Ity_I8, op, vatom1,vatom2, atom1,atom2 ); 407695448075345dc73986042f6dc68eb464d02bc6a8sewardj 4077350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_AndV256: 4078350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj uifu = mkUifUV256; difd = mkDifDV256; 4079350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj and_or_ty = Ity_V256; improve = mkImproveANDV256; goto do_And_Or; 408020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_AndV128: 408120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj uifu = mkUifUV128; difd = mkDifDV128; 408220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj and_or_ty = Ity_V128; improve = mkImproveANDV128; goto do_And_Or; 40837010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj case Iop_And64: 40847010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj uifu = mkUifU64; difd = mkDifD64; 40857010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj and_or_ty = Ity_I64; improve = mkImproveAND64; goto do_And_Or; 408695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_And32: 408795448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU32; difd = mkDifD32; 408895448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or; 408995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_And16: 409095448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU16; difd = mkDifD16; 409195448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or; 409295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_And8: 409395448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU8; difd = mkDifD8; 409495448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or; 409595448075345dc73986042f6dc68eb464d02bc6a8sewardj 4096350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_OrV256: 4097350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj uifu = mkUifUV256; difd = mkDifDV256; 4098350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj and_or_ty = Ity_V256; improve = mkImproveORV256; goto do_And_Or; 409920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_OrV128: 410020d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj uifu = mkUifUV128; difd = mkDifDV128; 410120d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj and_or_ty = Ity_V128; improve = mkImproveORV128; goto do_And_Or; 41027010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj case Iop_Or64: 41037010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj uifu = mkUifU64; difd = mkDifD64; 41047010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj and_or_ty = Ity_I64; improve = mkImproveOR64; goto do_And_Or; 410595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Or32: 410695448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU32; difd = mkDifD32; 410795448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or; 410895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Or16: 410995448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU16; difd = mkDifD16; 411095448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or; 411195448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Or8: 411295448075345dc73986042f6dc68eb464d02bc6a8sewardj uifu = mkUifU8; difd = mkDifD8; 411395448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or; 411495448075345dc73986042f6dc68eb464d02bc6a8sewardj 411595448075345dc73986042f6dc68eb464d02bc6a8sewardj do_And_Or: 411695448075345dc73986042f6dc68eb464d02bc6a8sewardj return 411795448075345dc73986042f6dc68eb464d02bc6a8sewardj assignNew( 41187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 'V', mce, 411995448075345dc73986042f6dc68eb464d02bc6a8sewardj and_or_ty, 412095448075345dc73986042f6dc68eb464d02bc6a8sewardj difd(mce, uifu(mce, vatom1, vatom2), 412195448075345dc73986042f6dc68eb464d02bc6a8sewardj difd(mce, improve(mce, atom1, vatom1), 412295448075345dc73986042f6dc68eb464d02bc6a8sewardj improve(mce, atom2, vatom2) ) ) ); 412395448075345dc73986042f6dc68eb464d02bc6a8sewardj 412495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Xor8: 412595448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkUifU8(mce, vatom1, vatom2); 412695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Xor16: 412795448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkUifU16(mce, vatom1, vatom2); 412895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Xor32: 412995448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkUifU32(mce, vatom1, vatom2); 41307010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj case Iop_Xor64: 41317010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj return mkUifU64(mce, vatom1, vatom2); 413220d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_XorV128: 413320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj return mkUifUV128(mce, vatom1, vatom2); 4134350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_XorV256: 4135350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return mkUifUV256(mce, vatom1, vatom2); 4136e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4137a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj /* V256-bit SIMD */ 4138a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4139a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShrN16x16: 4140a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShrN32x8: 4141a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShrN64x4: 4142a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_SarN16x16: 4143a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_SarN32x8: 4144a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShlN16x16: 4145a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShlN32x8: 4146a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_ShlN64x4: 4147a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj /* Same scheme as with all other shifts. Note: 22 Oct 05: 4148a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj this is wrong now, scalar shifts are done properly lazily. 4149a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj Vector shifts should be fixed too. */ 4150b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, atom2, NULL); 4151a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return assignNew('V', mce, Ity_V256, binop(op, vatom1, atom2)); 4152a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4153a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QSub8Ux32: 4154a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QSub8Sx32: 4155a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Sub8x32: 4156a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min8Ux32: 4157a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min8Sx32: 4158a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max8Ux32: 4159a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max8Sx32: 4160a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpGT8Sx32: 4161a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpEQ8x32: 4162a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Avg8Ux32: 4163a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QAdd8Ux32: 4164a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QAdd8Sx32: 4165a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Add8x32: 4166a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return binary8Ix32(mce, vatom1, vatom2); 4167a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4168a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QSub16Ux16: 4169a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QSub16Sx16: 4170a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Sub16x16: 4171a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Mul16x16: 4172a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_MulHi16Sx16: 4173a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_MulHi16Ux16: 4174a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min16Sx16: 4175a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min16Ux16: 4176a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max16Sx16: 4177a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max16Ux16: 4178a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpGT16Sx16: 4179a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpEQ16x16: 4180a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Avg16Ux16: 4181a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QAdd16Ux16: 4182a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_QAdd16Sx16: 4183a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Add16x16: 4184a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return binary16Ix16(mce, vatom1, vatom2); 4185a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4186a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Sub32x8: 4187a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpGT32Sx8: 4188a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpEQ32x8: 4189a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Add32x8: 4190a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max32Ux8: 4191a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Max32Sx8: 4192a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min32Ux8: 4193a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Min32Sx8: 4194a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Mul32x8: 4195a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return binary32Ix8(mce, vatom1, vatom2); 4196a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4197a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Sub64x4: 4198a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Add64x4: 4199a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpEQ64x4: 4200a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_CmpGT64Sx4: 4201a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return binary64Ix4(mce, vatom1, vatom2); 4202a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4203a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj /* Perm32x8: rearrange values in left arg using steering values 4204a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj from right arg. So rearrange the vbits in the same way but 4205a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj pessimise wrt steering values. */ 4206a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj case Iop_Perm32x8: 4207a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj return mkUifUV256( 4208a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj mce, 4209a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj assignNew('V', mce, Ity_V256, binop(op, vatom1, atom2)), 4210a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj mkPCast32x8(mce, vatom2) 4211a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj ); 4212a2f309566f7bdd7ac8e2347ef50e873894f95498sewardj 4213bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj /* Q-and-Qshift-by-vector of the form (V128, V128) -> V256. 4214bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj Handle the shifted results in the same way that other 4215bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binary Q ops are handled, eg QSub: UifU the two args, 4216bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj then pessimise -- which is binaryNIxM. But for the upper 4217bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj V128, we require to generate just 1 bit which is the 4218bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj pessimised shift result, with 127 defined zeroes above it. 4219bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 4220bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj Note that this overly pessimistic in that in fact only the 4221bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj bottom 8 bits of each lane of the second arg determine the shift 4222bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj amount. Really we ought to ignore any undefinedness in the 4223bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj rest of the lanes of the second arg. */ 4224bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh64x2: case Iop_QandUQsh64x2: 4225bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh64x2: case Iop_QandUQRsh64x2: 4226bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh32x4: case Iop_QandUQsh32x4: 4227bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh32x4: case Iop_QandUQRsh32x4: 4228bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh16x8: case Iop_QandUQsh16x8: 4229bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh16x8: case Iop_QandUQRsh16x8: 4230bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh8x16: case Iop_QandUQsh8x16: 4231bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh8x16: case Iop_QandUQRsh8x16: 4232bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj { 4233bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // The function to generate the pessimised shift result 4234bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* (*binaryNIxM)(MCEnv*,IRAtom*,IRAtom*) = NULL; 4235bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj switch (op) { 4236bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh64x2: 4237bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQsh64x2: 4238bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh64x2: 4239bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQRsh64x2: 4240bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binaryNIxM = binary64Ix2; 4241bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 4242bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh32x4: 4243bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQsh32x4: 4244bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh32x4: 4245bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQRsh32x4: 4246bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binaryNIxM = binary32Ix4; 4247bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 4248bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh16x8: 4249bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQsh16x8: 4250bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh16x8: 4251bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQRsh16x8: 4252bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binaryNIxM = binary16Ix8; 4253bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 4254bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQsh8x16: 4255bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQsh8x16: 4256bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandSQRsh8x16: 4257bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_QandUQRsh8x16: 4258bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binaryNIxM = binary8Ix16; 4259bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj break; 4260bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj default: 4261bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj tl_assert(0); 4262bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 4263bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj tl_assert(binaryNIxM); 4264bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Pessimised shift result, shV[127:0] 4265bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* shV = binaryNIxM(mce, vatom1, vatom2); 4266bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // Generates: Def--(127)--Def PCast-to-I1(shV) 4267bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj IRAtom* qV = mkPCastXXtoXXlsb(mce, shV, Ity_V128); 4268bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj // and assemble the result 4269bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj return assignNew('V', mce, Ity_V256, 4270bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj binop(Iop_V128HLtoV256, qV, shV)); 4271bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj } 4272bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj 427395448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 427495448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIROp(op); 427595448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck:expr2vbits_Binop"); 427695448075345dc73986042f6dc68eb464d02bc6a8sewardj } 427795448075345dc73986042f6dc68eb464d02bc6a8sewardj} 4278e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4279e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 428095448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 428195448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom ) 428295448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 4283cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* For the widening operations {8,16,32}{U,S}to{16,32,64}, the 4284cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj selection of shadow operation implicitly duplicates the logic in 4285cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_shadow_LoadG and should be kept in sync (in the very unlikely 4286cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj event that the interpretation of such widening ops changes in 4287cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj future). See comment in do_shadow_LoadG. */ 428895448075345dc73986042f6dc68eb464d02bc6a8sewardj IRAtom* vatom = expr2vbits( mce, atom ); 428995448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,atom)); 429095448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (op) { 429195448075345dc73986042f6dc68eb464d02bc6a8sewardj 4292c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_Abs64Fx2: 4293c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_Neg64Fx2: 4294143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RSqrtEst64Fx2: 4295143507687feede3a6ff901684859e1e0db3c4f98sewardj case Iop_RecipEst64Fx2: 42960b07059814aee8563905f2caeef186a8c83072cfsewardj return unary64Fx2(mce, vatom); 42970b07059814aee8563905f2caeef186a8c83072cfsewardj 42980b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_Sqrt64F0x2: 42990b07059814aee8563905f2caeef186a8c83072cfsewardj return unary64F0x2(mce, vatom); 43000b07059814aee8563905f2caeef186a8c83072cfsewardj 4301350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Sqrt32Fx8: 4302ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtEst32Fx8: 4303ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32Fx8: 4304350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return unary32Fx8(mce, vatom); 4305350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 4306350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_Sqrt64Fx4: 4307350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj return unary64Fx4(mce, vatom); 4308350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj 4309ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32Fx4: 4310176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_I32UtoFx4: 4311176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_I32StoFx4: 4312176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_QFtoI32Ux4_RZ: 4313176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_QFtoI32Sx4_RZ: 4314176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_RoundF32x4_RM: 4315176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_RoundF32x4_RP: 4316176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_RoundF32x4_RN: 4317176cb4c42c42d4f126237eedbf324fdd3469eeb5cerion case Iop_RoundF32x4_RZ: 4318ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32Ux4: 431957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs32Fx4: 432057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Neg32Fx4: 4321ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtEst32Fx4: 4322170ee210842367a5cc52390358ba560774f76329sewardj return unary32Fx4(mce, vatom); 4323170ee210842367a5cc52390358ba560774f76329sewardj 432457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_I32UtoFx2: 432557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_I32StoFx2: 4326ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32Fx2: 4327ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32Ux2: 432857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs32Fx2: 432957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Neg32Fx2: 4330ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtEst32Fx2: 433157f92b0326e164124201034afc0c51dcd8db6d07sewardj return unary32Fx2(mce, vatom); 433257f92b0326e164124201034afc0c51dcd8db6d07sewardj 4333170ee210842367a5cc52390358ba560774f76329sewardj case Iop_Sqrt32F0x4: 4334ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtEst32F0x4: 4335ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RecipEst32F0x4: 4336170ee210842367a5cc52390358ba560774f76329sewardj return unary32F0x4(mce, vatom); 4337170ee210842367a5cc52390358ba560774f76329sewardj 433820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_32UtoV128: 433920d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_64UtoV128: 4340620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj case Iop_Dup8x16: 4341620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj case Iop_Dup16x8: 4342620eb5bbfb2d16c432ec7fdedad0eaa898d0df5esewardj case Iop_Dup32x4: 4343bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_Reverse1sIn8_x16: 434455404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn16_x8: 434555404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn32_x4: 434655404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse16sIn32_x4: 434755404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn64_x2: 434855404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse16sIn64_x2: 434955404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse32sIn64_x2: 4350350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_V256toV128_1: case Iop_V256toV128_0: 4351c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_ZeroHI64ofV128: 4352c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_ZeroHI96ofV128: 4353c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_ZeroHI112ofV128: 4354c46e6ccde63cd661f1f781d78054ef8cd86f8536sewardj case Iop_ZeroHI120ofV128: 43557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_V128, unop(op, vatom)); 4356170ee210842367a5cc52390358ba560774f76329sewardj 4357b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128HItoF64: /* F128 -> high half of F128 */ 4358b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_D128HItoD64: /* D128 -> high half of D128 */ 4359b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, vatom)); 4360b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F128LOtoF64: /* F128 -> low half of F128 */ 4361b0ccb4d09a74c94a712b2edf9894b408f270493asewardj case Iop_D128LOtoD64: /* D128 -> low half of D128 */ 4362b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return assignNew('V', mce, Ity_I64, unop(Iop_128to64, vatom)); 4363b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 4364b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_NegF128: 4365b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_AbsF128: 4366b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkPCastTo(mce, Ity_I128, vatom); 4367b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 4368b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_I32StoF128: /* signed I32 -> F128 */ 4369b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_I64StoF128: /* signed I64 -> F128 */ 43701b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_I32UtoF128: /* unsigned I32 -> F128 */ 43711b9609aa2638e4c81f3eb0d27fdaa4c944aaf33eflorian case Iop_I64UtoF128: /* unsigned I64 -> F128 */ 4372b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F32toF128: /* F32 -> F128 */ 4373b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Iop_F64toF128: /* F64 -> F128 */ 437453eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I32StoD128: /* signed I64 -> D128 */ 4375ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_I64StoD128: /* signed I64 -> D128 */ 437653eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I32UtoD128: /* unsigned I32 -> D128 */ 437753eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I64UtoD128: /* unsigned I64 -> D128 */ 4378b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return mkPCastTo(mce, Ity_I128, vatom); 4379b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 43801f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj case Iop_F16toF64: 438195448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_F32toF64: 438206f96d01b9471616c142af3b9f4298cb265973cdsewardj case Iop_I32StoF64: 438359570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_I32UtoF64: 438495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_NegF64: 438595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_AbsF64: 4386ee6bb779947e3e5350a083d5e87efa18ffddedcfsewardj case Iop_RSqrtEst5GoodF64: 4387dead90ad64759d1c800951ea2372949d43b29cc5sewardj case Iop_RoundF64toF64_NEAREST: 4388dead90ad64759d1c800951ea2372949d43b29cc5sewardj case Iop_RoundF64toF64_NegINF: 4389dead90ad64759d1c800951ea2372949d43b29cc5sewardj case Iop_RoundF64toF64_PosINF: 4390dead90ad64759d1c800951ea2372949d43b29cc5sewardj case Iop_RoundF64toF64_ZERO: 439139cc73532a985e3fecf9bf3822fffc6466b38d80sewardj case Iop_Clz64: 4392ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_D32toD64: 439353eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I32StoD64: 439453eb2a0f3b35eafb8fa713566ca5b4e6e4f3490cflorian case Iop_I32UtoD64: 439518c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_ExtractExpD64: /* D64 -> I64 */ 439618c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_ExtractExpD128: /* D128 -> I64 */ 4397974b409a9c293f1341f26bb2cfc13982af76b19bflorian case Iop_ExtractSigD64: /* D64 -> I64 */ 4398974b409a9c293f1341f26bb2cfc13982af76b19bflorian case Iop_ExtractSigD128: /* D128 -> I64 */ 43991943eb58b7e3a5c7b7108d33765b810192cda32cflorian case Iop_DPBtoBCD: 44001943eb58b7e3a5c7b7108d33765b810192cda32cflorian case Iop_BCDtoDPB: 440195448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, Ity_I64, vatom); 440295448075345dc73986042f6dc68eb464d02bc6a8sewardj 4403ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj case Iop_D64toD128: 4404ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj return mkPCastTo(mce, Ity_I128, vatom); 4405ea8b02f730f184b4edb9ebe1ad07a5d823ef8155sewardj 440695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Clz32: 4407ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iop_TruncF64asF32: 440859570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_NegF32: 440959570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_AbsF32: 44101f4b1ebde67b0277f4f61ee3a00f8f47163f0678sewardj case Iop_F16toF32: 441195448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkPCastTo(mce, Ity_I32, vatom); 441295448075345dc73986042f6dc68eb464d02bc6a8sewardj 44134cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_Ctz32: 44144cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_Ctz64: 44154cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj return expensiveCountTrailingZeroes(mce, op, atom, vatom); 44164cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj 4417d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_1Uto64: 4418a201c45bddd4b13c00c171d707ad58b102569f41sewardj case Iop_1Sto64: 4419d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_8Uto64: 4420d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_8Sto64: 4421d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_16Uto64: 4422d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_16Sto64: 442395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32Sto64: 442495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32Uto64: 442520d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_V128to64: 442620d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_V128HIto64: 44276cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Iop_128HIto64: 44286cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj case Iop_128to64: 442957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Dup8x8: 443057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Dup16x4: 443157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Dup32x2: 443255404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn16_x4: 443355404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn32_x2: 443455404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse16sIn32_x2: 443555404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse8sIn64_x1: 443655404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse16sIn64_x1: 443755404925be52fe200bf22e31959573df7ba870a4sewardj case Iop_Reverse32sIn64_x1: 4438350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_V256to64_0: case Iop_V256to64_1: 4439350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_V256to64_2: case Iop_V256to64_3: 44407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I64, unop(op, vatom)); 444195448075345dc73986042f6dc68eb464d02bc6a8sewardj 444295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_64to32: 444395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_64HIto32: 444495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_1Uto32: 4445463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj case Iop_1Sto32: 444695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_8Uto32: 444795448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_16Uto32: 444895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_16Sto32: 444995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_8Sto32: 4450fafaa0d8a9f70c01dc72052f22e53a617e9d2e2fcerion case Iop_V128to32: 44517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I32, unop(op, vatom)); 445295448075345dc73986042f6dc68eb464d02bc6a8sewardj 445395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_8Sto16: 445495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_8Uto16: 445595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32to16: 445695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32HIto16: 4457d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_64to16: 4458f517634b4a879b7653efa40d60c62fa3419809edsewardj case Iop_GetMSBs8x16: 44597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I16, unop(op, vatom)); 446095448075345dc73986042f6dc68eb464d02bc6a8sewardj 446195448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_1Uto8: 4462a201c45bddd4b13c00c171d707ad58b102569f41sewardj case Iop_1Sto8: 446395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_16to8: 44649a807e021bdfbcfb86cb0051e0e6e8a88e9eba5fsewardj case Iop_16HIto8: 446595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32to8: 4466d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_64to8: 44674cfa81b027d5952bfa9cc0ca05638483fde2eb9asewardj case Iop_GetMSBs8x8: 44687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I8, unop(op, vatom)); 446995448075345dc73986042f6dc68eb464d02bc6a8sewardj 447095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_32to1: 44717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I1, unop(Iop_32to1, vatom)); 447295448075345dc73986042f6dc68eb464d02bc6a8sewardj 4473d9dbc19c507323f02079ea4ee3cca66149f7357csewardj case Iop_64to1: 44747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, Ity_I1, unop(Iop_64to1, vatom)); 4475d9dbc19c507323f02079ea4ee3cca66149f7357csewardj 447695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_ReinterpF64asI64: 447795448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_ReinterpI64asF64: 44780b07059814aee8563905f2caeef186a8c83072cfsewardj case Iop_ReinterpI32asF32: 447959570ffbe31930ab4d678754daaeec0715117a3dsewardj case Iop_ReinterpF32asI32: 448018c72faa664f18877f33a40c8b429f3aa41dc5e2sewardj case Iop_ReinterpI64asD64: 44810892b8268c61648ba031eba3dc83db8f4b036613sewardj case Iop_ReinterpD64asI64: 4482350e8f7a0ef0b83d7e9cf2d699284668e5b146f5sewardj case Iop_NotV256: 448320d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj case Iop_NotV128: 44847010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj case Iop_Not64: 448595448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Not32: 448695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Not16: 448795448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Not8: 448895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iop_Not1: 448995448075345dc73986042f6dc68eb464d02bc6a8sewardj return vatom; 44907010f6eec42f5ace7c02c582e12d8150c2a2c964sewardj 449157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ8x8: 449257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Cnt8x8: 44932e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz8x8: 44942e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls8x8: 449557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs8x8: 449657f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x8(mce, vatom); 449757f92b0326e164124201034afc0c51dcd8db6d07sewardj 449857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ8x16: 449957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Cnt8x16: 45002e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz8x16: 45012e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls8x16: 450257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs8x16: 450357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast8x16(mce, vatom); 450457f92b0326e164124201034afc0c51dcd8db6d07sewardj 450557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ16x4: 45062e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz16x4: 45072e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls16x4: 450857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs16x4: 450957f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x4(mce, vatom); 451057f92b0326e164124201034afc0c51dcd8db6d07sewardj 451157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ16x8: 45122e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz16x8: 45132e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls16x8: 451457f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs16x8: 451557f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x8(mce, vatom); 451657f92b0326e164124201034afc0c51dcd8db6d07sewardj 451757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ32x2: 45182e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz32x2: 45192e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls32x2: 452057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_FtoI32Ux2_RZ: 452157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_FtoI32Sx2_RZ: 452257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs32x2: 452357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, vatom); 452457f92b0326e164124201034afc0c51dcd8db6d07sewardj 452557f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ32x4: 45262e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Clz32x4: 45272e4d5af35b4e326fef32e503d210f3bcc25238cfsewardj case Iop_Cls32x4: 452857f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_FtoI32Ux4_RZ: 452957f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_FtoI32Sx4_RZ: 453057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_Abs32x4: 4531bfd03f8a6388bf367e61b7b2523f34eb215a8168sewardj case Iop_RSqrtEst32Ux4: 453257f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, vatom); 453357f92b0326e164124201034afc0c51dcd8db6d07sewardj 4534537ed2d090e7472a6cb2ee80239d4780551a5f19florian case Iop_CmpwNEZ32: 4535537ed2d090e7472a6cb2ee80239d4780551a5f19florian return mkPCastTo(mce, Ity_I32, vatom); 4536537ed2d090e7472a6cb2ee80239d4780551a5f19florian 453757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpwNEZ64: 453857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCastTo(mce, Ity_I64, vatom); 453957f92b0326e164124201034afc0c51dcd8db6d07sewardj 454057f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_CmpNEZ64x2: 454124e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_CipherSV128: 454224e40de8f2127d70117ed9af3bc4474cbc29cb8acarll case Iop_Clz64x2: 454387a5bad8b2742f75dd60ba505d9f8d660cde3abasewardj case Iop_Abs64x2: 454457f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast64x2(mce, vatom); 454557f92b0326e164124201034afc0c51dcd8db6d07sewardj 4546e6bd3e49c6f37b871974c3b5212476f1eed3fb77carll case Iop_PwBitMtxXpose64x2: 4547e6bd3e49c6f37b871974c3b5212476f1eed3fb77carll return assignNew('V', mce, Ity_V128, unop(op, vatom)); 4548e6bd3e49c6f37b871974c3b5212476f1eed3fb77carll 45497ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_NarrowUn16to8x8: 45507ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_NarrowUn32to16x4: 45517ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_NarrowUn64to32x2: 45527ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Sto8Sx8: 45537ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Sto8Ux8: 45547ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn16Uto8Ux8: 45557ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Sto16Sx4: 45567ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Sto16Ux4: 45577ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn32Uto16Ux4: 45587ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Sto32Sx2: 45597ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Sto32Ux2: 45607ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_QNarrowUn64Uto32Ux2: 45617ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorNarrowUnV128(mce, op, vatom); 45627ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj 45637ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen8Sto16x8: 45647ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen8Uto16x8: 45657ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen16Sto32x4: 45667ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen16Uto32x4: 45677ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen32Sto64x2: 45687ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj case Iop_Widen32Uto64x2: 45697ee7d85cd336a7c3486b1e82306ef4bb248c82e0sewardj return vectorWidenI64(mce, op, vatom); 457057f92b0326e164124201034afc0c51dcd8db6d07sewardj 457157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL32Ux2: 457257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL32Sx2: 457357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCastTo(mce, Ity_I64, 457457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, unop(op, mkPCast32x2(mce, vatom)))); 457557f92b0326e164124201034afc0c51dcd8db6d07sewardj 457657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL16Ux4: 457757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL16Sx4: 457857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x2(mce, 457957f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, unop(op, mkPCast16x4(mce, vatom)))); 458057f92b0326e164124201034afc0c51dcd8db6d07sewardj 458157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL8Ux8: 458257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL8Sx8: 458357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x4(mce, 458457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_I64, unop(op, mkPCast8x8(mce, vatom)))); 458557f92b0326e164124201034afc0c51dcd8db6d07sewardj 458657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL32Ux4: 458757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL32Sx4: 458857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast64x2(mce, 458957f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, unop(op, mkPCast32x4(mce, vatom)))); 459057f92b0326e164124201034afc0c51dcd8db6d07sewardj 459157f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL16Ux8: 459257f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL16Sx8: 459357f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast32x4(mce, 459457f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, unop(op, mkPCast16x8(mce, vatom)))); 459557f92b0326e164124201034afc0c51dcd8db6d07sewardj 459657f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL8Ux16: 459757f92b0326e164124201034afc0c51dcd8db6d07sewardj case Iop_PwAddL8Sx16: 459857f92b0326e164124201034afc0c51dcd8db6d07sewardj return mkPCast16x8(mce, 459957f92b0326e164124201034afc0c51dcd8db6d07sewardj assignNew('V', mce, Ity_V128, unop(op, mkPCast8x16(mce, vatom)))); 460057f92b0326e164124201034afc0c51dcd8db6d07sewardj 4601f34eb496099507090f26dcf94bb780da8b3894e5sewardj case Iop_I64UtoF32: 460295448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 460395448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIROp(op); 460495448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck:expr2vbits_Unop"); 460595448075345dc73986042f6dc68eb464d02bc6a8sewardj } 460695448075345dc73986042f6dc68eb464d02bc6a8sewardj} 4607e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4608e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4609b9e6d244e474c971ea88181de1f83a30057db9dasewardj/* Worker function -- do not call directly. See comments on 4610b9e6d244e474c971ea88181de1f83a30057db9dasewardj expr2vbits_Load for the meaning of |guard|. 4611b9e6d244e474c971ea88181de1f83a30057db9dasewardj 4612b9e6d244e474c971ea88181de1f83a30057db9dasewardj Generates IR to (1) perform a definedness test of |addr|, (2) 4613b9e6d244e474c971ea88181de1f83a30057db9dasewardj perform a validity test of |addr|, and (3) return the Vbits for the 4614b9e6d244e474c971ea88181de1f83a30057db9dasewardj location indicated by |addr|. All of this only happens when 4615b9e6d244e474c971ea88181de1f83a30057db9dasewardj |guard| is NULL or |guard| evaluates to True at run time. 4616b9e6d244e474c971ea88181de1f83a30057db9dasewardj 4617b9e6d244e474c971ea88181de1f83a30057db9dasewardj If |guard| evaluates to False at run time, the returned value is 4618b9e6d244e474c971ea88181de1f83a30057db9dasewardj the IR-mandated 0x55..55 value, and no checks nor shadow loads are 4619b9e6d244e474c971ea88181de1f83a30057db9dasewardj performed. 4620b9e6d244e474c971ea88181de1f83a30057db9dasewardj 4621b9e6d244e474c971ea88181de1f83a30057db9dasewardj The definedness of |guard| itself is not checked. That is assumed 4622b9e6d244e474c971ea88181de1f83a30057db9dasewardj to have been done before this point, by the caller. */ 462395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 46246756454dd872134b243a7a4ff43b953c5bb309eesewardjIRAtom* expr2vbits_Load_WRK ( MCEnv* mce, 46256756454dd872134b243a7a4ff43b953c5bb309eesewardj IREndness end, IRType ty, 4626cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* addr, UInt bias, IRAtom* guard ) 462795448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 462895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,addr)); 46292e595858903b80f29f271dc94e32a9e052bb4c8asewardj tl_assert(end == Iend_LE || end == Iend_BE); 463095448075345dc73986042f6dc68eb464d02bc6a8sewardj 463195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* First, emit a definedness test for the address. This also sets 463295448075345dc73986042f6dc68eb464d02bc6a8sewardj the address (shadow) to 'defined' following the test. */ 4633b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined( mce, addr, guard ); 463495448075345dc73986042f6dc68eb464d02bc6a8sewardj 463595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Now cook up a call to the relevant helper function, to read the 463695448075345dc73986042f6dc68eb464d02bc6a8sewardj data V bits from shadow memory. */ 46377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ty = shadowTypeV(ty); 46382e595858903b80f29f271dc94e32a9e052bb4c8asewardj 463921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj void* helper = NULL; 464021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj const HChar* hname = NULL; 464121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj Bool ret_via_outparam = False; 464221a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 46436756454dd872134b243a7a4ff43b953c5bb309eesewardj if (end == Iend_LE) { 46442e595858903b80f29f271dc94e32a9e052bb4c8asewardj switch (ty) { 46456756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_V256: helper = &MC_(helperc_LOADV256le); 46466756454dd872134b243a7a4ff43b953c5bb309eesewardj hname = "MC_(helperc_LOADV256le)"; 46476756454dd872134b243a7a4ff43b953c5bb309eesewardj ret_via_outparam = True; 46486756454dd872134b243a7a4ff43b953c5bb309eesewardj break; 464921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_V128: helper = &MC_(helperc_LOADV128le); 465021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV128le)"; 465121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj ret_via_outparam = True; 465221a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 465321a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I64: helper = &MC_(helperc_LOADV64le); 465421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV64le)"; 465521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 465621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I32: helper = &MC_(helperc_LOADV32le); 465721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV32le)"; 465821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 465921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I16: helper = &MC_(helperc_LOADV16le); 466021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV16le)"; 466121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 466221a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I8: helper = &MC_(helperc_LOADV8); 466321a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV8)"; 466421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 466521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj default: ppIRType(ty); 466621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj VG_(tool_panic)("memcheck:expr2vbits_Load_WRK(LE)"); 46672e595858903b80f29f271dc94e32a9e052bb4c8asewardj } 46682e595858903b80f29f271dc94e32a9e052bb4c8asewardj } else { 46698cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj switch (ty) { 46706756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_V256: helper = &MC_(helperc_LOADV256be); 46716756454dd872134b243a7a4ff43b953c5bb309eesewardj hname = "MC_(helperc_LOADV256be)"; 46726756454dd872134b243a7a4ff43b953c5bb309eesewardj ret_via_outparam = True; 46736756454dd872134b243a7a4ff43b953c5bb309eesewardj break; 467421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_V128: helper = &MC_(helperc_LOADV128be); 467521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV128be)"; 467621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj ret_via_outparam = True; 467721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 467821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I64: helper = &MC_(helperc_LOADV64be); 467921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV64be)"; 468021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 468121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I32: helper = &MC_(helperc_LOADV32be); 468221a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV32be)"; 468321a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 468421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I16: helper = &MC_(helperc_LOADV16be); 468521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV16be)"; 468621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 468721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_I8: helper = &MC_(helperc_LOADV8); 468821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname = "MC_(helperc_LOADV8)"; 468921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj break; 469021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj default: ppIRType(ty); 469121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj VG_(tool_panic)("memcheck:expr2vbits_Load_WRK(BE)"); 46928cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj } 469395448075345dc73986042f6dc68eb464d02bc6a8sewardj } 4694e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 469521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj tl_assert(helper); 469621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj tl_assert(hname); 469721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 469895448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Generate the actual address into addrAct. */ 469921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRAtom* addrAct; 470095448075345dc73986042f6dc68eb464d02bc6a8sewardj if (bias == 0) { 470195448075345dc73986042f6dc68eb464d02bc6a8sewardj addrAct = addr; 470295448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 47037cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IROp mkAdd; 47047cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRAtom* eBias; 470595448075345dc73986042f6dc68eb464d02bc6a8sewardj IRType tyAddr = mce->hWordTy; 470695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); 47077cf97ee841afd255879bff9ff791fbabb7f95cecsewardj mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; 47087cf97ee841afd255879bff9ff791fbabb7f95cecsewardj eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); 47097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj addrAct = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBias) ); 471095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 4711e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 471295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* We need to have a place to park the V bits we're just about to 471395448075345dc73986042f6dc68eb464d02bc6a8sewardj read. */ 471421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRTemp datavbits = newTemp(mce, ty, VSh); 471521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 471621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj /* Here's the call. */ 471721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRDirty* di; 471821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj if (ret_via_outparam) { 471921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj di = unsafeIRDirty_1_N( datavbits, 472021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 2/*regparms*/, 472121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname, VG_(fnptr_to_fnentry)( helper ), 4722a5c3ecb923e27dcd995ba763d436b477e1e2a61eflorian mkIRExprVec_2( IRExpr_VECRET(), addrAct ) ); 472321a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj } else { 472421a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj di = unsafeIRDirty_1_N( datavbits, 472521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 1/*regparms*/, 472621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj hname, VG_(fnptr_to_fnentry)( helper ), 472721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj mkIRExprVec_1( addrAct ) ); 472821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj } 472921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj 473095448075345dc73986042f6dc68eb464d02bc6a8sewardj setHelperAnns( mce, di ); 4731cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj if (guard) { 4732cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj di->guard = guard; 4733cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* Ideally the didn't-happen return value here would be all-ones 4734cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj (all-undefined), so it'd be obvious if it got used 4735ad4e979f408239dabbaae955d8ffcb84a51a5c85florian inadvertently. We can get by with the IR-mandated default 4736cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj value (0b01 repeating, 0x55 etc) as that'll still look pretty 4737cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj undefined if it ever leaks out. */ 4738cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 47397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(di) ); 4740e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 474195448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkexpr(datavbits); 474295448075345dc73986042f6dc68eb464d02bc6a8sewardj} 4743e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4744e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4745cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate IR to do a shadow load. The helper is expected to check 4746cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj the validity of the address and return the V bits for that address. 4747cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj This can optionally be controlled by a guard, which is assumed to 4748cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj be True if NULL. In the case where the guard is False at runtime, 4749b9e6d244e474c971ea88181de1f83a30057db9dasewardj the helper will return the didn't-do-the-call value of 0x55..55. 4750b9e6d244e474c971ea88181de1f83a30057db9dasewardj Since that means "completely undefined result", the caller of 4751cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj this function will need to fix up the result somehow in that 4752cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case. 4753b9e6d244e474c971ea88181de1f83a30057db9dasewardj 4754b9e6d244e474c971ea88181de1f83a30057db9dasewardj Caller of this function is also expected to have checked the 4755b9e6d244e474c971ea88181de1f83a30057db9dasewardj definedness of |guard| before this point. 4756cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 475795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 47586756454dd872134b243a7a4ff43b953c5bb309eesewardjIRAtom* expr2vbits_Load ( MCEnv* mce, 47596756454dd872134b243a7a4ff43b953c5bb309eesewardj IREndness end, IRType ty, 4760cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* addr, UInt bias, 4761cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* guard ) 4762170ee210842367a5cc52390358ba560774f76329sewardj{ 47632e595858903b80f29f271dc94e32a9e052bb4c8asewardj tl_assert(end == Iend_LE || end == Iend_BE); 47647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj switch (shadowTypeV(ty)) { 47656756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_I8: 47666756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_I16: 47676756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_I32: 4768170ee210842367a5cc52390358ba560774f76329sewardj case Ity_I64: 476921a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj case Ity_V128: 47706756454dd872134b243a7a4ff43b953c5bb309eesewardj case Ity_V256: 4771cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return expr2vbits_Load_WRK(mce, end, ty, addr, bias, guard); 4772170ee210842367a5cc52390358ba560774f76329sewardj default: 47732e595858903b80f29f271dc94e32a9e052bb4c8asewardj VG_(tool_panic)("expr2vbits_Load"); 4774170ee210842367a5cc52390358ba560774f76329sewardj } 4775170ee210842367a5cc52390358ba560774f76329sewardj} 4776170ee210842367a5cc52390358ba560774f76329sewardj 4777170ee210842367a5cc52390358ba560774f76329sewardj 4778cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* The most general handler for guarded loads. Assumes the 4779b9e6d244e474c971ea88181de1f83a30057db9dasewardj definedness of GUARD has already been checked by the caller. A 4780b9e6d244e474c971ea88181de1f83a30057db9dasewardj GUARD of NULL is assumed to mean "always True". Generates code to 4781b9e6d244e474c971ea88181de1f83a30057db9dasewardj check the definedness and validity of ADDR. 4782cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 4783cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj Generate IR to do a shadow load from ADDR and return the V bits. 4784cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj The loaded type is TY. The loaded data is then (shadow) widened by 4785cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj using VWIDEN, which can be Iop_INVALID to denote a no-op. If GUARD 4786cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj evaluates to False at run time then the returned Vbits are simply 4787cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj VALT instead. Note therefore that the argument type of VWIDEN must 4788cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj be TY and the result type of VWIDEN must equal the type of VALT. 4789cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 4790434ffae63b5e5460c0475dc24cd0383bc63fe1b8florianstatic 4791cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjIRAtom* expr2vbits_Load_guarded_General ( MCEnv* mce, 4792cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IREndness end, IRType ty, 4793cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* addr, UInt bias, 4794cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* guard, 4795cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IROp vwiden, IRAtom* valt ) 4796434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian{ 4797cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* Sanity check the conversion operation, and also set TYWIDE. */ 4798cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRType tyWide = Ity_INVALID; 4799cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj switch (vwiden) { 4800cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Iop_INVALID: 4801cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj tyWide = ty; 4802cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 4803cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Iop_16Uto32: case Iop_16Sto32: case Iop_8Uto32: case Iop_8Sto32: 4804cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj tyWide = Ity_I32; 4805cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 4806cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj default: 4807cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj VG_(tool_panic)("memcheck:expr2vbits_Load_guarded_General"); 4808434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian } 4809434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 4810cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* If the guard evaluates to True, this will hold the loaded V bits 4811cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj at TY. If the guard evaluates to False, this will be all 4812cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj ones, meaning "all undefined", in which case we will have to 48135686b2d7e97a6f65e436531dac999a52a3d3dac9florian replace it using an ITE below. */ 4814cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* iftrue1 4815cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = assignNew('V', mce, ty, 4816cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj expr2vbits_Load(mce, end, ty, addr, bias, guard)); 4817cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* Now (shadow-) widen the loaded V bits to the desired width. In 4818cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj the guard-is-False case, the allowable widening operators will 4819cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj in the worst case (unsigned widening) at least leave the 4820cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj pre-widened part as being marked all-undefined, and in the best 4821cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case (signed widening) mark the whole widened result as 4822cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj undefined. Anyway, it doesn't matter really, since in this case 48235686b2d7e97a6f65e436531dac999a52a3d3dac9florian we will replace said value with the default value |valt| using an 48245686b2d7e97a6f65e436531dac999a52a3d3dac9florian ITE. */ 4825cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* iftrue2 4826cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = vwiden == Iop_INVALID 4827cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj ? iftrue1 4828cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj : assignNew('V', mce, tyWide, unop(vwiden, iftrue1)); 4829cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* These are the V bits we will return if the load doesn't take 4830cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj place. */ 4831cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* iffalse 4832cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = valt; 48335686b2d7e97a6f65e436531dac999a52a3d3dac9florian /* Prepare the cond for the ITE. Convert a NULL cond into 4834cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj something that iropt knows how to fold out later. */ 4835cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* cond 4836cc9616506450cb02944b62dc07774c29462bfefcsewardj = guard == NULL ? mkU1(1) : guard; 4837cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* And assemble the final result. */ 48385686b2d7e97a6f65e436531dac999a52a3d3dac9florian return assignNew('V', mce, tyWide, IRExpr_ITE(cond, iftrue2, iffalse)); 4839cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 4840cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 4841cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 4842cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* A simpler handler for guarded loads, in which there is no 4843cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj conversion operation, and the default V bit return (when the guard 4844cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj evaluates to False at runtime) is "all defined". If there is no 4845cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj guard expression or the guard is always TRUE this function behaves 4846b9e6d244e474c971ea88181de1f83a30057db9dasewardj like expr2vbits_Load. It is assumed that definedness of GUARD has 4847b9e6d244e474c971ea88181de1f83a30057db9dasewardj already been checked at the call site. */ 4848cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic 4849cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjIRAtom* expr2vbits_Load_guarded_Simple ( MCEnv* mce, 4850cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IREndness end, IRType ty, 4851cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* addr, UInt bias, 4852cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom *guard ) 4853cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 4854cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return expr2vbits_Load_guarded_General( 4855cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj mce, end, ty, addr, bias, guard, Iop_INVALID, definedOfType(ty) 4856cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj ); 4857434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian} 4858434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 4859434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 4860170ee210842367a5cc52390358ba560774f76329sewardjstatic 48615686b2d7e97a6f65e436531dac999a52a3d3dac9florianIRAtom* expr2vbits_ITE ( MCEnv* mce, 48625686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRAtom* cond, IRAtom* iftrue, IRAtom* iffalse ) 486395448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 48645686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRAtom *vbitsC, *vbits0, *vbits1; 486595448075345dc73986042f6dc68eb464d02bc6a8sewardj IRType ty; 486607bfda2113275e92f0eacf9aaf5d6944a75fe86esewardj /* Given ITE(cond, iftrue, iffalse), generate 486707bfda2113275e92f0eacf9aaf5d6944a75fe86esewardj ITE(cond, iftrue#, iffalse#) `UifU` PCast(cond#) 486895448075345dc73986042f6dc68eb464d02bc6a8sewardj That is, steer the V bits like the originals, but trash the 486995448075345dc73986042f6dc68eb464d02bc6a8sewardj result if the steering value is undefined. This gives 487095448075345dc73986042f6dc68eb464d02bc6a8sewardj lazy propagation. */ 487195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, cond)); 48725686b2d7e97a6f65e436531dac999a52a3d3dac9florian tl_assert(isOriginalAtom(mce, iftrue)); 48735686b2d7e97a6f65e436531dac999a52a3d3dac9florian tl_assert(isOriginalAtom(mce, iffalse)); 487495448075345dc73986042f6dc68eb464d02bc6a8sewardj 487595448075345dc73986042f6dc68eb464d02bc6a8sewardj vbitsC = expr2vbits(mce, cond); 48765686b2d7e97a6f65e436531dac999a52a3d3dac9florian vbits1 = expr2vbits(mce, iftrue); 487707bfda2113275e92f0eacf9aaf5d6944a75fe86esewardj vbits0 = expr2vbits(mce, iffalse); 48781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ty = typeOfIRExpr(mce->sb->tyenv, vbits0); 487995448075345dc73986042f6dc68eb464d02bc6a8sewardj 488095448075345dc73986042f6dc68eb464d02bc6a8sewardj return 48817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mkUifU(mce, ty, assignNew('V', mce, ty, 48825686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRExpr_ITE(cond, vbits1, vbits0)), 488395448075345dc73986042f6dc68eb464d02bc6a8sewardj mkPCastTo(mce, ty, vbitsC) ); 488495448075345dc73986042f6dc68eb464d02bc6a8sewardj} 488595448075345dc73986042f6dc68eb464d02bc6a8sewardj 488695448075345dc73986042f6dc68eb464d02bc6a8sewardj/* --------- This is the main expression-handling function. --------- */ 4887e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 488895448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 488995448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* expr2vbits ( MCEnv* mce, IRExpr* e ) 489095448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 489195448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (e->tag) { 4892e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 489395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Get: 489495448075345dc73986042f6dc68eb464d02bc6a8sewardj return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty ); 4895e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 489695448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_GetI: 489795448075345dc73986042f6dc68eb464d02bc6a8sewardj return shadow_GETI( mce, e->Iex.GetI.descr, 489895448075345dc73986042f6dc68eb464d02bc6a8sewardj e->Iex.GetI.ix, e->Iex.GetI.bias ); 4899e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 49000b9d74abd0a663b530d290b2b788ddeda46e5400sewardj case Iex_RdTmp: 49017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) ); 4902e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 490395448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Const: 49041c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return definedOfType(shadowTypeV(typeOfIRExpr(mce->sb->tyenv, e))); 4905e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 4906e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iex_Qop: 4907e91cea71129edc807428c8228d0d9f5b13894a5asewardj return expr2vbits_Qop( 4908e91cea71129edc807428c8228d0d9f5b13894a5asewardj mce, 4909e2ab2974c8bcaf3863956ba2d5368092a54e0703florian e->Iex.Qop.details->op, 4910e2ab2974c8bcaf3863956ba2d5368092a54e0703florian e->Iex.Qop.details->arg1, e->Iex.Qop.details->arg2, 4911e2ab2974c8bcaf3863956ba2d5368092a54e0703florian e->Iex.Qop.details->arg3, e->Iex.Qop.details->arg4 4912e91cea71129edc807428c8228d0d9f5b13894a5asewardj ); 4913e91cea71129edc807428c8228d0d9f5b13894a5asewardj 4914ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iex_Triop: 4915ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj return expr2vbits_Triop( 4916ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj mce, 491726441746bda788fc0327527a62427ca562f25311florian e->Iex.Triop.details->op, 491826441746bda788fc0327527a62427ca562f25311florian e->Iex.Triop.details->arg1, e->Iex.Triop.details->arg2, 491926441746bda788fc0327527a62427ca562f25311florian e->Iex.Triop.details->arg3 4920ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj ); 4921ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj 492295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Binop: 492395448075345dc73986042f6dc68eb464d02bc6a8sewardj return expr2vbits_Binop( 492495448075345dc73986042f6dc68eb464d02bc6a8sewardj mce, 492595448075345dc73986042f6dc68eb464d02bc6a8sewardj e->Iex.Binop.op, 492695448075345dc73986042f6dc68eb464d02bc6a8sewardj e->Iex.Binop.arg1, e->Iex.Binop.arg2 492795448075345dc73986042f6dc68eb464d02bc6a8sewardj ); 4928e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 492995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Unop: 493095448075345dc73986042f6dc68eb464d02bc6a8sewardj return expr2vbits_Unop( mce, e->Iex.Unop.op, e->Iex.Unop.arg ); 493196b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes 49322e595858903b80f29f271dc94e32a9e052bb4c8asewardj case Iex_Load: 49332e595858903b80f29f271dc94e32a9e052bb4c8asewardj return expr2vbits_Load( mce, e->Iex.Load.end, 49342e595858903b80f29f271dc94e32a9e052bb4c8asewardj e->Iex.Load.ty, 4935cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj e->Iex.Load.addr, 0/*addr bias*/, 4936cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/* guard == "always True"*/ ); 493796b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes 493895448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_CCall: 493995448075345dc73986042f6dc68eb464d02bc6a8sewardj return mkLazyN( mce, e->Iex.CCall.args, 494095448075345dc73986042f6dc68eb464d02bc6a8sewardj e->Iex.CCall.retty, 494195448075345dc73986042f6dc68eb464d02bc6a8sewardj e->Iex.CCall.cee ); 494296b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes 49435686b2d7e97a6f65e436531dac999a52a3d3dac9florian case Iex_ITE: 49445686b2d7e97a6f65e436531dac999a52a3d3dac9florian return expr2vbits_ITE( mce, e->Iex.ITE.cond, e->Iex.ITE.iftrue, 494507bfda2113275e92f0eacf9aaf5d6944a75fe86esewardj e->Iex.ITE.iffalse); 494696b466ac1bc4b09b45c08b79cdadd3d42461bc2bthughes 494795448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 494895448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 494995448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIRExpr(e); 495095448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 495195448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck: expr2vbits"); 495295448075345dc73986042f6dc68eb464d02bc6a8sewardj } 495395448075345dc73986042f6dc68eb464d02bc6a8sewardj} 4954b6d9b5426120bb87736591d22376e94355130bfbdaywalker 495595448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 495695448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Generate shadow stmts from all kinds of IRStmts. ---*/ 495795448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 4958b11168575af550e72048e09e1f372eeb13a32be6sewardj 495995448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Widen a value to the host word size. */ 4960e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 496195448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 496295448075345dc73986042f6dc68eb464d02bc6a8sewardjIRExpr* zwidenToHostWord ( MCEnv* mce, IRAtom* vatom ) 496395448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 49647cf97ee841afd255879bff9ff791fbabb7f95cecsewardj IRType ty, tyH; 49657cf97ee841afd255879bff9ff791fbabb7f95cecsewardj 496695448075345dc73986042f6dc68eb464d02bc6a8sewardj /* vatom is vbits-value and as such can only have a shadow type. */ 496795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,vatom)); 496895448075345dc73986042f6dc68eb464d02bc6a8sewardj 49691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ty = typeOfIRExpr(mce->sb->tyenv, vatom); 49707cf97ee841afd255879bff9ff791fbabb7f95cecsewardj tyH = mce->hWordTy; 497195448075345dc73986042f6dc68eb464d02bc6a8sewardj 497295448075345dc73986042f6dc68eb464d02bc6a8sewardj if (tyH == Ity_I32) { 497395448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (ty) { 49747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I32: 49757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return vatom; 49767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I16: 49777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, tyH, unop(Iop_16Uto32, vatom)); 49787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I8: 49797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, tyH, unop(Iop_8Uto32, vatom)); 49807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 49817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj goto unhandled; 498295448075345dc73986042f6dc68eb464d02bc6a8sewardj } 49836cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj } else 49846cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj if (tyH == Ity_I64) { 49856cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj switch (ty) { 49867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I32: 49877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, tyH, unop(Iop_32Uto64, vatom)); 49887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I16: 49897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, tyH, unop(Iop_32Uto64, 49907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I32, unop(Iop_16Uto32, vatom)))); 49917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ity_I8: 49927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew('V', mce, tyH, unop(Iop_32Uto64, 49937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assignNew('V', mce, Ity_I32, unop(Iop_8Uto32, vatom)))); 49947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 49957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj goto unhandled; 49966cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj } 499795448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 499895448075345dc73986042f6dc68eb464d02bc6a8sewardj goto unhandled; 499995448075345dc73986042f6dc68eb464d02bc6a8sewardj } 500095448075345dc73986042f6dc68eb464d02bc6a8sewardj unhandled: 500195448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\nty = "); ppIRType(ty); VG_(printf)("\n"); 500295448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("zwidenToHostWord"); 500395448075345dc73986042f6dc68eb464d02bc6a8sewardj} 5004901a4a946376b70c7c87f750dc3eef44e78032besewardj 50053d7c9c8c2e4882c787a9b63befe095785f3d5d07sewardj 5006cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate a shadow store. |addr| is always the original address 5007cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj atom. You can pass in either originals or V-bits for the data 5008cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj atom, but obviously not both. This function generates a check for 5009b9e6d244e474c971ea88181de1f83a30057db9dasewardj the definedness and (indirectly) the validity of |addr|, but only 5010b9e6d244e474c971ea88181de1f83a30057db9dasewardj when |guard| evaluates to True at run time (or is NULL). 5011e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 5012cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj |guard| :: Ity_I1 controls whether the store really happens; NULL 5013cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj means it unconditionally does. Note that |guard| itself is not 5014cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj checked for definedness; the caller of this function must do that 5015cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj if necessary. 5016cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 501795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 50182e595858903b80f29f271dc94e32a9e052bb4c8asewardjvoid do_shadow_Store ( MCEnv* mce, 50192e595858903b80f29f271dc94e32a9e052bb4c8asewardj IREndness end, 50202e595858903b80f29f271dc94e32a9e052bb4c8asewardj IRAtom* addr, UInt bias, 50211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* data, IRAtom* vdata, 50221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* guard ) 502395448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 5024170ee210842367a5cc52390358ba560774f76329sewardj IROp mkAdd; 5025170ee210842367a5cc52390358ba560774f76329sewardj IRType ty, tyAddr; 502695448075345dc73986042f6dc68eb464d02bc6a8sewardj void* helper = NULL; 5027a5f894c271248c13e0bb387e5ca33fa122b4819cflorian const HChar* hname = NULL; 50281d0825ff46d57f0ce83c3fa88538a42f67022eeenjn IRConst* c; 5029170ee210842367a5cc52390358ba560774f76329sewardj 5030170ee210842367a5cc52390358ba560774f76329sewardj tyAddr = mce->hWordTy; 5031170ee210842367a5cc52390358ba560774f76329sewardj mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; 5032170ee210842367a5cc52390358ba560774f76329sewardj tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); 50332e595858903b80f29f271dc94e32a9e052bb4c8asewardj tl_assert( end == Iend_LE || end == Iend_BE ); 5034170ee210842367a5cc52390358ba560774f76329sewardj 503595448075345dc73986042f6dc68eb464d02bc6a8sewardj if (data) { 503695448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(!vdata); 503795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce, data)); 503895448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(bias == 0); 503995448075345dc73986042f6dc68eb464d02bc6a8sewardj vdata = expr2vbits( mce, data ); 504095448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 504195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(vdata); 504295448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5043e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 504495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isOriginalAtom(mce,addr)); 504595448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(isShadowAtom(mce,vdata)); 504695448075345dc73986042f6dc68eb464d02bc6a8sewardj 50471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) { 50481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, guard)); 50491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1); 50501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 50511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 50521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ty = typeOfIRExpr(mce->sb->tyenv, vdata); 505395448075345dc73986042f6dc68eb464d02bc6a8sewardj 50541d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // If we're not doing undefined value checking, pretend that this value 50551d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // is "all valid". That lets Vex's optimiser remove some of the V bit 50561d0825ff46d57f0ce83c3fa88538a42f67022eeenjn // shadow computation ops that precede it. 50577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) == 1) { 50581d0825ff46d57f0ce83c3fa88538a42f67022eeenjn switch (ty) { 505945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case Ity_V256: // V256 weirdness -- used four times 5060bd43bfa3f1672bae00037a1a213d8e452735af64sewardj c = IRConst_V256(V_BITS32_DEFINED); break; 506145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case Ity_V128: // V128 weirdness -- used twice 50621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj c = IRConst_V128(V_BITS16_DEFINED); break; 50631d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I64: c = IRConst_U64 (V_BITS64_DEFINED); break; 50641d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I32: c = IRConst_U32 (V_BITS32_DEFINED); break; 50651d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I16: c = IRConst_U16 (V_BITS16_DEFINED); break; 50661d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I8: c = IRConst_U8 (V_BITS8_DEFINED); break; 50671d0825ff46d57f0ce83c3fa88538a42f67022eeenjn default: VG_(tool_panic)("memcheck:do_shadow_Store(LE)"); 50681d0825ff46d57f0ce83c3fa88538a42f67022eeenjn } 50691d0825ff46d57f0ce83c3fa88538a42f67022eeenjn vdata = IRExpr_Const( c ); 50701d0825ff46d57f0ce83c3fa88538a42f67022eeenjn } 50711d0825ff46d57f0ce83c3fa88538a42f67022eeenjn 507295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* First, emit a definedness test for the address. This also sets 5073b9e6d244e474c971ea88181de1f83a30057db9dasewardj the address (shadow) to 'defined' following the test. Both of 5074b9e6d244e474c971ea88181de1f83a30057db9dasewardj those actions are gated on |guard|. */ 5075b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined( mce, addr, guard ); 507695448075345dc73986042f6dc68eb464d02bc6a8sewardj 5077170ee210842367a5cc52390358ba560774f76329sewardj /* Now decide which helper function to call to write the data V 5078170ee210842367a5cc52390358ba560774f76329sewardj bits into shadow memory. */ 50792e595858903b80f29f271dc94e32a9e052bb4c8asewardj if (end == Iend_LE) { 50802e595858903b80f29f271dc94e32a9e052bb4c8asewardj switch (ty) { 508145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case Ity_V256: /* we'll use the helper four times */ 50822e595858903b80f29f271dc94e32a9e052bb4c8asewardj case Ity_V128: /* we'll use the helper twice */ 50831d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I64: helper = &MC_(helperc_STOREV64le); 50841d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV64le)"; 50852e595858903b80f29f271dc94e32a9e052bb4c8asewardj break; 50861d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I32: helper = &MC_(helperc_STOREV32le); 50871d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV32le)"; 50882e595858903b80f29f271dc94e32a9e052bb4c8asewardj break; 50891d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I16: helper = &MC_(helperc_STOREV16le); 50901d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV16le)"; 50912e595858903b80f29f271dc94e32a9e052bb4c8asewardj break; 50921d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I8: helper = &MC_(helperc_STOREV8); 50931d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV8)"; 50942e595858903b80f29f271dc94e32a9e052bb4c8asewardj break; 50952e595858903b80f29f271dc94e32a9e052bb4c8asewardj default: VG_(tool_panic)("memcheck:do_shadow_Store(LE)"); 50962e595858903b80f29f271dc94e32a9e052bb4c8asewardj } 50972e595858903b80f29f271dc94e32a9e052bb4c8asewardj } else { 50988cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj switch (ty) { 50998cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj case Ity_V128: /* we'll use the helper twice */ 51001d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I64: helper = &MC_(helperc_STOREV64be); 51011d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV64be)"; 51028cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj break; 51031d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I32: helper = &MC_(helperc_STOREV32be); 51041d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV32be)"; 51058cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj break; 51061d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I16: helper = &MC_(helperc_STOREV16be); 51071d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV16be)"; 51088cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj break; 51091d0825ff46d57f0ce83c3fa88538a42f67022eeenjn case Ity_I8: helper = &MC_(helperc_STOREV8); 51101d0825ff46d57f0ce83c3fa88538a42f67022eeenjn hname = "MC_(helperc_STOREV8)"; 51118cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj break; 511245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj /* Note, no V256 case here, because no big-endian target that 511345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj we support, has 256 vectors. */ 51148cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj default: VG_(tool_panic)("memcheck:do_shadow_Store(BE)"); 51158cf88b7b5d8325e098b455f502c9a9239c6ee011sewardj } 511695448075345dc73986042f6dc68eb464d02bc6a8sewardj } 511795448075345dc73986042f6dc68eb464d02bc6a8sewardj 511845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj if (UNLIKELY(ty == Ity_V256)) { 511945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 512045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj /* V256-bit case -- phrased in terms of 64 bit units (Qs), with 512145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj Q3 being the most significant lane. */ 512245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj /* These are the offsets of the Qs in memory. */ 512345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj Int offQ0, offQ1, offQ2, offQ3; 512445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 512545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj /* Various bits for constructing the 4 lane helper calls */ 512645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj IRDirty *diQ0, *diQ1, *diQ2, *diQ3; 512745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj IRAtom *addrQ0, *addrQ1, *addrQ2, *addrQ3; 512845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj IRAtom *vdataQ0, *vdataQ1, *vdataQ2, *vdataQ3; 512945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj IRAtom *eBiasQ0, *eBiasQ1, *eBiasQ2, *eBiasQ3; 513045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 513145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj if (end == Iend_LE) { 513245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj offQ0 = 0; offQ1 = 8; offQ2 = 16; offQ3 = 24; 513345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj } else { 513445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj offQ3 = 0; offQ2 = 8; offQ1 = 16; offQ0 = 24; 513545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj } 513645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 513745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj eBiasQ0 = tyAddr==Ity_I32 ? mkU32(bias+offQ0) : mkU64(bias+offQ0); 513845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj addrQ0 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasQ0) ); 513945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj vdataQ0 = assignNew('V', mce, Ity_I64, unop(Iop_V256to64_0, vdata)); 514045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj diQ0 = unsafeIRDirty_0_N( 514145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 1/*regparms*/, 514245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hname, VG_(fnptr_to_fnentry)( helper ), 514345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj mkIRExprVec_2( addrQ0, vdataQ0 ) 514445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj ); 514545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 514645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj eBiasQ1 = tyAddr==Ity_I32 ? mkU32(bias+offQ1) : mkU64(bias+offQ1); 514745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj addrQ1 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasQ1) ); 514845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj vdataQ1 = assignNew('V', mce, Ity_I64, unop(Iop_V256to64_1, vdata)); 514945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj diQ1 = unsafeIRDirty_0_N( 515045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 1/*regparms*/, 515145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hname, VG_(fnptr_to_fnentry)( helper ), 515245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj mkIRExprVec_2( addrQ1, vdataQ1 ) 515345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj ); 515445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 515545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj eBiasQ2 = tyAddr==Ity_I32 ? mkU32(bias+offQ2) : mkU64(bias+offQ2); 515645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj addrQ2 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasQ2) ); 515745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj vdataQ2 = assignNew('V', mce, Ity_I64, unop(Iop_V256to64_2, vdata)); 515845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj diQ2 = unsafeIRDirty_0_N( 515945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 1/*regparms*/, 516045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hname, VG_(fnptr_to_fnentry)( helper ), 516145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj mkIRExprVec_2( addrQ2, vdataQ2 ) 516245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj ); 516345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 516445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj eBiasQ3 = tyAddr==Ity_I32 ? mkU32(bias+offQ3) : mkU64(bias+offQ3); 516545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj addrQ3 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasQ3) ); 516645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj vdataQ3 = assignNew('V', mce, Ity_I64, unop(Iop_V256to64_3, vdata)); 516745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj diQ3 = unsafeIRDirty_0_N( 516845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 1/*regparms*/, 516945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hname, VG_(fnptr_to_fnentry)( helper ), 517045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj mkIRExprVec_2( addrQ3, vdataQ3 ) 517145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj ); 517245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 517345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj if (guard) 517445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj diQ0->guard = diQ1->guard = diQ2->guard = diQ3->guard = guard; 517545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 517645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj setHelperAnns( mce, diQ0 ); 517745fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj setHelperAnns( mce, diQ1 ); 517845fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj setHelperAnns( mce, diQ2 ); 517945fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj setHelperAnns( mce, diQ3 ); 518045fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj stmt( 'V', mce, IRStmt_Dirty(diQ0) ); 518145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj stmt( 'V', mce, IRStmt_Dirty(diQ1) ); 518245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj stmt( 'V', mce, IRStmt_Dirty(diQ2) ); 518345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj stmt( 'V', mce, IRStmt_Dirty(diQ3) ); 518445fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj 518545fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj } 518645fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj else if (UNLIKELY(ty == Ity_V128)) { 5187170ee210842367a5cc52390358ba560774f76329sewardj 518820d38f29475b36dc3ced6ee96fd6b7651faf31c8sewardj /* V128-bit case */ 5189170ee210842367a5cc52390358ba560774f76329sewardj /* See comment in next clause re 64-bit regparms */ 51902e595858903b80f29f271dc94e32a9e052bb4c8asewardj /* also, need to be careful about endianness */ 51912e595858903b80f29f271dc94e32a9e052bb4c8asewardj 51924c245e595b9f6300d3120408ca873f7115d9cc7dnjn Int offLo64, offHi64; 51934c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRDirty *diLo64, *diHi64; 51944c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRAtom *addrLo64, *addrHi64; 51954c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRAtom *vdataLo64, *vdataHi64; 51964c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRAtom *eBiasLo64, *eBiasHi64; 51974c245e595b9f6300d3120408ca873f7115d9cc7dnjn 51982e595858903b80f29f271dc94e32a9e052bb4c8asewardj if (end == Iend_LE) { 51992e595858903b80f29f271dc94e32a9e052bb4c8asewardj offLo64 = 0; 52002e595858903b80f29f271dc94e32a9e052bb4c8asewardj offHi64 = 8; 52012e595858903b80f29f271dc94e32a9e052bb4c8asewardj } else { 52022e595858903b80f29f271dc94e32a9e052bb4c8asewardj offLo64 = 8; 52032e595858903b80f29f271dc94e32a9e052bb4c8asewardj offHi64 = 0; 52042e595858903b80f29f271dc94e32a9e052bb4c8asewardj } 52052e595858903b80f29f271dc94e32a9e052bb4c8asewardj 52062e595858903b80f29f271dc94e32a9e052bb4c8asewardj eBiasLo64 = tyAddr==Ity_I32 ? mkU32(bias+offLo64) : mkU64(bias+offLo64); 52077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj addrLo64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasLo64) ); 52087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj vdataLo64 = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vdata)); 5209170ee210842367a5cc52390358ba560774f76329sewardj diLo64 = unsafeIRDirty_0_N( 521053ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj 1/*regparms*/, 521153ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj hname, VG_(fnptr_to_fnentry)( helper ), 521253ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj mkIRExprVec_2( addrLo64, vdataLo64 ) 521353ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj ); 52142e595858903b80f29f271dc94e32a9e052bb4c8asewardj eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64); 52157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj addrHi64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasHi64) ); 52167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj vdataHi64 = assignNew('V', mce, Ity_I64, unop(Iop_V128HIto64, vdata)); 5217170ee210842367a5cc52390358ba560774f76329sewardj diHi64 = unsafeIRDirty_0_N( 521853ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj 1/*regparms*/, 521953ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj hname, VG_(fnptr_to_fnentry)( helper ), 522053ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj mkIRExprVec_2( addrHi64, vdataHi64 ) 522153ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj ); 52221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) diLo64->guard = guard; 52231c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) diHi64->guard = guard; 5224170ee210842367a5cc52390358ba560774f76329sewardj setHelperAnns( mce, diLo64 ); 5225170ee210842367a5cc52390358ba560774f76329sewardj setHelperAnns( mce, diHi64 ); 52267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(diLo64) ); 52277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(diHi64) ); 5228e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 522995448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 5230170ee210842367a5cc52390358ba560774f76329sewardj 52314c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRDirty *di; 52324c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRAtom *addrAct; 52334c245e595b9f6300d3120408ca873f7115d9cc7dnjn 5234170ee210842367a5cc52390358ba560774f76329sewardj /* 8/16/32/64-bit cases */ 5235170ee210842367a5cc52390358ba560774f76329sewardj /* Generate the actual address into addrAct. */ 5236170ee210842367a5cc52390358ba560774f76329sewardj if (bias == 0) { 5237170ee210842367a5cc52390358ba560774f76329sewardj addrAct = addr; 5238170ee210842367a5cc52390358ba560774f76329sewardj } else { 52394c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRAtom* eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); 52407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj addrAct = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBias)); 5241170ee210842367a5cc52390358ba560774f76329sewardj } 5242170ee210842367a5cc52390358ba560774f76329sewardj 5243170ee210842367a5cc52390358ba560774f76329sewardj if (ty == Ity_I64) { 5244170ee210842367a5cc52390358ba560774f76329sewardj /* We can't do this with regparm 2 on 32-bit platforms, since 5245170ee210842367a5cc52390358ba560774f76329sewardj the back ends aren't clever enough to handle 64-bit 5246170ee210842367a5cc52390358ba560774f76329sewardj regparm args. Therefore be different. */ 5247170ee210842367a5cc52390358ba560774f76329sewardj di = unsafeIRDirty_0_N( 524853ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj 1/*regparms*/, 524953ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj hname, VG_(fnptr_to_fnentry)( helper ), 525053ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj mkIRExprVec_2( addrAct, vdata ) 525153ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj ); 5252170ee210842367a5cc52390358ba560774f76329sewardj } else { 5253170ee210842367a5cc52390358ba560774f76329sewardj di = unsafeIRDirty_0_N( 525453ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj 2/*regparms*/, 525553ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj hname, VG_(fnptr_to_fnentry)( helper ), 5256170ee210842367a5cc52390358ba560774f76329sewardj mkIRExprVec_2( addrAct, 525753ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj zwidenToHostWord( mce, vdata )) 525853ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj ); 5259170ee210842367a5cc52390358ba560774f76329sewardj } 52601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) di->guard = guard; 5261170ee210842367a5cc52390358ba560774f76329sewardj setHelperAnns( mce, di ); 52627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(di) ); 526395448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5264170ee210842367a5cc52390358ba560774f76329sewardj 5265e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 5266e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 5267e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 526895448075345dc73986042f6dc68eb464d02bc6a8sewardj/* Do lazy pessimistic propagation through a dirty helper call, by 526995448075345dc73986042f6dc68eb464d02bc6a8sewardj looking at the annotations on it. This is the most complex part of 527095448075345dc73986042f6dc68eb464d02bc6a8sewardj Memcheck. */ 5271e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 527295448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic IRType szToITy ( Int n ) 527395448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 527495448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (n) { 527595448075345dc73986042f6dc68eb464d02bc6a8sewardj case 1: return Ity_I8; 527695448075345dc73986042f6dc68eb464d02bc6a8sewardj case 2: return Ity_I16; 527795448075345dc73986042f6dc68eb464d02bc6a8sewardj case 4: return Ity_I32; 527895448075345dc73986042f6dc68eb464d02bc6a8sewardj case 8: return Ity_I64; 527995448075345dc73986042f6dc68eb464d02bc6a8sewardj default: VG_(tool_panic)("szToITy(memcheck)"); 528095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 528195448075345dc73986042f6dc68eb464d02bc6a8sewardj} 5282e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 528395448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic 528495448075345dc73986042f6dc68eb464d02bc6a8sewardjvoid do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) 528595448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 52862eecb74d4a8816485c97ae8e535ce25511460bc8sewardj Int i, k, n, toDo, gSz, gOff; 52872e595858903b80f29f271dc94e32a9e052bb4c8asewardj IRAtom *src, *here, *curr; 52884c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRType tySrc, tyDst; 52892e595858903b80f29f271dc94e32a9e052bb4c8asewardj IRTemp dst; 52902e595858903b80f29f271dc94e32a9e052bb4c8asewardj IREndness end; 52912e595858903b80f29f271dc94e32a9e052bb4c8asewardj 52922e595858903b80f29f271dc94e32a9e052bb4c8asewardj /* What's the native endianness? We need to know this. */ 52936e340c7a2c09971ac5ead854c40bbc0491b67636sewardj# if defined(VG_BIGENDIAN) 52942e595858903b80f29f271dc94e32a9e052bb4c8asewardj end = Iend_BE; 52956e340c7a2c09971ac5ead854c40bbc0491b67636sewardj# elif defined(VG_LITTLEENDIAN) 52962e595858903b80f29f271dc94e32a9e052bb4c8asewardj end = Iend_LE; 52972e595858903b80f29f271dc94e32a9e052bb4c8asewardj# else 52982e595858903b80f29f271dc94e32a9e052bb4c8asewardj# error "Unknown endianness" 52992e595858903b80f29f271dc94e32a9e052bb4c8asewardj# endif 530095448075345dc73986042f6dc68eb464d02bc6a8sewardj 530195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* First check the guard. */ 5302b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, d->guard, NULL); 530395448075345dc73986042f6dc68eb464d02bc6a8sewardj 530495448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Now round up all inputs and PCast over them. */ 53057cf97ee841afd255879bff9ff791fbabb7f95cecsewardj curr = definedOfType(Ity_I32); 530695448075345dc73986042f6dc68eb464d02bc6a8sewardj 5307434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian /* Inputs: unmasked args 5308434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian Note: arguments are evaluated REGARDLESS of the guard expression */ 530995448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; d->args[i]; i++) { 531021a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRAtom* arg = d->args[i]; 531121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj if ( (d->cee->mcx_mask & (1<<i)) 5312a5c3ecb923e27dcd995ba763d436b477e1e2a61eflorian || UNLIKELY(is_IRExpr_VECRET_or_BBPTR(arg)) ) { 531395448075345dc73986042f6dc68eb464d02bc6a8sewardj /* ignore this arg */ 531495448075345dc73986042f6dc68eb464d02bc6a8sewardj } else { 531521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, arg) ); 531695448075345dc73986042f6dc68eb464d02bc6a8sewardj curr = mkUifU32(mce, here, curr); 531795448075345dc73986042f6dc68eb464d02bc6a8sewardj } 531895448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5319e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 532095448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Inputs: guest state that we read. */ 532195448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; i < d->nFxState; i++) { 532295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(d->fxState[i].fx != Ifx_None); 532395448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->fxState[i].fx == Ifx_Write) 532495448075345dc73986042f6dc68eb464d02bc6a8sewardj continue; 5325a72032508d826f53df7e1211327f5321d9fba56fsewardj 53262eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Enumerate the described state segments */ 53272eecb74d4a8816485c97ae8e535ce25511460bc8sewardj for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { 53282eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; 53292eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz = d->fxState[i].size; 53302eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 53312eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Ignore any sections marked as 'always defined'. */ 53322eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (isAlwaysDefd(mce, gOff, gSz)) { 53332eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (0) 53342eecb74d4a8816485c97ae8e535ce25511460bc8sewardj VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", 53352eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff, gSz); 53362eecb74d4a8816485c97ae8e535ce25511460bc8sewardj continue; 53372eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 5338a72032508d826f53df7e1211327f5321d9fba56fsewardj 53392eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* This state element is read or modified. So we need to 53402eecb74d4a8816485c97ae8e535ce25511460bc8sewardj consider it. If larger than 8 bytes, deal with it in 53412eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 8-byte chunks. */ 53422eecb74d4a8816485c97ae8e535ce25511460bc8sewardj while (True) { 53432eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tl_assert(gSz >= 0); 53442eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (gSz == 0) break; 53452eecb74d4a8816485c97ae8e535ce25511460bc8sewardj n = gSz <= 8 ? gSz : 8; 53462eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* update 'curr' with UifU of the state slice 53472eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff .. gOff+n-1 */ 53482eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tySrc = szToITy( n ); 5349434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 5350434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian /* Observe the guard expression. If it is false use an 5351434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian all-bits-defined bit pattern */ 5352434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRAtom *cond, *iffalse, *iftrue; 5353434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 5354cc9616506450cb02944b62dc07774c29462bfefcsewardj cond = assignNew('V', mce, Ity_I1, d->guard); 5355434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian iftrue = assignNew('V', mce, tySrc, shadow_GET(mce, gOff, tySrc)); 5356434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian iffalse = assignNew('V', mce, tySrc, definedOfType(tySrc)); 5357434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian src = assignNew('V', mce, tySrc, 53585686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRExpr_ITE(cond, iftrue, iffalse)); 5359434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 53602eecb74d4a8816485c97ae8e535ce25511460bc8sewardj here = mkPCastTo( mce, Ity_I32, src ); 53612eecb74d4a8816485c97ae8e535ce25511460bc8sewardj curr = mkUifU32(mce, here, curr); 53622eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz -= n; 53632eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff += n; 53642eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 5365e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj } 536695448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5367e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 536895448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Inputs: memory. First set up some info needed regardless of 536995448075345dc73986042f6dc68eb464d02bc6a8sewardj whether we're doing reads or writes. */ 537095448075345dc73986042f6dc68eb464d02bc6a8sewardj 537195448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->mFx != Ifx_None) { 537295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Because we may do multiple shadow loads/stores from the same 537395448075345dc73986042f6dc68eb464d02bc6a8sewardj base address, it's best to do a single test of its 537495448075345dc73986042f6dc68eb464d02bc6a8sewardj definedness right now. Post-instrumentation optimisation 537595448075345dc73986042f6dc68eb464d02bc6a8sewardj should remove all but this test. */ 53764c245e595b9f6300d3120408ca873f7115d9cc7dnjn IRType tyAddr; 537795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(d->mAddr); 5378b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, d->mAddr, d->guard); 537995448075345dc73986042f6dc68eb464d02bc6a8sewardj 53801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tyAddr = typeOfIRExpr(mce->sb->tyenv, d->mAddr); 538195448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64); 538295448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(tyAddr == mce->hWordTy); /* not really right */ 538395448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5384e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 538595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Deal with memory inputs (reads or modifies) */ 538695448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) { 538795448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo = d->mSize; 53882e595858903b80f29f271dc94e32a9e052bb4c8asewardj /* chew off 32-bit chunks. We don't care about the endianness 53892e595858903b80f29f271dc94e32a9e052bb4c8asewardj since it's all going to be condensed down to a single bit, 53902e595858903b80f29f271dc94e32a9e052bb4c8asewardj but nevertheless choose an endianness which is hopefully 53912e595858903b80f29f271dc94e32a9e052bb4c8asewardj native to the platform. */ 539295448075345dc73986042f6dc68eb464d02bc6a8sewardj while (toDo >= 4) { 539395448075345dc73986042f6dc68eb464d02bc6a8sewardj here = mkPCastTo( 539495448075345dc73986042f6dc68eb464d02bc6a8sewardj mce, Ity_I32, 5395cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj expr2vbits_Load_guarded_Simple( 5396cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj mce, end, Ity_I32, d->mAddr, d->mSize - toDo, d->guard ) 539795448075345dc73986042f6dc68eb464d02bc6a8sewardj ); 539895448075345dc73986042f6dc68eb464d02bc6a8sewardj curr = mkUifU32(mce, here, curr); 539995448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo -= 4; 540095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 540195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* chew off 16-bit chunks */ 540295448075345dc73986042f6dc68eb464d02bc6a8sewardj while (toDo >= 2) { 540395448075345dc73986042f6dc68eb464d02bc6a8sewardj here = mkPCastTo( 540495448075345dc73986042f6dc68eb464d02bc6a8sewardj mce, Ity_I32, 5405cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj expr2vbits_Load_guarded_Simple( 5406cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj mce, end, Ity_I16, d->mAddr, d->mSize - toDo, d->guard ) 540795448075345dc73986042f6dc68eb464d02bc6a8sewardj ); 540895448075345dc73986042f6dc68eb464d02bc6a8sewardj curr = mkUifU32(mce, here, curr); 540995448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo -= 2; 541095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5411cda994be0e7356b10ad5771ffec348e42569762fflorian /* chew off the remaining 8-bit chunk, if any */ 5412cda994be0e7356b10ad5771ffec348e42569762fflorian if (toDo == 1) { 5413cda994be0e7356b10ad5771ffec348e42569762fflorian here = mkPCastTo( 5414cda994be0e7356b10ad5771ffec348e42569762fflorian mce, Ity_I32, 5415cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj expr2vbits_Load_guarded_Simple( 5416cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj mce, end, Ity_I8, d->mAddr, d->mSize - toDo, d->guard ) 5417cda994be0e7356b10ad5771ffec348e42569762fflorian ); 5418cda994be0e7356b10ad5771ffec348e42569762fflorian curr = mkUifU32(mce, here, curr); 5419cda994be0e7356b10ad5771ffec348e42569762fflorian toDo -= 1; 5420cda994be0e7356b10ad5771ffec348e42569762fflorian } 5421cda994be0e7356b10ad5771ffec348e42569762fflorian tl_assert(toDo == 0); 542295448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5423e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 542495448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Whew! So curr is a 32-bit V-value summarising pessimistically 542595448075345dc73986042f6dc68eb464d02bc6a8sewardj all the inputs to the helper. Now we need to re-distribute the 542695448075345dc73986042f6dc68eb464d02bc6a8sewardj results to all destinations. */ 5427e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 542895448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Outputs: the destination temporary, if there is one. */ 542995448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->tmp != IRTemp_INVALID) { 54307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj dst = findShadowTmpV(mce, d->tmp); 54311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tyDst = typeOfIRTemp(mce->sb->tyenv, d->tmp); 54327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) ); 543395448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5434e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 543595448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Outputs: guest state that we write or modify. */ 543695448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; i < d->nFxState; i++) { 543795448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(d->fxState[i].fx != Ifx_None); 543895448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->fxState[i].fx == Ifx_Read) 543995448075345dc73986042f6dc68eb464d02bc6a8sewardj continue; 54402eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 54412eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Enumerate the described state segments */ 54422eecb74d4a8816485c97ae8e535ce25511460bc8sewardj for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { 54432eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; 54442eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz = d->fxState[i].size; 54452eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 54462eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Ignore any sections marked as 'always defined'. */ 54472eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (isAlwaysDefd(mce, gOff, gSz)) 54482eecb74d4a8816485c97ae8e535ce25511460bc8sewardj continue; 54492eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 54502eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* This state element is written or modified. So we need to 54512eecb74d4a8816485c97ae8e535ce25511460bc8sewardj consider it. If larger than 8 bytes, deal with it in 54522eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 8-byte chunks. */ 54532eecb74d4a8816485c97ae8e535ce25511460bc8sewardj while (True) { 54542eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tl_assert(gSz >= 0); 54552eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (gSz == 0) break; 54562eecb74d4a8816485c97ae8e535ce25511460bc8sewardj n = gSz <= 8 ? gSz : 8; 54572eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Write suitably-casted 'curr' to the state slice 54582eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff .. gOff+n-1 */ 54592eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tyDst = szToITy( n ); 54602eecb74d4a8816485c97ae8e535ce25511460bc8sewardj do_shadow_PUT( mce, gOff, 54612eecb74d4a8816485c97ae8e535ce25511460bc8sewardj NULL, /* original atom */ 5462434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian mkPCastTo( mce, tyDst, curr ), d->guard ); 54632eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz -= n; 54642eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff += n; 54652eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 5466e9e16d3699cb81d5610a567c3e11d54402b0c162sewardj } 546795448075345dc73986042f6dc68eb464d02bc6a8sewardj } 5468e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 54692e595858903b80f29f271dc94e32a9e052bb4c8asewardj /* Outputs: memory that we write or modify. Same comments about 54702e595858903b80f29f271dc94e32a9e052bb4c8asewardj endianness as above apply. */ 547195448075345dc73986042f6dc68eb464d02bc6a8sewardj if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) { 547295448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo = d->mSize; 547395448075345dc73986042f6dc68eb464d02bc6a8sewardj /* chew off 32-bit chunks */ 547495448075345dc73986042f6dc68eb464d02bc6a8sewardj while (toDo >= 4) { 54752e595858903b80f29f271dc94e32a9e052bb4c8asewardj do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo, 54762e595858903b80f29f271dc94e32a9e052bb4c8asewardj NULL, /* original data */ 54771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mkPCastTo( mce, Ity_I32, curr ), 5478434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 547995448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo -= 4; 548095448075345dc73986042f6dc68eb464d02bc6a8sewardj } 548195448075345dc73986042f6dc68eb464d02bc6a8sewardj /* chew off 16-bit chunks */ 548295448075345dc73986042f6dc68eb464d02bc6a8sewardj while (toDo >= 2) { 54832e595858903b80f29f271dc94e32a9e052bb4c8asewardj do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo, 54842e595858903b80f29f271dc94e32a9e052bb4c8asewardj NULL, /* original data */ 54851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mkPCastTo( mce, Ity_I16, curr ), 5486434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 548795448075345dc73986042f6dc68eb464d02bc6a8sewardj toDo -= 2; 5488e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 5489cda994be0e7356b10ad5771ffec348e42569762fflorian /* chew off the remaining 8-bit chunk, if any */ 5490cda994be0e7356b10ad5771ffec348e42569762fflorian if (toDo == 1) { 5491cda994be0e7356b10ad5771ffec348e42569762fflorian do_shadow_Store( mce, end, d->mAddr, d->mSize - toDo, 5492cda994be0e7356b10ad5771ffec348e42569762fflorian NULL, /* original data */ 5493cda994be0e7356b10ad5771ffec348e42569762fflorian mkPCastTo( mce, Ity_I8, curr ), 5494434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 5495cda994be0e7356b10ad5771ffec348e42569762fflorian toDo -= 1; 5496cda994be0e7356b10ad5771ffec348e42569762fflorian } 5497cda994be0e7356b10ad5771ffec348e42569762fflorian tl_assert(toDo == 0); 5498e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 5499e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 550095448075345dc73986042f6dc68eb464d02bc6a8sewardj} 5501e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 55021c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5503826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj/* We have an ABI hint telling us that [base .. base+len-1] is to 5504826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj become undefined ("writable"). Generate code to call a helper to 5505826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj notify the A/V bit machinery of this fact. 5506826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj 5507826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj We call 55087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len, 55097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Addr nia ); 5510826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj*/ 5511826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardjstatic 55127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid do_AbiHint ( MCEnv* mce, IRExpr* base, Int len, IRExpr* nia ) 5513826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj{ 5514826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj IRDirty* di; 55157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Minor optimisation: if not doing origin tracking, ignore the 55167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj supplied nia and pass zero instead. This is on the basis that 55177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj MC_(helperc_MAKE_STACK_UNINIT) will ignore it anyway, and we can 55187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj almost always generate a shorter instruction to put zero into a 55197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj register than any other value. */ 55207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (MC_(clo_mc_level) < 3) 55217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nia = mkIRExpr_HWord(0); 55227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 5523826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj di = unsafeIRDirty_0_N( 5524826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj 0/*regparms*/, 5525826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj "MC_(helperc_MAKE_STACK_UNINIT)", 552653ee1fc8a2968c7e4d1eb75b89a8d4ff6908483csewardj VG_(fnptr_to_fnentry)( &MC_(helperc_MAKE_STACK_UNINIT) ), 55277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mkIRExprVec_3( base, mkIRExpr_HWord( (UInt)len), nia ) 5528826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj ); 55297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'V', mce, IRStmt_Dirty(di) ); 5530826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj} 5531826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj 5532e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 55331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* ------ Dealing with IRCAS (big and complex) ------ */ 55341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* FWDS */ 55361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic IRAtom* gen_load_b ( MCEnv* mce, Int szB, 55371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* baseaddr, Int offset ); 55381c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 ); 55391c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void gen_store_b ( MCEnv* mce, Int szB, 55401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* baseaddr, Int offset, IRAtom* dataB, 55411c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* guard ); 55421c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55431c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void do_shadow_CAS_single ( MCEnv* mce, IRCAS* cas ); 55441c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void do_shadow_CAS_double ( MCEnv* mce, IRCAS* cas ); 55451c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* Either ORIG and SHADOW are both IRExpr.RdTmps, or they are both 55481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRExpr.Consts, else this asserts. If they are both Consts, it 55491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj doesn't do anything. So that just leaves the RdTmp case. 55501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj In which case: this assigns the shadow value SHADOW to the IR 55521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj shadow temporary associated with ORIG. That is, ORIG, being an 55531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj original temporary, will have a shadow temporary associated with 55541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj it. However, in the case envisaged here, there will so far have 55551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj been no IR emitted to actually write a shadow value into that 55561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj temporary. What this routine does is to (emit IR to) copy the 55571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj value in SHADOW into said temporary, so that after this call, 55581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRExpr.RdTmps of ORIG's shadow temp will correctly pick up the 55591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj value in SHADOW. 55601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Point is to allow callers to compute "by hand" a shadow value for 55621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ORIG, and force it to be associated with ORIG. 55631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj How do we know that that shadow associated with ORIG has not so far 55651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj been assigned to? Well, we don't per se know that, but supposing 55661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj it had. Then this routine would create a second assignment to it, 55671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj and later the IR sanity checker would barf. But that never 55681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj happens. QED. 55691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj*/ 55701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void bind_shadow_tmp_to_orig ( UChar how, 55711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj MCEnv* mce, 55721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* orig, IRAtom* shadow ) 55731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 55741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, orig)); 55751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, shadow)); 55761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj switch (orig->tag) { 55771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Iex_Const: 55781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(shadow->tag == Iex_Const); 55791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 55801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Iex_RdTmp: 55811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(shadow->tag == Iex_RdTmp); 55821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (how == 'V') { 55831c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj assign('V', mce, findShadowTmpV(mce,orig->Iex.RdTmp.tmp), 55841c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj shadow); 55851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } else { 55861c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(how == 'B'); 55871c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj assign('B', mce, findShadowTmpB(mce,orig->Iex.RdTmp.tmp), 55881c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj shadow); 55891c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 55901c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 55911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj default: 55921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(0); 55931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 55941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj} 55951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55961c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 55971c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic 55981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjvoid do_shadow_CAS ( MCEnv* mce, IRCAS* cas ) 55991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 56001c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* Scheme is (both single- and double- cases): 56011c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56021c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 1. fetch data#,dataB (the proposed new value) 56031c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56041c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 2. fetch expd#,expdB (what we expect to see at the address) 56051c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56061c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 3. check definedness of address 56071c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56081c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 4. load old#,oldB from shadow memory; this also checks 56091c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj addressibility of the address 56101c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5. the CAS itself 56121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5613afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 6. compute "expected == old". See COMMENT_ON_CasCmpEQ below. 56141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5615afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 7. if "expected == old" (as computed by (6)) 56161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj store data#,dataB to shadow memory 56171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Note that 5 reads 'old' but 4 reads 'old#'. Similarly, 5 stores 56191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 'data' but 7 stores 'data#'. Hence it is possible for the 56201c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj shadow data to be incorrectly checked and/or updated: 56211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj * 7 is at least gated correctly, since the 'expected == old' 56231c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj condition is derived from outputs of 5. However, the shadow 56241c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj write could happen too late: imagine after 5 we are 56251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj descheduled, a different thread runs, writes a different 56261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj (shadow) value at the address, and then we resume, hence 56271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj overwriting the shadow value written by the other thread. 56281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Because the original memory access is atomic, there's no way to 56301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj make both the original and shadow accesses into a single atomic 56311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj thing, hence this is unavoidable. 56321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj At least as Valgrind stands, I don't think it's a problem, since 56341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj we're single threaded *and* we guarantee that there are no 56351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj context switches during the execution of any specific superblock 56361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj -- context switches can only happen at superblock boundaries. 56371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 56381c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj If Valgrind ever becomes MT in the future, then it might be more 56391c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj of a problem. A possible kludge would be to artificially 56401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj associate with the location, a lock, which we must acquire and 56411c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj release around the transaction as a whole. Hmm, that probably 56421c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj would't work properly since it only guards us against other 56431c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj threads doing CASs on the same location, not against other 56441c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj threads doing normal reads and writes. 5645afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5646afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj ------------------------------------------------------------ 5647afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5648afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj COMMENT_ON_CasCmpEQ: 5649afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5650afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj Note two things. Firstly, in the sequence above, we compute 5651afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj "expected == old", but we don't check definedness of it. Why 5652afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj not? Also, the x86 and amd64 front ends use 5653b9e6d244e474c971ea88181de1f83a30057db9dasewardj Iop_CasCmp{EQ,NE}{8,16,32,64} comparisons to make the equivalent 5654afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj determination (expected == old ?) for themselves, and we also 5655afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj don't check definedness for those primops; we just say that the 5656afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj result is defined. Why? Details follow. 5657afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5658afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj x86/amd64 contains various forms of locked insns: 5659afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj * lock prefix before all basic arithmetic insn; 5660afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj eg lock xorl %reg1,(%reg2) 5661afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj * atomic exchange reg-mem 5662afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj * compare-and-swaps 5663afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5664afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj Rather than attempt to represent them all, which would be a 5665afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj royal PITA, I used a result from Maurice Herlihy 5666afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj (http://en.wikipedia.org/wiki/Maurice_Herlihy), in which he 5667afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj demonstrates that compare-and-swap is a primitive more general 5668afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj than the other two, and so can be used to represent all of them. 5669afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj So the translation scheme for (eg) lock incl (%reg) is as 5670afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj follows: 5671afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5672afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj again: 5673afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj old = * %reg 5674afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj new = old + 1 5675afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj atomically { if (* %reg == old) { * %reg = new } else { goto again } } 5676afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5677afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj The "atomically" is the CAS bit. The scheme is always the same: 5678afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj get old value from memory, compute new value, atomically stuff 5679afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj new value back in memory iff the old value has not changed (iow, 5680afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj no other thread modified it in the meantime). If it has changed 5681afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj then we've been out-raced and we have to start over. 5682afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5683afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj Now that's all very neat, but it has the bad side effect of 5684afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj introducing an explicit equality test into the translation. 5685afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj Consider the behaviour of said code on a memory location which 5686afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj is uninitialised. We will wind up doing a comparison on 5687afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj uninitialised data, and mc duly complains. 5688afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5689afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj What's difficult about this is, the common case is that the 5690afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj location is uncontended, and so we're usually comparing the same 5691afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj value (* %reg) with itself. So we shouldn't complain even if it 5692afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj is undefined. But mc doesn't know that. 5693afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5694afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj My solution is to mark the == in the IR specially, so as to tell 5695afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj mc that it almost certainly compares a value with itself, and we 5696afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj should just regard the result as always defined. Rather than 5697afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj add a bit to all IROps, I just cloned Iop_CmpEQ{8,16,32,64} into 5698afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj Iop_CasCmpEQ{8,16,32,64} so as not to disturb anything else. 5699afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5700afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj So there's always the question of, can this give a false 5701afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj negative? eg, imagine that initially, * %reg is defined; and we 5702afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj read that; but then in the gap between the read and the CAS, a 5703afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj different thread writes an undefined (and different) value at 5704afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj the location. Then the CAS in this thread will fail and we will 5705afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj go back to "again:", but without knowing that the trip back 5706afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj there was based on an undefined comparison. No matter; at least 5707afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj the other thread won the race and the location is correctly 5708afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj marked as undefined. What if it wrote an uninitialised version 5709afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj of the same value that was there originally, though? 5710afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5711afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj etc etc. Seems like there's a small corner case in which we 5712afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj might lose the fact that something's defined -- we're out-raced 5713afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj in between the "old = * reg" and the "atomically {", _and_ the 5714afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj other thread is writing in an undefined version of what's 5715afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj already there. Well, that seems pretty unlikely. 5716afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5717afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj --- 5718afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj 5719afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj If we ever need to reinstate it .. code which generates a 5720afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj definedness test for "expected == old" was removed at r10432 of 5721afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj this file. 57221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj */ 57231c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (cas->oldHi == IRTemp_INVALID) { 57241c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_CAS_single( mce, cas ); 57251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } else { 57261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_CAS_double( mce, cas ); 57271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 57281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj} 57291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void do_shadow_CAS_single ( MCEnv* mce, IRCAS* cas ) 57321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 57331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vdataLo = NULL, *bdataLo = NULL; 57341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vexpdLo = NULL, *bexpdLo = NULL; 57351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *voldLo = NULL, *boldLo = NULL; 5736afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IRAtom *expd_eq_old = NULL; 5737afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IROp opCasCmpEQ; 57381c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Int elemSzB; 57391c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType elemTy; 57401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */ 57411c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57421c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* single CAS */ 57431c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->oldHi == IRTemp_INVALID); 57441c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->expdHi == NULL); 57451c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->dataHi == NULL); 57461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo); 57481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj switch (elemTy) { 5749afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Ity_I8: elemSzB = 1; opCasCmpEQ = Iop_CasCmpEQ8; break; 5750afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Ity_I16: elemSzB = 2; opCasCmpEQ = Iop_CasCmpEQ16; break; 5751afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Ity_I32: elemSzB = 4; opCasCmpEQ = Iop_CasCmpEQ32; break; 5752afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Ity_I64: elemSzB = 8; opCasCmpEQ = Iop_CasCmpEQ64; break; 57531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj default: tl_assert(0); /* IR defn disallows any other types */ 57541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 57551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 1. fetch data# (the proposed new value) */ 57571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->dataLo)); 57581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vdataLo 57591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->dataLo)); 57601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vdataLo)); 57611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 57621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataLo 57631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->dataLo)); 57641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bdataLo)); 57651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 57661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 2. fetch expected# (what we expect to see at the address) */ 57681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->expdLo)); 57691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vexpdLo 57701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->expdLo)); 57711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vexpdLo)); 57721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 57731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bexpdLo 57741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->expdLo)); 57751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bexpdLo)); 57761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 57771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 3. check definedness of address */ 57791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 4. fetch old# from shadow memory; this also checks 57801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj addressibility of the address */ 57811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj voldLo 57821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew( 57831c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 'V', mce, elemTy, 57841c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expr2vbits_Load( 57851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mce, 5786cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj cas->end, elemTy, cas->addr, 0/*Addr bias*/, 5787cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/*always happens*/ 57881c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj )); 5789afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('V', mce, mkexpr(cas->oldLo), voldLo); 57901c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 57911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj boldLo 57921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, 57931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_load_b(mce, elemSzB, cas->addr, 0/*addr bias*/)); 5794afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('B', mce, mkexpr(cas->oldLo), boldLo); 57951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 57961c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 57971c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 5. the CAS itself */ 57981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj stmt( 'C', mce, IRStmt_CAS(cas) ); 57991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5800afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* 6. compute "expected == old" */ 5801afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* See COMMENT_ON_CasCmpEQ in this file background/rationale. */ 58021c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* Note that 'C' is kinda faking it; it is indeed a non-shadow 58031c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tree, but it's not copied from the input block. */ 58041c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old 58051c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('C', mce, Ity_I1, 5806afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj binop(opCasCmpEQ, cas->expdLo, mkexpr(cas->oldLo))); 58071c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58081c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 7. if "expected == old" 58091c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj store data# to shadow memory */ 58101c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_Store( mce, cas->end, cas->addr, 0/*bias*/, 58111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj NULL/*data*/, vdataLo/*vdata*/, 58121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 58131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 58141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_store_b( mce, elemSzB, cas->addr, 0/*offset*/, 58151c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataLo/*bdata*/, 58161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 58171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 58181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj} 58191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58201c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardjstatic void do_shadow_CAS_double ( MCEnv* mce, IRCAS* cas ) 58221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj{ 58231c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vdataHi = NULL, *bdataHi = NULL; 58241c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vdataLo = NULL, *bdataLo = NULL; 58251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vexpdHi = NULL, *bexpdHi = NULL; 58261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *vexpdLo = NULL, *bexpdLo = NULL; 58271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *voldHi = NULL, *boldHi = NULL; 58281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom *voldLo = NULL, *boldLo = NULL; 5829afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IRAtom *xHi = NULL, *xLo = NULL, *xHL = NULL; 5830afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IRAtom *expd_eq_old = NULL, *zero = NULL; 5831afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IROp opCasCmpEQ, opOr, opXor; 58321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Int elemSzB, memOffsLo, memOffsHi; 58331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType elemTy; 58341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */ 58351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* double CAS */ 58371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->oldHi != IRTemp_INVALID); 58381c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->expdHi != NULL); 58391c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->dataHi != NULL); 58401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58411c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo); 58421c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj switch (elemTy) { 58431c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ity_I8: 5844afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj opCasCmpEQ = Iop_CasCmpEQ8; opOr = Iop_Or8; opXor = Iop_Xor8; 58451c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemSzB = 1; zero = mkU8(0); 58461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 58471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ity_I16: 5848afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj opCasCmpEQ = Iop_CasCmpEQ16; opOr = Iop_Or16; opXor = Iop_Xor16; 58491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemSzB = 2; zero = mkU16(0); 58501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 58511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ity_I32: 5852afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj opCasCmpEQ = Iop_CasCmpEQ32; opOr = Iop_Or32; opXor = Iop_Xor32; 58531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemSzB = 4; zero = mkU32(0); 58541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 58551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ity_I64: 5856afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj opCasCmpEQ = Iop_CasCmpEQ64; opOr = Iop_Or64; opXor = Iop_Xor64; 58571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj elemSzB = 8; zero = mkU64(0); 58581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 58591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj default: 58601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(0); /* IR defn disallows any other types */ 58611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 58621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 1. fetch data# (the proposed new value) */ 58641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->dataHi)); 58651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->dataLo)); 58661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vdataHi 58671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->dataHi)); 58681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vdataLo 58691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->dataLo)); 58701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vdataHi)); 58711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vdataLo)); 58721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 58731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataHi 58741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->dataHi)); 58751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataLo 58761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->dataLo)); 58771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bdataHi)); 58781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bdataLo)); 58791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 58801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 2. fetch expected# (what we expect to see at the address) */ 58821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->expdHi)); 58831c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, cas->expdLo)); 58841c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vexpdHi 58851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->expdHi)); 58861c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj vexpdLo 58871c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('V', mce, elemTy, expr2vbits(mce, cas->expdLo)); 58881c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vexpdHi)); 58891c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, vexpdLo)); 58901c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 58911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bexpdHi 58921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->expdHi)); 58931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bexpdLo 58941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, schemeE(mce, cas->expdLo)); 58951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bexpdHi)); 58961c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isShadowAtom(mce, bexpdLo)); 58971c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 58981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 58991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 3. check definedness of address */ 59001c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 4. fetch old# from shadow memory; this also checks 59011c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj addressibility of the address */ 59021c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (cas->end == Iend_LE) { 59031c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsLo = 0; 59041c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsHi = elemSzB; 59051c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } else { 59061c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(cas->end == Iend_BE); 59071c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsLo = elemSzB; 59081c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsHi = 0; 59091c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 59101c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj voldHi 59111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew( 59121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 'V', mce, elemTy, 59131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expr2vbits_Load( 59141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mce, 5915cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj cas->end, elemTy, cas->addr, memOffsHi/*Addr bias*/, 5916cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/*always happens*/ 59171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj )); 59181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj voldLo 59191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew( 59201c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 'V', mce, elemTy, 59211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expr2vbits_Load( 59221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mce, 5923cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj cas->end, elemTy, cas->addr, memOffsLo/*Addr bias*/, 5924cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/*always happens*/ 59251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj )); 5926afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('V', mce, mkexpr(cas->oldHi), voldHi); 5927afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('V', mce, mkexpr(cas->oldLo), voldLo); 59281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 59291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj boldHi 59301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, 59311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_load_b(mce, elemSzB, cas->addr, 59321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsHi/*addr bias*/)); 59331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj boldLo 59341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('B', mce, Ity_I32, 59351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_load_b(mce, elemSzB, cas->addr, 59361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj memOffsLo/*addr bias*/)); 5937afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('B', mce, mkexpr(cas->oldHi), boldHi); 5938afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj bind_shadow_tmp_to_orig('B', mce, mkexpr(cas->oldLo), boldLo); 59391c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 59401c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 59411c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 5. the CAS itself */ 59421c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj stmt( 'C', mce, IRStmt_CAS(cas) ); 59431c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5944afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* 6. compute "expected == old" */ 5945afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* See COMMENT_ON_CasCmpEQ in this file background/rationale. */ 59461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* Note that 'C' is kinda faking it; it is indeed a non-shadow 59471c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tree, but it's not copied from the input block. */ 59481c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 59491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xHi = oldHi ^ expdHi; 59501c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xLo = oldLo ^ expdLo; 59511c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xHL = xHi | xLo; 59521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old = xHL == 0; 59531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj */ 59541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xHi = assignNew('C', mce, elemTy, 59551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj binop(opXor, cas->expdHi, mkexpr(cas->oldHi))); 59561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xLo = assignNew('C', mce, elemTy, 59571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj binop(opXor, cas->expdLo, mkexpr(cas->oldLo))); 59581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj xHL = assignNew('C', mce, elemTy, 59591c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj binop(opOr, xHi, xLo)); 59601c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old 59611c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = assignNew('C', mce, Ity_I1, 5962afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj binop(opCasCmpEQ, xHL, zero)); 59631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 59641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* 7. if "expected == old" 59651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj store data# to shadow memory */ 59661c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_Store( mce, cas->end, cas->addr, memOffsHi/*bias*/, 59671c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj NULL/*data*/, vdataHi/*vdata*/, 59681c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 59691c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_Store( mce, cas->end, cas->addr, memOffsLo/*bias*/, 59701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj NULL/*data*/, vdataLo/*vdata*/, 59711c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 59721c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (otrak) { 59731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_store_b( mce, elemSzB, cas->addr, memOffsHi/*offset*/, 59741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataHi/*bdata*/, 59751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 59761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_store_b( mce, elemSzB, cas->addr, memOffsLo/*offset*/, 59771c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bdataLo/*bdata*/, 59781c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj expd_eq_old/*guard for store*/ ); 59791c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 59801c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj} 59811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 59821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 5983db5907d7b94ce492f29a96c95e186fdcda23a149sewardj/* ------ Dealing with LL/SC (not difficult) ------ */ 5984db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 5985db5907d7b94ce492f29a96c95e186fdcda23a149sewardjstatic void do_shadow_LLSC ( MCEnv* mce, 5986db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IREndness stEnd, 5987db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRTemp stResult, 5988db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRExpr* stAddr, 5989db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRExpr* stStoredata ) 5990db5907d7b94ce492f29a96c95e186fdcda23a149sewardj{ 5991db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* In short: treat a load-linked like a normal load followed by an 5992db5907d7b94ce492f29a96c95e186fdcda23a149sewardj assignment of the loaded (shadow) data to the result temporary. 5993db5907d7b94ce492f29a96c95e186fdcda23a149sewardj Treat a store-conditional like a normal store, and mark the 5994db5907d7b94ce492f29a96c95e186fdcda23a149sewardj result temporary as defined. */ 5995db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRType resTy = typeOfIRTemp(mce->sb->tyenv, stResult); 5996db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRTemp resTmp = findShadowTmpV(mce, stResult); 5997db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 5998db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(isIRAtom(stAddr)); 5999db5907d7b94ce492f29a96c95e186fdcda23a149sewardj if (stStoredata) 6000db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(isIRAtom(stStoredata)); 6001db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 6002db5907d7b94ce492f29a96c95e186fdcda23a149sewardj if (stStoredata == NULL) { 6003db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Load Linked */ 6004db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Just treat this as a normal load, followed by an assignment of 6005db5907d7b94ce492f29a96c95e186fdcda23a149sewardj the value to .result. */ 6006db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Stay sane */ 6007db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(resTy == Ity_I64 || resTy == Ity_I32 6008db5907d7b94ce492f29a96c95e186fdcda23a149sewardj || resTy == Ity_I16 || resTy == Ity_I8); 6009db5907d7b94ce492f29a96c95e186fdcda23a149sewardj assign( 'V', mce, resTmp, 6010db5907d7b94ce492f29a96c95e186fdcda23a149sewardj expr2vbits_Load( 6011cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj mce, stEnd, resTy, stAddr, 0/*addr bias*/, 6012cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/*always happens*/) ); 6013db5907d7b94ce492f29a96c95e186fdcda23a149sewardj } else { 6014db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Store Conditional */ 6015db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Stay sane */ 6016db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRType dataTy = typeOfIRExpr(mce->sb->tyenv, 6017db5907d7b94ce492f29a96c95e186fdcda23a149sewardj stStoredata); 6018db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32 6019db5907d7b94ce492f29a96c95e186fdcda23a149sewardj || dataTy == Ity_I16 || dataTy == Ity_I8); 6020db5907d7b94ce492f29a96c95e186fdcda23a149sewardj do_shadow_Store( mce, stEnd, 6021db5907d7b94ce492f29a96c95e186fdcda23a149sewardj stAddr, 0/* addr bias */, 6022db5907d7b94ce492f29a96c95e186fdcda23a149sewardj stStoredata, 6023db5907d7b94ce492f29a96c95e186fdcda23a149sewardj NULL /* shadow data */, 6024db5907d7b94ce492f29a96c95e186fdcda23a149sewardj NULL/*guard*/ ); 6025db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* This is a store conditional, so it writes to .result a value 6026db5907d7b94ce492f29a96c95e186fdcda23a149sewardj indicating whether or not the store succeeded. Just claim 6027db5907d7b94ce492f29a96c95e186fdcda23a149sewardj this value is always defined. In the PowerPC interpretation 6028db5907d7b94ce492f29a96c95e186fdcda23a149sewardj of store-conditional, definedness of the success indication 6029db5907d7b94ce492f29a96c95e186fdcda23a149sewardj depends on whether the address of the store matches the 6030db5907d7b94ce492f29a96c95e186fdcda23a149sewardj reservation address. But we can't tell that here (and 6031db5907d7b94ce492f29a96c95e186fdcda23a149sewardj anyway, we're not being PowerPC-specific). At least we are 6032db5907d7b94ce492f29a96c95e186fdcda23a149sewardj guaranteed that the definedness of the store address, and its 6033db5907d7b94ce492f29a96c95e186fdcda23a149sewardj addressibility, will be checked as per normal. So it seems 6034db5907d7b94ce492f29a96c95e186fdcda23a149sewardj pretty safe to just say that the success indication is always 6035db5907d7b94ce492f29a96c95e186fdcda23a149sewardj defined. 6036db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 6037db5907d7b94ce492f29a96c95e186fdcda23a149sewardj In schemeS, for origin tracking, we must correspondingly set 6038db5907d7b94ce492f29a96c95e186fdcda23a149sewardj a no-origin value for the origin shadow of .result. 6039db5907d7b94ce492f29a96c95e186fdcda23a149sewardj */ 6040db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(resTy == Ity_I1); 6041db5907d7b94ce492f29a96c95e186fdcda23a149sewardj assign( 'V', mce, resTmp, definedOfType(resTy) ); 6042db5907d7b94ce492f29a96c95e186fdcda23a149sewardj } 6043db5907d7b94ce492f29a96c95e186fdcda23a149sewardj} 6044db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 6045db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 6046cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* ---- Dealing with LoadG/StoreG (not entirely simple) ---- */ 6047cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6048cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_shadow_StoreG ( MCEnv* mce, IRStoreG* sg ) 6049cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 6050b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, sg->guard, NULL); 6051b9e6d244e474c971ea88181de1f83a30057db9dasewardj /* do_shadow_Store will generate code to check the definedness and 6052b9e6d244e474c971ea88181de1f83a30057db9dasewardj validity of sg->addr, in the case where sg->guard evaluates to 6053b9e6d244e474c971ea88181de1f83a30057db9dasewardj True at run-time. */ 6054cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_shadow_Store( mce, sg->end, 6055cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj sg->addr, 0/* addr bias */, 6056cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj sg->data, 6057cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL /* shadow data */, 6058cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj sg->guard ); 6059cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 6060cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6061cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_shadow_LoadG ( MCEnv* mce, IRLoadG* lg ) 6062cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 6063b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined(mce, lg->guard, NULL); 6064b9e6d244e474c971ea88181de1f83a30057db9dasewardj /* expr2vbits_Load_guarded_General will generate code to check the 6065b9e6d244e474c971ea88181de1f83a30057db9dasewardj definedness and validity of lg->addr, in the case where 6066b9e6d244e474c971ea88181de1f83a30057db9dasewardj lg->guard evaluates to True at run-time. */ 6067cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6068cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* Look at the LoadG's built-in conversion operation, to determine 6069cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj the source (actual loaded data) type, and the equivalent IROp. 6070cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NOTE that implicitly we are taking a widening operation to be 6071cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj applied to original atoms and producing one that applies to V 6072cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj bits. Since signed and unsigned widening are self-shadowing, 6073cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj this is a straight copy of the op (modulo swapping from the 6074cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRLoadGOp form to the IROp form). Note also therefore that this 6075cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj implicitly duplicates the logic to do with said widening ops in 6076cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj expr2vbits_Unop. See comment at the start of expr2vbits_Unop. */ 6077cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IROp vwiden = Iop_INVALID; 6078cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRType loadedTy = Ity_INVALID; 6079cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj switch (lg->cvt) { 6080290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_IdentV128: loadedTy = Ity_V128; vwiden = Iop_INVALID; break; 6081290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_Ident64: loadedTy = Ity_I64; vwiden = Iop_INVALID; break; 6082290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_Ident32: loadedTy = Ity_I32; vwiden = Iop_INVALID; break; 6083290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_16Uto32: loadedTy = Ity_I16; vwiden = Iop_16Uto32; break; 6084290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_16Sto32: loadedTy = Ity_I16; vwiden = Iop_16Sto32; break; 6085290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_8Uto32: loadedTy = Ity_I8; vwiden = Iop_8Uto32; break; 6086290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_8Sto32: loadedTy = Ity_I8; vwiden = Iop_8Sto32; break; 6087cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj default: VG_(tool_panic)("do_shadow_LoadG"); 6088cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 6089cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6090cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* vbits_alt 6091cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = expr2vbits( mce, lg->alt ); 6092cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* vbits_final 6093cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = expr2vbits_Load_guarded_General(mce, lg->end, loadedTy, 6094cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj lg->addr, 0/*addr bias*/, 6095cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj lg->guard, vwiden, vbits_alt ); 6096cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* And finally, bind the V bits to the destination temporary. */ 6097cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj assign( 'V', mce, findShadowTmpV(mce, lg->dst), vbits_final ); 6098cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 6099cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6100cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 610195448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 610295448075345dc73986042f6dc68eb464d02bc6a8sewardj/*--- Memcheck main ---*/ 610395448075345dc73986042f6dc68eb464d02bc6a8sewardj/*------------------------------------------------------------*/ 6104e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 61057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void schemeS ( MCEnv* mce, IRStmt* st ); 61067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 610795448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool isBogusAtom ( IRAtom* at ) 6108e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 610995448075345dc73986042f6dc68eb464d02bc6a8sewardj ULong n = 0; 611095448075345dc73986042f6dc68eb464d02bc6a8sewardj IRConst* con; 6111710d6c27c3ce7bf26639bda3ab4f42695bc92c2csewardj tl_assert(isIRAtom(at)); 61120b9d74abd0a663b530d290b2b788ddeda46e5400sewardj if (at->tag == Iex_RdTmp) 611395448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 611495448075345dc73986042f6dc68eb464d02bc6a8sewardj tl_assert(at->tag == Iex_Const); 611595448075345dc73986042f6dc68eb464d02bc6a8sewardj con = at->Iex.Const.con; 611695448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (con->tag) { 6117d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_U1: return False; 6118d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_U8: n = (ULong)con->Ico.U8; break; 6119d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_U16: n = (ULong)con->Ico.U16; break; 6120d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_U32: n = (ULong)con->Ico.U32; break; 6121d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_U64: n = (ULong)con->Ico.U64; break; 6122f837aa7d6dfed0424b23b9c46d7fadbc6af2a060sewardj case Ico_F32: return False; 6123d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_F64: return False; 6124b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Ico_F32i: return False; 6125d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_F64i: return False; 6126d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ico_V128: return False; 61271eb272f53fadb410dd27fb38fb1be75af84868d0sewardj case Ico_V256: return False; 612895448075345dc73986042f6dc68eb464d02bc6a8sewardj default: ppIRExpr(at); tl_assert(0); 612995448075345dc73986042f6dc68eb464d02bc6a8sewardj } 613095448075345dc73986042f6dc68eb464d02bc6a8sewardj /* VG_(printf)("%llx\n", n); */ 613196a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj return (/*32*/ n == 0xFEFEFEFFULL 613296a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj /*32*/ || n == 0x80808080ULL 613317b4743b17a25cade63cdd72c8f5a558d412c39bsewardj /*32*/ || n == 0x7F7F7F7FULL 6134a150fe951e31f5bfde41e5c12e65f5a48f07779asewardj /*32*/ || n == 0x7EFEFEFFULL 6135a150fe951e31f5bfde41e5c12e65f5a48f07779asewardj /*32*/ || n == 0x81010100ULL 6136d9774d73807c7292c72e1254119d6bd8ded81f15tom /*64*/ || n == 0xFFFFFFFFFEFEFEFFULL 613796a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj /*64*/ || n == 0xFEFEFEFEFEFEFEFFULL 6138d9774d73807c7292c72e1254119d6bd8ded81f15tom /*64*/ || n == 0x0000000000008080ULL 613996a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj /*64*/ || n == 0x8080808080808080ULL 614017b4743b17a25cade63cdd72c8f5a558d412c39bsewardj /*64*/ || n == 0x0101010101010101ULL 614196a922e5fe4ef47150f1116001ebab3b98c61ea3sewardj ); 614295448075345dc73986042f6dc68eb464d02bc6a8sewardj} 6143e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 614495448075345dc73986042f6dc68eb464d02bc6a8sewardjstatic Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st ) 614595448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 6146d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj Int i; 6147d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRExpr* e; 6148d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj IRDirty* d; 61491c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRCAS* cas; 615095448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (st->tag) { 61510b9d74abd0a663b530d290b2b788ddeda46e5400sewardj case Ist_WrTmp: 61520b9d74abd0a663b530d290b2b788ddeda46e5400sewardj e = st->Ist.WrTmp.data; 615395448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (e->tag) { 615495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Get: 61550b9d74abd0a663b530d290b2b788ddeda46e5400sewardj case Iex_RdTmp: 615695448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 6157d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Iex_Const: 6158d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return isBogusAtom(e); 615995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Unop: 6160a150fe951e31f5bfde41e5c12e65f5a48f07779asewardj return isBogusAtom(e->Iex.Unop.arg) 6161a150fe951e31f5bfde41e5c12e65f5a48f07779asewardj || e->Iex.Unop.op == Iop_GetMSBs8x16; 6162d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Iex_GetI: 6163d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return isBogusAtom(e->Iex.GetI.ix); 616495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_Binop: 616595448075345dc73986042f6dc68eb464d02bc6a8sewardj return isBogusAtom(e->Iex.Binop.arg1) 616695448075345dc73986042f6dc68eb464d02bc6a8sewardj || isBogusAtom(e->Iex.Binop.arg2); 6167ed69fdb48673f1aaaa5ce3ff1997fb50d1e15e40sewardj case Iex_Triop: 616826441746bda788fc0327527a62427ca562f25311florian return isBogusAtom(e->Iex.Triop.details->arg1) 616926441746bda788fc0327527a62427ca562f25311florian || isBogusAtom(e->Iex.Triop.details->arg2) 617026441746bda788fc0327527a62427ca562f25311florian || isBogusAtom(e->Iex.Triop.details->arg3); 6171e91cea71129edc807428c8228d0d9f5b13894a5asewardj case Iex_Qop: 6172e2ab2974c8bcaf3863956ba2d5368092a54e0703florian return isBogusAtom(e->Iex.Qop.details->arg1) 6173e2ab2974c8bcaf3863956ba2d5368092a54e0703florian || isBogusAtom(e->Iex.Qop.details->arg2) 6174e2ab2974c8bcaf3863956ba2d5368092a54e0703florian || isBogusAtom(e->Iex.Qop.details->arg3) 6175e2ab2974c8bcaf3863956ba2d5368092a54e0703florian || isBogusAtom(e->Iex.Qop.details->arg4); 61765686b2d7e97a6f65e436531dac999a52a3d3dac9florian case Iex_ITE: 61775686b2d7e97a6f65e436531dac999a52a3d3dac9florian return isBogusAtom(e->Iex.ITE.cond) 61785686b2d7e97a6f65e436531dac999a52a3d3dac9florian || isBogusAtom(e->Iex.ITE.iftrue) 61795686b2d7e97a6f65e436531dac999a52a3d3dac9florian || isBogusAtom(e->Iex.ITE.iffalse); 61802e595858903b80f29f271dc94e32a9e052bb4c8asewardj case Iex_Load: 61812e595858903b80f29f271dc94e32a9e052bb4c8asewardj return isBogusAtom(e->Iex.Load.addr); 618295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Iex_CCall: 618395448075345dc73986042f6dc68eb464d02bc6a8sewardj for (i = 0; e->Iex.CCall.args[i]; i++) 618495448075345dc73986042f6dc68eb464d02bc6a8sewardj if (isBogusAtom(e->Iex.CCall.args[i])) 618595448075345dc73986042f6dc68eb464d02bc6a8sewardj return True; 618695448075345dc73986042f6dc68eb464d02bc6a8sewardj return False; 618795448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 618895448075345dc73986042f6dc68eb464d02bc6a8sewardj goto unhandled; 618995448075345dc73986042f6dc68eb464d02bc6a8sewardj } 6190d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ist_Dirty: 6191d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj d = st->Ist.Dirty.details; 619221a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj for (i = 0; d->args[i]; i++) { 619321a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRAtom* atom = d->args[i]; 6194a5c3ecb923e27dcd995ba763d436b477e1e2a61eflorian if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(atom))) { 619521a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj if (isBogusAtom(atom)) 619621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj return True; 619721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj } 619821a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj } 61996c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian if (isBogusAtom(d->guard)) 6200d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return True; 6201d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj if (d->mAddr && isBogusAtom(d->mAddr)) 6202d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return True; 6203d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return False; 620495448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_Put: 620595448075345dc73986042f6dc68eb464d02bc6a8sewardj return isBogusAtom(st->Ist.Put.data); 6206d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj case Ist_PutI: 6207d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian return isBogusAtom(st->Ist.PutI.details->ix) 6208d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian || isBogusAtom(st->Ist.PutI.details->data); 62092e595858903b80f29f271dc94e32a9e052bb4c8asewardj case Ist_Store: 62102e595858903b80f29f271dc94e32a9e052bb4c8asewardj return isBogusAtom(st->Ist.Store.addr) 62112e595858903b80f29f271dc94e32a9e052bb4c8asewardj || isBogusAtom(st->Ist.Store.data); 6212cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_StoreG: { 6213cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRStoreG* sg = st->Ist.StoreG.details; 6214cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return isBogusAtom(sg->addr) || isBogusAtom(sg->data) 6215cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj || isBogusAtom(sg->guard); 6216cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 6217cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_LoadG: { 6218cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRLoadG* lg = st->Ist.LoadG.details; 6219cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return isBogusAtom(lg->addr) || isBogusAtom(lg->alt) 6220cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj || isBogusAtom(lg->guard); 6221cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 622295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_Exit: 6223d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj return isBogusAtom(st->Ist.Exit.guard); 6224826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj case Ist_AbiHint: 62257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return isBogusAtom(st->Ist.AbiHint.base) 62267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || isBogusAtom(st->Ist.AbiHint.nia); 622721dc345ce861ac5a5686391b77659934c1d49a3esewardj case Ist_NoOp: 622829faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj case Ist_IMark: 622972d75132068882b52b67dddc9af85ffaae5ac14fsewardj case Ist_MBE: 6230bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj return False; 62311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ist_CAS: 62321c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj cas = st->Ist.CAS.details; 62331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return isBogusAtom(cas->addr) 62341c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj || (cas->expdHi ? isBogusAtom(cas->expdHi) : False) 62351c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj || isBogusAtom(cas->expdLo) 62361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj || (cas->dataHi ? isBogusAtom(cas->dataHi) : False) 62371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj || isBogusAtom(cas->dataLo); 6238db5907d7b94ce492f29a96c95e186fdcda23a149sewardj case Ist_LLSC: 6239db5907d7b94ce492f29a96c95e186fdcda23a149sewardj return isBogusAtom(st->Ist.LLSC.addr) 6240db5907d7b94ce492f29a96c95e186fdcda23a149sewardj || (st->Ist.LLSC.storedata 6241db5907d7b94ce492f29a96c95e186fdcda23a149sewardj ? isBogusAtom(st->Ist.LLSC.storedata) 6242db5907d7b94ce492f29a96c95e186fdcda23a149sewardj : False); 624395448075345dc73986042f6dc68eb464d02bc6a8sewardj default: 624495448075345dc73986042f6dc68eb464d02bc6a8sewardj unhandled: 624595448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIRStmt(st); 624695448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("hasBogusLiterals"); 624795448075345dc73986042f6dc68eb464d02bc6a8sewardj } 624895448075345dc73986042f6dc68eb464d02bc6a8sewardj} 6249e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 6250e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 62510b9d74abd0a663b530d290b2b788ddeda46e5400sewardjIRSB* MC_(instrument) ( VgCallbackClosure* closure, 62521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRSB* sb_in, 62533c0c94777f547bcb5eadbe8cb4328debf0f51875florian const VexGuestLayout* layout, 62543c0c94777f547bcb5eadbe8cb4328debf0f51875florian const VexGuestExtents* vge, 62553c0c94777f547bcb5eadbe8cb4328debf0f51875florian const VexArchInfo* archinfo_host, 6256d54babf82db303dfe43082bfe1af75d7b58b3267sewardj IRType gWordTy, IRType hWordTy ) 625795448075345dc73986042f6dc68eb464d02bc6a8sewardj{ 62587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Bool verboze = 0||False; 6259d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj Int i, j, first_stmt; 626095448075345dc73986042f6dc68eb464d02bc6a8sewardj IRStmt* st; 6261d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj MCEnv mce; 62621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRSB* sb_out; 6263d54babf82db303dfe43082bfe1af75d7b58b3267sewardj 6264d54babf82db303dfe43082bfe1af75d7b58b3267sewardj if (gWordTy != hWordTy) { 6265d54babf82db303dfe43082bfe1af75d7b58b3267sewardj /* We don't currently support this case. */ 6266d54babf82db303dfe43082bfe1af75d7b58b3267sewardj VG_(tool_panic)("host/guest word size mismatch"); 6267d54babf82db303dfe43082bfe1af75d7b58b3267sewardj } 626895448075345dc73986042f6dc68eb464d02bc6a8sewardj 62696cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj /* Check we're not completely nuts */ 62707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(UWord) == sizeof(void*)); 62717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(Word) == sizeof(void*)); 62727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(Addr) == sizeof(void*)); 62737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(ULong) == 8); 62747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(Long) == 8); 62757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(UInt) == 4); 62767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeof(Int) == 4); 62777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 62787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(MC_(clo_mc_level) >= 1 && MC_(clo_mc_level) <= 3); 62796cf40ffd6d17589c81b6fe6a0da6f4b6b83c4f80sewardj 62800b9d74abd0a663b530d290b2b788ddeda46e5400sewardj /* Set up SB */ 62811c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj sb_out = deepCopyIRSBExceptStmts(sb_in); 62821c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 62831c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* Set up the running environment. Both .sb and .tmpMap are 62841c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj modified as we go along. Note that tmps are added to both 62851c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj .sb->tyenv and .tmpMap together, so the valid index-set for 62861c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj those two arrays should always be identical. */ 62871c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj VG_(memset)(&mce, 0, sizeof(mce)); 62881c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mce.sb = sb_out; 62897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mce.trace = verboze; 629095448075345dc73986042f6dc68eb464d02bc6a8sewardj mce.layout = layout; 629195448075345dc73986042f6dc68eb464d02bc6a8sewardj mce.hWordTy = hWordTy; 6292d5204dcce510ae2bc6cc956c13cd4700980fe6d1sewardj mce.bogusLiterals = False; 62931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 629454eac25a54a255d5deaa228547d2ef145590929bsewardj /* Do expensive interpretation for Iop_Add32 and Iop_Add64 on 629554eac25a54a255d5deaa228547d2ef145590929bsewardj Darwin. 10.7 is mostly built with LLVM, which uses these for 629654eac25a54a255d5deaa228547d2ef145590929bsewardj bitfield inserts, and we get a lot of false errors if the cheap 629754eac25a54a255d5deaa228547d2ef145590929bsewardj interpretation is used, alas. Could solve this much better if 629854eac25a54a255d5deaa228547d2ef145590929bsewardj we knew which of such adds came from x86/amd64 LEA instructions, 629954eac25a54a255d5deaa228547d2ef145590929bsewardj since these are the only ones really needing the expensive 630054eac25a54a255d5deaa228547d2ef145590929bsewardj interpretation, but that would require some way to tag them in 630154eac25a54a255d5deaa228547d2ef145590929bsewardj the _toIR.c front ends, which is a lot of faffing around. So 630254eac25a54a255d5deaa228547d2ef145590929bsewardj for now just use the slow and blunt-instrument solution. */ 630354eac25a54a255d5deaa228547d2ef145590929bsewardj mce.useLLVMworkarounds = False; 630454eac25a54a255d5deaa228547d2ef145590929bsewardj# if defined(VGO_darwin) 630554eac25a54a255d5deaa228547d2ef145590929bsewardj mce.useLLVMworkarounds = True; 630654eac25a54a255d5deaa228547d2ef145590929bsewardj# endif 630754eac25a54a255d5deaa228547d2ef145590929bsewardj 63081c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj mce.tmpMap = VG_(newXA)( VG_(malloc), "mc.MC_(instrument).1", VG_(free), 63091c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj sizeof(TempMapEnt)); 6310d4dc5fc0e4091cead54ebbcdfddc60e0f3ff8081philippe VG_(hintSizeXA) (mce.tmpMap, sb_in->tyenv->types_used); 63111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj for (i = 0; i < sb_in->tyenv->types_used; i++) { 63121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt ent; 63131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.kind = Orig; 63141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.shadowV = IRTemp_INVALID; 63151c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent.shadowB = IRTemp_INVALID; 63161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj VG_(addToXA)( mce.tmpMap, &ent ); 63177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 63181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert( VG_(sizeXA)( mce.tmpMap ) == sb_in->tyenv->types_used ); 631995448075345dc73986042f6dc68eb464d02bc6a8sewardj 63202672faefb066656b3c757a711c7eda4189aa2c89sewardj if (MC_(clo_expensive_definedness_checks)) { 63219ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian /* For expensive definedness checking skip looking for bogus 63229ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian literals. */ 63239ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian mce.bogusLiterals = True; 63249ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian } else { 63259ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian /* Make a preliminary inspection of the statements, to see if there 63269ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian are any dodgy-looking literals. If there are, we generate 63279ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian extra-detailed (hence extra-expensive) instrumentation in 63289ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian places. Scan the whole bb even if dodgyness is found earlier, 63299ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian so that the flatness assertion is applied to all stmts. */ 63309ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian Bool bogus = False; 63319ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian 63329ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian for (i = 0; i < sb_in->stmts_used; i++) { 63339ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian st = sb_in->stmts[i]; 63349ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian tl_assert(st); 63359ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian tl_assert(isFlatIRStmt(st)); 63369ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian 63379ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian if (!bogus) { 63389ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian bogus = checkForBogusLiterals(st); 63399ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian if (0 && bogus) { 63409ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian VG_(printf)("bogus: "); 63419ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian ppIRStmt(st); 63429ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian VG_(printf)("\n"); 63439ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian } 63449ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian if (bogus) break; 634595448075345dc73986042f6dc68eb464d02bc6a8sewardj } 634695448075345dc73986042f6dc68eb464d02bc6a8sewardj } 63479ee20ebd0a2f2872b9fc4d93648e044ede2f2d87florian mce.bogusLiterals = bogus; 6348151b90d888b37cc8694684433cbed2ddc5fcd205sewardj } 6349151b90d888b37cc8694684433cbed2ddc5fcd205sewardj 6350a087148a278b59856ec2247361d1902524c68f95sewardj /* Copy verbatim any IR preamble preceding the first IMark */ 6351151b90d888b37cc8694684433cbed2ddc5fcd205sewardj 63521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(mce.sb == sb_out); 63531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(mce.sb != sb_in); 6354f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj 6355a087148a278b59856ec2247361d1902524c68f95sewardj i = 0; 63561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj while (i < sb_in->stmts_used && sb_in->stmts[i]->tag != Ist_IMark) { 6357a087148a278b59856ec2247361d1902524c68f95sewardj 63581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj st = sb_in->stmts[i]; 6359a087148a278b59856ec2247361d1902524c68f95sewardj tl_assert(st); 6360a087148a278b59856ec2247361d1902524c68f95sewardj tl_assert(isFlatIRStmt(st)); 6361a087148a278b59856ec2247361d1902524c68f95sewardj 63621c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj stmt( 'C', &mce, sb_in->stmts[i] ); 6363a087148a278b59856ec2247361d1902524c68f95sewardj i++; 6364a087148a278b59856ec2247361d1902524c68f95sewardj } 6365a087148a278b59856ec2247361d1902524c68f95sewardj 6366f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj /* Nasty problem. IR optimisation of the pre-instrumented IR may 6367f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj cause the IR following the preamble to contain references to IR 6368f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj temporaries defined in the preamble. Because the preamble isn't 6369f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj instrumented, these temporaries don't have any shadows. 6370f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj Nevertheless uses of them following the preamble will cause 6371f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj memcheck to generate references to their shadows. End effect is 6372f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj to cause IR sanity check failures, due to references to 6373f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj non-existent shadows. This is only evident for the complex 6374f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj preambles used for function wrapping on TOC-afflicted platforms 63756e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj (ppc64-linux). 6376f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj 6377f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj The following loop therefore scans the preamble looking for 6378f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj assignments to temporaries. For each one found it creates an 6379afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj assignment to the corresponding (V) shadow temp, marking it as 6380f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj 'defined'. This is the same resulting IR as if the main 6381f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj instrumentation loop before had been applied to the statement 6382f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj 'tmp = CONSTANT'. 6383afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj 6384afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj Similarly, if origin tracking is enabled, we must generate an 6385afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj assignment for the corresponding origin (B) shadow, claiming 6386afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj no-origin, as appropriate for a defined value. 6387f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj */ 6388f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj for (j = 0; j < i; j++) { 63891c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (sb_in->stmts[j]->tag == Ist_WrTmp) { 63907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* findShadowTmpV checks its arg is an original tmp; 6391f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj no need to assert that here. */ 63921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp tmp_o = sb_in->stmts[j]->Ist.WrTmp.tmp; 6393afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj IRTemp tmp_v = findShadowTmpV(&mce, tmp_o); 63941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType ty_v = typeOfIRTemp(sb_out->tyenv, tmp_v); 6395afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj assign( 'V', &mce, tmp_v, definedOfType( ty_v ) ); 6396afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj if (MC_(clo_mc_level) == 3) { 6397afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj IRTemp tmp_b = findShadowTmpB(&mce, tmp_o); 63981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(typeOfIRTemp(sb_out->tyenv, tmp_b) == Ity_I32); 6399afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj assign( 'B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */); 6400afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj } 6401f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj if (0) { 6402afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj VG_(printf)("create shadow tmp(s) for preamble tmp [%d] ty ", j); 6403afa617b9d5792ae31fc201b3549da3e3288bb37dsewardj ppIRType( ty_v ); 6404f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj VG_(printf)("\n"); 6405f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj } 6406f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj } 6407f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj } 6408f1962d3683b9bc0b8ba361e3d0194590fde7090bsewardj 6409a087148a278b59856ec2247361d1902524c68f95sewardj /* Iterate over the remaining stmts to generate instrumentation. */ 6410a087148a278b59856ec2247361d1902524c68f95sewardj 64111c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(sb_in->stmts_used > 0); 6412a087148a278b59856ec2247361d1902524c68f95sewardj tl_assert(i >= 0); 64131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(i < sb_in->stmts_used); 64141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(sb_in->stmts[i]->tag == Ist_IMark); 6415a087148a278b59856ec2247361d1902524c68f95sewardj 64161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj for (/* use current i*/; i < sb_in->stmts_used; i++) { 6417151b90d888b37cc8694684433cbed2ddc5fcd205sewardj 64181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj st = sb_in->stmts[i]; 64191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj first_stmt = sb_out->stmts_used; 6420e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 642195448075345dc73986042f6dc68eb464d02bc6a8sewardj if (verboze) { 64227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("\n"); 642395448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIRStmt(st); 64247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("\n"); 642595448075345dc73986042f6dc68eb464d02bc6a8sewardj } 6426e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 64271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (MC_(clo_mc_level) == 3) { 64281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* See comments on case Ist_CAS below. */ 64291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (st->tag != Ist_CAS) 64301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj schemeS( &mce, st ); 64311c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 64327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 643329faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj /* Generate instrumentation code for each stmt ... */ 643429faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj 643595448075345dc73986042f6dc68eb464d02bc6a8sewardj switch (st->tag) { 6436e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 64370b9d74abd0a663b530d290b2b788ddeda46e5400sewardj case Ist_WrTmp: 64387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign( 'V', &mce, findShadowTmpV(&mce, st->Ist.WrTmp.tmp), 64397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expr2vbits( &mce, st->Ist.WrTmp.data) ); 6440e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6441e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 644295448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_Put: 644395448075345dc73986042f6dc68eb464d02bc6a8sewardj do_shadow_PUT( &mce, 644495448075345dc73986042f6dc68eb464d02bc6a8sewardj st->Ist.Put.offset, 644595448075345dc73986042f6dc68eb464d02bc6a8sewardj st->Ist.Put.data, 6446434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian NULL /* shadow atom */, NULL /* guard */ ); 6447e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6448e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 644995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_PutI: 6450d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian do_shadow_PUTI( &mce, st->Ist.PutI.details); 6451e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6452e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 64532e595858903b80f29f271dc94e32a9e052bb4c8asewardj case Ist_Store: 64542e595858903b80f29f271dc94e32a9e052bb4c8asewardj do_shadow_Store( &mce, st->Ist.Store.end, 64552e595858903b80f29f271dc94e32a9e052bb4c8asewardj st->Ist.Store.addr, 0/* addr bias */, 64562e595858903b80f29f271dc94e32a9e052bb4c8asewardj st->Ist.Store.data, 64571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj NULL /* shadow data */, 64581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj NULL/*guard*/ ); 6459e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6460e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 6461cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_StoreG: 6462cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_shadow_StoreG( &mce, st->Ist.StoreG.details ); 6463cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 6464cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6465cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_LoadG: 6466cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_shadow_LoadG( &mce, st->Ist.LoadG.details ); 6467cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 6468cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 646995448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_Exit: 6470b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined( &mce, st->Ist.Exit.guard, NULL ); 6471e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6472e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 647329faa50dd7ea4d4a8aa3c82b299bb38880e19237sewardj case Ist_IMark: 64747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 64757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 64767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_NoOp: 647772d75132068882b52b67dddc9af85ffaae5ac14fsewardj case Ist_MBE: 6478bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj break; 6479bd598e1577f3e9c70978d2f7c77cbbd5af0c7ecdsewardj 648095448075345dc73986042f6dc68eb464d02bc6a8sewardj case Ist_Dirty: 648195448075345dc73986042f6dc68eb464d02bc6a8sewardj do_shadow_Dirty( &mce, st->Ist.Dirty.details ); 6482e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn break; 6483e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 6484826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj case Ist_AbiHint: 64857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj do_AbiHint( &mce, st->Ist.AbiHint.base, 64867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj st->Ist.AbiHint.len, 64877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj st->Ist.AbiHint.nia ); 6488826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj break; 6489826ec49ac9fcbc4f9bb1134d3b8827e4ee0f7687sewardj 64901c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj case Ist_CAS: 64911c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj do_shadow_CAS( &mce, st->Ist.CAS.details ); 64921c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* Note, do_shadow_CAS copies the CAS itself to the output 64931c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj block, because it needs to add instrumentation both 64941c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj before and after it. Hence skip the copy below. Also 64951c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj skip the origin-tracking stuff (call to schemeS) above, 64961c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj since that's all tangled up with it too; do_shadow_CAS 64971c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj does it all. */ 64981c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj break; 64991c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 6500db5907d7b94ce492f29a96c95e186fdcda23a149sewardj case Ist_LLSC: 6501db5907d7b94ce492f29a96c95e186fdcda23a149sewardj do_shadow_LLSC( &mce, 6502db5907d7b94ce492f29a96c95e186fdcda23a149sewardj st->Ist.LLSC.end, 6503db5907d7b94ce492f29a96c95e186fdcda23a149sewardj st->Ist.LLSC.result, 6504db5907d7b94ce492f29a96c95e186fdcda23a149sewardj st->Ist.LLSC.addr, 6505db5907d7b94ce492f29a96c95e186fdcda23a149sewardj st->Ist.LLSC.storedata ); 6506db5907d7b94ce492f29a96c95e186fdcda23a149sewardj break; 6507db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 6508e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn default: 650995448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 651095448075345dc73986042f6dc68eb464d02bc6a8sewardj ppIRStmt(st); 651195448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 651295448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(tool_panic)("memcheck: unhandled IRStmt"); 651395448075345dc73986042f6dc68eb464d02bc6a8sewardj 651495448075345dc73986042f6dc68eb464d02bc6a8sewardj } /* switch (st->tag) */ 651595448075345dc73986042f6dc68eb464d02bc6a8sewardj 65167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (0 && verboze) { 65171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj for (j = first_stmt; j < sb_out->stmts_used; j++) { 651895448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)(" "); 65191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ppIRStmt(sb_out->stmts[j]); 652095448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 652195448075345dc73986042f6dc68eb464d02bc6a8sewardj } 652295448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 6523e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 652495448075345dc73986042f6dc68eb464d02bc6a8sewardj 65251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* ... and finally copy the stmt itself to the output. Except, 65261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj skip the copy of IRCASs; see comments on case Ist_CAS 65271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj above. */ 65281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (st->tag != Ist_CAS) 65291c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj stmt('C', &mce, st); 6530e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 6531e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 653295448075345dc73986042f6dc68eb464d02bc6a8sewardj /* Now we need to complain if the jump target is undefined. */ 65331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj first_stmt = sb_out->stmts_used; 6534e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 653595448075345dc73986042f6dc68eb464d02bc6a8sewardj if (verboze) { 65361c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj VG_(printf)("sb_in->next = "); 65371c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ppIRExpr(sb_in->next); 653895448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n\n"); 653995448075345dc73986042f6dc68eb464d02bc6a8sewardj } 6540e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 6541b9e6d244e474c971ea88181de1f83a30057db9dasewardj complainIfUndefined( &mce, sb_in->next, NULL ); 6542e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 65437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (0 && verboze) { 65441c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj for (j = first_stmt; j < sb_out->stmts_used; j++) { 654595448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)(" "); 65461c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ppIRStmt(sb_out->stmts[j]); 654795448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 6548e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 654995448075345dc73986042f6dc68eb464d02bc6a8sewardj VG_(printf)("\n"); 6550e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 6551e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 65521c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* If this fails, there's been some serious snafu with tmp management, 65531c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj that should be investigated. */ 65541c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert( VG_(sizeXA)( mce.tmpMap ) == mce.sb->tyenv->types_used ); 65551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj VG_(deleteXA)( mce.tmpMap ); 65561c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 65571c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(mce.sb == sb_out); 65581c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return sb_out; 655995448075345dc73986042f6dc68eb464d02bc6a8sewardj} 6560e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 656181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/*------------------------------------------------------------*/ 656281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/*--- Post-tree-build final tidying ---*/ 656381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/*------------------------------------------------------------*/ 656481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 656581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/* This exploits the observation that Memcheck often produces 656681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj repeated conditional calls of the form 656781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 65687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Dirty G MC_(helperc_value_check0/1/4/8_fail)(UInt otag) 656981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 657081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj with the same guard expression G guarding the same helper call. 657181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj The second and subsequent calls are redundant. This usually 657281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj results from instrumentation of guest code containing multiple 657381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj memory references at different constant offsets from the same base 657481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj register. After optimisation of the instrumentation, you get a 657581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj test for the definedness of the base register for each memory 657681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj reference, which is kinda pointless. MC_(final_tidy) therefore 657781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj looks for such repeated calls and removes all but the first. */ 657881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 657981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/* A struct for recording which (helper, guard) pairs we have already 658081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj seen. */ 658181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardjtypedef 658281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj struct { void* entry; IRExpr* guard; } 658381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Pair; 658481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 658581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/* Return True if e1 and e2 definitely denote the same value (used to 658681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj compare guards). Return False if unknown; False is the safe 658781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj answer. Since guest registers and guest memory do not have the 658881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj SSA property we must return False if any Gets or Loads appear in 658981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj the expression. */ 659081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 659181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardjstatic Bool sameIRValue ( IRExpr* e1, IRExpr* e2 ) 659281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj{ 659381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (e1->tag != e2->tag) 659481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return False; 659581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj switch (e1->tag) { 659681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Const: 659781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return eqIRConst( e1->Iex.Const.con, e2->Iex.Const.con ); 659881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Binop: 659981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return e1->Iex.Binop.op == e2->Iex.Binop.op 660081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj && sameIRValue(e1->Iex.Binop.arg1, e2->Iex.Binop.arg1) 660181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj && sameIRValue(e1->Iex.Binop.arg2, e2->Iex.Binop.arg2); 660281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Unop: 660381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return e1->Iex.Unop.op == e2->Iex.Unop.op 660481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj && sameIRValue(e1->Iex.Unop.arg, e2->Iex.Unop.arg); 660581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_RdTmp: 660681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return e1->Iex.RdTmp.tmp == e2->Iex.RdTmp.tmp; 66075686b2d7e97a6f65e436531dac999a52a3d3dac9florian case Iex_ITE: 66085686b2d7e97a6f65e436531dac999a52a3d3dac9florian return sameIRValue( e1->Iex.ITE.cond, e2->Iex.ITE.cond ) 66095686b2d7e97a6f65e436531dac999a52a3d3dac9florian && sameIRValue( e1->Iex.ITE.iftrue, e2->Iex.ITE.iftrue ) 66105686b2d7e97a6f65e436531dac999a52a3d3dac9florian && sameIRValue( e1->Iex.ITE.iffalse, e2->Iex.ITE.iffalse ); 661181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Qop: 661281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Triop: 661381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_CCall: 661481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* be lazy. Could define equality for these, but they never 661581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj appear to be used. */ 661681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return False; 661781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Get: 661881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_GetI: 661981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Load: 662081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* be conservative - these may not give the same value each 662181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj time */ 662281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return False; 662381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj case Iex_Binder: 662481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* should never see this */ 662581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* fallthrough */ 662681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj default: 662781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj VG_(printf)("mc_translate.c: sameIRValue: unhandled: "); 662881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj ppIRExpr(e1); 662981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj VG_(tool_panic)("memcheck:sameIRValue"); 663081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return False; 663181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj } 663281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj} 663381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 663481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj/* See if 'pairs' already has an entry for (entry, guard). Return 663581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj True if so. If not, add an entry. */ 663681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 663781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardjstatic 663881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardjBool check_or_add ( XArray* /*of Pair*/ pairs, IRExpr* guard, void* entry ) 663981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj{ 664081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Pair p; 664181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Pair* pp; 664281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Int i, n = VG_(sizeXA)( pairs ); 664381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj for (i = 0; i < n; i++) { 664481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj pp = VG_(indexXA)( pairs, i ); 664581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (pp->entry == entry && sameIRValue(pp->guard, guard)) 664681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return True; 664781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj } 664881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj p.guard = guard; 664981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj p.entry = entry; 665081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj VG_(addToXA)( pairs, &p ); 665181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return False; 665281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj} 665381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 665411f3cc844c38a8388063230bbf7deb69fdf2b812florianstatic Bool is_helperc_value_checkN_fail ( const HChar* name ) 665581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj{ 665681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return 66577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 0==VG_(strcmp)(name, "MC_(helperc_value_check0_fail_no_o)") 66587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check1_fail_no_o)") 66597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check4_fail_no_o)") 66607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check8_fail_no_o)") 66617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check0_fail_w_o)") 66627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check1_fail_w_o)") 66637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check4_fail_w_o)") 66647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj || 0==VG_(strcmp)(name, "MC_(helperc_value_check8_fail_w_o)"); 666581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj} 666681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 666781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardjIRSB* MC_(final_tidy) ( IRSB* sb_in ) 666881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj{ 666981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Int i; 667081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj IRStmt* st; 667181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj IRDirty* di; 667281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj IRExpr* guard; 667381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj IRCallee* cee; 667481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj Bool alreadyPresent; 66759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* pairs = VG_(newXA)( VG_(malloc), "mc.ft.1", 66769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(free), sizeof(Pair) ); 667781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* Scan forwards through the statements. Each time a call to one 667881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj of the relevant helpers is seen, check if we have made a 667981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj previous call to the same helper using the same guard 668081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj expression, and if so, delete the call. */ 668181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj for (i = 0; i < sb_in->stmts_used; i++) { 668281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj st = sb_in->stmts[i]; 668381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj tl_assert(st); 668481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (st->tag != Ist_Dirty) 668581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj continue; 668681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj di = st->Ist.Dirty.details; 668781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj guard = di->guard; 66886c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian tl_assert(guard); 668981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (0) { ppIRExpr(guard); VG_(printf)("\n"); } 669081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj cee = di->cee; 669181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (!is_helperc_value_checkN_fail( cee->name )) 669281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj continue; 669381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj /* Ok, we have a call to helperc_value_check0/1/4/8_fail with 669481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj guard 'guard'. Check if we have already seen a call to this 669581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj function with the same guard. If so, delete it. If not, 669681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj add it to the set of calls we do know about. */ 669781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj alreadyPresent = check_or_add( pairs, guard, cee->addr ); 669881651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (alreadyPresent) { 669981651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj sb_in->stmts[i] = IRStmt_NoOp(); 670081651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj if (0) VG_(printf)("XX\n"); 670181651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj } 670281651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj } 670381651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj VG_(deleteXA)( pairs ); 670481651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj return sb_in; 670581651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj} 670681651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 670781651dc1ae8cc13a5c857a0fb4137304ed17aa43sewardj 67087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*------------------------------------------------------------*/ 67097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Origin tracking stuff ---*/ 67107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*------------------------------------------------------------*/ 67117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 67121c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj/* Almost identical to findShadowTmpV. */ 67137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRTemp findShadowTmpB ( MCEnv* mce, IRTemp orig ) 67147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 67151c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj TempMapEnt* ent; 67161c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* VG_(indexXA) range-checks 'orig', hence no need to check 67171c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj here. */ 67181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 67191c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 67201c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (ent->shadowB == IRTemp_INVALID) { 67211c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp tmpB 67221c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj = newTemp( mce, Ity_I32, BSh ); 67231c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj /* newTemp may cause mce->tmpMap to resize, hence previous results 67241c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj from VG_(indexXA) are invalid. */ 67251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig ); 67261c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->kind == Orig); 67271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(ent->shadowB == IRTemp_INVALID); 67281c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj ent->shadowB = tmpB; 67297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 67301c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj return ent->shadowB; 67317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 67327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 67337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 ) 67347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 67357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew( 'B', mce, Ity_I32, binop(Iop_Max32U, b1, b2) ); 67367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 67377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 6738cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6739cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Make a guarded origin load, with no special handling in the 6740cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj didn't-happen case. A GUARD of NULL is assumed to mean "always 6741cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj True". 6742cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6743cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj Generate IR to do a shadow origins load from BASEADDR+OFFSET and 6744cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return the otag. The loaded size is SZB. If GUARD evaluates to 6745cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj False at run time then the returned otag is zero. 6746cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 6747cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic IRAtom* gen_guarded_load_b ( MCEnv* mce, Int szB, 6748cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* baseaddr, 6749cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj Int offset, IRExpr* guard ) 67507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 67517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void* hFun; 67526bd9dc18c043927c1196caba20a327238a179c42florian const HChar* hName; 67537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRTemp bTmp; 67547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRDirty* di; 67551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr ); 67567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64; 67577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* ea = baseaddr; 67587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (offset != 0) { 67597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* off = aTy == Ity_I32 ? mkU32( offset ) 67607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj : mkU64( (Long)(Int)offset ); 67617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off)); 67627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 67631c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj bTmp = newTemp(mce, mce->hWordTy, BSh); 67647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 67657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj switch (szB) { 67667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 1: hFun = (void*)&MC_(helperc_b_load1); 67677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_load1)"; 67687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 67697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 2: hFun = (void*)&MC_(helperc_b_load2); 67707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_load2)"; 67717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 67727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 4: hFun = (void*)&MC_(helperc_b_load4); 67737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_load4)"; 67747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 67757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 8: hFun = (void*)&MC_(helperc_b_load8); 67767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_load8)"; 67777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 67787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 16: hFun = (void*)&MC_(helperc_b_load16); 67797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_load16)"; 67807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 678145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case 32: hFun = (void*)&MC_(helperc_b_load32); 678245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hName = "MC_(helperc_b_load32)"; 678345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj break; 67847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 67857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("mc_translate.c: gen_load_b: unhandled szB == %d\n", szB); 67867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(0); 67877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 67887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj di = unsafeIRDirty_1_N( 67897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj bTmp, 1/*regparms*/, hName, VG_(fnptr_to_fnentry)( hFun ), 67907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mkIRExprVec_1( ea ) 67917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ); 6792cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj if (guard) { 6793cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj di->guard = guard; 6794cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* Ideally the didn't-happen return value here would be 6795cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj all-zeroes (unknown-origin), so it'd be harmless if it got 6796ad4e979f408239dabbaae955d8ffcb84a51a5c85florian used inadvertently. We slum it out with the IR-mandated 6797cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj default value (0b01 repeating, 0x55 etc) as that'll probably 6798cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj trump all legitimate otags via Max32, and it's pretty 6799cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj obviously bogus. */ 6800cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 68017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* no need to mess with any annotations. This call accesses 68027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj neither guest state nor guest memory. */ 68037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'B', mce, IRStmt_Dirty(di) ); 68047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (mce->hWordTy == Ity_I64) { 68057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* 64-bit host */ 68061c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRTemp bTmp32 = newTemp(mce, Ity_I32, BSh); 68077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign( 'B', mce, bTmp32, unop(Iop_64to32, mkexpr(bTmp)) ); 68087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkexpr(bTmp32); 68097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 68107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* 32-bit host */ 68117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkexpr(bTmp); 68127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 68137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 68141c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj 6815434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 6816cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate IR to do a shadow origins load from BASEADDR+OFFSET. The 6817cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj loaded size is SZB. The load is regarded as unconditional (always 6818cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj happens). 6819cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 6820cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic IRAtom* gen_load_b ( MCEnv* mce, Int szB, IRAtom* baseaddr, 6821cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj Int offset ) 6822cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 6823cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj return gen_guarded_load_b(mce, szB, baseaddr, offset, NULL/*guard*/); 6824cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 6825434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 6826434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 6827cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* The most general handler for guarded origin loads. A GUARD of NULL 6828cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj is assumed to mean "always True". 6829434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 6830cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj Generate IR to do a shadow origin load from ADDR+BIAS and return 6831cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj the B bits. The loaded type is TY. If GUARD evaluates to False at 6832cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj run time then the returned B bits are simply BALT instead. 6833cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj*/ 6834cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic 6835cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjIRAtom* expr2ori_Load_guarded_General ( MCEnv* mce, 6836cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRType ty, 6837cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* addr, UInt bias, 6838cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* guard, IRAtom* balt ) 6839cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 6840cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* If the guard evaluates to True, this will hold the loaded 6841cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj origin. If the guard evaluates to False, this will be zero, 6842cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj meaning "unknown origin", in which case we will have to replace 68435686b2d7e97a6f65e436531dac999a52a3d3dac9florian it using an ITE below. */ 6844cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* iftrue 6845cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = assignNew('B', mce, Ity_I32, 6846cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj gen_guarded_load_b(mce, sizeofIRType(ty), 6847cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj addr, bias, guard)); 6848cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* These are the bits we will return if the load doesn't take 6849cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj place. */ 6850cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* iffalse 6851cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = balt; 68525686b2d7e97a6f65e436531dac999a52a3d3dac9florian /* Prepare the cond for the ITE. Convert a NULL cond into 6853cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj something that iropt knows how to fold out later. */ 6854cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* cond 6855cc9616506450cb02944b62dc07774c29462bfefcsewardj = guard == NULL ? mkU1(1) : guard; 6856cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* And assemble the final result. */ 68575686b2d7e97a6f65e436531dac999a52a3d3dac9florian return assignNew('B', mce, Ity_I32, IRExpr_ITE(cond, iftrue, iffalse)); 6858cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 6859cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6860cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 6861cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate a shadow origins store. guard :: Ity_I1 controls whether 6862cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj the store really happens; NULL means it unconditionally does. */ 68637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void gen_store_b ( MCEnv* mce, Int szB, 68641c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* baseaddr, Int offset, IRAtom* dataB, 68651c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRAtom* guard ) 68667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 68677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj void* hFun; 68686bd9dc18c043927c1196caba20a327238a179c42florian const HChar* hName; 68697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRDirty* di; 68701c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr ); 68717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64; 68727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* ea = baseaddr; 68731c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) { 68741c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(isOriginalAtom(mce, guard)); 68751c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1); 68761c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 68777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (offset != 0) { 68787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* off = aTy == Ity_I32 ? mkU32( offset ) 68797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj : mkU64( (Long)(Int)offset ); 68807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off)); 68817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 68827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (mce->hWordTy == Ity_I64) 68837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj dataB = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, dataB)); 68847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 68857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj switch (szB) { 68867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 1: hFun = (void*)&MC_(helperc_b_store1); 68877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_store1)"; 68887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 68897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 2: hFun = (void*)&MC_(helperc_b_store2); 68907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_store2)"; 68917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 68927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 4: hFun = (void*)&MC_(helperc_b_store4); 68937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_store4)"; 68947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 68957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 8: hFun = (void*)&MC_(helperc_b_store8); 68967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_store8)"; 68977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 68987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case 16: hFun = (void*)&MC_(helperc_b_store16); 68997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName = "MC_(helperc_b_store16)"; 69007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 690145fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj case 32: hFun = (void*)&MC_(helperc_b_store32); 690245fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj hName = "MC_(helperc_b_store32)"; 690345fa9f4bd1819c7ac0d9469df4e35cee0c130153sewardj break; 69047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 69057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(0); 69067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 69077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj di = unsafeIRDirty_0_N( 2/*regparms*/, 69087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj hName, VG_(fnptr_to_fnentry)( hFun ), 69097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mkIRExprVec_2( ea, dataB ) 69107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ); 69117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* no need to mess with any annotations. This call accesses 69127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj neither guest state nor guest memory. */ 69131c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj if (guard) di->guard = guard; 69147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'B', mce, IRStmt_Dirty(di) ); 69157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 69167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 69177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRAtom* narrowTo32 ( MCEnv* mce, IRAtom* e ) { 69181c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType eTy = typeOfIRExpr(mce->sb->tyenv, e); 69197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (eTy == Ity_I64) 69207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew( 'B', mce, Ity_I32, unop(Iop_64to32, e) ); 69217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (eTy == Ity_I32) 69227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return e; 69237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(0); 69247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 69257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 69267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRAtom* zWidenFrom32 ( MCEnv* mce, IRType dstTy, IRAtom* e ) { 69271c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj IRType eTy = typeOfIRExpr(mce->sb->tyenv, e); 69287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(eTy == Ity_I32); 69297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (dstTy == Ity_I64) 69307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, e) ); 69317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(0); 69327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 69337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 6934db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 69357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic IRAtom* schemeE ( MCEnv* mce, IRExpr* e ) 69367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 69377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(MC_(clo_mc_level) == 3); 69387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 69397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj switch (e->tag) { 69407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 69417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_GetI: { 69427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRRegArray* descr_b; 69437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom *t1, *t2, *t3, *t4; 69447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRRegArray* descr = e->Iex.GetI.descr; 69457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRType equivIntTy 69467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = MC_(get_otrack_reg_array_equiv_int_type)(descr); 69477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* If this array is unshadowable for whatever reason, use the 69487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj usual approximation. */ 69497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (equivIntTy == Ity_INVALID) 69507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkU32(0); 69517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeofIRType(equivIntTy) >= 4); 69527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy)); 69537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj descr_b = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB, 69547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj equivIntTy, descr->nElems ); 69557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Do a shadow indexed get of the same size, giving t1. Take 69567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the bottom 32 bits of it, giving t2. Compute into t3 the 69577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj origin for the index (almost certainly zero, but there's 69587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj no harm in being completely general here, since iropt will 69597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj remove any useless code), and fold it in, giving a final 69607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj value t4. */ 69617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t1 = assignNew( 'B', mce, equivIntTy, 69627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRExpr_GetI( descr_b, e->Iex.GetI.ix, 69637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj e->Iex.GetI.bias )); 69647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t2 = narrowTo32( mce, t1 ); 69657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t3 = schemeE( mce, e->Iex.GetI.ix ); 69667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t4 = gen_maxU32( mce, t2, t3 ); 69677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return t4; 69687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 69697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_CCall: { 69707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Int i; 69717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* here; 69727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRExpr** args = e->Iex.CCall.args; 69737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* curr = mkU32(0); 69747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj for (i = 0; args[i]; i++) { 69757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(i < 32); 69767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(isOriginalAtom(mce, args[i])); 69777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Only take notice of this arg if the callee's 69787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj mc-exclusion mask does not say it is to be excluded. */ 69797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (e->Iex.CCall.cee->mcx_mask & (1<<i)) { 69807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* the arg is to be excluded from definedness checking. 69817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Do nothing. */ 69827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (0) VG_(printf)("excluding %s(%d)\n", 69837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj e->Iex.CCall.cee->name, i); 69847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 69857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* calculate the arg's definedness, and pessimistically 69867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj merge it in. */ 69877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj here = schemeE( mce, args[i] ); 69887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj curr = gen_maxU32( mce, curr, here ); 69897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 69907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 69917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return curr; 69927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 69937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Load: { 69947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Int dszB; 69957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj dszB = sizeofIRType(e->Iex.Load.ty); 69967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* assert that the B value for the address is already 69977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj available (somewhere) */ 69987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(isIRAtom(e->Iex.Load.addr)); 69997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(mce->hWordTy == Ity_I32 || mce->hWordTy == Ity_I64); 70007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return gen_load_b( mce, dszB, e->Iex.Load.addr, 0 ); 70017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70025686b2d7e97a6f65e436531dac999a52a3d3dac9florian case Iex_ITE: { 70035686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRAtom* b1 = schemeE( mce, e->Iex.ITE.cond ); 70045686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRAtom* b3 = schemeE( mce, e->Iex.ITE.iftrue ); 700507bfda2113275e92f0eacf9aaf5d6944a75fe86esewardj IRAtom* b2 = schemeE( mce, e->Iex.ITE.iffalse ); 70067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return gen_maxU32( mce, b1, gen_maxU32( mce, b2, b3 )); 70077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Qop: { 7009e2ab2974c8bcaf3863956ba2d5368092a54e0703florian IRAtom* b1 = schemeE( mce, e->Iex.Qop.details->arg1 ); 7010e2ab2974c8bcaf3863956ba2d5368092a54e0703florian IRAtom* b2 = schemeE( mce, e->Iex.Qop.details->arg2 ); 7011e2ab2974c8bcaf3863956ba2d5368092a54e0703florian IRAtom* b3 = schemeE( mce, e->Iex.Qop.details->arg3 ); 7012e2ab2974c8bcaf3863956ba2d5368092a54e0703florian IRAtom* b4 = schemeE( mce, e->Iex.Qop.details->arg4 ); 70137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return gen_maxU32( mce, gen_maxU32( mce, b1, b2 ), 70147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj gen_maxU32( mce, b3, b4 ) ); 70157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Triop: { 701726441746bda788fc0327527a62427ca562f25311florian IRAtom* b1 = schemeE( mce, e->Iex.Triop.details->arg1 ); 701826441746bda788fc0327527a62427ca562f25311florian IRAtom* b2 = schemeE( mce, e->Iex.Triop.details->arg2 ); 701926441746bda788fc0327527a62427ca562f25311florian IRAtom* b3 = schemeE( mce, e->Iex.Triop.details->arg3 ); 70207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return gen_maxU32( mce, b1, gen_maxU32( mce, b2, b3 ) ); 70217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Binop: { 7023afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj switch (e->Iex.Binop.op) { 7024afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ8: case Iop_CasCmpNE8: 7025afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ16: case Iop_CasCmpNE16: 7026afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ32: case Iop_CasCmpNE32: 7027afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj case Iop_CasCmpEQ64: case Iop_CasCmpNE64: 7028afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /* Just say these all produce a defined result, 7029afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj regardless of their arguments. See 7030afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj COMMENT_ON_CasCmpEQ in this file. */ 7031afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj return mkU32(0); 7032afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj default: { 7033afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IRAtom* b1 = schemeE( mce, e->Iex.Binop.arg1 ); 7034afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj IRAtom* b2 = schemeE( mce, e->Iex.Binop.arg2 ); 7035afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj return gen_maxU32( mce, b1, b2 ); 7036afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj } 7037afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj } 7038afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj tl_assert(0); 7039afed4c5c73996f3039bf7dddc9cbe3fa105b68f9sewardj /*NOTREACHED*/ 70407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Unop: { 70427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom* b1 = schemeE( mce, e->Iex.Unop.arg ); 70437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return b1; 70447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Const: 70467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkU32(0); 70477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_RdTmp: 70487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkexpr( findShadowTmpB( mce, e->Iex.RdTmp.tmp )); 70497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Iex_Get: { 70507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Int b_offset = MC_(get_otrack_shadow_offset)( 70517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj e->Iex.Get.offset, 70527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj sizeofIRType(e->Iex.Get.ty) 70537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ); 70547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(b_offset >= -1 70557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && b_offset <= mce->layout->total_sizeB -4); 70567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (b_offset >= 0) { 70577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* FIXME: this isn't an atom! */ 70587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return IRExpr_Get( b_offset + 2*mce->layout->total_sizeB, 70597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Ity_I32 ); 70607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj return mkU32(0); 70627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 70647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("mc_translate.c: schemeE: unhandled: "); 70657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ppIRExpr(e); 70667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(tool_panic)("memcheck:schemeE"); 70677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 70697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 7070db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 70717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void do_origins_Dirty ( MCEnv* mce, IRDirty* d ) 70727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 70737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj // This is a hacked version of do_shadow_Dirty 70742eecb74d4a8816485c97ae8e535ce25511460bc8sewardj Int i, k, n, toDo, gSz, gOff; 70757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom *here, *curr; 70767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRTemp dst; 70777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 70787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* First check the guard. */ 70797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj curr = schemeE( mce, d->guard ); 70807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 70817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Now round up all inputs and maxU32 over them. */ 70827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 7083434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian /* Inputs: unmasked args 7084434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian Note: arguments are evaluated REGARDLESS of the guard expression */ 70857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj for (i = 0; d->args[i]; i++) { 708621a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj IRAtom* arg = d->args[i]; 708721a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj if ( (d->cee->mcx_mask & (1<<i)) 7088a5c3ecb923e27dcd995ba763d436b477e1e2a61eflorian || UNLIKELY(is_IRExpr_VECRET_or_BBPTR(arg)) ) { 70897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* ignore this arg */ 70907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } else { 709121a5f8cd6b05e19a644ee9a9f8623f0be1d4badcsewardj here = schemeE( mce, arg ); 70927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj curr = gen_maxU32( mce, curr, here ); 70937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 70957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 70967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Inputs: guest state that we read. */ 70977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj for (i = 0; i < d->nFxState; i++) { 70987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(d->fxState[i].fx != Ifx_None); 70997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->fxState[i].fx == Ifx_Write) 71007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj continue; 71017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71022eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Enumerate the described state segments */ 71032eecb74d4a8816485c97ae8e535ce25511460bc8sewardj for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { 71042eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; 71052eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz = d->fxState[i].size; 71062eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 71072eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Ignore any sections marked as 'always defined'. */ 71082eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (isAlwaysDefd(mce, gOff, gSz)) { 71092eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (0) 71102eecb74d4a8816485c97ae8e535ce25511460bc8sewardj VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", 71112eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff, gSz); 71122eecb74d4a8816485c97ae8e535ce25511460bc8sewardj continue; 71132eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 71147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71152eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* This state element is read or modified. So we need to 71162eecb74d4a8816485c97ae8e535ce25511460bc8sewardj consider it. If larger than 4 bytes, deal with it in 71172eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 4-byte chunks. */ 71182eecb74d4a8816485c97ae8e535ce25511460bc8sewardj while (True) { 71192eecb74d4a8816485c97ae8e535ce25511460bc8sewardj Int b_offset; 71202eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tl_assert(gSz >= 0); 71212eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (gSz == 0) break; 71222eecb74d4a8816485c97ae8e535ce25511460bc8sewardj n = gSz <= 4 ? gSz : 4; 71232eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* update 'curr' with maxU32 of the state slice 71242eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff .. gOff+n-1 */ 71252eecb74d4a8816485c97ae8e535ce25511460bc8sewardj b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); 71262eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (b_offset != -1) { 7127434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian /* Observe the guard expression. If it is false use 0, i.e. 7128434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian nothing is known about the origin */ 7129434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRAtom *cond, *iffalse, *iftrue; 7130434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian 7131cc9616506450cb02944b62dc07774c29462bfefcsewardj cond = assignNew( 'B', mce, Ity_I1, d->guard); 7132434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian iffalse = mkU32(0); 7133434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian iftrue = assignNew( 'B', mce, Ity_I32, 7134434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian IRExpr_Get(b_offset 7135434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian + 2*mce->layout->total_sizeB, 7136434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian Ity_I32)); 7137434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian here = assignNew( 'B', mce, Ity_I32, 71385686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRExpr_ITE(cond, iftrue, iffalse)); 71392eecb74d4a8816485c97ae8e535ce25511460bc8sewardj curr = gen_maxU32( mce, curr, here ); 71402eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 71412eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz -= n; 71422eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff += n; 71437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Inputs: memory */ 71487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->mFx != Ifx_None) { 71507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Because we may do multiple shadow loads/stores from the same 71517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj base address, it's best to do a single test of its 71527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj definedness right now. Post-instrumentation optimisation 71537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj should remove all but this test. */ 71547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(d->mAddr); 71557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj here = schemeE( mce, d->mAddr ); 71567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj curr = gen_maxU32( mce, curr, here ); 71577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Deal with memory inputs (reads or modifies) */ 71607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) { 71617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj toDo = d->mSize; 71627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* chew off 32-bit chunks. We don't care about the endianness 71637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj since it's all going to be condensed down to a single bit, 71647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj but nevertheless choose an endianness which is hopefully 71657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj native to the platform. */ 71667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj while (toDo >= 4) { 7167434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian here = gen_guarded_load_b( mce, 4, d->mAddr, d->mSize - toDo, 7168434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 71697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj curr = gen_maxU32( mce, curr, here ); 71707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj toDo -= 4; 71717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71728c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj /* handle possible 16-bit excess */ 71738c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj while (toDo >= 2) { 7174434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian here = gen_guarded_load_b( mce, 2, d->mAddr, d->mSize - toDo, 7175434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 71768c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj curr = gen_maxU32( mce, curr, here ); 71778c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj toDo -= 2; 71788c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj } 7179cda994be0e7356b10ad5771ffec348e42569762fflorian /* chew off the remaining 8-bit chunk, if any */ 7180cda994be0e7356b10ad5771ffec348e42569762fflorian if (toDo == 1) { 7181434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian here = gen_guarded_load_b( mce, 1, d->mAddr, d->mSize - toDo, 7182434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 7183cda994be0e7356b10ad5771ffec348e42569762fflorian curr = gen_maxU32( mce, curr, here ); 7184cda994be0e7356b10ad5771ffec348e42569762fflorian toDo -= 1; 7185cda994be0e7356b10ad5771ffec348e42569762fflorian } 7186cda994be0e7356b10ad5771ffec348e42569762fflorian tl_assert(toDo == 0); 71877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Whew! So curr is a 32-bit B-value which should give an origin 71907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj of some use if any of the inputs to the helper are undefined. 71917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Now we need to re-distribute the results to all destinations. */ 71927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Outputs: the destination temporary, if there is one. */ 71947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->tmp != IRTemp_INVALID) { 71957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj dst = findShadowTmpB(mce, d->tmp); 71967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign( 'V', mce, dst, curr ); 71977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 71987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 71997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Outputs: guest state that we write or modify. */ 72007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj for (i = 0; i < d->nFxState; i++) { 72017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(d->fxState[i].fx != Ifx_None); 72027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->fxState[i].fx == Ifx_Read) 72037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj continue; 72047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 72052eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Enumerate the described state segments */ 72062eecb74d4a8816485c97ae8e535ce25511460bc8sewardj for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { 72072eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; 72082eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz = d->fxState[i].size; 72092eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 72102eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Ignore any sections marked as 'always defined'. */ 72112eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (isAlwaysDefd(mce, gOff, gSz)) 72122eecb74d4a8816485c97ae8e535ce25511460bc8sewardj continue; 72132eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 72142eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* This state element is written or modified. So we need to 72152eecb74d4a8816485c97ae8e535ce25511460bc8sewardj consider it. If larger than 4 bytes, deal with it in 72162eecb74d4a8816485c97ae8e535ce25511460bc8sewardj 4-byte chunks. */ 72172eecb74d4a8816485c97ae8e535ce25511460bc8sewardj while (True) { 72182eecb74d4a8816485c97ae8e535ce25511460bc8sewardj Int b_offset; 72192eecb74d4a8816485c97ae8e535ce25511460bc8sewardj tl_assert(gSz >= 0); 72202eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (gSz == 0) break; 72212eecb74d4a8816485c97ae8e535ce25511460bc8sewardj n = gSz <= 4 ? gSz : 4; 72222eecb74d4a8816485c97ae8e535ce25511460bc8sewardj /* Write 'curr' to the state slice gOff .. gOff+n-1 */ 72232eecb74d4a8816485c97ae8e535ce25511460bc8sewardj b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); 72242eecb74d4a8816485c97ae8e535ce25511460bc8sewardj if (b_offset != -1) { 72256c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian 72266c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian /* If the guard expression evaluates to false we simply Put 72276c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian the value that is already stored in the guest state slot */ 72286c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian IRAtom *cond, *iffalse; 72296c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian 7230cc9616506450cb02944b62dc07774c29462bfefcsewardj cond = assignNew('B', mce, Ity_I1, 7231cc9616506450cb02944b62dc07774c29462bfefcsewardj d->guard); 72326c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian iffalse = assignNew('B', mce, Ity_I32, 72336c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian IRExpr_Get(b_offset + 72346c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian 2*mce->layout->total_sizeB, 72356c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian Ity_I32)); 72366c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian curr = assignNew('V', mce, Ity_I32, 72375686b2d7e97a6f65e436531dac999a52a3d3dac9florian IRExpr_ITE(cond, curr, iffalse)); 72386c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian 72392eecb74d4a8816485c97ae8e535ce25511460bc8sewardj stmt( 'B', mce, IRStmt_Put(b_offset 72406c0aa2cf8701e2ab6c4cc69db30654c24afc7dd5florian + 2*mce->layout->total_sizeB, 72412eecb74d4a8816485c97ae8e535ce25511460bc8sewardj curr )); 72422eecb74d4a8816485c97ae8e535ce25511460bc8sewardj } 72432eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gSz -= n; 72442eecb74d4a8816485c97ae8e535ce25511460bc8sewardj gOff += n; 72457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 72467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 72477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 72487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 72497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Outputs: memory that we write or modify. Same comments about 72507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj endianness as above apply. */ 72517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) { 72527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj toDo = d->mSize; 72537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* chew off 32-bit chunks */ 72547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj while (toDo >= 4) { 72551c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj gen_store_b( mce, 4, d->mAddr, d->mSize - toDo, curr, 7256434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 72577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj toDo -= 4; 72587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 72598c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj /* handle possible 16-bit excess */ 72608c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj while (toDo >= 2) { 7261cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj gen_store_b( mce, 2, d->mAddr, d->mSize - toDo, curr, 7262cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj d->guard ); 72638c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj toDo -= 2; 72648c93fcc1247c3c9fc3ac0617c607825a27c46c9dsewardj } 7265cda994be0e7356b10ad5771ffec348e42569762fflorian /* chew off the remaining 8-bit chunk, if any */ 7266cda994be0e7356b10ad5771ffec348e42569762fflorian if (toDo == 1) { 7267cda994be0e7356b10ad5771ffec348e42569762fflorian gen_store_b( mce, 1, d->mAddr, d->mSize - toDo, curr, 7268434ffae63b5e5460c0475dc24cd0383bc63fe1b8florian d->guard ); 7269cda994be0e7356b10ad5771ffec348e42569762fflorian toDo -= 1; 7270cda994be0e7356b10ad5771ffec348e42569762fflorian } 7271cda994be0e7356b10ad5771ffec348e42569762fflorian tl_assert(toDo == 0); 72727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 72737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 72747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 7275db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 7276cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate IR for origin shadowing for a general guarded store. */ 7277cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_origins_Store_guarded ( MCEnv* mce, 7278cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IREndness stEnd, 7279cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRExpr* stAddr, 7280cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRExpr* stData, 7281cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRExpr* guard ) 7282db5907d7b94ce492f29a96c95e186fdcda23a149sewardj{ 7283db5907d7b94ce492f29a96c95e186fdcda23a149sewardj Int dszB; 7284db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRAtom* dataB; 7285db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* assert that the B value for the address is already available 7286db5907d7b94ce492f29a96c95e186fdcda23a149sewardj (somewhere), since the call to schemeE will want to see it. 7287db5907d7b94ce492f29a96c95e186fdcda23a149sewardj XXXX how does this actually ensure that?? */ 7288db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(isIRAtom(stAddr)); 7289db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(isIRAtom(stData)); 7290db5907d7b94ce492f29a96c95e186fdcda23a149sewardj dszB = sizeofIRType( typeOfIRExpr(mce->sb->tyenv, stData ) ); 7291db5907d7b94ce492f29a96c95e186fdcda23a149sewardj dataB = schemeE( mce, stData ); 7292cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj gen_store_b( mce, dszB, stAddr, 0/*offset*/, dataB, guard ); 7293cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 7294cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7295cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7296cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* Generate IR for origin shadowing for a plain store. */ 7297cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_origins_Store_plain ( MCEnv* mce, 7298cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IREndness stEnd, 7299cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRExpr* stAddr, 7300cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRExpr* stData ) 7301cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 7302cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_Store_guarded ( mce, stEnd, stAddr, stData, 7303cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj NULL/*guard*/ ); 7304cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 7305cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7306cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7307cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj/* ---- Dealing with LoadG/StoreG (not entirely simple) ---- */ 7308cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7309cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_origins_StoreG ( MCEnv* mce, IRStoreG* sg ) 7310cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 7311cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_Store_guarded( mce, sg->end, sg->addr, 7312cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj sg->data, sg->guard ); 7313cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj} 7314cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7315cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardjstatic void do_origins_LoadG ( MCEnv* mce, IRLoadG* lg ) 7316cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj{ 7317cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRType loadedTy = Ity_INVALID; 7318cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj switch (lg->cvt) { 7319290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_IdentV128: loadedTy = Ity_V128; break; 7320290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_Ident64: loadedTy = Ity_I64; break; 7321290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_Ident32: loadedTy = Ity_I32; break; 7322290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_16Uto32: loadedTy = Ity_I16; break; 7323290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_16Sto32: loadedTy = Ity_I16; break; 7324290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_8Uto32: loadedTy = Ity_I8; break; 7325290b9cabbd2b2c42db10cd79921403cc231e4f7csewardj case ILGop_8Sto32: loadedTy = Ity_I8; break; 7326cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj default: VG_(tool_panic)("schemeS.IRLoadG"); 7327cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj } 7328cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* ori_alt 7329cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = schemeE( mce,lg->alt ); 7330cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj IRAtom* ori_final 7331cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj = expr2ori_Load_guarded_General(mce, loadedTy, 7332cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj lg->addr, 0/*addr bias*/, 7333cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj lg->guard, ori_alt ); 7334cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj /* And finally, bind the origin to the destination temporary. */ 7335cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj assign( 'B', mce, findShadowTmpB(mce, lg->dst), ori_final ); 7336db5907d7b94ce492f29a96c95e186fdcda23a149sewardj} 7337db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 7338db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 73397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void schemeS ( MCEnv* mce, IRStmt* st ) 73407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{ 73417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(MC_(clo_mc_level) == 3); 73427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 73437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj switch (st->tag) { 73447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 73457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_AbiHint: 73467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* The value-check instrumenter handles this - by arranging 73477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj to pass the address of the next instruction to 73487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj MC_(helperc_MAKE_STACK_UNINIT). This is all that needs to 73497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj happen for origin tracking w.r.t. AbiHints. So there is 73507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj nothing to do here. */ 73517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 73527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 73537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_PutI: { 7354d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian IRPutI *puti = st->Ist.PutI.details; 73557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRRegArray* descr_b; 73567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRAtom *t1, *t2, *t3, *t4; 7357d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian IRRegArray* descr = puti->descr; 73587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj IRType equivIntTy 73597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = MC_(get_otrack_reg_array_equiv_int_type)(descr); 73607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* If this array is unshadowable for whatever reason, 73617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj generate no code. */ 73627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (equivIntTy == Ity_INVALID) 73637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 73647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeofIRType(equivIntTy) >= 4); 73657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy)); 73667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj descr_b 73677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB, 73687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj equivIntTy, descr->nElems ); 73697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Compute a value to Put - the conjoinment of the origin for 73707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the data to be Put-ted (obviously) and of the index value 73717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj (not so obviously). */ 7372d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian t1 = schemeE( mce, puti->data ); 7373d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian t2 = schemeE( mce, puti->ix ); 73747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t3 = gen_maxU32( mce, t1, t2 ); 73757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj t4 = zWidenFrom32( mce, equivIntTy, t3 ); 7376d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian stmt( 'B', mce, IRStmt_PutI( mkIRPutI(descr_b, puti->ix, 7377d39b02261c40ae7b51bd2cdf56f8abf93c87bd46florian puti->bias, t4) )); 73787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 73797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 7380db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 73817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_Dirty: 73827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj do_origins_Dirty( mce, st->Ist.Dirty.details ); 73837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 7384db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 7385db5907d7b94ce492f29a96c95e186fdcda23a149sewardj case Ist_Store: 7386cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_Store_plain( mce, st->Ist.Store.end, 7387cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj st->Ist.Store.addr, 7388cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj st->Ist.Store.data ); 7389cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 7390cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7391cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_StoreG: 7392cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_StoreG( mce, st->Ist.StoreG.details ); 7393cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj break; 7394cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj 7395cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj case Ist_LoadG: 7396cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_LoadG( mce, st->Ist.LoadG.details ); 7397db5907d7b94ce492f29a96c95e186fdcda23a149sewardj break; 7398db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 7399db5907d7b94ce492f29a96c95e186fdcda23a149sewardj case Ist_LLSC: { 7400db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* In short: treat a load-linked like a normal load followed 7401db5907d7b94ce492f29a96c95e186fdcda23a149sewardj by an assignment of the loaded (shadow) data the result 7402db5907d7b94ce492f29a96c95e186fdcda23a149sewardj temporary. Treat a store-conditional like a normal store, 7403db5907d7b94ce492f29a96c95e186fdcda23a149sewardj and mark the result temporary as defined. */ 7404db5907d7b94ce492f29a96c95e186fdcda23a149sewardj if (st->Ist.LLSC.storedata == NULL) { 7405db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Load Linked */ 7406db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRType resTy 7407db5907d7b94ce492f29a96c95e186fdcda23a149sewardj = typeOfIRTemp(mce->sb->tyenv, st->Ist.LLSC.result); 7408db5907d7b94ce492f29a96c95e186fdcda23a149sewardj IRExpr* vanillaLoad 7409db5907d7b94ce492f29a96c95e186fdcda23a149sewardj = IRExpr_Load(st->Ist.LLSC.end, resTy, st->Ist.LLSC.addr); 7410db5907d7b94ce492f29a96c95e186fdcda23a149sewardj tl_assert(resTy == Ity_I64 || resTy == Ity_I32 7411db5907d7b94ce492f29a96c95e186fdcda23a149sewardj || resTy == Ity_I16 || resTy == Ity_I8); 7412db5907d7b94ce492f29a96c95e186fdcda23a149sewardj assign( 'B', mce, findShadowTmpB(mce, st->Ist.LLSC.result), 7413db5907d7b94ce492f29a96c95e186fdcda23a149sewardj schemeE(mce, vanillaLoad)); 7414db5907d7b94ce492f29a96c95e186fdcda23a149sewardj } else { 7415db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* Store conditional */ 7416cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj do_origins_Store_plain( mce, st->Ist.LLSC.end, 7417cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj st->Ist.LLSC.addr, 7418cafe50502ae73d6d6d0f214e06a4619e6cb1b278sewardj st->Ist.LLSC.storedata ); 7419db5907d7b94ce492f29a96c95e186fdcda23a149sewardj /* For the rationale behind this, see comments at the 7420db5907d7b94ce492f29a96c95e186fdcda23a149sewardj place where the V-shadow for .result is constructed, in 7421db5907d7b94ce492f29a96c95e186fdcda23a149sewardj do_shadow_LLSC. In short, we regard .result as 7422db5907d7b94ce492f29a96c95e186fdcda23a149sewardj always-defined. */ 7423db5907d7b94ce492f29a96c95e186fdcda23a149sewardj assign( 'B', mce, findShadowTmpB(mce, st->Ist.LLSC.result), 7424db5907d7b94ce492f29a96c95e186fdcda23a149sewardj mkU32(0) ); 74251c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj } 74267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 74277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 7428db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 74297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_Put: { 74307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj Int b_offset 74317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj = MC_(get_otrack_shadow_offset)( 74327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj st->Ist.Put.offset, 74331c0ce7a9edf8772773f6216dbad4bb04317d23b6sewardj sizeofIRType(typeOfIRExpr(mce->sb->tyenv, st->Ist.Put.data)) 74347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ); 74357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if (b_offset >= 0) { 74367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* FIXME: this isn't an atom! */ 74377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj stmt( 'B', mce, IRStmt_Put(b_offset + 2*mce->layout->total_sizeB, 74387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj schemeE( mce, st->Ist.Put.data )) ); 74397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 74407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 74417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 7442db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 74437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_WrTmp: 74447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj assign( 'B', mce, findShadowTmpB(mce, st->Ist.WrTmp.tmp), 74457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj schemeE(mce, st->Ist.WrTmp.data) ); 74467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 7447db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 74487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_MBE: 74497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_NoOp: 74507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_Exit: 74517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj case Ist_IMark: 74527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj break; 7453db5907d7b94ce492f29a96c95e186fdcda23a149sewardj 74547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj default: 74557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(printf)("mc_translate.c: schemeS: unhandled: "); 74567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ppIRStmt(st); 74577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(tool_panic)("memcheck:schemeS"); 74587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj } 74597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj} 74607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 74617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj 7462e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/ 7463cac76cb18577b9c51d331f56e8ea241f6effaf31njn/*--- end mc_translate.c ---*/ 7464e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--------------------------------------------------------------------*/ 7465