guest_x86_helpers.c revision 2eef773d07df9bbc5d62c0058ae99d5511c2759d
136ca51378f8851635df814230fa23f2c409b9eddsewardj 236ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 336ca51378f8851635df814230fa23f2c409b9eddsewardj/*--- ---*/ 4c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- This file (guest-x86/ghelpers.c) is ---*/ 5dbcfae724d5338205befbcd379a48f2303658198sewardj/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/ 636ca51378f8851635df814230fa23f2c409b9eddsewardj/*--- ---*/ 736ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 836ca51378f8851635df814230fa23f2c409b9eddsewardj 9f8ed9d874a7b8651654591c68c6d431c758d787csewardj/* 10f8ed9d874a7b8651654591c68c6d431c758d787csewardj This file is part of LibVEX, a library for dynamic binary 11f8ed9d874a7b8651654591c68c6d431c758d787csewardj instrumentation and translation. 12f8ed9d874a7b8651654591c68c6d431c758d787csewardj 137bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj Copyright (C) 2004-2005 OpenWorks LLP. All rights reserved. 147bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 157bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj This library is made available under a dual licensing scheme. 167bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj If you link LibVEX against other code all of which is itself 187bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj licensed under the GNU General Public License, version 2 dated June 197bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL 207bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL 217bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj is missing, you can obtain a copy of the GPL v2 from the Free 227bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA 237bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 02110-1301, USA. 247bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 257bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj For any other uses of LibVEX, you must first obtain a commercial 267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj license from OpenWorks LLP. Please contact info@open-works.co.uk 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj for information about commercial licensing. 287bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 297bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj This software is provided by OpenWorks LLP "as is" and any express 307bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj or implied warranties, including, but not limited to, the implied 317bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj warranties of merchantability and fitness for a particular purpose 327bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj are disclaimed. In no event shall OpenWorks LLP be liable for any 337bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj direct, indirect, incidental, special, exemplary, or consequential 347bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj damages (including, but not limited to, procurement of substitute 357bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj goods or services; loss of use, data, or profits; or business 367bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj interruption) however caused and on any theory of liability, 377bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj whether in contract, strict liability, or tort (including 387bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj negligence or otherwise) arising in any way out of the use of this 397bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj software, even if advised of the possibility of such damage. 40f8ed9d874a7b8651654591c68c6d431c758d787csewardj 41f8ed9d874a7b8651654591c68c6d431c758d787csewardj Neither the names of the U.S. Department of Energy nor the 42f8ed9d874a7b8651654591c68c6d431c758d787csewardj University of California nor the names of its contributors may be 43f8ed9d874a7b8651654591c68c6d431c758d787csewardj used to endorse or promote products derived from this software 44f8ed9d874a7b8651654591c68c6d431c758d787csewardj without prior written permission. 45f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/ 46f8ed9d874a7b8651654591c68c6d431c758d787csewardj 4736ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_basictypes.h" 48893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj#include "libvex_emwarn.h" 490c2cb623cca372a2b42b073121c7413cdaaf75besewardj#include "libvex_guest_x86.h" 5036ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_ir.h" 5149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj#include "libvex.h" 52c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj 53c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_util.h" 549e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "guest-generic/bb_to_IR.h" 55c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "guest-x86/gdefs.h" 5652ff4ccb51f48b40a9b0f4884923637e0329a542sewardj#include "guest-generic/g_generic_x87.h" 57c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 58893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 5936ca51378f8851635df814230fa23f2c409b9eddsewardj/* This file contains helper functions for x86 guest code. 6036ca51378f8851635df814230fa23f2c409b9eddsewardj Calls to these functions are generated by the back end. 6136ca51378f8851635df814230fa23f2c409b9eddsewardj These calls are of course in the host machine code and 6236ca51378f8851635df814230fa23f2c409b9eddsewardj this file will be compiled to host machine code, so that 6336ca51378f8851635df814230fa23f2c409b9eddsewardj all makes sense. 6436ca51378f8851635df814230fa23f2c409b9eddsewardj 6536ca51378f8851635df814230fa23f2c409b9eddsewardj Only change the signatures of these helper functions very 6636ca51378f8851635df814230fa23f2c409b9eddsewardj carefully. If you change the signature here, you'll have to change 6736ca51378f8851635df814230fa23f2c409b9eddsewardj the parameters passed to it in the IR calls constructed by 682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj guest-x86/toIR.c. 6989050e58e7bee40892662fe94231aefc33768cf5sewardj 70893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj The convention used is that all functions called from generated 71893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj code are named x86g_<something>, and any function whose name lacks 72893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj that prefix is not called from generated code. Note that some 73893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj LibVEX_* functions can however be called by VEX's client, but that 74893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj is not the same as calling them from VEX-generated code. 7536ca51378f8851635df814230fa23f2c409b9eddsewardj*/ 7636ca51378f8851635df814230fa23f2c409b9eddsewardj 77893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 7884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Set to 1 to get detailed profiling info about use of the flag 7984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj machinery. */ 8084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#define PROFILE_EFLAGS 0 8184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 8284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 83893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 84893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags run-time helpers. ---*/ 85893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 86893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 87d44bc6e6692dfb0881dcc249bd4ba3d8f8e97fcasewardjstatic const UChar parity_table[256] = { 882a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 892a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1152a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1162a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 12014731f22bf7759d6d23383ca870ac89d9581f1e9sewardj}; 12114731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1224a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* generalised left-shifter */ 123df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardjinline static Int lshift ( Int x, Int n ) 12414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj{ 125df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj if (n >= 0) 126df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj return x << n; 127df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj else 128df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj return x >> (-n); 12914731f22bf7759d6d23383ca870ac89d9581f1e9sewardj} 13014731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1314a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* identity on ULong */ 1324a6f3844a29aebc9774ab0d71418421c14ba9c41sewardjstatic inline ULong idULong ( ULong x ) 1334a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj{ 1344a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj return x; 1354a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj} 1364a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 13714731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 138b9c5cf639b3b21b972599d27207a033afc76ef67sewardj#define PREAMBLE(__data_bits) \ 139df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* const */ UInt DATA_MASK \ 140b9c5cf639b3b21b972599d27207a033afc76ef67sewardj = __data_bits==8 ? 0xFF \ 141b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : (__data_bits==16 ? 0xFFFF \ 142b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : 0xFFFFFFFF); \ 143df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* const */ UInt SIGN_MASK = 1 << (__data_bits - 1); \ 1442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP1 = cc_dep1_formal; \ 1452a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP2 = cc_dep2_formal; \ 1462a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_NDEP = cc_ndep_formal; \ 1472a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* Four bogus assignments, which hopefully gcc can */ \ 148df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* optimise away, and which stop it complaining about */ \ 149df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* unused variables. */ \ 150df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj SIGN_MASK = SIGN_MASK; \ 151df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj DATA_MASK = DATA_MASK; \ 1522a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_DEP2 = CC_DEP2; \ 1532a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_NDEP = CC_NDEP; 154df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj 15514731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 156b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 157b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 158df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE) \ 159b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 160b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 1618fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 1628fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 1638fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1648fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1658fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL + argR; \ 1668fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 1678fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1688fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1698fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1708fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1718fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 1722a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1738fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1748fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1752ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1762ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 177b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 178b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 1792a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE) \ 180b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 181b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 1828fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 1838fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 1848fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1858fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1868fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL - argR; \ 1878fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 1888fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1898fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1908fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1918fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1928fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 1932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1948fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1958fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1962ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1972ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 198b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 199b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 2002a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE) \ 201b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 202b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2038fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2048fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, oldC, res; \ 2052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 2068fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 2078fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 2088fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL + argR) + oldC; \ 2098fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 2108fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 2118fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2128fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 2138fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2148fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2158fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2168fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2178fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 2182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2198fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2208fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 2212ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 2222ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 223b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 224b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 225df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE) \ 226b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 227b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2288fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2298fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, oldC, res; \ 2302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 2318fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 2328fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 2338fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL - argR) - oldC; \ 2348fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 2358fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR; \ 2368fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2378fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 2388fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2398fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2408fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2418fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2428fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 2432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2448fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2458fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 246a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 247a238471814bd386aeb58a76718b41e68b1a794b2sewardj 248b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 249b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 250df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE) \ 251b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 252b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2538fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2548fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = 0; \ 2558fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 2568fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; \ 2578fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 2588fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 2598fc937421c954ff9f707254f028b1fa0410c473dsewardj of = 0; \ 2608fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2618fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 262a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 263a238471814bd386aeb58a76718b41e68b1a794b2sewardj 264b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 265b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 266df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_INC(DATA_BITS,DATA_UTYPE) \ 267b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 268b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2698fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2708fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 2718fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2728fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res - 1; \ 2738fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2758fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2768fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2778fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2788fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2798fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) == SIGN_MASK) << 11; \ 2808fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2818fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 28289050e58e7bee40892662fe94231aefc33768cf5sewardj} 28389050e58e7bee40892662fe94231aefc33768cf5sewardj 284b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 285b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 286df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE) \ 287b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 288b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2898fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2908fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 2918fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2928fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res + 1; \ 2938fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2958fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2968fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2978fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2988fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2998fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) \ 3008fc937421c954ff9f707254f028b1fa0410c473dsewardj == ((UInt)SIGN_MASK - 1)) << 11; \ 3018fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3028fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 30389050e58e7bee40892662fe94231aefc33768cf5sewardj} 30489050e58e7bee40892662fe94231aefc33768cf5sewardj 305b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 306b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 307df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE) \ 308b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 309b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3108fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (CC_DEP2 >> (DATA_BITS - 1)) & X86G_CC_MASK_C; \ 3128fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3138fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3148fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3158fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3168fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3198fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3208fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3215f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3225f6303579435ddb8315e11c2f02c904b978782a0sewardj 323b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 324b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3252a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE) \ 326b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 327b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3288fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3298fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = CC_DEP2 & 1; \ 3308fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3318fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3328fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3338fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3348fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3378fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3388fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3395f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3405f6303579435ddb8315e11c2f02c904b978782a0sewardj 341b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 342b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3438ee2de1f5f72c13120f59c0ca6ac8291219123dfsewardj/* ROL: cf' = lsb(result). of' = msb(result) ^ lsb(result). */ 3442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 345df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE) \ 346b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 347b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3488fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int fl \ 3492a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & CC_DEP1) \ 3512a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3538fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11))); \ 3548fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3558fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3568c7f1abe9e022f6382634efea09c9cac89ec6336sewardj} 3578c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 358b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 359b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3601813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj/* ROR: cf' = msb(result). of' = msb(result) ^ msb-1(result). */ 3612a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 362df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE) \ 363b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 364b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3658fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int fl \ 3662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1))) \ 3682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3708fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1))); \ 3718fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3728fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3731813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj} 3741813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 375b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 376b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3774a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_UMUL(DATA_BITS, DATA_UTYPE, NARROWtoU, \ 3784a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE, NARROWto2U) \ 3792a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 3802a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 3818fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3828fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_UTYPE hi; \ 3834a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_UTYPE lo \ 3844a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ 3854a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_UTYPE)CC_DEP2) ); \ 3864a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE rr \ 3874a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2U( \ 3884a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ 3894a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ 3904a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ 3918fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != 0); \ 3928fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 3938fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3948fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 3958fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 3968fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 3978fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3988fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 39956296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj} 40056296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj 401b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 402b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 4034a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ 4044a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE, NARROWto2S) \ 4052a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 4062a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 4078fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 4088fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_STYPE hi; \ 4094a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_STYPE lo \ 4104a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWtoS( ((DATA_STYPE)CC_DEP1) \ 4114a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_STYPE)CC_DEP2) ); \ 4124a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE rr \ 4134a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2S( \ 4144a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ 4154a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ 4164a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ 4178fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ 4188fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 4198fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 4208fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 4218fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 4228fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 4238fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 4248fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 4257ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj} 426741153c4301023a420ab45b8a10b8e1bac968822sewardj 42736ca51378f8851635df814230fa23f2c409b9eddsewardj 42884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#if PROFILE_EFLAGS 42984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 4309eab588e223e52b1e7b710ff1c0da7b032ab2837sewardjstatic Bool initted = False; 431893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 432893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, fast route */ 433893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_fast[X86G_CC_OP_NUMBER]; 434893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, slow route */ 435893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_slow[X86G_CC_OP_NUMBER]; 436893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* table for calculate_cond */ 437893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tab_cond[X86G_CC_OP_NUMBER][16]; 438893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* total entry counts for calc_all, calc_c, calc_cond. */ 43984ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_all = 0; 44084ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_c = 0; 441893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt n_calc_cond = 0; 442893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 443893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond))) 444893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 44584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 44684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void showCounts ( void ) 44784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 44884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 44984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Char ch; 450a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", 451893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all, n_calc_cond, n_calc_c); 452893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 453893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" 45484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj " S NS P NP L NL LE NLE\n"); 455893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" -----------------------------------------------------" 45684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj "----------------------------------------\n"); 4572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 45884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 45984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = ' '; 46093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 0) 46193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'B'; 46293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 1) 46393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'W'; 46484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (op > 0 && (op-1) % 3 == 2) 46584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = 'L'; 46684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 46784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("%2d%c: ", op, ch); 468a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_slow[op]); 469a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_fast[op]); 47084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) { 471893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int n = tab_cond[op][co]; 47284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 1000) { 47384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %3dK", n / 1000); 47484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else 47584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 0) { 476893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" %3d ", n ); 47784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else { 47884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 47984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 48084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 48184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 48284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 48384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 48484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 48584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 48684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void initCounts ( void ) 48784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 48884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 48984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj initted = True; 4902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 491893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[op] = tabc_slow[op] = 0; 49284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) 493893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[op][co] = 0; 49484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 49584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 49684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 49784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#endif /* PROFILE_EFLAGS */ 49884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 499893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 5009aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 501893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. 502893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Worker function, not directly called from generated code. */ 503893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic 504893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all_WRK ( UInt cc_op, 505893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1_formal, 506893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2_formal, 507893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep_formal ) 50836ca51378f8851635df814230fa23f2c409b9eddsewardj{ 50936ca51378f8851635df814230fa23f2c409b9eddsewardj switch (cc_op) { 5102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_COPY: 5112a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj return cc_dep1_formal 5122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & (X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 5132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P); 51414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 5152a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); 5162a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); 5172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); 518a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); 5202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); 5212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); 522a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5232a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); 5242a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); 5252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); 526afc5787e1c4b8e9678669577cf57ac509c6cd6b5sewardj 5272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); 5282a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); 5292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); 530741153c4301023a420ab45b8a10b8e1bac968822sewardj 5312a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); 5322a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); 5332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); 5345f6303579435ddb8315e11c2f02c904b978782a0sewardj 5352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); 5362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); 5372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); 5381813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); 5402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); 5412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); 5428c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); 5442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); 5452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); 5468c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); 5482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); 5492a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); 5501813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5512a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); 5522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); 5532a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); 554750f407b6be1aac303964a219acf0a6de8b8c4dasewardj 5552a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); 5562a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); 5572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); 5587ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj 5594a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, 5604a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UShort, toUShort ); 5614a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, 5624a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UInt, toUInt ); 5634a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, 5644a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ULong, idULong ); 5654a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 5664a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, 5674a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Short, toUShort ); 5684a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, 5694a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Int, toUInt ); 5704a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, 5714a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Long, idULong ); 572741153c4301023a420ab45b8a10b8e1bac968822sewardj 57336ca51378f8851635df814230fa23f2c409b9eddsewardj default: 57436ca51378f8851635df814230fa23f2c409b9eddsewardj /* shouldn't really make these calls from generated code */ 575893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("x86g_calculate_eflags_all_WRK(X86)" 576a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj "( %u, 0x%x, 0x%x, 0x%x )\n", 5772a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); 578893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_eflags_all_WRK(X86)"); 57936ca51378f8851635df814230fa23f2c409b9eddsewardj } 58036ca51378f8851635df814230fa23f2c409b9eddsewardj} 58136ca51378f8851635df814230fa23f2c409b9eddsewardj 582b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 5839aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 584893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. */ 585893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all ( UInt cc_op, 586893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1, 587893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2, 588893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep ) 589893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 590893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 591893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 592893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all++; 593893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 594893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 595893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 596893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_calculate_eflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep ); 597893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 598893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 599893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 600893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 601b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/* Calculate just the carry flag from the supplied thunk parameters. */ 602893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj__attribute((regparm(3))) 6032a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_eflags_c ( UInt cc_op, 6042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 6052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 6062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 60736ca51378f8851635df814230fa23f2c409b9eddsewardj{ 608893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 609893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 610893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_c++; 611893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]++; 612893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 613893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 614893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 6159eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj /* Fast-case some common ones. */ 61643c46951628d616290f7245c3af2f9a652180806sewardj switch (cc_op) { 6172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: 6182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: 6192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: 62043c46951628d616290f7245c3af2f9a652180806sewardj return 0; 6212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: 62293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)cc_dep1) < ((UInt)cc_dep2) 6232a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 624893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj case X86G_CC_OP_SUBW: 625893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) 626893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ? X86G_CC_MASK_C : 0; 6272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: 62893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) 6292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 630e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj case X86G_CC_OP_INCL: 6312a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: 632e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj return cc_ndep & X86G_CC_MASK_C; 63343c46951628d616290f7245c3af2f9a652180806sewardj default: 63443c46951628d616290f7245c3af2f9a652180806sewardj break; 63543c46951628d616290f7245c3af2f9a652180806sewardj } 6369eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj 63784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 638893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]--; 639893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_slow[cc_op]++; 64084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 641893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 642893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return x86g_calculate_eflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) 6432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_C; 64436ca51378f8851635df814230fa23f2c409b9eddsewardj} 64536ca51378f8851635df814230fa23f2c409b9eddsewardj 64636ca51378f8851635df814230fa23f2c409b9eddsewardj 6479aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 64884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* returns 1 or 0 */ 6492a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_condition ( UInt/*X86Condcode*/ cond, 6502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_op, 6512a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 6522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 6532a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 6542a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{ 655893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK(cc_op, cc_dep1, 656893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2, cc_ndep); 65784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt of,sf,zf,cf,pf; 65884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt inv = cond & 1; 65984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 66084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 661893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 662893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[cc_op][cond]++; 66384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj n_calc_cond++; 664893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 66584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 66684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 66784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj switch (cond) { 6682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNO: 6692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondO: /* OF == 1 */ 6702a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 67184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ of); 67284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6732a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNZ: 6742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondZ: /* ZF == 1 */ 6752a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 67684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ zf); 67784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6782a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNB: 6792a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondB: /* CF == 1 */ 6802a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 68184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ cf); 68284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 68384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNBE: 6852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondBE: /* (CF or ZF) == 1 */ 6862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 6872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 68884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (cf | zf)); 68984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 69084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNS: 6922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondS: /* SF == 1 */ 6932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 69484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ sf); 69584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNP: 6972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondP: /* PF == 1 */ 6982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj pf = eflags >> X86G_CC_SHIFT_P; 69984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ pf); 70084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNL: 7022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondL: /* (SF xor OF) == 1 */ 7032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 7042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 70584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (sf ^ of)); 70684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 70784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNLE: 7092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondLE: /* ((SF xor OF) or ZF) == 1 */ 7102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 7112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 7122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 71384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ ((sf ^ of) | zf)); 71484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 71584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 71684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj default: 71784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* shouldn't really make these calls from generated code */ 718a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("x86g_calculate_condition( %u, %u, 0x%x, 0x%x, 0x%x )\n", 7192a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); 720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_condition"); 72184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 72284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 72384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 72484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 726893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state ) 727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK( 729893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP, 730893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1, 731893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2, 732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP 733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt dflag = vex_state->guest_DFLAG; 735893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(dflag == 1 || dflag == 0xFFFFFFFF); 736893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (dflag == 0xFFFFFFFF) 737893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<10); 738893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_state->guest_IDFLAG == 1) 739893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<21); 7406d26984a0df6a7d20b658bac6edf869eb872cca3sewardj if (vex_state->guest_ACFLAG == 1) 7416d26984a0df6a7d20b658bac6edf869eb872cca3sewardj eflags |= (1<<18); 742893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 743893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return eflags; 744893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 745893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 746893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 747893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 748893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags translation-time function specialisers. ---*/ 749893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- These help iropt specialise calls the above run-time ---*/ 750893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags functions. ---*/ 751893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 752893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 75384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Used by the optimiser to try specialisations. Returns an 75484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj equivalent expression, or NULL if none. */ 75584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 75684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic Bool isU32 ( IRExpr* e, UInt n ) 75784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 758a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return 759a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj toBool( e->tag == Iex_Const 760a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->tag == Ico_U32 761a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->Ico.U32 == n ); 76284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 76384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7645827784e6bb74e2a032b66ec310776c24fd88729sewardjIRExpr* guest_x86_spechelper ( HChar* function_name, 7652a9ad023890d3b34cf45e429df2a8ae88b419128sewardj IRExpr** args ) 76684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 76784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 76884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 76984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 7704afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 77184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 77284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int i, arity = 0; 77384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; args[i]; i++) 77484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj arity++; 77584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if 0 77684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("spec request:\n"); 77784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %s ", function_name); 77884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; i < arity; i++) { 77984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 78084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ppIRExpr(args[i]); 78184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 78284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 78384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 78493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 7853835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj /* --------- specialising "x86g_calculate_condition" --------- */ 78693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 7873835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj if (vex_streq(function_name, "x86g_calculate_condition")) { 78884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* specialise calls to above "calculate condition" function */ 789a8415ffe6c6f0e73519301a55026a4071c701fd1sewardj IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2; 79093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj vassert(arity == 5); 79193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cond = args[0]; 79293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_op = args[1]; 79393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep1 = args[2]; 79493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep2 = args[3]; 79584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 796d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- ADDL ----------------*/ 797d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 7982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_ADDL) && isU32(cond, X86CondZ)) { 799d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* long add, then Z --> test (dst+src == 0) */ 800d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 801d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, 802d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_Add32, cc_dep1, cc_dep2), 803d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 804d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 805d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 80646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBL ----------------*/ 80746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondZ)) { 80946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then Z --> test dst==src */ 81084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 81193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, cc_dep1, cc_dep2)); 81246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 81346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 81466f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNZ)) { 81566f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long sub/cmp, then NZ --> test dst!=src */ 81666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32, 81766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj binop(Iop_CmpNE32, cc_dep1, cc_dep2)); 81866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 81966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 8202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondL)) { 82146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then L (signed less than) 82246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <s src */ 82346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 82493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLT32S, cc_dep1, cc_dep2)); 82546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 82646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondLE)) { 82846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then LE (signed less than or equal) 82946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=s src */ 83046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 83193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32S, cc_dep1, cc_dep2)); 83246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 83346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondBE)) { 83546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then BE (unsigned less than or equal) 83646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=u src */ 83746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 83893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32U, cc_dep1, cc_dep2)); 83946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 840e664ec4b9f27ed7d7ca87a2d4188fd479059351csewardj 8412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondB)) { 84246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then B (unsigned less than) 84346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <u src */ 84446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 845e664ec4b9f27ed7d7ca87a2d4188fd479059351csewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 84684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 847e664ec4b9f27ed7d7ca87a2d4188fd479059351csewardj 848e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)) { 849e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* long sub/cmp, then S --> test (dst-src <s 0) */ 850e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return unop(Iop_1Uto32, 851e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_CmpLT32S, 852e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Sub32, cc_dep1, cc_dep2), 853e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(0))); 854e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 855e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj 85646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBW ----------------*/ 85746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondZ)) { 859b9c5cf639b3b21b972599d27207a033afc76ef67sewardj /* byte sub/cmp, then Z --> test dst==src */ 860b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 861b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ16, 8627e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep1), 8637e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep2))); 864b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 865b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 86646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBB ----------------*/ 8677e6644c38b3e0148ff95c2f6f4667f54148b611esewardj 8682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondZ)) { 869b9c5cf639b3b21b972599d27207a033afc76ef67sewardj /* byte sub/cmp, then Z --> test dst==src */ 87084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 871b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ8, 87293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 87393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 87484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 87584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 8762a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNZ)) { 8777e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* byte sub/cmp, then NZ --> test dst!=src */ 87884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 879b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpNE8, 88093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 88193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 882b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 88322419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 8842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNBE)) { 885b9c5cf639b3b21b972599d27207a033afc76ef67sewardj /* long sub/cmp, then NBE (unsigned greater than) 886b9c5cf639b3b21b972599d27207a033afc76ef67sewardj --> test src <=u dst */ 8877e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* Note, args are opposite way round from the usual */ 888b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 889b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpLT32U, 8907e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)), 8917e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)))); 89284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 89384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 89446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICL ----------------*/ 89546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondZ)) { 89784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then Z --> test dst==0 */ 89893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 89984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 90022419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 9012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) { 902fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj /* long and/or/xor, then S --> test dst <s 0 */ 9037e6644c38b3e0148ff95c2f6f4667f54148b611esewardj return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0))); 904fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj } 90522419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 9062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondLE)) { 90784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then LE 90884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj This is pretty subtle. LOGIC sets SF and ZF according to the 90984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj result and makes OF be zero. LE computes (SZ ^ OF) | ZF, but 91084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj OF is zero, so this reduces to SZ | ZF -- which will be 1 iff 91184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj the result is <=signed 0. Hence ... 91284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj */ 91393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpLE32S, cc_dep1, mkU32(0))); 91484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 91584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 91666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondBE)) { 91766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long and/or/xor, then BE 91866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj LOGIC sets ZF according to the result and makes CF be zero. 91966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj BE computes (CF | ZF), but CF is zero, so this reduces ZF 92066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj -- which will be 1 iff the result is zero. Hence ... 92166f7a54d5425853debcb5fe77be1021f0c2b6620sewardj */ 92266f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 92366f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 92466f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 925d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- LOGICW ----------------*/ 926d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 9272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) { 928d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* byte and/or/xor, then Z --> test dst==0 */ 929d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 930d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(0xFFFF)), 931d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 932d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 933d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 93446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICB ----------------*/ 93584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 9362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) { 93746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* byte and/or/xor, then Z --> test dst==0 */ 93884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 93993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(255)), 94046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj mkU32(0))); 94184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 94284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 94346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- DECL ----------------*/ 944af991dede2815b7570828b9d9174cf989e636254sewardj 9452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondZ)) { 94684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* dec L, then Z --> test dst == 0 */ 94793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 94884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 94922419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 9502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondS)) { 951fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj /* dec L, then S --> compare DST <s 0 */ 9527e6644c38b3e0148ff95c2f6f4667f54148b611esewardj return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0))); 953fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj } 954fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj 955d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- SHRL ----------------*/ 956d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 9572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) { 958d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* SHRL, then Z --> test dep1 == 0 */ 959d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 960d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 961d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 9624afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /*---------------- COPY ----------------*/ 9634afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /* This can happen, as a result of x87 FP compares: "fcom ... ; 9644afab82eb869f21ccabc3efb5b93f31a5c343956sewardj fnstsw %ax ; sahf ; jbe" for example. */ 9654afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 96666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_COPY) && 96766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj (isU32(cond, X86CondBE) || isU32(cond, X86CondNBE))) { 9684afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /* COPY, then BE --> extract C and Z from dep1, and test (C 9694afab82eb869f21ccabc3efb5b93f31a5c343956sewardj or Z == 1). */ 97066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* COPY, then NBE --> extract C and Z from dep1, and test (C 97166f7a54d5425853debcb5fe77be1021f0c2b6620sewardj or Z == 0). */ 97266f7a54d5425853debcb5fe77be1021f0c2b6620sewardj UInt nnn = isU32(cond, X86CondBE) ? 1 : 0; 9734afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 9744afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 9754afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 9764afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 97766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj Iop_CmpEQ32, 9784afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 9794afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 9804afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 9814afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_Or32, 9824afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 9834afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)) 9844afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 9854afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 9864afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 98766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj mkU32(nnn) 9884afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 9894afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 9904afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 9914afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 992e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj if (isU32(cc_op, X86G_CC_OP_COPY) && 993e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj (isU32(cond, X86CondB) || isU32(cond, X86CondNB))) { 994e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then B --> extract C from dep1, and test (C == 1). */ 995e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then NB --> extract C from dep1, and test (C == 0). */ 996e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj UInt nnn = isU32(cond, X86CondB) ? 1 : 0; 9974afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 9984afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 9994afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 10004afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 1001e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_CmpEQ32, 10024afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 10034afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 10044afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 10054afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 10064afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 1007e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(nnn) 1008e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ) 1009e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ); 1010e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 1011e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj 1012e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj if (isU32(cc_op, X86G_CC_OP_COPY) && isU32(cond, X86CondZ)) { 1013e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */ 1014e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return 1015e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj unop( 1016e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_1Uto32, 1017e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 1018e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_CmpNE32, 1019e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 1020e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_And32, 1021e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)), 1022e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(1) 1023e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ), 10244afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(0) 10254afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 10264afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 10274afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 10284afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 102984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 103084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 103184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 1032893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_c" --------- */ 1033893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1034893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_c")) { 1035893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_c" function */ 1036893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1037893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1038893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1039893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 1040893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2 = args[2]; 1041893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_ndep = args[3]; 1042893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1043893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBL)) { 1044893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1045893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1046893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 1047893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1048893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBB)) { 1049893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1050893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1051893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, 1052893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)), 1053893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)))); 1054893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1055893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) 1056893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICW) 1057893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICB)) { 1058893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after logic is zero */ 1059893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return mkU32(0); 1060893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1061893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_DECL) || isU32(cc_op, X86G_CC_OP_INCL)) { 1062893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */ 1063893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return cc_ndep; 1064893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1065893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1066893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after COPY is stored in DEP1. */ 1067893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1068893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1069893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1070893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 1071893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(1) 1072893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1073893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1074893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if 0 1075893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (cc_op->tag == Iex_Const) { 1076893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n"); 1077893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1078893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 1079893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1080893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1081893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1082893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1083893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_all" --------- */ 1084893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1085893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_all")) { 1086893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_all" function */ 108740e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj IRExpr *cc_op, *cc_dep1; /*, *cc_dep2, *cc_ndep; */ 1088893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1089893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1090893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 109140e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_dep2 = args[2]; */ 109240e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_ndep = args[3]; */ 1093893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1094893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1095893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* eflags after COPY are stored in DEP1. */ 1096893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1097893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1098893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1099893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1, 1100893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 1101893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P) 1102893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1103893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1104893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1105893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1106893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 110784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef unop 110884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef binop 110984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef mkU32 11104afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# undef mkU8 111184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 111284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 111384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 111484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 111536ca51378f8851635df814230fa23f2c409b9eddsewardj 1116893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1117893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Supporting functions for x87 FPU activities. ---*/ 1118893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1119893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1120893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic inline Bool host_is_little_endian ( void ) 1121893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1122893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt x = 0x76543210; 1123893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* p = (UChar*)(&x); 1124a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toBool(*p == 0x10); 1125893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1126893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 11270c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* 80 and 64-bit floating point formats: 11280c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11290c2cb623cca372a2b42b073121c7413cdaaf75besewardj 80-bit: 11300c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11310c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0-------0 zero 11320c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0X------X denormals 11330c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FFE 1X------X normals (all normals have leading 1) 11340c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10------0 infinity 11350c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10X-----X snan 11360c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 11X-----X qnan 11370c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11380c2cb623cca372a2b42b073121c7413cdaaf75besewardj S is the sign bit. For runs X----X, at least one of the Xs must be 11390c2cb623cca372a2b42b073121c7413cdaaf75besewardj nonzero. Exponent is 15 bits, fractional part is 63 bits, and 11400c2cb623cca372a2b42b073121c7413cdaaf75besewardj there is an explicitly represented leading 1, and a sign bit, 11410c2cb623cca372a2b42b073121c7413cdaaf75besewardj giving 80 in total. 11420c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11430c2cb623cca372a2b42b073121c7413cdaaf75besewardj 64-bit avoids the confusion of an explicitly represented leading 1 11440c2cb623cca372a2b42b073121c7413cdaaf75besewardj and so is simpler: 11450c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11460c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0------0 zero 11470c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 X------X denormals 11480c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FE any normals 11490c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0------0 infinity 11500c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0X-----X snan 11510c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 1X-----X qnan 11520c2cb623cca372a2b42b073121c7413cdaaf75besewardj 11530c2cb623cca372a2b42b073121c7413cdaaf75besewardj Exponent is 11 bits, fractional part is 52 bits, and there is a 11540c2cb623cca372a2b42b073121c7413cdaaf75besewardj sign bit, giving 64 in total. 11550c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/ 11560c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1157893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Inspect a value and its tag, as per the x87 'FXAM' instruction. */ 11589aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 11592a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_FXAM ( UInt tag, ULong dbl ) 1160c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj{ 1161c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Bool mantissaIsZero; 1162c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Int bexp; 1163c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar sign; 1164c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar* f64; 1165c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1166a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vassert(host_is_little_endian()); 1167c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1168c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */ 1169c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1170c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj f64 = (UChar*)(&dbl); 1171a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj sign = toUChar( (f64[7] >> 7) & 1 ); 1172c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1173c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* First off, if the tag indicates the register was empty, 1174c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj return 1,0,sign,1 */ 1175c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (tag == 0) { 1176c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Empty\n"); */ 1177e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 | (sign << X86G_FC_SHIFT_C1) 1178e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1179c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1180c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1181c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F); 1182c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp &= 0x7FF; 1183c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1184c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj mantissaIsZero 1185a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toBool( 1186a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj (f64[6] & 0x0F) == 0 1187a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0 1188a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj ); 1189c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1190c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If both exponent and mantissa are zero, the value is zero. 1191c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,0,sign,0. */ 1192c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && mantissaIsZero) { 1193c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Zero\n"); */ 1194e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 1195e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1196c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1197c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1198c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If exponent is zero but mantissa isn't, it's a denormal. 1199c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,1,sign,0. */ 1200c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && !mantissaIsZero) { 1201c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Denormal\n"); */ 1202e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | X86G_FC_MASK_C2 1203e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1204c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1205c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1206c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa is zero, this is an infinity. 1207c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,1. */ 1208c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && mantissaIsZero) { 1209c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Inf\n"); */ 1210e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) 1211e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1212c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1213c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1214c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN. 1215c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,0,sign,1. */ 1216c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && !mantissaIsZero) { 1217c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("NaN\n"); */ 1218e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | 0 | (sign << X86G_FC_SHIFT_C1) | X86G_FC_MASK_C0; 1219c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1220c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1221c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* Uh, ok, we give up. It must be a normal finite number. 1222c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,0. 1223c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj */ 1224c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("normal\n"); */ 1225e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) | 0; 1226c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj} 1227c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 12280c2cb623cca372a2b42b073121c7413cdaaf75besewardj 122917442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 123017442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (reads guest memory) */ 12312a9ad023890d3b34cf45e429df2a8ae88b419128sewardjULong x86g_loadF80le ( UInt addrU ) 123217442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 123317442fe8094d0f82266e5a05509f62cac8f7539esewardj ULong f64; 1234c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj convert_f80le_to_f64le ( (UChar*)ULong_to_Ptr(addrU), (UChar*)&f64 ); 123517442fe8094d0f82266e5a05509f62cac8f7539esewardj return f64; 123617442fe8094d0f82266e5a05509f62cac8f7539esewardj} 123717442fe8094d0f82266e5a05509f62cac8f7539esewardj 123817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 123917442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (writes guest memory) */ 12402a9ad023890d3b34cf45e429df2a8ae88b419128sewardjvoid x86g_storeF80le ( UInt addrU, ULong f64 ) 124117442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 1242c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj convert_f64le_to_f80le( (UChar*)&f64, (UChar*)ULong_to_Ptr(addrU) ); 124317442fe8094d0f82266e5a05509f62cac8f7539esewardj} 124417442fe8094d0f82266e5a05509f62cac8f7539esewardj 12450c2cb623cca372a2b42b073121c7413cdaaf75besewardj 12460c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 12470c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*--- The exported fns .. ---*/ 12480c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 12490c2cb623cca372a2b42b073121c7413cdaaf75besewardj 12500c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Layout of the real x87 state. */ 12514017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* 13 June 05: Fpu_State and auxiliary constants was moved to 12524017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj g_generic_x87.h */ 12530c2cb623cca372a2b42b073121c7413cdaaf75besewardj 12540c2cb623cca372a2b42b073121c7413cdaaf75besewardj 12557df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1256a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* fpucw[15:0] contains a x87 native format FPU control word. 1257d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj Extract from it the required FPROUND value and any resulting 1258d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj emulation warning, and return (warn << 32) | fpround value. 1259d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj*/ 12603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_fldcw ( UInt fpucw ) 1261893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1262d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* Decide on a rounding mode. fpucw[11:10] holds it. */ 1263d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 1264893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj UInt rmode = (fpucw >> 10) & 3; 1265893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1266893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* Detect any required emulation warnings. */ 1267893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj VexEmWarn ew = EmWarn_NONE; 1268893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1269893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if ((fpucw & 0x3F) != 0x3F) { 1270893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unmasked exceptions! */ 1271893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87exns; 1272893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1273893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj else 1274893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if (((fpucw >> 8) & 3) != 3) { 1275893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unsupported precision */ 1276893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87precision; 1277893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1278893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1279d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return (((ULong)ew) << 32) | ((ULong)rmode); 1280893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1281893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1282893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* CLEAN HELPER */ 12837df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given fpround as an IRRoundingMode value, create a suitable x87 12847df596b1e36840e2d74c90aa55589934add61ccfsewardj native format FPU control word. */ 12853bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_fpucw ( UInt fpround ) 1286893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1287d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround &= 3; 1288d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return 0x037F | (fpround << 10); 1289893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1290893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1291893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 12927df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1293a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* mxcsr[15:0] contains a SSE native format MXCSR value. 12947df596b1e36840e2d74c90aa55589934add61ccfsewardj Extract from it the required SSEROUND value and any resulting 12957df596b1e36840e2d74c90aa55589934add61ccfsewardj emulation warning, and return (warn << 32) | sseround value. 12967df596b1e36840e2d74c90aa55589934add61ccfsewardj*/ 12973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_ldmxcsr ( UInt mxcsr ) 12987df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 12997df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Decide on a rounding mode. mxcsr[14:13] holds it. */ 13007df596b1e36840e2d74c90aa55589934add61ccfsewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 13017df596b1e36840e2d74c90aa55589934add61ccfsewardj UInt rmode = (mxcsr >> 13) & 3; 13027df596b1e36840e2d74c90aa55589934add61ccfsewardj 13037df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Detect any required emulation warnings. */ 13047df596b1e36840e2d74c90aa55589934add61ccfsewardj VexEmWarn ew = EmWarn_NONE; 13057df596b1e36840e2d74c90aa55589934add61ccfsewardj 13067df596b1e36840e2d74c90aa55589934add61ccfsewardj if ((mxcsr & 0x1F80) != 0x1F80) { 13077df596b1e36840e2d74c90aa55589934add61ccfsewardj /* unmasked exceptions! */ 13087df596b1e36840e2d74c90aa55589934add61ccfsewardj ew = EmWarn_X86_sseExns; 13097df596b1e36840e2d74c90aa55589934add61ccfsewardj } 13107df596b1e36840e2d74c90aa55589934add61ccfsewardj else 13115edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<15)) { 13125edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* FZ is set */ 13135edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_fz; 13145edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj } 13155edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj else 13165edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<6)) { 13175edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* DAZ is set */ 13185edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_daz; 13197df596b1e36840e2d74c90aa55589934add61ccfsewardj } 13207df596b1e36840e2d74c90aa55589934add61ccfsewardj 13217df596b1e36840e2d74c90aa55589934add61ccfsewardj return (((ULong)ew) << 32) | ((ULong)rmode); 13227df596b1e36840e2d74c90aa55589934add61ccfsewardj} 13237df596b1e36840e2d74c90aa55589934add61ccfsewardj 13247df596b1e36840e2d74c90aa55589934add61ccfsewardj 13257df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 13267df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given sseround as an IRRoundingMode value, create a suitable SSE 13277df596b1e36840e2d74c90aa55589934add61ccfsewardj native format MXCSR value. */ 13283bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_mxcsr ( UInt sseround ) 13297df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 13307df596b1e36840e2d74c90aa55589934add61ccfsewardj sseround &= 3; 13317df596b1e36840e2d74c90aa55589934add61ccfsewardj return 0x1F80 | (sseround << 13); 13327df596b1e36840e2d74c90aa55589934add61ccfsewardj} 13337df596b1e36840e2d74c90aa55589934add61ccfsewardj 13347df596b1e36840e2d74c90aa55589934add61ccfsewardj 1335a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* CALLED FROM GENERATED CODE */ 1336a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* DIRTY HELPER (writes guest state) */ 1337a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Initialise the x87 FPU state as per 'finit'. */ 1338a0e83b06f304527e3e9aec527c344e35e7023d76sewardjvoid x86g_dirtyhelper_FINIT ( VexGuestX86State* gst ) 1339a0e83b06f304527e3e9aec527c344e35e7023d76sewardj{ 1340a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i; 1341a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FTOP = 0; 1342a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (i = 0; i < 8; i++) { 1343a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPTAG[i] = 0; /* empty */ 1344a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */ 1345a0e83b06f304527e3e9aec527c344e35e7023d76sewardj } 1346a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPROUND = (UInt)Irrm_NEAREST; 1347a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FC3210 = 0; 1348a0e83b06f304527e3e9aec527c344e35e7023d76sewardj} 1349a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 1350a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 13517df596b1e36840e2d74c90aa55589934add61ccfsewardj/* This is used to implement both 'frstor' and 'fldenv'. The latter 13527df596b1e36840e2d74c90aa55589934add61ccfsewardj appears to differ from the former only in that the 8 FP registers 13537df596b1e36840e2d74c90aa55589934add61ccfsewardj themselves are not transferred into the guest state. */ 13547df596b1e36840e2d74c90aa55589934add61ccfsewardjstatic 135538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjVexEmWarn do_put_x87 ( Bool moveRegs, 135638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*IN*/UChar* x87_state, 135738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/VexGuestX86State* vex_state ) 13580c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1359a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int stno, preg; 13600c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tag; 1361f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj Double* vexRegs = (Double*)(&vex_state->guest_FPREG[0]); 1362f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 13630c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 13640c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt ftop = (x87->env[FP_ENV_STAT] >> 11) & 7; 13650c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw = x87->env[FP_ENV_TAG]; 13666e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj UInt fpucw = x87->env[FP_ENV_CTRL]; 1367c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UInt c3210 = x87->env[FP_ENV_STAT] & 0x4700; 1368893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj VexEmWarn ew; 1369d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj UInt fpround; 1370893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ULong pair; 13710c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13720c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* Copy registers and tags */ 1373a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1374a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1375a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tag = (tagw >> (2*preg)) & 3; 13760c2cb623cca372a2b42b073121c7413cdaaf75besewardj if (tag == 3) { 13770c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1378a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* hmm, if it's empty, does it still get written? Probably 1379a0e83b06f304527e3e9aec527c344e35e7023d76sewardj safer to say it does. If we don't, memcheck could get out 1380a0e83b06f304527e3e9aec527c344e35e7023d76sewardj of sync, in that it thinks all FP registers are defined by 1381a0e83b06f304527e3e9aec527c344e35e7023d76sewardj this helper, but in reality some have not been updated. */ 13820f33861a0aaf18e89f5f24fd5bdfa39a9049dadasewardj if (moveRegs) 1383a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexRegs[preg] = 0.0; 1384a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 0; 13850c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 13860c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is non-empty */ 13877df596b1e36840e2d74c90aa55589934add61ccfsewardj if (moveRegs) 1388a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f80le_to_f64le( &x87->reg[10*stno], 1389a0e83b06f304527e3e9aec527c344e35e7023d76sewardj (UChar*)&vexRegs[preg] ); 1390a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 1; 13910c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 13920c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 13930c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13940c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* stack pointer */ 1395f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FTOP = ftop; 13960c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13973f868e5262a8d2488f41cc49058ba60c24843c3esewardj /* status word */ 1398f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FC3210 = c3210; 1399893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1400d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* handle the control word, setting FPROUND and detecting any 1401893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj emulation warnings. */ 14023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj pair = x86g_check_fldcw ( (UInt)fpucw ); 1403d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround = (UInt)pair; 1404d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj ew = (VexEmWarn)(pair >> 32); 1405893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1406d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj vex_state->guest_FPROUND = fpround & 3; 1407893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1408893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* emulation warnings --> caller */ 1409893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj return ew; 14100c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 14110c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14126e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj 1413a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Create an x87 FPU state from the guest state, as close as 1414a0e83b06f304527e3e9aec527c344e35e7023d76sewardj we can approximate it. */ 141538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic 141638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjvoid do_get_x87 ( /*IN*/VexGuestX86State* vex_state, 141738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/UChar* x87_state ) 14180c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1419a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i, stno, preg; 14200c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw; 1421f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj Double* vexRegs = (Double*)(&vex_state->guest_FPREG[0]); 1422f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 14230c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 1424f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt ftop = vex_state->guest_FTOP; 1425f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt c3210 = vex_state->guest_FC3210; 14260c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14270c2cb623cca372a2b42b073121c7413cdaaf75besewardj for (i = 0; i < 14; i++) 14280c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[i] = 0; 14290c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14300c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 1431a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_STAT] 1432a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 1433893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj x87->env[FP_ENV_CTRL] 1434a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(x86g_create_fpucw( vex_state->guest_FPROUND )); 14350c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1436a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* Dump the register stack in ST order. */ 14370c2cb623cca372a2b42b073121c7413cdaaf75besewardj tagw = 0; 1438a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1439a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1440a0e83b06f304527e3e9aec527c344e35e7023d76sewardj if (vexTags[preg] == 0) { 14410c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1442a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (3 << (2*preg)); 1443a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1444a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 14450c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 14460c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is full. */ 1447a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (0 << (2*preg)); 1448a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1449a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 14500c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 14510c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 1452a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_TAG] = toUShort(tagw); 14530c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 14540c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14550c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1456893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1457893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1458893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FXSAVE ( VexGuestX86State* gst, HWord addr ) 1459f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj{ 1460893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1461893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1462893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrS = (UShort*)addr; 1463893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* addrC = (UChar*)addr; 1464893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj U128* xmm = (U128*)(addr + 160); 1465893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt mxcsr; 1466893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort fp_tags; 1467a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt summary_tags; 1468893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int r, stno; 1469893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort *srcS, *dstS; 1470f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1471893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1472893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mxcsr = x86g_create_mxcsr( gst->guest_SSEROUND ); 147376bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1474893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Now build the proper fxsave image from the x87 image we just 1475893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj made. */ 147676bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1477893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[0] = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */ 1478893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[1] = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */ 147976bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1480893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* set addrS[2] in an endian-independent way */ 1481893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags = 0; 1482893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj fp_tags = tmp.env[FP_ENV_TAG]; 1483893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (r = 0; r < 8; r++) { 1484893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if ( ((fp_tags >> (2*r)) & 3) != 3 ) 1485893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags |= (1 << r); 1486893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1487a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrC[4] = toUChar(summary_tags); /* FTW: tag summary byte */ 1488893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrC[5] = 0; /* pad */ 148976bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1490893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[3] = 0; /* FOP: fpu opcode (bogus) */ 1491893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[4] = 0; 1492893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[5] = 0; /* FPU IP (bogus) */ 1493893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[6] = 0; /* FPU IP's segment selector (bogus) (although we 1494893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj could conceivably dump %CS here) */ 1495c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1496893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[7] = 0; /* Intel reserved */ 1497c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1498893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[8] = 0; /* FPU DP (operand pointer) (bogus) */ 1499893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[9] = 0; /* FPU DP (operand pointer) (bogus) */ 1500893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[10] = 0; /* segment selector for above operand pointer; %DS 1501893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj perhaps? */ 1502893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[11] = 0; /* Intel reserved */ 1503c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1504a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[12] = toUShort(mxcsr); /* MXCSR */ 1505a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[13] = toUShort(mxcsr >> 16); 1506893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1507893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[14] = 0xFFFF; /* MXCSR mask (lo16); who knows what for */ 1508893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[15] = 0xFFFF; /* MXCSR mask (hi16); who knows what for */ 1509893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1510893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Copy in the FP registers, in ST order. */ 1511893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (stno = 0; stno < 8; stno++) { 1512893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj srcS = (UShort*)(&tmp.reg[10*stno]); 1513893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS = (UShort*)(&addrS[16 + 8*stno]); 1514893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[0] = srcS[0]; 1515893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[1] = srcS[1]; 1516893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[2] = srcS[2]; 1517893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[3] = srcS[3]; 1518893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[4] = srcS[4]; 1519893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[5] = 0; 1520893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[6] = 0; 1521893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[7] = 0; 1522893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1523893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1524893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* That's the first 160 bytes of the image done. Now only %xmm0 1525893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj .. %xmm7 remain to be copied. If the host is big-endian, these 1526893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj need to be byte-swapped. */ 1527893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(host_is_little_endian()); 1528893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1529893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define COPY_U128(_dst,_src) \ 1530893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 1531893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 1532893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj while (0) 1533893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1534893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[0], gst->guest_XMM0 ); 1535893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[1], gst->guest_XMM1 ); 1536893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[2], gst->guest_XMM2 ); 1537893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[3], gst->guest_XMM3 ); 1538893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[4], gst->guest_XMM4 ); 1539893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[5], gst->guest_XMM5 ); 1540893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[6], gst->guest_XMM6 ); 1541893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[7], gst->guest_XMM7 ); 1542893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1543893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef COPY_U128 1544dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj} 1545f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1546f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1547893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1548893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1549893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSAVE ( VexGuestX86State* gst, HWord addr ) 1550893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1551893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)addr ); 1552893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1553893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1554893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1555893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 1556893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State* gst, HWord addr ) 1557893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1558893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( True/*regs too*/, (UChar*)addr, gst ); 1559893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1560893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1561893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1562893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1563893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSTENV ( VexGuestX86State* gst, HWord addr ) 1564893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1565893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1566893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int i; 1567893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrP = (UShort*)addr; 1568893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1569893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1570893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (i = 0; i < 14; i++) 1571893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrP[i] = tmp.env[i]; 1572893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1573893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1574893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1575893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 1576893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr ) 1577893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1578893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst); 1579893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1580893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1581893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1582893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1583893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Misc integer helpers, including rotates and CPUID. ---*/ 1584893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 15859aebb0c3f7a7f43313786826f31402f2b733badfsewardj 15869aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 15879aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* Calculate both flags and value result for rotate right 15889aebb0c3f7a7f43313786826f31402f2b733badfsewardj through the carry bit. Result in low 32 bits, 15899aebb0c3f7a7f43313786826f31402f2b733badfsewardj new flags (OSZACP) in high 32 bits. 15909aebb0c3f7a7f43313786826f31402f2b733badfsewardj*/ 15912a9ad023890d3b34cf45e429df2a8ae88b419128sewardjULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 15929aebb0c3f7a7f43313786826f31402f2b733badfsewardj{ 15939aebb0c3f7a7f43313786826f31402f2b733badfsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 15949aebb0c3f7a7f43313786826f31402f2b733badfsewardj 15959aebb0c3f7a7f43313786826f31402f2b733badfsewardj switch (sz) { 15969aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 4: 15972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 15989aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 31) ^ cf) & 1; 15999aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 16009aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 16019aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = (arg >> 1) | (cf << 31); 16029aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 16039aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 16049aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 16059aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 16069aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 2: 16079aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 16082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 16099aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 15) ^ cf) & 1; 16109aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 16119aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 16129aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7FFF) | (cf << 15); 16139aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 16149aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 16159aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 16169aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 16179aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 1: 16189aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 16192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 16209aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 7) ^ cf) & 1; 16219aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 16229aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 16239aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7F) | (cf << 7); 16249aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 16259aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 16269aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 16279aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 16289aebb0c3f7a7f43313786826f31402f2b733badfsewardj default: 16299aebb0c3f7a7f43313786826f31402f2b733badfsewardj vpanic("calculate_RCR: invalid size"); 16309aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 16319aebb0c3f7a7f43313786826f31402f2b733badfsewardj 16329aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf &= 1; 16339aebb0c3f7a7f43313786826f31402f2b733badfsewardj of &= 1; 16342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 16352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 16369aebb0c3f7a7f43313786826f31402f2b733badfsewardj 16379aebb0c3f7a7f43313786826f31402f2b733badfsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 16389aebb0c3f7a7f43313786826f31402f2b733badfsewardj} 16399aebb0c3f7a7f43313786826f31402f2b733badfsewardj 16407cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 16412eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 16422eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* Calculate both flags and value result for rotate left 16432eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj through the carry bit. Result in low 32 bits, 16442eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj new flags (OSZACP) in high 32 bits. 16452eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj*/ 16462eef773d07df9bbc5d62c0058ae99d5511c2759dsewardjULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 16472eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj{ 16482eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 16492eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 16502eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj switch (sz) { 16512eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 4: 16522eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 16532eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 16542eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 31) & 1; 16552eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = (arg << 1) | (cf & 1); 16562eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 16572eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 16582eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 16592eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 31) ^ cf) & 1; 16602eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 16612eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 2: 16622eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 16632eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 16642eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 16652eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 15) & 1; 16662eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFFFF & ((arg << 1) | (cf & 1)); 16672eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 16682eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 16692eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 16702eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 15) ^ cf) & 1; 16712eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 16722eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 1: 16732eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 16742eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 16752eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 16762eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 7) & 1; 16772eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFF & ((arg << 1) | (cf & 1)); 16782eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 16792eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 16802eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 16812eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 7) ^ cf) & 1; 16822eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 16832eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj default: 16842eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj vpanic("calculate_RCL: invalid size"); 16852eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 16862eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 16872eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf &= 1; 16882eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of &= 1; 16892eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 16902eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 16912eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 16922eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 16932eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj} 16942eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 16952eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 16967cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* CALLED FROM GENERATED CODE */ 16977cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* DIRTY HELPER (modifies guest state) */ 16984ba6ed0799fcf768e3fb9627fabc52fb1d6c2a6csewardj/* Claim to be a P55C (Intel Pentium/MMX) */ 16999df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* st ) 17007cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj{ 17019df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 17029df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 17039df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x1; 17049df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 17059df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 17069df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 17079df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17089df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 17099df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x543; 17109df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x0; 17119df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x0; 17129df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x8001bf; 17139df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17149df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 17159df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 17169df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 17179df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* CALLED FROM GENERATED CODE */ 17189df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* DIRTY HELPER (modifies guest state) */ 17199df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* Claim to be the following SSE1-capable CPU: 17209df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 17219df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu family : 6 17229df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model : 11 17239df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model name : Intel(R) Pentium(R) III CPU family 1133MHz 17249df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj stepping : 1 17259df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu MHz : 1131.013 17269df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cache size : 512 KB 17279df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 17289df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st ) 17299df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 17309df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 17319df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 17329df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x00000002; 17339df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 17349df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 17359df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 17369df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17379df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 1: 17389df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x000006b1; 17399df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000004; 17409df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 17419df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0383fbff; 17429df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17439df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 17449df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x03020101; 17459df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000000; 17469df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 17479df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0c040883; 17489df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17499df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 17509df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 17519df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 17529df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* Claim to be the following SSE2-capable CPU: 17539df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 17549df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu family : 15 17559df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model : 2 17569df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model name : Intel(R) Pentium(R) 4 CPU 2.40GHz 17579df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj stepping : 7 17589df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu MHz : 2394.234 17599df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cache size : 512 KB 17609df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 17619df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) 17629df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 17639df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 17649df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 17659df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x00000002; 17669df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 17679df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 17689df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 17699df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17709df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 1: 17719df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x00000f27; 17729df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00010809; 17739df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00004400; 17749df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0xbfebfbff; 17759df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17769df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 17779df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x665b5101; 17789df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000000; 17799df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 17809df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x007b7040; 17819df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 17827cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj } 17837cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj} 17847cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 1785464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 1786893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1787893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for MMX/SSE/SSE2. ---*/ 1788893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1789464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 179038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar abdU8 ( UChar xx, UChar yy ) { 1791a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(xx>yy ? xx-yy : yy-xx); 179238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj} 1793464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 179438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) { 1795464efa446b2db97115d3e5f04af5db3464cc0e93sewardj return (((ULong)w1) << 32) | ((ULong)w0); 1796464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 1797464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 179838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_3 ( ULong w64 ) { 1799a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1800a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32 >> 16); 1801464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 180238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_2 ( ULong w64 ) { 1803a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1804a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32); 1805464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 180638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_1 ( ULong w64 ) { 1807a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1808a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32 >> 16); 1809464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 181038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_0 ( ULong w64 ) { 1811a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1812a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32); 1813464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 1814464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 181538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_7 ( ULong w64 ) { 1816a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1817a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 24); 1818464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 181938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_6 ( ULong w64 ) { 1820a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1821a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 16); 1822464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 182338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_5 ( ULong w64 ) { 1824a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1825a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 8); 1826464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 182738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_4 ( ULong w64 ) { 1828a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 1829a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 0); 1830464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 183138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_3 ( ULong w64 ) { 1832a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1833a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 24); 1834464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 183538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_2 ( ULong w64 ) { 1836a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1837a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 16); 1838464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 183938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_1 ( ULong w64 ) { 1840a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1841a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 8); 1842464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 184338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_0 ( ULong w64 ) { 1844a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 1845a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 0); 1846464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 1847464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 184838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 184938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) 18504340dac5c2cede4962868e6da5b73282da2bc465sewardj{ 18514340dac5c2cede4962868e6da5b73282da2bc465sewardj return 18524340dac5c2cede4962868e6da5b73282da2bc465sewardj mk32x2( 18534340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) 18544340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), 18554340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) 18564340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) 18574340dac5c2cede4962868e6da5b73282da2bc465sewardj ); 18584340dac5c2cede4962868e6da5b73282da2bc465sewardj} 18594340dac5c2cede4962868e6da5b73282da2bc465sewardj 186038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 186138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjUInt x86g_calculate_mmx_pmovmskb ( ULong xx ) 1862b54520819b40c3fe907725b56bcd8db5112c0b9asewardj{ 1863b54520819b40c3fe907725b56bcd8db5112c0b9asewardj UInt r = 0; 1864b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (64-1))) r |= (1<<7); 1865b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (56-1))) r |= (1<<6); 1866b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (48-1))) r |= (1<<5); 1867b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (40-1))) r |= (1<<4); 1868b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (32-1))) r |= (1<<3); 1869b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (24-1))) r |= (1<<2); 1870b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (16-1))) r |= (1<<1); 1871b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << ( 8-1))) r |= (1<<0); 1872b54520819b40c3fe907725b56bcd8db5112c0b9asewardj return r; 1873b54520819b40c3fe907725b56bcd8db5112c0b9asewardj} 1874b54520819b40c3fe907725b56bcd8db5112c0b9asewardj 187538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 187638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy ) 18770bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj{ 18780bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj UInt t = 0; 18790bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); 18800bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); 18810bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); 18820bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); 18830bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 18840bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 18850bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 18860bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 18870bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t &= 0xFFFF; 18880bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj return (ULong)t; 18890bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj} 18900bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj 189138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 1892e5854d6d470f21677ec84f71d09129434b044246sewardjUInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo ) 1893e5854d6d470f21677ec84f71d09129434b044246sewardj{ 189438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj UInt rHi8 = x86g_calculate_mmx_pmovmskb ( w64hi ); 189538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj UInt rLo8 = x86g_calculate_mmx_pmovmskb ( w64lo ); 1896e5854d6d470f21677ec84f71d09129434b044246sewardj return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF); 1897e5854d6d470f21677ec84f71d09129434b044246sewardj} 1898e5854d6d470f21677ec84f71d09129434b044246sewardj 1899464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 1900893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1901893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with segment overrides. ---*/ 1902893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 19033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 19053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_base ( VexGuestX86SegDescr* ent ) 19063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 19073bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.BaseLow; 19083bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt mid = 0xFF & (UInt)ent->LdtEnt.Bits.BaseMid; 19093bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xFF & (UInt)ent->LdtEnt.Bits.BaseHi; 19103bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (hi << 24) | (mid << 16) | lo; 19113bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 19123bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19133bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 19143bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_limit ( VexGuestX86SegDescr* ent ) 19153bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 19163bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.LimitLow; 19173bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xF & (UInt)ent->LdtEnt.Bits.LimitHi; 19183bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt limit = (hi << 16) | lo; 19193bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ent->LdtEnt.Bits.Granularity) 19203bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = (limit << 12) | 0xFFF; 19213bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return limit; 19223bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 19233bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 192438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 19253bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_use_seg_selector ( HWord ldt, HWord gdt, 19263bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt seg_selector, UInt virtual_addr ) 19273bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 19283bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt tiBit, base, limit; 19293bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj VexGuestX86SegDescr* the_descrs; 19303bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19313bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj Bool verboze = False; 19323bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19333bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* If this isn't true, we're in Big Trouble. */ 19343bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(8 == sizeof(VexGuestX86SegDescr)); 19353bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19363bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 19373bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 19383bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "seg_selector = 0x%x, vaddr = 0x%x\n", 19393bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector, virtual_addr); 19403bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19413bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for wildly invalid selector. */ 19423bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector & ~0xFFFF) 19433bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19443bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19453bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector &= 0x0000FFFF; 19463bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19473bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Sanity check the segment selector. Ensure that RPL=11b (least 19483bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj privilege). This forms the bottom 2 bits of the selector. */ 19493bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if ((seg_selector & 3) != 3) 19503bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19513bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19523bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Extract the TI bit (0 means GDT, 1 means LDT) */ 19533bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj tiBit = (seg_selector >> 2) & 1; 19543bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19553bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Convert the segment selector onto a table index */ 19563bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector >>= 3; 19573bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(seg_selector >= 0 && seg_selector < 8192); 19583bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19593bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (tiBit == 0) { 19603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19613bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* GDT access. */ 19623bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do we actually have a GDT to look at? */ 19633bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (gdt == 0) 19643bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19653bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19663bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for access to non-existent entry. */ 19673bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_GDT_NENT) 19683bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19693bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19703bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)gdt; 19713bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 19723bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 19733bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19743bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } else { 19753bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19763bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* All the same stuff, except for the LDT. */ 19773bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ldt == 0) 19783bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19793bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19803bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_LDT_NENT) 19813bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19823bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19833bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)ldt; 19843bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 19853bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 19863bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19873bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } 19883bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19893bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do the limit check. Note, this check is just slightly too 19903bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj slack. Really it should be "if (virtual_addr + size - 1 >= 19913bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit)," but we don't have the size info to hand. Getting it 19923bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj could be significantly complex. */ 19933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (virtual_addr >= limit) 19943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 19953bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 19963bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 19973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 19983bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "base = 0x%x, addr = 0x%x\n", 19993bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base, base + virtual_addr); 20003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 20013bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* High 32 bits are zero, indicating success. */ 20023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (ULong)( ((UInt)virtual_addr) + base ); 20033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 20043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj bad: 20053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return 1ULL << 32; 20063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 20073bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 20083bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 2009893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2010893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with, and describing, ---*/ 2011893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- guest state as a whole. ---*/ 2012893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2013893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2014893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Initialise the entire x86 guest state. */ 2015893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 2016893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state ) 2017893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 2018893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EAX = 0; 2019893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ECX = 0; 2020893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDX = 0; 2021893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBX = 0; 2022893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESP = 0; 2023893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBP = 0; 2024893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESI = 0; 2025893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDI = 0; 2026893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2027893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP = X86G_CC_OP_COPY; 2028893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1 = 0; 2029893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2 = 0; 2030893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP = 0; 2031893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DFLAG = 1; /* forwards */ 2032893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_IDFLAG = 0; 20336d26984a0df6a7d20b658bac6edf869eb872cca3sewardj vex_state->guest_ACFLAG = 0; 2034893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2035893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EIP = 0; 2036893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2037893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialise the simulated FPU */ 2038893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_dirtyhelper_FINIT( vex_state ); 2039893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2040893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialse the SSE state. */ 2041893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define SSEZERO(_xmm) _xmm[0]=_xmm[1]=_xmm[2]=_xmm[3] = 0; 2042893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2043893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SSEROUND = (UInt)Irrm_NEAREST; 2044893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM0); 2045893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM1); 2046893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM2); 2047893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM3); 2048893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM4); 2049893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM5); 2050893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM6); 2051893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM7); 2052893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2053893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef SSEZERO 2054893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2055893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CS = 0; 2056893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DS = 0; 2057893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ES = 0; 2058893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_FS = 0; 2059893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GS = 0; 2060893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SS = 0; 2061893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_LDT = 0; 2062893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GDT = 0; 2063893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2064893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EMWARN = EmWarn_NONE; 20651f126c5c092801acfc1ac968d2f1a37dde334bccsewardj 20661f126c5c092801acfc1ac968d2f1a37dde334bccsewardj /* These should not ever be either read or written, but we 20671f126c5c092801acfc1ac968d2f1a37dde334bccsewardj initialise them anyway. */ 20681f126c5c092801acfc1ac968d2f1a37dde334bccsewardj vex_state->guest_TISTART = 0; 20691f126c5c092801acfc1ac968d2f1a37dde334bccsewardj vex_state->guest_TILEN = 0; 2070893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 2071893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 20728d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 20738d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/* Figure out if any part of the guest state contained in minoff 20748d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj .. maxoff requires precise memory exceptions. If in doubt return 20758d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj True (but this is generates significantly slower code). 20768d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 20774cca75cb48776ceda40e8e305232d85f62021804sewardj By default we enforce precise exns for guest %ESP, %EBP and %EIP 20784cca75cb48776ceda40e8e305232d85f62021804sewardj only. These are the minimum needed to extract correct stack 20794cca75cb48776ceda40e8e305232d85f62021804sewardj backtraces from x86 code. 20808d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj*/ 20818d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardjBool guest_x86_state_requires_precise_mem_exns ( Int minoff, 20828d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int maxoff) 20838d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj{ 20844cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_min = offsetof(VexGuestX86State, guest_EBP); 20854cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_max = ebp_min + 4 - 1; 20868d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_min = offsetof(VexGuestX86State, guest_ESP); 20878d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_max = esp_min + 4 - 1; 20888d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_min = offsetof(VexGuestX86State, guest_EIP); 20898d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_max = eip_min + 4 - 1; 20908d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 20914cca75cb48776ceda40e8e305232d85f62021804sewardj if (maxoff < ebp_min || minoff > ebp_max) { 20924cca75cb48776ceda40e8e305232d85f62021804sewardj /* no overlap with ebp */ 20934cca75cb48776ceda40e8e305232d85f62021804sewardj } else { 20944cca75cb48776ceda40e8e305232d85f62021804sewardj return True; 20954cca75cb48776ceda40e8e305232d85f62021804sewardj } 20964cca75cb48776ceda40e8e305232d85f62021804sewardj 20978d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj if (maxoff < esp_min || minoff > esp_max) { 2098eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* no overlap with esp */ 20998d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2100eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 21018d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 21028d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 21038d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj if (maxoff < eip_min || minoff > eip_max) { 2104eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* no overlap with eip */ 21058d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2106eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 21078d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 21088d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 21098d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj return False; 21108d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj} 21118d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 21128d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 2113eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj#define ALWAYSDEFD(field) \ 2114eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj { offsetof(VexGuestX86State, field), \ 2115eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj (sizeof ((VexGuestX86State*)0)->field) } 2116eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2117eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardjVexGuestLayout 211849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj x86guest_layout 2119eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj = { 2120eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Total size of the guest state, in bytes. */ 2121eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .total_sizeB = sizeof(VexGuestX86State), 2122eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2123eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe the stack pointer. */ 2124eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .offset_SP = offsetof(VexGuestX86State,guest_ESP), 2125eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .sizeof_SP = 4, 2126eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2127cf7879021370aabcccb1a9347244fcc7d5680141sewardj /* Describe the instruction pointer. */ 2128cf7879021370aabcccb1a9347244fcc7d5680141sewardj .offset_IP = offsetof(VexGuestX86State,guest_EIP), 2129cf7879021370aabcccb1a9347244fcc7d5680141sewardj .sizeof_IP = 4, 2130eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2131eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe any sections to be regarded by Memcheck as 2132eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 'always-defined'. */ 21336d26984a0df6a7d20b658bac6edf869eb872cca3sewardj .n_alwaysDefd = 22, 21343bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 21352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* flags thunk: OP and NDEP are always defd, whereas DEP1 21362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj and DEP2 have to be tracked. See detailed comment in 21372a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj gdefs.h on meaning of thunk fields. */ 21388fc937421c954ff9f707254f028b1fa0410c473dsewardj .alwaysDefd 21398fc937421c954ff9f707254f028b1fa0410c473dsewardj = { /* 0 */ ALWAYSDEFD(guest_CC_OP), 21408fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), 21418fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 2 */ ALWAYSDEFD(guest_DFLAG), 21428fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 3 */ ALWAYSDEFD(guest_IDFLAG), 21436d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 4 */ ALWAYSDEFD(guest_ACFLAG), 21446d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 5 */ ALWAYSDEFD(guest_EIP), 21456d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 6 */ ALWAYSDEFD(guest_FTOP), 21466d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 7 */ ALWAYSDEFD(guest_FPTAG), 21476d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 8 */ ALWAYSDEFD(guest_FPROUND), 21486d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 9 */ ALWAYSDEFD(guest_FC3210), 21496d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 10 */ ALWAYSDEFD(guest_CS), 21506d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 11 */ ALWAYSDEFD(guest_DS), 21516d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 12 */ ALWAYSDEFD(guest_ES), 21526d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 13 */ ALWAYSDEFD(guest_FS), 21536d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 14 */ ALWAYSDEFD(guest_GS), 21546d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 15 */ ALWAYSDEFD(guest_SS), 21556d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 16 */ ALWAYSDEFD(guest_LDT), 21566d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 17 */ ALWAYSDEFD(guest_GDT), 21576d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 18 */ ALWAYSDEFD(guest_EMWARN), 21586d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 19 */ ALWAYSDEFD(guest_SSEROUND), 21596d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 20 */ ALWAYSDEFD(guest_TISTART), 21606d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 21 */ ALWAYSDEFD(guest_TILEN) 21618fc937421c954ff9f707254f028b1fa0410c473dsewardj } 2162eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj }; 216349651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 216449651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 216536ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2166c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- end guest-x86/ghelpers.c ---*/ 216736ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2168