136ca51378f8851635df814230fa23f2c409b9eddsewardj 236ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin guest_x86_helpers.c ---*/ 436ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 536ca51378f8851635df814230fa23f2c409b9eddsewardj 6f8ed9d874a7b8651654591c68c6d431c758d787csewardj/* 7752f90673ebbb6b2f55fc5e46606dea371313713sewardj This file is part of Valgrind, a dynamic binary instrumentation 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj framework. 9f8ed9d874a7b8651654591c68c6d431c758d787csewardj 1089ae8477745fd2a15453557d729a50e627325ee2sewardj Copyright (C) 2004-2013 OpenWorks LLP 11752f90673ebbb6b2f55fc5e46606dea371313713sewardj info@open-works.net 127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 13752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is free software; you can redistribute it and/or 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj modify it under the terms of the GNU General Public License as 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj published by the Free Software Foundation; either version 2 of the 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj License, or (at your option) any later version. 177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 18752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is distributed in the hope that it will be useful, but 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj General Public License for more details. 22752f90673ebbb6b2f55fc5e46606dea371313713sewardj 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj You should have received a copy of the GNU General Public License 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj along with this program; if not, write to the Free Software 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 02110-1301, USA. 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 28752f90673ebbb6b2f55fc5e46606dea371313713sewardj The GNU General Public License is contained in the file COPYING. 29f8ed9d874a7b8651654591c68c6d431c758d787csewardj 30f8ed9d874a7b8651654591c68c6d431c758d787csewardj Neither the names of the U.S. Department of Energy nor the 31f8ed9d874a7b8651654591c68c6d431c758d787csewardj University of California nor the names of its contributors may be 32f8ed9d874a7b8651654591c68c6d431c758d787csewardj used to endorse or promote products derived from this software 33f8ed9d874a7b8651654591c68c6d431c758d787csewardj without prior written permission. 34f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/ 35f8ed9d874a7b8651654591c68c6d431c758d787csewardj 3636ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_basictypes.h" 3733b024301d2311965cc68dc4cc900f3d0fdd8085florian#include "libvex_emnote.h" 380c2cb623cca372a2b42b073121c7413cdaaf75besewardj#include "libvex_guest_x86.h" 3936ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_ir.h" 4049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj#include "libvex.h" 41c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj 42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 436c46befd9eb90c1b6e739926c1fa335cba75bf46philippe#include "main_globals.h" 44cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h" 45cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_x86_defs.h" 46cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_x87.h" 47c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 48893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 4936ca51378f8851635df814230fa23f2c409b9eddsewardj/* This file contains helper functions for x86 guest code. 5036ca51378f8851635df814230fa23f2c409b9eddsewardj Calls to these functions are generated by the back end. 5136ca51378f8851635df814230fa23f2c409b9eddsewardj These calls are of course in the host machine code and 5236ca51378f8851635df814230fa23f2c409b9eddsewardj this file will be compiled to host machine code, so that 5336ca51378f8851635df814230fa23f2c409b9eddsewardj all makes sense. 5436ca51378f8851635df814230fa23f2c409b9eddsewardj 5536ca51378f8851635df814230fa23f2c409b9eddsewardj Only change the signatures of these helper functions very 5636ca51378f8851635df814230fa23f2c409b9eddsewardj carefully. If you change the signature here, you'll have to change 5736ca51378f8851635df814230fa23f2c409b9eddsewardj the parameters passed to it in the IR calls constructed by 582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj guest-x86/toIR.c. 5989050e58e7bee40892662fe94231aefc33768cf5sewardj 60893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj The convention used is that all functions called from generated 61893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj code are named x86g_<something>, and any function whose name lacks 62893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj that prefix is not called from generated code. Note that some 63893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj LibVEX_* functions can however be called by VEX's client, but that 64893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj is not the same as calling them from VEX-generated code. 6536ca51378f8851635df814230fa23f2c409b9eddsewardj*/ 6636ca51378f8851635df814230fa23f2c409b9eddsewardj 67893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 6884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Set to 1 to get detailed profiling info about use of the flag 6984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj machinery. */ 7084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#define PROFILE_EFLAGS 0 7184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 73893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 74893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags run-time helpers. ---*/ 75893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 76893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 77d44bc6e6692dfb0881dcc249bd4ba3d8f8e97fcasewardjstatic const UChar parity_table[256] = { 782a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 792a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 802a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 812a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 822a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 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 X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 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 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 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 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 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 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 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, 11014731f22bf7759d6d23383ca870ac89d9581f1e9sewardj}; 11114731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1124a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* generalised left-shifter */ 113df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardjinline static Int lshift ( Int x, Int n ) 11414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj{ 115df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj if (n >= 0) 116108e03fcb0a4ef42164235b1988aa540aa1e5298florian return (UInt)x << n; 117df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj else 118df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj return x >> (-n); 11914731f22bf7759d6d23383ca870ac89d9581f1e9sewardj} 12014731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1214a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* identity on ULong */ 1224a6f3844a29aebc9774ab0d71418421c14ba9c41sewardjstatic inline ULong idULong ( ULong x ) 1234a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj{ 1244a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj return x; 1254a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj} 1264a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 12714731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 128b9c5cf639b3b21b972599d27207a033afc76ef67sewardj#define PREAMBLE(__data_bits) \ 129df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* const */ UInt DATA_MASK \ 130b9c5cf639b3b21b972599d27207a033afc76ef67sewardj = __data_bits==8 ? 0xFF \ 131b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : (__data_bits==16 ? 0xFFFF \ 132b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : 0xFFFFFFFF); \ 133108e03fcb0a4ef42164235b1988aa540aa1e5298florian /* const */ UInt SIGN_MASK = 1u << (__data_bits - 1); \ 1342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP1 = cc_dep1_formal; \ 1352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP2 = cc_dep2_formal; \ 1362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_NDEP = cc_ndep_formal; \ 1372a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* Four bogus assignments, which hopefully gcc can */ \ 138df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* optimise away, and which stop it complaining about */ \ 139df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* unused variables. */ \ 140df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj SIGN_MASK = SIGN_MASK; \ 141df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj DATA_MASK = DATA_MASK; \ 1422a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_DEP2 = CC_DEP2; \ 1432a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_NDEP = CC_NDEP; 144df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj 14514731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 146b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 147b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 148df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE) \ 149b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 150b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 151108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 152108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, res; \ 1538fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1548fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1558fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL + argR; \ 1568fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 1578fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1588fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1598fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1608fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1618fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 1622a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1638fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1648fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1652ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1662ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 167b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 168b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 1692a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE) \ 170b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 171b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 172108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 173108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, res; \ 1748fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1758fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1768fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL - argR; \ 1778fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 1788fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1798fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1808fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1818fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1828fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 1832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1848fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1858fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1862ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1872ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 188b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 189b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 1902a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE) \ 191b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 192b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 193108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 194108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, oldC, res; \ 1952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 1968fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1978fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 1988fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL + argR) + oldC; \ 1998fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 2008fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 2018fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2028fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 2038fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2048fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2058fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2068fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2078fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 2082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2098fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2108fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 2112ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 2122ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 213b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 214b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 215df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE) \ 216b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 217b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 218108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 219108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, oldC, res; \ 2202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 2218fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 2228fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 2238fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL - argR) - oldC; \ 2248fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 2258fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR; \ 2268fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2278fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 2288fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2298fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2308fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2318fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2328fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 2332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2348fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2358fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 236a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 237a238471814bd386aeb58a76718b41e68b1a794b2sewardj 238b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 239b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 240df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE) \ 241b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 242b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 243108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 2448fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = 0; \ 2458fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 2468fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; \ 2478fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 2488fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 2498fc937421c954ff9f707254f028b1fa0410c473dsewardj of = 0; \ 2508fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2518fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 252a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 253a238471814bd386aeb58a76718b41e68b1a794b2sewardj 254b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 255b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 256df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_INC(DATA_BITS,DATA_UTYPE) \ 257b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 258b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 259108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 260108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, res; \ 2618fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2628fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res - 1; \ 2638fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2658fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2668fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2678fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2688fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2698fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) == SIGN_MASK) << 11; \ 2708fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2718fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 27289050e58e7bee40892662fe94231aefc33768cf5sewardj} 27389050e58e7bee40892662fe94231aefc33768cf5sewardj 274b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 275b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 276df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE) \ 277b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 278b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 279108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 280108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt argL, argR, res; \ 2818fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2828fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res + 1; \ 2838fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2858fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2868fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2878fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2888fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2898fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) \ 2908fc937421c954ff9f707254f028b1fa0410c473dsewardj == ((UInt)SIGN_MASK - 1)) << 11; \ 2918fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2928fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 29389050e58e7bee40892662fe94231aefc33768cf5sewardj} 29489050e58e7bee40892662fe94231aefc33768cf5sewardj 295b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 296b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 297df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE) \ 298b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 299b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 300108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 3012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (CC_DEP2 >> (DATA_BITS - 1)) & X86G_CC_MASK_C; \ 3028fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3038fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3048fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3058fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3068fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3098fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3108fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3115f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3125f6303579435ddb8315e11c2f02c904b978782a0sewardj 313b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 314b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3152a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE) \ 316b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 317b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 318108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 3198fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = CC_DEP2 & 1; \ 3208fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3218fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3228fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3238fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3248fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3262a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3278fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3288fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3295f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3305f6303579435ddb8315e11c2f02c904b978782a0sewardj 331b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 332b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3338ee2de1f5f72c13120f59c0ca6ac8291219123dfsewardj/* ROL: cf' = lsb(result). of' = msb(result) ^ lsb(result). */ 3342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 335df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE) \ 336b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 337b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 338108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt fl \ 3392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & CC_DEP1) \ 3412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3438fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11))); \ 3448fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3458fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3468c7f1abe9e022f6382634efea09c9cac89ec6336sewardj} 3478c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 348b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 349b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3501813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj/* ROR: cf' = msb(result). of' = msb(result) ^ msb-1(result). */ 3512a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 352df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE) \ 353b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 354b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 355108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt fl \ 3562a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1))) \ 3582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3592a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3608fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1))); \ 3618fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3628fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3631813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj} 3641813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 365b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 366b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3674a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_UMUL(DATA_BITS, DATA_UTYPE, NARROWtoU, \ 3684a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE, NARROWto2U) \ 3692a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 3702a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 371108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 3728fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_UTYPE hi; \ 3734a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_UTYPE lo \ 3744a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ 3754a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_UTYPE)CC_DEP2) ); \ 3764a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE rr \ 3774a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2U( \ 3784a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ 3794a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ 3804a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ 3818fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != 0); \ 3828fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 3838fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3848fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 3858fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 3868fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 3878fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3888fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 38956296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj} 39056296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj 391b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 392b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3934a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ 3944a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE, NARROWto2S) \ 3952a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 3962a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 397108e03fcb0a4ef42164235b1988aa540aa1e5298florian { UInt cf, pf, af, zf, sf, of; \ 3988fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_STYPE hi; \ 3994a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_STYPE lo \ 40045f8de626643cea67d0741f2b8a0b33dc69cbf84florian = NARROWtoS( ((DATA_S2TYPE)(DATA_STYPE)CC_DEP1) \ 40145f8de626643cea67d0741f2b8a0b33dc69cbf84florian * ((DATA_S2TYPE)(DATA_STYPE)CC_DEP2) ); \ 4024a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE rr \ 4034a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2S( \ 4044a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ 4054a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ 4064a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ 4078fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ 4088fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 4098fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 4108fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 4118fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 4128fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 4138fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 4148fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 4157ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj} 416741153c4301023a420ab45b8a10b8e1bac968822sewardj 41736ca51378f8851635df814230fa23f2c409b9eddsewardj 41884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#if PROFILE_EFLAGS 41984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 4209eab588e223e52b1e7b710ff1c0da7b032ab2837sewardjstatic Bool initted = False; 421893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 422893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, fast route */ 423893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_fast[X86G_CC_OP_NUMBER]; 424893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, slow route */ 425893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_slow[X86G_CC_OP_NUMBER]; 426893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* table for calculate_cond */ 427893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tab_cond[X86G_CC_OP_NUMBER][16]; 428893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* total entry counts for calc_all, calc_c, calc_cond. */ 42984ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_all = 0; 43084ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_c = 0; 431893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt n_calc_cond = 0; 432893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 433893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond))) 434893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 43584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 43684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void showCounts ( void ) 43784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 43884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 4395df8ab0739ec95e8de9d9f43fa0e68b3e7125554florian HChar ch; 440a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", 441893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all, n_calc_cond, n_calc_c); 442893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 443893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" 44484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj " S NS P NP L NL LE NLE\n"); 445893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" -----------------------------------------------------" 44684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj "----------------------------------------\n"); 4472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 44884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 44984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = ' '; 45093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 0) 45193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'B'; 45293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 1) 45393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'W'; 45484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (op > 0 && (op-1) % 3 == 2) 45584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = 'L'; 45684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 45784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("%2d%c: ", op, ch); 458a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_slow[op]); 459a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_fast[op]); 46084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) { 461893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int n = tab_cond[op][co]; 46284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 1000) { 46384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %3dK", n / 1000); 46484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else 46584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 0) { 466893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" %3d ", n ); 46784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else { 46884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 46984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 47084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 47184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 47284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 47384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 47484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 47584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 47684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void initCounts ( void ) 47784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 47884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 47984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj initted = True; 4802a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 481893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[op] = tabc_slow[op] = 0; 48284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) 483893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[op][co] = 0; 48484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 48584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 48684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 48784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#endif /* PROFILE_EFLAGS */ 48884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 489893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 4909aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 491893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. 492893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Worker function, not directly called from generated code. */ 493893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic 494893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all_WRK ( UInt cc_op, 495893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1_formal, 496893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2_formal, 497893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep_formal ) 49836ca51378f8851635df814230fa23f2c409b9eddsewardj{ 49936ca51378f8851635df814230fa23f2c409b9eddsewardj switch (cc_op) { 5002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_COPY: 5012a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj return cc_dep1_formal 5022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & (X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 5032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P); 50414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 5052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); 5062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); 5072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); 508a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); 5102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); 5112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); 512a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); 5142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); 5152a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); 516afc5787e1c4b8e9678669577cf57ac509c6cd6b5sewardj 5172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); 5182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); 5192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); 520741153c4301023a420ab45b8a10b8e1bac968822sewardj 5212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); 5222a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); 5232a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); 5245f6303579435ddb8315e11c2f02c904b978782a0sewardj 5252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); 5262a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); 5272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); 5281813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); 5302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); 5312a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); 5328c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); 5342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); 5352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); 5368c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); 5382a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); 5392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); 5401813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); 5422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); 5432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); 544750f407b6be1aac303964a219acf0a6de8b8c4dasewardj 5452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); 5462a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); 5472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); 5487ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj 5494a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, 5504a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UShort, toUShort ); 5514a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, 5524a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UInt, toUInt ); 5534a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, 5544a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ULong, idULong ); 5554a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 5564a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, 5574a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Short, toUShort ); 5584a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, 5594a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Int, toUInt ); 5604a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, 5614a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Long, idULong ); 562741153c4301023a420ab45b8a10b8e1bac968822sewardj 56336ca51378f8851635df814230fa23f2c409b9eddsewardj default: 56436ca51378f8851635df814230fa23f2c409b9eddsewardj /* shouldn't really make these calls from generated code */ 565893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("x86g_calculate_eflags_all_WRK(X86)" 566a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj "( %u, 0x%x, 0x%x, 0x%x )\n", 5672a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); 568893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_eflags_all_WRK(X86)"); 56936ca51378f8851635df814230fa23f2c409b9eddsewardj } 57036ca51378f8851635df814230fa23f2c409b9eddsewardj} 57136ca51378f8851635df814230fa23f2c409b9eddsewardj 572b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 5739aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 574893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. */ 575893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all ( UInt cc_op, 576893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1, 577893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2, 578893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep ) 579893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 580893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 581893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 582893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all++; 583893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 584893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 585893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 586893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_calculate_eflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep ); 587893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 588893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 589893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 590893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 591b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/* Calculate just the carry flag from the supplied thunk parameters. */ 59203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(3) 5932a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_eflags_c ( UInt cc_op, 5942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 5952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 5962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 59736ca51378f8851635df814230fa23f2c409b9eddsewardj{ 598893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 599893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 600893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_c++; 601893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]++; 602893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 603893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 604893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 6059eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj /* Fast-case some common ones. */ 60643c46951628d616290f7245c3af2f9a652180806sewardj switch (cc_op) { 6072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: 6082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: 6092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: 61043c46951628d616290f7245c3af2f9a652180806sewardj return 0; 6112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: 61293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)cc_dep1) < ((UInt)cc_dep2) 6132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 614893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj case X86G_CC_OP_SUBW: 615893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) 616893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ? X86G_CC_MASK_C : 0; 6172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: 61893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) 6192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 620e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj case X86G_CC_OP_INCL: 6212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: 622e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj return cc_ndep & X86G_CC_MASK_C; 62343c46951628d616290f7245c3af2f9a652180806sewardj default: 62443c46951628d616290f7245c3af2f9a652180806sewardj break; 62543c46951628d616290f7245c3af2f9a652180806sewardj } 6269eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj 62784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 628893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]--; 629893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_slow[cc_op]++; 63084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 631893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 632893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return x86g_calculate_eflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) 6332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_C; 63436ca51378f8851635df814230fa23f2c409b9eddsewardj} 63536ca51378f8851635df814230fa23f2c409b9eddsewardj 63636ca51378f8851635df814230fa23f2c409b9eddsewardj 6379aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 63884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* returns 1 or 0 */ 6392a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_condition ( UInt/*X86Condcode*/ cond, 6402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_op, 6412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 6422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 6432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 6442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{ 645893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK(cc_op, cc_dep1, 646893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2, cc_ndep); 64784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt of,sf,zf,cf,pf; 64884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt inv = cond & 1; 64984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 65084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 651893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 652893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[cc_op][cond]++; 65384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj n_calc_cond++; 654893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 65584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 65684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 65784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj switch (cond) { 6582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNO: 6592a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondO: /* OF == 1 */ 6602a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 66184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ of); 66284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNZ: 6642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondZ: /* ZF == 1 */ 6652a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 66684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ zf); 66784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNB: 6692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondB: /* CF == 1 */ 6702a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 67184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ cf); 67284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 67384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNBE: 6752a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondBE: /* (CF or ZF) == 1 */ 6762a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 6772a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 67884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (cf | zf)); 67984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 68084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6812a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNS: 6822a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondS: /* SF == 1 */ 6832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 68484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ sf); 68584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNP: 6872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondP: /* PF == 1 */ 6882a9ad023890d3b34cf45e429df2a8ae88b419128sewardj pf = eflags >> X86G_CC_SHIFT_P; 68984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ pf); 69084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNL: 6922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondL: /* (SF xor OF) == 1 */ 6932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 6942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 69584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (sf ^ of)); 69684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 69784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNLE: 6992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondLE: /* ((SF xor OF) or ZF) == 1 */ 7002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 7012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 7022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 70384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ ((sf ^ of) | zf)); 70484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 70584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 70684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj default: 70784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* shouldn't really make these calls from generated code */ 708a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("x86g_calculate_condition( %u, %u, 0x%x, 0x%x, 0x%x )\n", 7092a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); 710893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_condition"); 71184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 71284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 71384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 71484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 715893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 716efa834abaded25c8aff2f3923e476ef7cc1d0396florianUInt LibVEX_GuestX86_get_eflags ( /*IN*/const VexGuestX86State* vex_state ) 717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK( 719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP, 720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1, 721893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2, 722893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP 723893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 724893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt dflag = vex_state->guest_DFLAG; 725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(dflag == 1 || dflag == 0xFFFFFFFF); 726893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (dflag == 0xFFFFFFFF) 727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<10); 728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_state->guest_IDFLAG == 1) 729893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<21); 7306d26984a0df6a7d20b658bac6edf869eb872cca3sewardj if (vex_state->guest_ACFLAG == 1) 7316d26984a0df6a7d20b658bac6edf869eb872cca3sewardj eflags |= (1<<18); 732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return eflags; 734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 735893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 736f32d5a5dd44a6d490c901949114d86441c24ef92sewardj/* VISIBLE TO LIBVEX CLIENT */ 737f32d5a5dd44a6d490c901949114d86441c24ef92sewardjvoid 738f32d5a5dd44a6d490c901949114d86441c24ef92sewardjLibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag, 739f32d5a5dd44a6d490c901949114d86441c24ef92sewardj /*MOD*/VexGuestX86State* vex_state ) 740f32d5a5dd44a6d490c901949114d86441c24ef92sewardj{ 741f32d5a5dd44a6d490c901949114d86441c24ef92sewardj UInt oszacp = x86g_calculate_eflags_all_WRK( 742f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_OP, 743f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP1, 744f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP2, 745f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_NDEP 746f32d5a5dd44a6d490c901949114d86441c24ef92sewardj ); 747f32d5a5dd44a6d490c901949114d86441c24ef92sewardj if (new_carry_flag & 1) { 748f32d5a5dd44a6d490c901949114d86441c24ef92sewardj oszacp |= X86G_CC_MASK_C; 749f32d5a5dd44a6d490c901949114d86441c24ef92sewardj } else { 750f32d5a5dd44a6d490c901949114d86441c24ef92sewardj oszacp &= ~X86G_CC_MASK_C; 751f32d5a5dd44a6d490c901949114d86441c24ef92sewardj } 752f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_OP = X86G_CC_OP_COPY; 753f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP1 = oszacp; 754f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP2 = 0; 755f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_NDEP = 0; 756f32d5a5dd44a6d490c901949114d86441c24ef92sewardj} 757f32d5a5dd44a6d490c901949114d86441c24ef92sewardj 758893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 759893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 760893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags translation-time function specialisers. ---*/ 761893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- These help iropt specialise calls the above run-time ---*/ 762893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags functions. ---*/ 763893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 764893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 76584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Used by the optimiser to try specialisations. Returns an 76684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj equivalent expression, or NULL if none. */ 76784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 768908854045e8ebf1495663bb50801c32d6f729bbesewardjstatic inline Bool isU32 ( IRExpr* e, UInt n ) 76984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 770a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return 771a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj toBool( e->tag == Iex_Const 772a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->tag == Ico_U32 773a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->Ico.U32 == n ); 77484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 77584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7761ff4756e1731485e6bf3cd96717cd8398daec1f2florianIRExpr* guest_x86_spechelper ( const HChar* function_name, 777be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRExpr** args, 778be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRStmt** precedingStmts, 779be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj Int n_precedingStmts ) 78084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 78184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 78284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 78384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 7844afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 78584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 78684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int i, arity = 0; 78784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; args[i]; i++) 78884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj arity++; 78984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if 0 79084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("spec request:\n"); 79184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %s ", function_name); 79284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; i < arity; i++) { 79384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 79484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ppIRExpr(args[i]); 79584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 79684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 79784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 79893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 7993835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj /* --------- specialising "x86g_calculate_condition" --------- */ 80093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 8013835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj if (vex_streq(function_name, "x86g_calculate_condition")) { 80284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* specialise calls to above "calculate condition" function */ 803a8415ffe6c6f0e73519301a55026a4071c701fd1sewardj IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2; 80493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj vassert(arity == 5); 80593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cond = args[0]; 80693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_op = args[1]; 80793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep1 = args[2]; 80893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep2 = args[3]; 80984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 810d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- ADDL ----------------*/ 811d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 8122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_ADDL) && isU32(cond, X86CondZ)) { 813d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* long add, then Z --> test (dst+src == 0) */ 814d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 815d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, 816d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_Add32, cc_dep1, cc_dep2), 817d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 818d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 819d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 82046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBL ----------------*/ 82146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8222a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondZ)) { 82346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then Z --> test dst==src */ 82484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 82593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, cc_dep1, cc_dep2)); 82646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 82766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNZ)) { 82866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long sub/cmp, then NZ --> test dst!=src */ 82966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32, 83066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj binop(Iop_CmpNE32, cc_dep1, cc_dep2)); 83166f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 83266f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 8332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondL)) { 83446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then L (signed less than) 83546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <s src */ 83646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 83793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLT32S, cc_dep1, cc_dep2)); 83846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8398a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNL)) { 8408a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NL (signed greater than or equal) 8418a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <s src) */ 8428a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8438a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8448a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32S, cc_dep1, cc_dep2)), 8458a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8468a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8478a81970fd71af3fa5725b85c65c7540a441071bfsewardj 8482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondLE)) { 84946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then LE (signed less than or equal) 85046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=s src */ 85146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 85293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32S, cc_dep1, cc_dep2)); 85346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8542eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNLE)) { 855c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* long sub/cmp, then NLE (signed not less than or equal) 8562eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj --> test dst >s src 8572eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj --> test !(dst <=s src) */ 8582eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj return binop(Iop_Xor32, 8592eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj unop(Iop_1Uto32, 8602eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj binop(Iop_CmpLE32S, cc_dep1, cc_dep2)), 8612eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj mkU32(1)); 8622eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj } 8632eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj 8642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondBE)) { 86546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then BE (unsigned less than or equal) 86646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=u src */ 86746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 86893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32U, cc_dep1, cc_dep2)); 86946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8708a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNBE)) { 8718a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then BE (unsigned greater than) 8728a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <=u src) */ 8738a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8748a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8758a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLE32U, cc_dep1, cc_dep2)), 8768a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8778a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8788a81970fd71af3fa5725b85c65c7540a441071bfsewardj 8792a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondB)) { 88046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then B (unsigned less than) 88146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <u src */ 88246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 883e664ec4b9f27ed7d7ca87a2d4188fd479059351csewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 88484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 8858a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNB)) { 8868a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NB (unsigned greater than or equal) 8878a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <u src) */ 8888a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8898a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8908a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)), 8918a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8928a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8938a81970fd71af3fa5725b85c65c7540a441071bfsewardj 894e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)) { 8958a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then S (negative) --> test (dst-src <s 0) */ 896e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return unop(Iop_1Uto32, 897e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_CmpLT32S, 898e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Sub32, cc_dep1, cc_dep2), 899e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(0))); 900e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 9011ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNS)) { 9028a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NS (not negative) --> test !(dst-src <s 0) */ 9038a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 9048a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 9058a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32S, 9068a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_Sub32, cc_dep1, cc_dep2), 9078a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(0))), 9088a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 9091ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj } 9101ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj 91146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBW ----------------*/ 91246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 9132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondZ)) { 914c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* word sub/cmp, then Z --> test dst==src */ 915b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 916b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ16, 9177e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep1), 9187e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep2))); 919b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 920beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondNZ)) { 921beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj /* word sub/cmp, then NZ --> test dst!=src */ 922beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj return unop(Iop_1Uto32, 923beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj binop(Iop_CmpNE16, 924beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_32to16,cc_dep1), 925beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_32to16,cc_dep2))); 926beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj } 927b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 92846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBB ----------------*/ 9297e6644c38b3e0148ff95c2f6f4667f54148b611esewardj 9302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondZ)) { 931b9c5cf639b3b21b972599d27207a033afc76ef67sewardj /* byte sub/cmp, then Z --> test dst==src */ 93284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 933b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ8, 93493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 93593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 93684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 9372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNZ)) { 9387e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* byte sub/cmp, then NZ --> test dst!=src */ 93984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 940b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpNE8, 94193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 94293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 943b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 94422419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 9452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNBE)) { 946c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* byte sub/cmp, then NBE (unsigned greater than) 947dc12d39f7112dd57bae91b1f87963d0acaa2e71asewardj --> test src <u dst */ 9487e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* Note, args are opposite way round from the usual */ 949b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 950b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpLT32U, 9517e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)), 9527e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)))); 95384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 95484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 955908854045e8ebf1495663bb50801c32d6f729bbesewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondS) 956908854045e8ebf1495663bb50801c32d6f729bbesewardj && isU32(cc_dep2, 0)) { 957c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* byte sub/cmp of zero, then S --> test (dst-0 <s 0) 958c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj --> test dst <s 0 959c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj --> (UInt)dst[7] 960908854045e8ebf1495663bb50801c32d6f729bbesewardj This is yet another scheme by which gcc figures out if the 961908854045e8ebf1495663bb50801c32d6f729bbesewardj top bit of a byte is 1 or 0. See also LOGICB/CondS below. */ 962908854045e8ebf1495663bb50801c32d6f729bbesewardj /* Note: isU32(cc_dep2, 0) is correct, even though this is 963908854045e8ebf1495663bb50801c32d6f729bbesewardj for an 8-bit comparison, since the args to the helper 964908854045e8ebf1495663bb50801c32d6f729bbesewardj function are always U32s. */ 965908854045e8ebf1495663bb50801c32d6f729bbesewardj return binop(Iop_And32, 966908854045e8ebf1495663bb50801c32d6f729bbesewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 967908854045e8ebf1495663bb50801c32d6f729bbesewardj mkU32(1)); 968908854045e8ebf1495663bb50801c32d6f729bbesewardj } 9699a3431c38a2e435c58a5e027943f50fa35c2369csewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNS) 9709a3431c38a2e435c58a5e027943f50fa35c2369csewardj && isU32(cc_dep2, 0)) { 9719a3431c38a2e435c58a5e027943f50fa35c2369csewardj /* byte sub/cmp of zero, then NS --> test !(dst-0 <s 0) 9729a3431c38a2e435c58a5e027943f50fa35c2369csewardj --> test !(dst <s 0) 9739a3431c38a2e435c58a5e027943f50fa35c2369csewardj --> (UInt) !dst[7] 9749a3431c38a2e435c58a5e027943f50fa35c2369csewardj */ 9759a3431c38a2e435c58a5e027943f50fa35c2369csewardj return binop(Iop_Xor32, 9769a3431c38a2e435c58a5e027943f50fa35c2369csewardj binop(Iop_And32, 9779a3431c38a2e435c58a5e027943f50fa35c2369csewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 9789a3431c38a2e435c58a5e027943f50fa35c2369csewardj mkU32(1)), 9799a3431c38a2e435c58a5e027943f50fa35c2369csewardj mkU32(1)); 9809a3431c38a2e435c58a5e027943f50fa35c2369csewardj } 9819a3431c38a2e435c58a5e027943f50fa35c2369csewardj 98246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICL ----------------*/ 98346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 9842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondZ)) { 98584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then Z --> test dst==0 */ 98693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 98784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 988b83767e0691bcd985a0f4986e42e013585db3e55sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNZ)) { 989b83767e0691bcd985a0f4986e42e013585db3e55sewardj /* long and/or/xor, then NZ --> test dst!=0 */ 990b83767e0691bcd985a0f4986e42e013585db3e55sewardj return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0))); 991b83767e0691bcd985a0f4986e42e013585db3e55sewardj } 992b83767e0691bcd985a0f4986e42e013585db3e55sewardj 9932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondLE)) { 99484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then LE 99584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj This is pretty subtle. LOGIC sets SF and ZF according to the 99684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj result and makes OF be zero. LE computes (SZ ^ OF) | ZF, but 99784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj OF is zero, so this reduces to SZ | ZF -- which will be 1 iff 99884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj the result is <=signed 0. Hence ... 99984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj */ 100093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpLE32S, cc_dep1, mkU32(0))); 100184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 100284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 100366f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondBE)) { 100466f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long and/or/xor, then BE 100566f7a54d5425853debcb5fe77be1021f0c2b6620sewardj LOGIC sets ZF according to the result and makes CF be zero. 100666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj BE computes (CF | ZF), but CF is zero, so this reduces ZF 100766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj -- which will be 1 iff the result is zero. Hence ... 100866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj */ 100966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 101066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 101166f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 101254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) { 101354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* see comment below for (LOGICB, CondS) */ 101454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* long and/or/xor, then S --> (UInt)result[31] */ 101554be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 101654be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(31)), 101754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 101854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 1019275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNS)) { 1020275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* see comment below for (LOGICB, CondNS) */ 1021275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* long and/or/xor, then S --> (UInt) ~ result[31] */ 1022275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return binop(Iop_Xor32, 1023275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_And32, 1024275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shr32,cc_dep1,mkU8(31)), 1025275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)), 1026275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)); 1027275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 102854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 1029d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- LOGICW ----------------*/ 1030d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 10312a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) { 1032c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* word and/or/xor, then Z --> test dst==0 */ 1033d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 1034d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(0xFFFF)), 1035d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 1036d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 1037d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 103854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondS)) { 103954be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* see comment below for (LOGICB, CondS) */ 104054be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* word and/or/xor, then S --> (UInt)result[15] */ 104154be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 104254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(15)), 104354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 104454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 104554be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 104646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICB ----------------*/ 104784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 10482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) { 104946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* byte and/or/xor, then Z --> test dst==0 */ 105084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 105193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(255)), 105246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj mkU32(0))); 105384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 1054275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNZ)) { 1055275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* byte and/or/xor, then Z --> test dst!=0 */ 1056275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* b9ac9: 84 c0 test %al,%al 1057275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj b9acb: 75 0d jne b9ada */ 1058275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return unop(Iop_1Uto32, 1059275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_CmpNE32, binop(Iop_And32,cc_dep1,mkU32(255)), 1060275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(0))); 1061275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 1062275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 106354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondS)) { 106454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* this is an idiom gcc sometimes uses to find out if the top 106554be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj bit of a byte register is set: eg testb %al,%al; js .. 106654be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj Since it just depends on the top bit of the byte, extract 106754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj that bit and explicitly get rid of all the rest. This 106854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj helps memcheck avoid false positives in the case where any 106954be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj of the other bits in the byte are undefined. */ 107054be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* byte and/or/xor, then S --> (UInt)result[7] */ 107154be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 107254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 107354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 107454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 1075275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNS)) { 1076275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* ditto, for negation-of-S. */ 1077275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* byte and/or/xor, then S --> (UInt) ~ result[7] */ 1078275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return binop(Iop_Xor32, 1079275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_And32, 1080275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 1081275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)), 1082275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)); 1083275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 108454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 108546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- DECL ----------------*/ 1086af991dede2815b7570828b9d9174cf989e636254sewardj 10872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondZ)) { 108884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* dec L, then Z --> test dst == 0 */ 108993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 109084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 109122419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 10922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondS)) { 1093fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj /* dec L, then S --> compare DST <s 0 */ 10947e6644c38b3e0148ff95c2f6f4667f54148b611esewardj return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0))); 1095fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj } 1096275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 109732d615b76c65938d815fe529e690a7f79a24a4ecsewardj /*---------------- DECW ----------------*/ 109832d615b76c65938d815fe529e690a7f79a24a4ecsewardj 109932d615b76c65938d815fe529e690a7f79a24a4ecsewardj if (isU32(cc_op, X86G_CC_OP_DECW) && isU32(cond, X86CondZ)) { 110032d615b76c65938d815fe529e690a7f79a24a4ecsewardj /* dec W, then Z --> test dst == 0 */ 110132d615b76c65938d815fe529e690a7f79a24a4ecsewardj return unop(Iop_1Uto32, 110232d615b76c65938d815fe529e690a7f79a24a4ecsewardj binop(Iop_CmpEQ32, 110332d615b76c65938d815fe529e690a7f79a24a4ecsewardj binop(Iop_Shl32,cc_dep1,mkU8(16)), 110432d615b76c65938d815fe529e690a7f79a24a4ecsewardj mkU32(0))); 110532d615b76c65938d815fe529e690a7f79a24a4ecsewardj } 110632d615b76c65938d815fe529e690a7f79a24a4ecsewardj 1107275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /*---------------- INCW ----------------*/ 1108275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 1109275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_INCW) && isU32(cond, X86CondZ)) { 1110275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* This rewrite helps memcheck on 'incw %ax ; je ...'. */ 1111275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* inc W, then Z --> test dst == 0 */ 1112275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return unop(Iop_1Uto32, 1113275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_CmpEQ32, 1114275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shl32,cc_dep1,mkU8(16)), 1115275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(0))); 1116275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 1117fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj 1118d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- SHRL ----------------*/ 1119d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 11202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) { 1121d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* SHRL, then Z --> test dep1 == 0 */ 1122d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 1123d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 1124d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 11254afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /*---------------- COPY ----------------*/ 11264afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /* This can happen, as a result of x87 FP compares: "fcom ... ; 11274afab82eb869f21ccabc3efb5b93f31a5c343956sewardj fnstsw %ax ; sahf ; jbe" for example. */ 11284afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 112966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_COPY) && 113066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj (isU32(cond, X86CondBE) || isU32(cond, X86CondNBE))) { 1131c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then BE --> extract C and Z from dep1, and test 1132c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj (C or Z) == 1. */ 1133c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then NBE --> extract C and Z from dep1, and test 1134c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj (C or Z) == 0. */ 113566f7a54d5425853debcb5fe77be1021f0c2b6620sewardj UInt nnn = isU32(cond, X86CondBE) ? 1 : 0; 11364afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 11374afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 11384afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 11394afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 114066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj Iop_CmpEQ32, 11414afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11424afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 11434afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11444afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_Or32, 11454afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 11464afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)) 11474afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 11484afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 11494afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 115066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj mkU32(nnn) 11514afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 11524afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 11534afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 11544afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 11551ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 11561ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj && (isU32(cond, X86CondB) || isU32(cond, X86CondNB))) { 1157e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then B --> extract C from dep1, and test (C == 1). */ 1158e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then NB --> extract C from dep1, and test (C == 0). */ 1159e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj UInt nnn = isU32(cond, X86CondB) ? 1 : 0; 11604afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 11614afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 11624afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 11634afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 1164e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_CmpEQ32, 11654afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11664afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 11674afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 11684afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 11694afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 1170e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(nnn) 1171e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ) 1172e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ); 1173e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 1174e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj 11751ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 11761ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj && (isU32(cond, X86CondZ) || isU32(cond, X86CondNZ))) { 1177e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */ 11781ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */ 11791ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj UInt nnn = isU32(cond, X86CondZ) ? 1 : 0; 1180e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return 1181e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj unop( 1182e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_1Uto32, 1183e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 11841ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj Iop_CmpEQ32, 1185e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 1186e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_And32, 1187e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)), 1188e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(1) 1189e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ), 11901ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj mkU32(nnn) 11914afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 11924afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 11934afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 11944afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 1195c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 1196c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj && (isU32(cond, X86CondP) || isU32(cond, X86CondNP))) { 1197c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj /* COPY, then P --> extract P from dep1, and test (P == 1). */ 1198c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then NP --> extract P from dep1, and test (P == 0). */ 1199c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj UInt nnn = isU32(cond, X86CondP) ? 1 : 0; 1200c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj return 1201c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj unop( 1202c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj Iop_1Uto32, 1203c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop( 1204c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj Iop_CmpEQ32, 1205c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop( 1206c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj Iop_And32, 1207c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_P)), 1208c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj mkU32(1) 1209c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ), 1210c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj mkU32(nnn) 1211c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ) 1212c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ); 1213c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj } 1214c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj 121584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 121684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 121784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 1218893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_c" --------- */ 1219893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1220893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_c")) { 1221893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_c" function */ 1222893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1223893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1224893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1225893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 1226893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2 = args[2]; 1227893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_ndep = args[3]; 1228893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1229893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBL)) { 1230893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1231893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1232893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 1233893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1234893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBB)) { 1235893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1236893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1237893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, 1238893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)), 1239893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)))); 1240893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1241893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) 1242893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICW) 1243893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICB)) { 1244893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after logic is zero */ 1245893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return mkU32(0); 1246893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1247893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_DECL) || isU32(cc_op, X86G_CC_OP_INCL)) { 1248893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */ 1249893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return cc_ndep; 1250893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1251893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1252893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after COPY is stored in DEP1. */ 1253893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1254893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1255893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1256893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 1257893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(1) 1258893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1259893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1260174c7709cb81c9358d4264a8109e37404338445fsewardj if (isU32(cc_op, X86G_CC_OP_ADDL)) { 1261174c7709cb81c9358d4264a8109e37404338445fsewardj /* C after add denotes sum <u either arg */ 1262174c7709cb81c9358d4264a8109e37404338445fsewardj return unop(Iop_1Uto32, 1263174c7709cb81c9358d4264a8109e37404338445fsewardj binop(Iop_CmpLT32U, 1264174c7709cb81c9358d4264a8109e37404338445fsewardj binop(Iop_Add32, cc_dep1, cc_dep2), 1265174c7709cb81c9358d4264a8109e37404338445fsewardj cc_dep1)); 1266174c7709cb81c9358d4264a8109e37404338445fsewardj } 1267ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // ATC, requires verification, no test case known 1268ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj //if (isU32(cc_op, X86G_CC_OP_SMULL)) { 1269ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // /* C after signed widening multiply denotes the case where 1270ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // the top half of the result isn't simply the sign extension 1271ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // of the bottom half (iow the result doesn't fit completely 1272ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // in the bottom half). Hence: 1273ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // C = hi-half(dep1 x dep2) != lo-half(dep1 x dep2) >>s 31 1274ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // where 'x' denotes signed widening multiply.*/ 1275ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // return 1276ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // unop(Iop_1Uto32, 1277ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_CmpNE32, 1278ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // unop(Iop_64HIto32, 1279ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_MullS32, cc_dep1, cc_dep2)), 1280ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_Sar32, 1281ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_Mul32, cc_dep1, cc_dep2), mkU8(31)) )); 1282ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj //} 1283893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if 0 1284893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (cc_op->tag == Iex_Const) { 1285893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n"); 1286893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1287893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 1288893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1289893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1290893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1291893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1292893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_all" --------- */ 1293893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1294893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_all")) { 1295893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_all" function */ 129640e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj IRExpr *cc_op, *cc_dep1; /*, *cc_dep2, *cc_ndep; */ 1297893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1298893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1299893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 130040e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_dep2 = args[2]; */ 130140e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_ndep = args[3]; */ 1302893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1303893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1304893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* eflags after COPY are stored in DEP1. */ 1305893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1306893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1307893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1308893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1, 1309893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 1310893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P) 1311893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1312893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1313893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1314893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1315893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 131684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef unop 131784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef binop 131884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef mkU32 13194afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# undef mkU8 132084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 132184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 132284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 132384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 132436ca51378f8851635df814230fa23f2c409b9eddsewardj 1325893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1326893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Supporting functions for x87 FPU activities. ---*/ 1327893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1328893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1329893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic inline Bool host_is_little_endian ( void ) 1330893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1331893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt x = 0x76543210; 1332893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* p = (UChar*)(&x); 1333a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toBool(*p == 0x10); 1334893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1335893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 13360c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* 80 and 64-bit floating point formats: 13370c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13380c2cb623cca372a2b42b073121c7413cdaaf75besewardj 80-bit: 13390c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13400c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0-------0 zero 13410c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0X------X denormals 13420c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FFE 1X------X normals (all normals have leading 1) 13430c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10------0 infinity 13440c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10X-----X snan 13450c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 11X-----X qnan 13460c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13470c2cb623cca372a2b42b073121c7413cdaaf75besewardj S is the sign bit. For runs X----X, at least one of the Xs must be 13480c2cb623cca372a2b42b073121c7413cdaaf75besewardj nonzero. Exponent is 15 bits, fractional part is 63 bits, and 13490c2cb623cca372a2b42b073121c7413cdaaf75besewardj there is an explicitly represented leading 1, and a sign bit, 13500c2cb623cca372a2b42b073121c7413cdaaf75besewardj giving 80 in total. 13510c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13520c2cb623cca372a2b42b073121c7413cdaaf75besewardj 64-bit avoids the confusion of an explicitly represented leading 1 13530c2cb623cca372a2b42b073121c7413cdaaf75besewardj and so is simpler: 13540c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13550c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0------0 zero 13560c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 X------X denormals 13570c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FE any normals 13580c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0------0 infinity 13590c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0X-----X snan 13600c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 1X-----X qnan 13610c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13620c2cb623cca372a2b42b073121c7413cdaaf75besewardj Exponent is 11 bits, fractional part is 52 bits, and there is a 13630c2cb623cca372a2b42b073121c7413cdaaf75besewardj sign bit, giving 64 in total. 13640c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/ 13650c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1366893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Inspect a value and its tag, as per the x87 'FXAM' instruction. */ 13679aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 13682a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_FXAM ( UInt tag, ULong dbl ) 1369c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj{ 1370c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Bool mantissaIsZero; 1371c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Int bexp; 1372c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar sign; 1373c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar* f64; 1374c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1375a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vassert(host_is_little_endian()); 1376c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1377c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */ 1378c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1379c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj f64 = (UChar*)(&dbl); 1380a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj sign = toUChar( (f64[7] >> 7) & 1 ); 1381c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1382c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* First off, if the tag indicates the register was empty, 1383c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj return 1,0,sign,1 */ 1384c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (tag == 0) { 1385c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Empty\n"); */ 1386e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 | (sign << X86G_FC_SHIFT_C1) 1387e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1388c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1389c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1390c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F); 1391c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp &= 0x7FF; 1392c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1393c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj mantissaIsZero 1394a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toBool( 1395a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj (f64[6] & 0x0F) == 0 1396a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0 1397a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj ); 1398c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1399c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If both exponent and mantissa are zero, the value is zero. 1400c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,0,sign,0. */ 1401c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && mantissaIsZero) { 1402c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Zero\n"); */ 1403e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 1404e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1405c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1406c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1407c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If exponent is zero but mantissa isn't, it's a denormal. 1408c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,1,sign,0. */ 1409c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && !mantissaIsZero) { 1410c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Denormal\n"); */ 1411e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | X86G_FC_MASK_C2 1412e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1413c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1414c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1415c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa is zero, this is an infinity. 1416c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,1. */ 1417c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && mantissaIsZero) { 1418c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Inf\n"); */ 1419e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) 1420e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1421c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1422c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1423c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN. 1424c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,0,sign,1. */ 1425c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && !mantissaIsZero) { 1426c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("NaN\n"); */ 1427e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | 0 | (sign << X86G_FC_SHIFT_C1) | X86G_FC_MASK_C0; 1428c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1429c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1430c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* Uh, ok, we give up. It must be a normal finite number. 1431c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,0. 1432c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj */ 1433c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("normal\n"); */ 1434e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) | 0; 1435c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj} 1436c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 14370c2cb623cca372a2b42b073121c7413cdaaf75besewardj 143817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 143917442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (reads guest memory) */ 1440bdf99f06a5f44fd617c51ac80861ff07da09a50fflorianULong x86g_dirtyhelper_loadF80le ( Addr addrU ) 144117442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 144217442fe8094d0f82266e5a05509f62cac8f7539esewardj ULong f64; 1443bdf99f06a5f44fd617c51ac80861ff07da09a50fflorian convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 ); 144417442fe8094d0f82266e5a05509f62cac8f7539esewardj return f64; 144517442fe8094d0f82266e5a05509f62cac8f7539esewardj} 144617442fe8094d0f82266e5a05509f62cac8f7539esewardj 144717442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 144817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (writes guest memory) */ 1449bdf99f06a5f44fd617c51ac80861ff07da09a50fflorianvoid x86g_dirtyhelper_storeF80le ( Addr addrU, ULong f64 ) 145017442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 1451bdf99f06a5f44fd617c51ac80861ff07da09a50fflorian convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU ); 145217442fe8094d0f82266e5a05509f62cac8f7539esewardj} 145317442fe8094d0f82266e5a05509f62cac8f7539esewardj 14540c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14550c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 14560c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*--- The exported fns .. ---*/ 14570c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 14580c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14590c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Layout of the real x87 state. */ 14604017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* 13 June 05: Fpu_State and auxiliary constants was moved to 14614017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj g_generic_x87.h */ 14620c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14630c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14647df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1465a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* fpucw[15:0] contains a x87 native format FPU control word. 1466d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj Extract from it the required FPROUND value and any resulting 1467d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj emulation warning, and return (warn << 32) | fpround value. 1468d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj*/ 14693bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_fldcw ( UInt fpucw ) 1470893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1471d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* Decide on a rounding mode. fpucw[11:10] holds it. */ 1472d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 1473893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj UInt rmode = (fpucw >> 10) & 3; 1474893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1475893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* Detect any required emulation warnings. */ 14766ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew = EmNote_NONE; 1477893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1478893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if ((fpucw & 0x3F) != 0x3F) { 1479893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unmasked exceptions! */ 1480893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87exns; 1481893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1482893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj else 1483893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if (((fpucw >> 8) & 3) != 3) { 1484893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unsupported precision */ 1485893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87precision; 1486893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1487893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1488d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return (((ULong)ew) << 32) | ((ULong)rmode); 1489893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1490893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1491893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* CLEAN HELPER */ 14927df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given fpround as an IRRoundingMode value, create a suitable x87 14937df596b1e36840e2d74c90aa55589934add61ccfsewardj native format FPU control word. */ 14943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_fpucw ( UInt fpround ) 1495893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1496d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround &= 3; 1497d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return 0x037F | (fpround << 10); 1498893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1499893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1500893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 15017df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1502a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* mxcsr[15:0] contains a SSE native format MXCSR value. 15037df596b1e36840e2d74c90aa55589934add61ccfsewardj Extract from it the required SSEROUND value and any resulting 15047df596b1e36840e2d74c90aa55589934add61ccfsewardj emulation warning, and return (warn << 32) | sseround value. 15057df596b1e36840e2d74c90aa55589934add61ccfsewardj*/ 15063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_ldmxcsr ( UInt mxcsr ) 15077df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 15087df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Decide on a rounding mode. mxcsr[14:13] holds it. */ 15097df596b1e36840e2d74c90aa55589934add61ccfsewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 15107df596b1e36840e2d74c90aa55589934add61ccfsewardj UInt rmode = (mxcsr >> 13) & 3; 15117df596b1e36840e2d74c90aa55589934add61ccfsewardj 15127df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Detect any required emulation warnings. */ 15136ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew = EmNote_NONE; 15147df596b1e36840e2d74c90aa55589934add61ccfsewardj 15157df596b1e36840e2d74c90aa55589934add61ccfsewardj if ((mxcsr & 0x1F80) != 0x1F80) { 15167df596b1e36840e2d74c90aa55589934add61ccfsewardj /* unmasked exceptions! */ 15177df596b1e36840e2d74c90aa55589934add61ccfsewardj ew = EmWarn_X86_sseExns; 15187df596b1e36840e2d74c90aa55589934add61ccfsewardj } 15197df596b1e36840e2d74c90aa55589934add61ccfsewardj else 15205edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<15)) { 15215edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* FZ is set */ 15225edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_fz; 15235edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj } 15245edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj else 15255edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<6)) { 15265edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* DAZ is set */ 15275edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_daz; 15287df596b1e36840e2d74c90aa55589934add61ccfsewardj } 15297df596b1e36840e2d74c90aa55589934add61ccfsewardj 15307df596b1e36840e2d74c90aa55589934add61ccfsewardj return (((ULong)ew) << 32) | ((ULong)rmode); 15317df596b1e36840e2d74c90aa55589934add61ccfsewardj} 15327df596b1e36840e2d74c90aa55589934add61ccfsewardj 15337df596b1e36840e2d74c90aa55589934add61ccfsewardj 15347df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 15357df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given sseround as an IRRoundingMode value, create a suitable SSE 15367df596b1e36840e2d74c90aa55589934add61ccfsewardj native format MXCSR value. */ 15373bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_mxcsr ( UInt sseround ) 15387df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 15397df596b1e36840e2d74c90aa55589934add61ccfsewardj sseround &= 3; 15407df596b1e36840e2d74c90aa55589934add61ccfsewardj return 0x1F80 | (sseround << 13); 15417df596b1e36840e2d74c90aa55589934add61ccfsewardj} 15427df596b1e36840e2d74c90aa55589934add61ccfsewardj 15437df596b1e36840e2d74c90aa55589934add61ccfsewardj 1544a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* CALLED FROM GENERATED CODE */ 1545a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* DIRTY HELPER (writes guest state) */ 1546a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Initialise the x87 FPU state as per 'finit'. */ 1547a0e83b06f304527e3e9aec527c344e35e7023d76sewardjvoid x86g_dirtyhelper_FINIT ( VexGuestX86State* gst ) 1548a0e83b06f304527e3e9aec527c344e35e7023d76sewardj{ 1549a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i; 1550a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FTOP = 0; 1551a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (i = 0; i < 8; i++) { 1552a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPTAG[i] = 0; /* empty */ 1553a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */ 1554a0e83b06f304527e3e9aec527c344e35e7023d76sewardj } 1555a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPROUND = (UInt)Irrm_NEAREST; 1556a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FC3210 = 0; 1557a0e83b06f304527e3e9aec527c344e35e7023d76sewardj} 1558a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 1559a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 15607df596b1e36840e2d74c90aa55589934add61ccfsewardj/* This is used to implement both 'frstor' and 'fldenv'. The latter 15617df596b1e36840e2d74c90aa55589934add61ccfsewardj appears to differ from the former only in that the 8 FP registers 15627df596b1e36840e2d74c90aa55589934add61ccfsewardj themselves are not transferred into the guest state. */ 15637df596b1e36840e2d74c90aa55589934add61ccfsewardjstatic 15646ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote do_put_x87 ( Bool moveRegs, 156538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*IN*/UChar* x87_state, 156638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/VexGuestX86State* vex_state ) 15670c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1568a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int stno, preg; 15690c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tag; 1570c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1571f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 15720c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 15730c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt ftop = (x87->env[FP_ENV_STAT] >> 11) & 7; 15740c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw = x87->env[FP_ENV_TAG]; 15756e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj UInt fpucw = x87->env[FP_ENV_CTRL]; 1576c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UInt c3210 = x87->env[FP_ENV_STAT] & 0x4700; 15776ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew; 1578d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj UInt fpround; 1579893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ULong pair; 15800c2cb623cca372a2b42b073121c7413cdaaf75besewardj 15810c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* Copy registers and tags */ 1582a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1583a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1584a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tag = (tagw >> (2*preg)) & 3; 15850c2cb623cca372a2b42b073121c7413cdaaf75besewardj if (tag == 3) { 15860c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1587a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* hmm, if it's empty, does it still get written? Probably 1588a0e83b06f304527e3e9aec527c344e35e7023d76sewardj safer to say it does. If we don't, memcheck could get out 1589a0e83b06f304527e3e9aec527c344e35e7023d76sewardj of sync, in that it thinks all FP registers are defined by 1590a0e83b06f304527e3e9aec527c344e35e7023d76sewardj this helper, but in reality some have not been updated. */ 15910f33861a0aaf18e89f5f24fd5bdfa39a9049dadasewardj if (moveRegs) 1592c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 1593a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 0; 15940c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 15950c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is non-empty */ 15967df596b1e36840e2d74c90aa55589934add61ccfsewardj if (moveRegs) 1597a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f80le_to_f64le( &x87->reg[10*stno], 1598a0e83b06f304527e3e9aec527c344e35e7023d76sewardj (UChar*)&vexRegs[preg] ); 1599a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 1; 16000c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16010c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16020c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16030c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* stack pointer */ 1604f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FTOP = ftop; 16050c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16063f868e5262a8d2488f41cc49058ba60c24843c3esewardj /* status word */ 1607f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FC3210 = c3210; 1608893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1609d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* handle the control word, setting FPROUND and detecting any 1610893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj emulation warnings. */ 16113bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj pair = x86g_check_fldcw ( (UInt)fpucw ); 1612d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround = (UInt)pair; 16136ef84bed9bb3af22060eb1759788034602bbcc88florian ew = (VexEmNote)(pair >> 32); 1614893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1615d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj vex_state->guest_FPROUND = fpround & 3; 1616893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1617893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* emulation warnings --> caller */ 1618893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj return ew; 16190c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 16200c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16216e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj 1622a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Create an x87 FPU state from the guest state, as close as 1623a0e83b06f304527e3e9aec527c344e35e7023d76sewardj we can approximate it. */ 162438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic 162538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjvoid do_get_x87 ( /*IN*/VexGuestX86State* vex_state, 162638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/UChar* x87_state ) 16270c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1628a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i, stno, preg; 16290c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw; 1630c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1631f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 16320c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 1633f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt ftop = vex_state->guest_FTOP; 1634f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt c3210 = vex_state->guest_FC3210; 16350c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16360c2cb623cca372a2b42b073121c7413cdaaf75besewardj for (i = 0; i < 14; i++) 16370c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[i] = 0; 16380c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16390c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 1640a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_STAT] 1641a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 1642893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj x87->env[FP_ENV_CTRL] 1643a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(x86g_create_fpucw( vex_state->guest_FPROUND )); 16440c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1645a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* Dump the register stack in ST order. */ 16460c2cb623cca372a2b42b073121c7413cdaaf75besewardj tagw = 0; 1647a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1648a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1649a0e83b06f304527e3e9aec527c344e35e7023d76sewardj if (vexTags[preg] == 0) { 16500c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1651a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (3 << (2*preg)); 1652a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1653a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 16540c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 16550c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is full. */ 1656a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (0 << (2*preg)); 1657a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1658a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 16590c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16600c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 1661a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_TAG] = toUShort(tagw); 16620c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 16630c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16640c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1665893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1666893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1667893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FXSAVE ( VexGuestX86State* gst, HWord addr ) 1668f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj{ 1669893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1670893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1671893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrS = (UShort*)addr; 1672893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* addrC = (UChar*)addr; 1673893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj U128* xmm = (U128*)(addr + 160); 1674893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt mxcsr; 1675893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort fp_tags; 1676a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt summary_tags; 1677893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int r, stno; 1678893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort *srcS, *dstS; 1679f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1680893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1681893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mxcsr = x86g_create_mxcsr( gst->guest_SSEROUND ); 168276bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1683893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Now build the proper fxsave image from the x87 image we just 1684893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj made. */ 168576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1686893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[0] = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */ 1687893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[1] = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */ 168876bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1689893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* set addrS[2] in an endian-independent way */ 1690893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags = 0; 1691893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj fp_tags = tmp.env[FP_ENV_TAG]; 1692893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (r = 0; r < 8; r++) { 1693893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if ( ((fp_tags >> (2*r)) & 3) != 3 ) 1694893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags |= (1 << r); 1695893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1696a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrC[4] = toUChar(summary_tags); /* FTW: tag summary byte */ 1697893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrC[5] = 0; /* pad */ 169876bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1699893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[3] = 0; /* FOP: fpu opcode (bogus) */ 1700893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[4] = 0; 1701893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[5] = 0; /* FPU IP (bogus) */ 1702893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[6] = 0; /* FPU IP's segment selector (bogus) (although we 1703893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj could conceivably dump %CS here) */ 1704c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1705893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[7] = 0; /* Intel reserved */ 1706c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1707893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[8] = 0; /* FPU DP (operand pointer) (bogus) */ 1708893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[9] = 0; /* FPU DP (operand pointer) (bogus) */ 1709893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[10] = 0; /* segment selector for above operand pointer; %DS 1710893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj perhaps? */ 1711893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[11] = 0; /* Intel reserved */ 1712c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1713a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[12] = toUShort(mxcsr); /* MXCSR */ 1714a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[13] = toUShort(mxcsr >> 16); 1715893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1716893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[14] = 0xFFFF; /* MXCSR mask (lo16); who knows what for */ 1717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[15] = 0xFFFF; /* MXCSR mask (hi16); who knows what for */ 1718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Copy in the FP registers, in ST order. */ 1720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (stno = 0; stno < 8; stno++) { 1721893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj srcS = (UShort*)(&tmp.reg[10*stno]); 1722893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS = (UShort*)(&addrS[16 + 8*stno]); 1723893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[0] = srcS[0]; 1724893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[1] = srcS[1]; 1725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[2] = srcS[2]; 1726893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[3] = srcS[3]; 1727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[4] = srcS[4]; 1728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[5] = 0; 1729893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[6] = 0; 1730893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[7] = 0; 1731893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* That's the first 160 bytes of the image done. Now only %xmm0 1734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj .. %xmm7 remain to be copied. If the host is big-endian, these 1735893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj need to be byte-swapped. */ 1736893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(host_is_little_endian()); 1737893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1738893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define COPY_U128(_dst,_src) \ 1739893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 1740893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 1741893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj while (0) 1742893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1743893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[0], gst->guest_XMM0 ); 1744893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[1], gst->guest_XMM1 ); 1745893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[2], gst->guest_XMM2 ); 1746893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[3], gst->guest_XMM3 ); 1747893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[4], gst->guest_XMM4 ); 1748893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[5], gst->guest_XMM5 ); 1749893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[6], gst->guest_XMM6 ); 1750893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[7], gst->guest_XMM7 ); 1751893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1752893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef COPY_U128 1753dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj} 1754f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1755f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1756893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 17573800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 17586ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote x86g_dirtyhelper_FXRSTOR ( VexGuestX86State* gst, HWord addr ) 17593800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj{ 17603800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Fpu_State tmp; 17616ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote warnX87 = EmNote_NONE; 17626ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote warnXMM = EmNote_NONE; 17633800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* addrS = (UShort*)addr; 17643800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UChar* addrC = (UChar*)addr; 17653800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj U128* xmm = (U128*)(addr + 160); 17663800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort fp_tags; 17673800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Int r, stno, i; 17683800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17693800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Restore %xmm0 .. %xmm7. If the host is big-endian, these need 17703800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj to be byte-swapped. */ 17713800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj vassert(host_is_little_endian()); 17723800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17733800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj# define COPY_U128(_dst,_src) \ 17743800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 17753800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 17763800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj while (0) 17773800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17783800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM0, xmm[0] ); 17793800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM1, xmm[1] ); 17803800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM2, xmm[2] ); 17813800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM3, xmm[3] ); 17823800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM4, xmm[4] ); 17833800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM5, xmm[5] ); 17843800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM6, xmm[6] ); 17853800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM7, xmm[7] ); 17863800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17873800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj# undef COPY_U128 17883800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17893800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Copy the x87 registers out of the image, into a temporary 17903800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Fpu_State struct. */ 17910f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj 17924ff2a1aa52dbed78055deba39c14c3978d12601csewardj /* LLVM on Darwin turns the following loop into a movaps plus a 17934ff2a1aa52dbed78055deba39c14c3978d12601csewardj handful of scalar stores. This would work fine except for the 17944ff2a1aa52dbed78055deba39c14c3978d12601csewardj fact that VEX doesn't keep the stack correctly (16-) aligned for 17954ff2a1aa52dbed78055deba39c14c3978d12601csewardj the call, so it segfaults. Hence, split the loop into two 17964ff2a1aa52dbed78055deba39c14c3978d12601csewardj pieces (and pray LLVM doesn't merely glue them back together) so 17974ff2a1aa52dbed78055deba39c14c3978d12601csewardj it's composed only of scalar stores and so is alignment 17984ff2a1aa52dbed78055deba39c14c3978d12601csewardj insensitive. Of course this is a kludge of the lamest kind -- 17994ff2a1aa52dbed78055deba39c14c3978d12601csewardj VEX should be fixed properly. */ 18000f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj /* Code that seems to trigger the problem: 18010f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 14; i++) tmp.env[i] = 0; */ 18020f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 7; i++) tmp.env[i+0] = 0; 18030f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 7; i++) tmp.env[i+7] = 0; 18040f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj 18053800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (i = 0; i < 80; i++) tmp.reg[i] = 0; 18063800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* fill in tmp.reg[0..7] */ 18073800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (stno = 0; stno < 8; stno++) { 18083800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* dstS = (UShort*)(&tmp.reg[10*stno]); 18093800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* srcS = (UShort*)(&addrS[16 + 8*stno]); 18103800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[0] = srcS[0]; 18113800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[1] = srcS[1]; 18123800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[2] = srcS[2]; 18133800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[3] = srcS[3]; 18143800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[4] = srcS[4]; 18153800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18163800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* fill in tmp.env[0..13] */ 18173800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_CTRL] = addrS[0]; /* FCW: fpu control word */ 18183800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_STAT] = addrS[1]; /* FCW: fpu status word */ 18193800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18203800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags = 0; 18213800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (r = 0; r < 8; r++) { 18223800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj if (addrC[4] & (1<<r)) 18233800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags |= (0 << (2*r)); /* EMPTY */ 18243800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj else 18253800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags |= (3 << (2*r)); /* VALID -- not really precise enough. */ 18263800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18273800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_TAG] = fp_tags; 18283800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18293800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Now write 'tmp' into the guest state. */ 18303800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj warnX87 = do_put_x87( True/*moveRegs*/, (UChar*)&tmp, gst ); 18313800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18323800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj { UInt w32 = (((UInt)addrS[12]) & 0xFFFF) 18333800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj | ((((UInt)addrS[13]) & 0xFFFF) << 16); 18343800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj ULong w64 = x86g_check_ldmxcsr( w32 ); 18353800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18366ef84bed9bb3af22060eb1759788034602bbcc88florian warnXMM = (VexEmNote)(w64 >> 32); 18373800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18383800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj gst->guest_SSEROUND = (UInt)w64; 18393800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18403800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18413800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Prefer an X87 emwarn over an XMM one, if both exist. */ 18426ef84bed9bb3af22060eb1759788034602bbcc88florian if (warnX87 != EmNote_NONE) 18433800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj return warnX87; 18443800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj else 18453800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj return warnXMM; 18463800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj} 18473800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18483800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18493800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj/* CALLED FROM GENERATED CODE */ 1850893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1851893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSAVE ( VexGuestX86State* gst, HWord addr ) 1852893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1853893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)addr ); 1854893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1855893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1856893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1857893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 18586ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote x86g_dirtyhelper_FRSTOR ( VexGuestX86State* gst, HWord addr ) 1859893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1860893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( True/*regs too*/, (UChar*)addr, gst ); 1861893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1862893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1863893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1864893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1865893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSTENV ( VexGuestX86State* gst, HWord addr ) 1866893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1867893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1868893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int i; 1869893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrP = (UShort*)addr; 1870893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1871893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1872893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (i = 0; i < 14; i++) 1873893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrP[i] = tmp.env[i]; 1874893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1875893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1876893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1877893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 18786ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr ) 1879893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1880893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst); 1881893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1882893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1883893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1884893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1885893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Misc integer helpers, including rotates and CPUID. ---*/ 1886893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 18879aebb0c3f7a7f43313786826f31402f2b733badfsewardj 18889aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 18899aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* Calculate both flags and value result for rotate right 18909aebb0c3f7a7f43313786826f31402f2b733badfsewardj through the carry bit. Result in low 32 bits, 18919aebb0c3f7a7f43313786826f31402f2b733badfsewardj new flags (OSZACP) in high 32 bits. 18929aebb0c3f7a7f43313786826f31402f2b733badfsewardj*/ 18932a9ad023890d3b34cf45e429df2a8ae88b419128sewardjULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 18949aebb0c3f7a7f43313786826f31402f2b733badfsewardj{ 18959aebb0c3f7a7f43313786826f31402f2b733badfsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 18969aebb0c3f7a7f43313786826f31402f2b733badfsewardj 18979aebb0c3f7a7f43313786826f31402f2b733badfsewardj switch (sz) { 18989aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 4: 18992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19009aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 31) ^ cf) & 1; 19019aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19029aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19039aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = (arg >> 1) | (cf << 31); 19049aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19059aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19069aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19079aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19089aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 2: 19099aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 19102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19119aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 15) ^ cf) & 1; 19129aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19139aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19149aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7FFF) | (cf << 15); 19159aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19169aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19179aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19189aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19199aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 1: 19209aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 19212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19229aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 7) ^ cf) & 1; 19239aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19249aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19259aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7F) | (cf << 7); 19269aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19279aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19289aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19299aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19309aebb0c3f7a7f43313786826f31402f2b733badfsewardj default: 19319aebb0c3f7a7f43313786826f31402f2b733badfsewardj vpanic("calculate_RCR: invalid size"); 19329aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19339aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19349aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf &= 1; 19359aebb0c3f7a7f43313786826f31402f2b733badfsewardj of &= 1; 19362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 19372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 19389aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19399aebb0c3f7a7f43313786826f31402f2b733badfsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 19409aebb0c3f7a7f43313786826f31402f2b733badfsewardj} 19419aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19427cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 19432eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 19442eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* Calculate both flags and value result for rotate left 19452eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj through the carry bit. Result in low 32 bits, 19462eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj new flags (OSZACP) in high 32 bits. 19472eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj*/ 19482eef773d07df9bbc5d62c0058ae99d5511c2759dsewardjULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 19492eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj{ 19502eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 19512eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19522eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj switch (sz) { 19532eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 4: 19542eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19552eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19562eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 31) & 1; 19572eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = (arg << 1) | (cf & 1); 19582eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19592eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19602eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19612eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 31) ^ cf) & 1; 19622eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19632eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 2: 19642eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 19652eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19662eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19672eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 15) & 1; 19682eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFFFF & ((arg << 1) | (cf & 1)); 19692eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19702eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19712eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19722eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 15) ^ cf) & 1; 19732eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19742eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 1: 19752eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 19762eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19772eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19782eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 7) & 1; 19792eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFF & ((arg << 1) | (cf & 1)); 19802eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19812eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19822eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19832eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 7) ^ cf) & 1; 19842eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19852eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj default: 19862eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj vpanic("calculate_RCL: invalid size"); 19872eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19882eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19892eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf &= 1; 19902eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of &= 1; 19912eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 19922eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 19932eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19942eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 19952eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj} 19962eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19972eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 19998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* Calculate both flags and value result for DAA/DAS/AAA/AAS. 20008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj AX value in low half of arg, OSZACP in upper half. 20018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj See guest-x86/toIR.c usage point for details. 20028edc36b45e95a7ec9879a25b80390129f1d334c1sewardj*/ 20038edc36b45e95a7ec9879a25b80390129f1d334c1sewardjstatic UInt calc_parity_8bit ( UInt w32 ) { 20048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt i; 20058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt p = 1; 20068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj for (i = 0; i < 8; i++) 20078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj p ^= (1 & (w32 >> i)); 20088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj return p; 20098edc36b45e95a7ec9879a25b80390129f1d334c1sewardj} 20108edc36b45e95a7ec9879a25b80390129f1d334c1sewardjUInt x86g_calculate_daa_das_aaa_aas ( UInt flags_and_AX, UInt opcode ) 20118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj{ 20128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_AL = (flags_and_AX >> 0) & 0xFF; 20138edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_AH = (flags_and_AX >> 8) & 0xFF; 20148edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_O = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1; 20158edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_S = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1; 20168edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_Z = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1; 20178edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_A = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1; 20188edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_C = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1; 20198edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_P = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1; 20208edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt result = 0; 20218edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 20228edc36b45e95a7ec9879a25b80390129f1d334c1sewardj switch (opcode) { 20238edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x27: { /* DAA */ 20248edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_AL = r_AL; 20258edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_C = r_C; 20268edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20278edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20288edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 6; 20298edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = old_C; 20308edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (r_AL >= 0x100) r_C = 1; 20318edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20328edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20338edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20348edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20358edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (old_AL > 0x99 || old_C == 1) { 20368edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 0x60; 20378edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20388edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20398edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20408edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20418edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O is undefined. S Z and P are set according to the 20428edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result. */ 20438edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL &= 0xFF; 20448edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = 0; /* let's say */ 20458edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_S = (r_AL & 0x80) ? 1 : 0; 20468edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_Z = (r_AL == 0) ? 1 : 0; 20478edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_P = calc_parity_8bit( r_AL ); 20488edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20498edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20508edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x2F: { /* DAS */ 20518edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_AL = r_AL; 20528edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_C = r_C; 20538edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20548edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20558edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool borrow = r_AL < 6; 20568edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 6; 20578edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = old_C; 20588edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (borrow) r_C = 1; 20598edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20608edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20618edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20628edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20638edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (old_AL > 0x99 || old_C == 1) { 20648edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 0x60; 20658edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20668edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20678edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* Intel docs are wrong: r_C = 0; */ 20688edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20698edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O is undefined. S Z and P are set according to the 20708edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result. */ 20718edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL &= 0xFF; 20728edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = 0; /* let's say */ 20738edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_S = (r_AL & 0x80) ? 1 : 0; 20748edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_Z = (r_AL == 0) ? 1 : 0; 20758edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_P = calc_parity_8bit( r_AL ); 20768edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20778edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20788edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x37: { /* AAA */ 20798edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool nudge = r_AL > 0xF9; 20808edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20818edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 6; 20828edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AH = r_AH + 1 + (nudge ? 1 : 0); 20838edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20848edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20858edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 20868edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20878edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20888edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20898edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 20908edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20918edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O S Z and P are undefined. */ 20928edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = r_S = r_Z = r_P = 0; /* let's say */ 20938edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20948edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20958edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x3F: { /* AAS */ 20968edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool nudge = r_AL < 0x06; 20978edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 6; 20998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AH = r_AH - 1 - (nudge ? 1 : 0); 21008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 21018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 21028edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 21038edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 21048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 21058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 21068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 21078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O S Z and P are undefined. */ 21098edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = r_S = r_Z = r_P = 0; /* let's say */ 21108edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 21118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj default: 21138edc36b45e95a7ec9879a25b80390129f1d334c1sewardj vassert(0); 21148edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21158edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result = ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) ) 21168edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) ) 21178edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) ) 21188edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) ) 21198edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) ) 21208edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) ) 21218edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_AH & 0xFF) << 8 ) 21228edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_AL & 0xFF) << 0 ); 21238edc36b45e95a7ec9879a25b80390129f1d334c1sewardj return result; 21248edc36b45e95a7ec9879a25b80390129f1d334c1sewardj} 21258edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 2126321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardjUInt x86g_calculate_aad_aam ( UInt flags_and_AX, UInt opcode ) 2127321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj{ 2128321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_AL = (flags_and_AX >> 0) & 0xFF; 2129321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_AH = (flags_and_AX >> 8) & 0xFF; 2130321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_O = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1; 2131321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_S = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1; 2132321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_Z = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1; 2133321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_A = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1; 2134321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_C = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1; 2135321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_P = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1; 2136321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt result = 0; 2137321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2138321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj switch (opcode) { 2139321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj case 0xD4: { /* AAM */ 2140321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AH = r_AL / 10; 2141321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AL = r_AL % 10; 2142321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj break; 2143321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2144321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj case 0xD5: { /* AAD */ 2145321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AL = ((r_AH * 10) + r_AL) & 0xff; 2146321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AH = 0; 2147321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj break; 2148321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2149321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj default: 2150321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj vassert(0); 2151321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2152321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2153321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_O = 0; /* let's say (undefined) */ 2154321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_C = 0; /* let's say (undefined) */ 2155321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_A = 0; /* let's say (undefined) */ 2156321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_S = (r_AL & 0x80) ? 1 : 0; 2157321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_Z = (r_AL == 0) ? 1 : 0; 2158321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_P = calc_parity_8bit( r_AL ); 2159321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2160321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj result = ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) ) 2161321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) ) 2162321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) ) 2163321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) ) 2164321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) ) 2165321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) ) 2166321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_AH & 0xFF) << 8 ) 2167321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_AL & 0xFF) << 0 ); 2168321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj return result; 2169321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj} 2170321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 21718edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 21727cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* CALLED FROM GENERATED CODE */ 21734ed6429074bf94661586d751fbecac530f5e8156sewardj/* DIRTY HELPER (non-referentially-transparent) */ 21744ed6429074bf94661586d751fbecac530f5e8156sewardj/* Horrible hack. On non-x86 platforms, return 1. */ 21754ed6429074bf94661586d751fbecac530f5e8156sewardjULong x86g_dirtyhelper_RDTSC ( void ) 21764ed6429074bf94661586d751fbecac530f5e8156sewardj{ 21774ed6429074bf94661586d751fbecac530f5e8156sewardj# if defined(__i386__) 21784ed6429074bf94661586d751fbecac530f5e8156sewardj ULong res; 21794ed6429074bf94661586d751fbecac530f5e8156sewardj __asm__ __volatile__("rdtsc" : "=A" (res)); 21804ed6429074bf94661586d751fbecac530f5e8156sewardj return res; 21814ed6429074bf94661586d751fbecac530f5e8156sewardj# else 21824ed6429074bf94661586d751fbecac530f5e8156sewardj return 1ULL; 21834ed6429074bf94661586d751fbecac530f5e8156sewardj# endif 21844ed6429074bf94661586d751fbecac530f5e8156sewardj} 21854ed6429074bf94661586d751fbecac530f5e8156sewardj 21864ed6429074bf94661586d751fbecac530f5e8156sewardj 21874ed6429074bf94661586d751fbecac530f5e8156sewardj/* CALLED FROM GENERATED CODE */ 21887cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* DIRTY HELPER (modifies guest state) */ 21894ba6ed0799fcf768e3fb9627fabc52fb1d6c2a6csewardj/* Claim to be a P55C (Intel Pentium/MMX) */ 21909df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* st ) 21917cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj{ 21929df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 21939df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 21949df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x1; 21959df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 21969df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 21979df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 21989df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 21999df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 22009df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x543; 22019df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x0; 22029df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x0; 22039df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x8001bf; 22049df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22059df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 22069df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 22079df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 22089df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* CALLED FROM GENERATED CODE */ 22099df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* DIRTY HELPER (modifies guest state) */ 22106c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw/* Claim to be a Athlon "Classic" (Model 2, K75 "Pluto/Orion") */ 22116c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw/* But without 3DNow support (weird, but we really don't support it). */ 22126c65c12ecf69436421ebc1b5637ee13bb4aaf41emjwvoid x86g_dirtyhelper_CPUID_mmxext ( VexGuestX86State* st ) 22136c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw{ 22146c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw switch (st->guest_EAX) { 22156c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw /* vendor ID */ 22166c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 0: 22176c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x1; 22186c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x68747541; 22196c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x444d4163; 22206c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x69746e65; 22216c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22226c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw /* feature bits */ 22236c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 1: 22246c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x621; 22256c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x0; 22266c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x0; 22276c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x183f9ff; 22286c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22296c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw /* Highest Extended Function Supported (0x80000004 brand string) */ 22306c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 0x80000000: 22316c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x80000004; 22326c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x68747541; 22336c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x444d4163; 22346c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x69746e65; 22356c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22366c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw /* Extended Processor Info and Feature Bits */ 22376c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 0x80000001: 22386c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x721; 22396c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x0; 22406c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x0; 22416c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x1c3f9ff; /* Note no 3DNow. */ 22426c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22436c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw /* Processor Brand String "AMD Athlon(tm) Processor" */ 22446c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 0x80000002: 22456c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x20444d41; 22466c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x6c687441; 22476c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x74286e6f; 22486c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x5020296d; 22496c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22506c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw case 0x80000003: 22516c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x65636f72; 22526c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x726f7373; 22536c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x0; 22546c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x0; 22556c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22566c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw default: 22576c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EAX = 0x0; 22586c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EBX = 0x0; 22596c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_ECX = 0x0; 22606c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw st->guest_EDX = 0x0; 22616c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw break; 22626c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw } 22636c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw} 22646c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw 22656c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw/* CALLED FROM GENERATED CODE */ 22666c65c12ecf69436421ebc1b5637ee13bb4aaf41emjw/* DIRTY HELPER (modifies guest state) */ 22679df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* Claim to be the following SSE1-capable CPU: 22689df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 22699df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu family : 6 22709df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model : 11 22719df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model name : Intel(R) Pentium(R) III CPU family 1133MHz 22729df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj stepping : 1 22739df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu MHz : 1131.013 22749df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cache size : 512 KB 22759df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 22769df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st ) 22779df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 22789df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 22799df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 22809df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x00000002; 22819df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 22829df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 22839df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 22849df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22859df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 1: 22869df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x000006b1; 22879df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000004; 22889df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 22899df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0383fbff; 22909df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22919df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 22929df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x03020101; 22939df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000000; 22949df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 22959df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0c040883; 22969df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22979df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 22989df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 22999df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 2300150c9cddb753ad4dc38f43484144523174d38b02sewardj/* Claim to be the following SSSE3-capable CPU (2 x ...): 23019df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 2302150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu family : 6 2303150c9cddb753ad4dc38f43484144523174d38b02sewardj model : 15 2304150c9cddb753ad4dc38f43484144523174d38b02sewardj model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz 2305150c9cddb753ad4dc38f43484144523174d38b02sewardj stepping : 6 2306150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu MHz : 2394.000 2307150c9cddb753ad4dc38f43484144523174d38b02sewardj cache size : 4096 KB 2308150c9cddb753ad4dc38f43484144523174d38b02sewardj physical id : 0 2309150c9cddb753ad4dc38f43484144523174d38b02sewardj siblings : 2 2310150c9cddb753ad4dc38f43484144523174d38b02sewardj core id : 0 2311150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu cores : 2 2312150c9cddb753ad4dc38f43484144523174d38b02sewardj fpu : yes 2313150c9cddb753ad4dc38f43484144523174d38b02sewardj fpu_exception : yes 2314150c9cddb753ad4dc38f43484144523174d38b02sewardj cpuid level : 10 2315150c9cddb753ad4dc38f43484144523174d38b02sewardj wp : yes 2316150c9cddb753ad4dc38f43484144523174d38b02sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2317150c9cddb753ad4dc38f43484144523174d38b02sewardj mtrr pge mca cmov pat pse36 clflush dts acpi 2318150c9cddb753ad4dc38f43484144523174d38b02sewardj mmx fxsr sse sse2 ss ht tm syscall nx lm 2319150c9cddb753ad4dc38f43484144523174d38b02sewardj constant_tsc pni monitor ds_cpl vmx est tm2 2320150c9cddb753ad4dc38f43484144523174d38b02sewardj cx16 xtpr lahf_lm 2321150c9cddb753ad4dc38f43484144523174d38b02sewardj bogomips : 4798.78 2322150c9cddb753ad4dc38f43484144523174d38b02sewardj clflush size : 64 2323150c9cddb753ad4dc38f43484144523174d38b02sewardj cache_alignment : 64 2324150c9cddb753ad4dc38f43484144523174d38b02sewardj address sizes : 36 bits physical, 48 bits virtual 2325150c9cddb753ad4dc38f43484144523174d38b02sewardj power management: 23269df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 23279df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) 23289df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 2329150c9cddb753ad4dc38f43484144523174d38b02sewardj# define SET_ABCD(_a,_b,_c,_d) \ 2330150c9cddb753ad4dc38f43484144523174d38b02sewardj do { st->guest_EAX = (UInt)(_a); \ 2331150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_EBX = (UInt)(_b); \ 2332150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_ECX = (UInt)(_c); \ 2333150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_EDX = (UInt)(_d); \ 2334150c9cddb753ad4dc38f43484144523174d38b02sewardj } while (0) 2335150c9cddb753ad4dc38f43484144523174d38b02sewardj 23369df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 2337150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000000: 2338150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69); 23399df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 2340150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000001: 2341150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x000006f6, 0x00020800, 0x0000e3bd, 0xbfebfbff); 23429df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 2343150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000002: 2344150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x05b0b101, 0x005657f0, 0x00000000, 0x2cb43049); 2345150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2346150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000003: 2347150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2348150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 234932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000004: { 235032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj switch (st->guest_ECX) { 235132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, 235232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 235332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, 235432bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 235532bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, 235632bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000fff, 0x00000001); break; 235732bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj default: SET_ABCD(0x00000000, 0x00000000, 235832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000000, 0x00000000); break; 235932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2360150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 236132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2362150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000005: 2363150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); 2364150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2365150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000006: 2366150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000001, 0x00000002, 0x00000001, 0x00000000); 2367150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2368150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000007: 2369150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2370150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2371150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000008: 2372150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000400, 0x00000000, 0x00000000, 0x00000000); 2373150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2374150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000009: 2375150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2376150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2377150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x0000000a: 237832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj unhandled_eax_value: 2379150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); 2380150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2381150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000000: 2382150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2383150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2384150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000001: 2385150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x20100000); 2386150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2387150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000002: 2388150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 2389150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2390150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000003: 2391150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x43203229, 0x20205550, 0x20202020, 0x20202020); 2392150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2393150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000004: 2394150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x30303636, 0x20402020, 0x30342e32, 0x007a4847); 2395150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2396150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000005: 2397150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2398150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2399150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000006: 2400150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x10008040, 0x00000000); 2401150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2402150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000007: 2403150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2404150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2405150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000008: 2406150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2407150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 240832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj default: 240932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj goto unhandled_eax_value; 24107cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj } 2411150c9cddb753ad4dc38f43484144523174d38b02sewardj# undef SET_ABCD 24127cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj} 24137cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 2414464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 2415d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */ 2416d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2417d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack. On non-x86 platforms, return 0. */ 2418d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjUInt x86g_dirtyhelper_IN ( UInt portno, UInt sz/*1,2 or 4*/ ) 2419d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{ 2420d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# if defined(__i386__) 2421d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj UInt r = 0; 2422d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj portno &= 0xFFFF; 2423d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj switch (sz) { 2424d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 4: 2425d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inl %w1,%0" 2426d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2427d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2428d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 2: 2429d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inw %w1,%w0" 2430d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2431d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2432d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 1: 2433d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inb %w1,%b0" 2434d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2435d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2436d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj default: 2437d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2438d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj } 2439d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj return r; 2440d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# else 2441d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj return 0; 2442d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# endif 2443d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj} 2444d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2445d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2446d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */ 2447d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2448d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack. On non-x86 platforms, do nothing. */ 2449d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjvoid x86g_dirtyhelper_OUT ( UInt portno, UInt data, UInt sz/*1,2 or 4*/ ) 2450d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{ 2451d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# if defined(__i386__) 2452d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj portno &= 0xFFFF; 2453d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj switch (sz) { 2454d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 4: 2455d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outl %0, %w1" 2456d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2457d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2458d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 2: 2459d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outw %w0, %w1" 2460d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2461d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2462d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 1: 2463d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outb %b0, %w1" 2464d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2465d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2466d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj default: 2467d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2468d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj } 2469d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# else 24705e55f492bb4e0d6cca529a31653d8682fbc5a6dasewardj /* do nothing */ 2471d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# endif 2472d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj} 2473d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2474b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* CALLED FROM GENERATED CODE */ 2475b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2476b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* Horrible hack. On non-x86 platforms, do nothing. */ 2477b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* op = 0: call the native SGDT instruction. 2478b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj op = 1: call the native SIDT instruction. 2479b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj*/ 2480b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardjvoid x86g_dirtyhelper_SxDT ( void *address, UInt op ) { 2481b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# if defined(__i386__) 2482b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj switch (op) { 2483b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 0: 2484b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory"); 2485b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 2486b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 1: 2487b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory"); 2488b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 2489b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj default: 2490b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj vpanic("x86g_dirtyhelper_SxDT"); 2491b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj } 2492b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# else 2493b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj /* do nothing */ 2494b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj UChar* p = (UChar*)address; 2495b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0; 2496b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# endif 2497b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj} 2498d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2499893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2500893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for MMX/SSE/SSE2. ---*/ 2501893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2502464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 250338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar abdU8 ( UChar xx, UChar yy ) { 2504a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(xx>yy ? xx-yy : yy-xx); 250538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj} 2506464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 250738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) { 2508464efa446b2db97115d3e5f04af5db3464cc0e93sewardj return (((ULong)w1) << 32) | ((ULong)w0); 2509464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2510464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 251138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_3 ( ULong w64 ) { 2512a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2513a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32 >> 16); 2514464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 251538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_2 ( ULong w64 ) { 2516a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2517a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32); 2518464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 251938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_1 ( ULong w64 ) { 2520a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2521a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32 >> 16); 2522464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 252338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_0 ( ULong w64 ) { 2524a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2525a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32); 2526464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2527464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 252838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_7 ( ULong w64 ) { 2529a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2530a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 24); 2531464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 253238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_6 ( ULong w64 ) { 2533a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2534a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 16); 2535464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 253638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_5 ( ULong w64 ) { 2537a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2538a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 8); 2539464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 254038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_4 ( ULong w64 ) { 2541a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2542a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 0); 2543464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 254438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_3 ( ULong w64 ) { 2545a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2546a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 24); 2547464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 254838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_2 ( ULong w64 ) { 2549a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2550a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 16); 2551464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 255238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_1 ( ULong w64 ) { 2553a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2554a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 8); 2555464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 255638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_0 ( ULong w64 ) { 2557a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2558a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 0); 2559464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2560464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 256138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 256238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) 25634340dac5c2cede4962868e6da5b73282da2bc465sewardj{ 25644340dac5c2cede4962868e6da5b73282da2bc465sewardj return 25654340dac5c2cede4962868e6da5b73282da2bc465sewardj mk32x2( 25664340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) 25674340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), 25684340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) 25694340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) 25704340dac5c2cede4962868e6da5b73282da2bc465sewardj ); 25714340dac5c2cede4962868e6da5b73282da2bc465sewardj} 25724340dac5c2cede4962868e6da5b73282da2bc465sewardj 257338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 257438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy ) 25750bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj{ 25760bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj UInt t = 0; 25770bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); 25780bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); 25790bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); 25800bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); 25810bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 25820bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 25830bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 25840bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 25850bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t &= 0xFFFF; 25860bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj return (ULong)t; 25870bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj} 25880bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj 2589464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 2590893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2591893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with segment overrides. ---*/ 2592893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 25933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 25953bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_base ( VexGuestX86SegDescr* ent ) 25963bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 25973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.BaseLow; 25983bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt mid = 0xFF & (UInt)ent->LdtEnt.Bits.BaseMid; 25993bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xFF & (UInt)ent->LdtEnt.Bits.BaseHi; 26003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (hi << 24) | (mid << 16) | lo; 26013bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 26023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 26043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_limit ( VexGuestX86SegDescr* ent ) 26053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 26063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.LimitLow; 26073bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xF & (UInt)ent->LdtEnt.Bits.LimitHi; 26083bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt limit = (hi << 16) | lo; 26093bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ent->LdtEnt.Bits.Granularity) 26103bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = (limit << 12) | 0xFFF; 26113bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return limit; 26123bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 26133bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 261438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 26153bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_use_seg_selector ( HWord ldt, HWord gdt, 26163bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt seg_selector, UInt virtual_addr ) 26173bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 26183bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt tiBit, base, limit; 26193bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj VexGuestX86SegDescr* the_descrs; 26203bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26213bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj Bool verboze = False; 26223bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26233bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* If this isn't true, we're in Big Trouble. */ 26243bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(8 == sizeof(VexGuestX86SegDescr)); 26253bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26263bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 26273bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 26283bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "seg_selector = 0x%x, vaddr = 0x%x\n", 26293bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector, virtual_addr); 26303bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26313bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for wildly invalid selector. */ 26323bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector & ~0xFFFF) 26333bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26343bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26353bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector &= 0x0000FFFF; 26363bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26373bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Sanity check the segment selector. Ensure that RPL=11b (least 26383bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj privilege). This forms the bottom 2 bits of the selector. */ 26393bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if ((seg_selector & 3) != 3) 26403bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26413bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26423bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Extract the TI bit (0 means GDT, 1 means LDT) */ 26433bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj tiBit = (seg_selector >> 2) & 1; 26443bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26453bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Convert the segment selector onto a table index */ 26463bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector >>= 3; 26473bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(seg_selector >= 0 && seg_selector < 8192); 26483bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26493bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (tiBit == 0) { 26503bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26513bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* GDT access. */ 26523bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do we actually have a GDT to look at? */ 26533bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (gdt == 0) 26543bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26553bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26563bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for access to non-existent entry. */ 26573bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_GDT_NENT) 26583bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26593bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)gdt; 26613bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 26623bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 26633bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26643bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } else { 26653bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26663bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* All the same stuff, except for the LDT. */ 26673bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ldt == 0) 26683bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26693bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26703bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_LDT_NENT) 26713bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26723bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26733bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)ldt; 26743bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 26753bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 26763bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26773bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } 26783bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26793bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do the limit check. Note, this check is just slightly too 26803bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj slack. Really it should be "if (virtual_addr + size - 1 >= 26813bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit)," but we don't have the size info to hand. Getting it 26823bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj could be significantly complex. */ 26833bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (virtual_addr >= limit) 26843bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26853bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26863bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 26873bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 26883bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "base = 0x%x, addr = 0x%x\n", 26893bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base, base + virtual_addr); 26903bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26913bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* High 32 bits are zero, indicating success. */ 26923bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (ULong)( ((UInt)virtual_addr) + base ); 26933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj bad: 26953bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return 1ULL << 32; 26963bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 26973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26983bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 2699893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2700893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with, and describing, ---*/ 2701893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- guest state as a whole. ---*/ 2702893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2703893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2704893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Initialise the entire x86 guest state. */ 2705893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 2706893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state ) 2707893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 2708c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->host_EvC_FAILADDR = 0; 2709c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->host_EvC_COUNTER = 0; 2710c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 2711893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EAX = 0; 2712893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ECX = 0; 2713893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDX = 0; 2714893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBX = 0; 2715893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESP = 0; 2716893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBP = 0; 2717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESI = 0; 2718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDI = 0; 2719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP = X86G_CC_OP_COPY; 2721893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1 = 0; 2722893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2 = 0; 2723893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP = 0; 2724893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DFLAG = 1; /* forwards */ 2725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_IDFLAG = 0; 27266d26984a0df6a7d20b658bac6edf869eb872cca3sewardj vex_state->guest_ACFLAG = 0; 2727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EIP = 0; 2729893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2730893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialise the simulated FPU */ 2731893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_dirtyhelper_FINIT( vex_state ); 2732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialse the SSE state. */ 2734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define SSEZERO(_xmm) _xmm[0]=_xmm[1]=_xmm[2]=_xmm[3] = 0; 2735893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2736893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SSEROUND = (UInt)Irrm_NEAREST; 2737893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM0); 2738893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM1); 2739893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM2); 2740893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM3); 2741893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM4); 2742893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM5); 2743893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM6); 2744893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM7); 2745893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2746893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef SSEZERO 2747893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2748893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CS = 0; 2749893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DS = 0; 2750893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ES = 0; 2751893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_FS = 0; 2752893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GS = 0; 2753893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SS = 0; 2754893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_LDT = 0; 2755893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GDT = 0; 2756893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 27576ef84bed9bb3af22060eb1759788034602bbcc88florian vex_state->guest_EMNOTE = EmNote_NONE; 27581f126c5c092801acfc1ac968d2f1a37dde334bccsewardj 2759bfceb089644ce9eee882bae5cec5902be4831cacsewardj /* SSE2 has a 'clflush' cache-line-invalidator which uses these. */ 276005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj vex_state->guest_CMSTART = 0; 276105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj vex_state->guest_CMLEN = 0; 2762ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj 2763d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_NRADDR = 0; 2764d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_SC_CLASS = 0; 2765e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->guest_IP_AT_SYSCALL = 0; 2766e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj 276795a487bc73c0f8c9371ad500988a51c9e78ee34aflorian vex_state->padding1 = 0; 2768893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 2769893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 27708d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27718d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/* Figure out if any part of the guest state contained in minoff 27728d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj .. maxoff requires precise memory exceptions. If in doubt return 27736c46befd9eb90c1b6e739926c1fa335cba75bf46philippe True (but this generates significantly slower code). 27748d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27754cca75cb48776ceda40e8e305232d85f62021804sewardj By default we enforce precise exns for guest %ESP, %EBP and %EIP 27764cca75cb48776ceda40e8e305232d85f62021804sewardj only. These are the minimum needed to extract correct stack 27774cca75cb48776ceda40e8e305232d85f62021804sewardj backtraces from x86 code. 27786c46befd9eb90c1b6e739926c1fa335cba75bf46philippe 27796c46befd9eb90c1b6e739926c1fa335cba75bf46philippe Only %ESP is needed in mode VexRegUpdSpAtMemAccess. 27808d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj*/ 2781ca2c3c75784d35d136fc7c952717cdee5063c193sewardjBool guest_x86_state_requires_precise_mem_exns ( 2782ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Int minoff, Int maxoff, VexRegisterUpdates pxControl 2783ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ) 27848d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj{ 27854cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_min = offsetof(VexGuestX86State, guest_EBP); 27864cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_max = ebp_min + 4 - 1; 27878d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_min = offsetof(VexGuestX86State, guest_ESP); 27888d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_max = esp_min + 4 - 1; 27898d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_min = offsetof(VexGuestX86State, guest_EIP); 27908d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_max = eip_min + 4 - 1; 27918d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27926c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < esp_min || minoff > esp_max) { 27936c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* no overlap with esp */ 2794ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl == VexRegUpdSpAtMemAccess) 27956c46befd9eb90c1b6e739926c1fa335cba75bf46philippe return False; // We only need to check stack pointer. 27964cca75cb48776ceda40e8e305232d85f62021804sewardj } else { 27974cca75cb48776ceda40e8e305232d85f62021804sewardj return True; 27984cca75cb48776ceda40e8e305232d85f62021804sewardj } 27994cca75cb48776ceda40e8e305232d85f62021804sewardj 28006c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < ebp_min || minoff > ebp_max) { 28016c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* no overlap with ebp */ 28028d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2803eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 28048d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 28058d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 28068d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj if (maxoff < eip_min || minoff > eip_max) { 2807eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* no overlap with eip */ 28088d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2809eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 28108d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 28118d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 28128d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj return False; 28138d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj} 28148d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 28158d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 2816eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj#define ALWAYSDEFD(field) \ 2817eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj { offsetof(VexGuestX86State, field), \ 2818eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj (sizeof ((VexGuestX86State*)0)->field) } 2819eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2820eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardjVexGuestLayout 282149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj x86guest_layout 2822eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj = { 2823eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Total size of the guest state, in bytes. */ 2824eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .total_sizeB = sizeof(VexGuestX86State), 2825eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2826eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe the stack pointer. */ 2827eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .offset_SP = offsetof(VexGuestX86State,guest_ESP), 2828eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .sizeof_SP = 4, 2829eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2830a203330aad67bc3e52ca1395a55e94ef9a091223sewardj /* Describe the frame pointer. */ 2831a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .offset_FP = offsetof(VexGuestX86State,guest_EBP), 2832a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .sizeof_FP = 4, 2833a203330aad67bc3e52ca1395a55e94ef9a091223sewardj 2834cf7879021370aabcccb1a9347244fcc7d5680141sewardj /* Describe the instruction pointer. */ 2835cf7879021370aabcccb1a9347244fcc7d5680141sewardj .offset_IP = offsetof(VexGuestX86State,guest_EIP), 2836cf7879021370aabcccb1a9347244fcc7d5680141sewardj .sizeof_IP = 4, 2837eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2838eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe any sections to be regarded by Memcheck as 2839eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 'always-defined'. */ 2840e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj .n_alwaysDefd = 24, 28413bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 28422a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* flags thunk: OP and NDEP are always defd, whereas DEP1 28432a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj and DEP2 have to be tracked. See detailed comment in 28442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj gdefs.h on meaning of thunk fields. */ 28458fc937421c954ff9f707254f028b1fa0410c473dsewardj .alwaysDefd 28468fc937421c954ff9f707254f028b1fa0410c473dsewardj = { /* 0 */ ALWAYSDEFD(guest_CC_OP), 28478fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), 28488fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 2 */ ALWAYSDEFD(guest_DFLAG), 28498fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 3 */ ALWAYSDEFD(guest_IDFLAG), 28506d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 4 */ ALWAYSDEFD(guest_ACFLAG), 28516d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 5 */ ALWAYSDEFD(guest_EIP), 28526d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 6 */ ALWAYSDEFD(guest_FTOP), 28536d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 7 */ ALWAYSDEFD(guest_FPTAG), 28546d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 8 */ ALWAYSDEFD(guest_FPROUND), 28556d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 9 */ ALWAYSDEFD(guest_FC3210), 28566d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 10 */ ALWAYSDEFD(guest_CS), 28576d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 11 */ ALWAYSDEFD(guest_DS), 28586d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 12 */ ALWAYSDEFD(guest_ES), 28596d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 13 */ ALWAYSDEFD(guest_FS), 28606d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 14 */ ALWAYSDEFD(guest_GS), 28616d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 15 */ ALWAYSDEFD(guest_SS), 28626d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 16 */ ALWAYSDEFD(guest_LDT), 28636d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 17 */ ALWAYSDEFD(guest_GDT), 28646ef84bed9bb3af22060eb1759788034602bbcc88florian /* 18 */ ALWAYSDEFD(guest_EMNOTE), 28656d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 19 */ ALWAYSDEFD(guest_SSEROUND), 286605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 20 */ ALWAYSDEFD(guest_CMSTART), 286705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 21 */ ALWAYSDEFD(guest_CMLEN), 2868e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 22 */ ALWAYSDEFD(guest_SC_CLASS), 2869e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 23 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) 28708fc937421c954ff9f707254f028b1fa0410c473dsewardj } 2871eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj }; 287249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 287349651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 287436ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2875cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end guest_x86_helpers.c ---*/ 287636ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2877