guest_x86_helpers.c revision 4ff2a1aa52dbed78055deba39c14c3978d12601c
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 10e6c53e08c7932ed3c1772a1838d615f88ed995ebsewardj Copyright (C) 2004-2011 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" 37893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj#include "libvex_emwarn.h" 380c2cb623cca372a2b42b073121c7413cdaaf75besewardj#include "libvex_guest_x86.h" 3936ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_ir.h" 4049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj#include "libvex.h" 41c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj 42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 43cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h" 44cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_x86_defs.h" 45cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_x87.h" 46c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 47893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 4836ca51378f8851635df814230fa23f2c409b9eddsewardj/* This file contains helper functions for x86 guest code. 4936ca51378f8851635df814230fa23f2c409b9eddsewardj Calls to these functions are generated by the back end. 5036ca51378f8851635df814230fa23f2c409b9eddsewardj These calls are of course in the host machine code and 5136ca51378f8851635df814230fa23f2c409b9eddsewardj this file will be compiled to host machine code, so that 5236ca51378f8851635df814230fa23f2c409b9eddsewardj all makes sense. 5336ca51378f8851635df814230fa23f2c409b9eddsewardj 5436ca51378f8851635df814230fa23f2c409b9eddsewardj Only change the signatures of these helper functions very 5536ca51378f8851635df814230fa23f2c409b9eddsewardj carefully. If you change the signature here, you'll have to change 5636ca51378f8851635df814230fa23f2c409b9eddsewardj the parameters passed to it in the IR calls constructed by 572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj guest-x86/toIR.c. 5889050e58e7bee40892662fe94231aefc33768cf5sewardj 59893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj The convention used is that all functions called from generated 60893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj code are named x86g_<something>, and any function whose name lacks 61893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj that prefix is not called from generated code. Note that some 62893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj LibVEX_* functions can however be called by VEX's client, but that 63893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj is not the same as calling them from VEX-generated code. 6436ca51378f8851635df814230fa23f2c409b9eddsewardj*/ 6536ca51378f8851635df814230fa23f2c409b9eddsewardj 66893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 6784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Set to 1 to get detailed profiling info about use of the flag 6884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj machinery. */ 6984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#define PROFILE_EFLAGS 0 7084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 7184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 72893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 73893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags run-time helpers. ---*/ 74893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 75893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 76d44bc6e6692dfb0881dcc249bd4ba3d8f8e97fcasewardjstatic const UChar parity_table[256] = { 772a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 782a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 792a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 802a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 812a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 822a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 882a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 892a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 1062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, 1082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 0, X86G_CC_MASK_P, X86G_CC_MASK_P, 0, X86G_CC_MASK_P, 0, 0, X86G_CC_MASK_P, 10914731f22bf7759d6d23383ca870ac89d9581f1e9sewardj}; 11014731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1114a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* generalised left-shifter */ 112df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardjinline static Int lshift ( Int x, Int n ) 11314731f22bf7759d6d23383ca870ac89d9581f1e9sewardj{ 114df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj if (n >= 0) 115df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj return x << n; 116df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj else 117df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj return x >> (-n); 11814731f22bf7759d6d23383ca870ac89d9581f1e9sewardj} 11914731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 1204a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* identity on ULong */ 1214a6f3844a29aebc9774ab0d71418421c14ba9c41sewardjstatic inline ULong idULong ( ULong x ) 1224a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj{ 1234a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj return x; 1244a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj} 1254a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 12614731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 127b9c5cf639b3b21b972599d27207a033afc76ef67sewardj#define PREAMBLE(__data_bits) \ 128df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* const */ UInt DATA_MASK \ 129b9c5cf639b3b21b972599d27207a033afc76ef67sewardj = __data_bits==8 ? 0xFF \ 130b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : (__data_bits==16 ? 0xFFFF \ 131b9c5cf639b3b21b972599d27207a033afc76ef67sewardj : 0xFFFFFFFF); \ 132df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* const */ UInt SIGN_MASK = 1 << (__data_bits - 1); \ 1332a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP1 = cc_dep1_formal; \ 1342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_DEP2 = cc_dep2_formal; \ 1352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* const */ UInt CC_NDEP = cc_ndep_formal; \ 1362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* Four bogus assignments, which hopefully gcc can */ \ 137df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* optimise away, and which stop it complaining about */ \ 138df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj /* unused variables. */ \ 139df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj SIGN_MASK = SIGN_MASK; \ 140df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj DATA_MASK = DATA_MASK; \ 1412a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_DEP2 = CC_DEP2; \ 1422a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj CC_NDEP = CC_NDEP; 143df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj 14414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 145b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 146b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 147df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE) \ 148b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 149b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 1508fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 1518fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 1528fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1538fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1548fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL + argR; \ 1558fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 1568fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1578fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1588fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1598fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1608fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 1612a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1628fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1638fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1642ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1652ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 166b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 167b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 1682a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE) \ 169b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 170b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 1718fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 1728fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 1738fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1748fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2; \ 1758fc937421c954ff9f707254f028b1fa0410c473dsewardj res = argL - argR; \ 1768fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 1778fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 1788fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 1798fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 1808fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 1818fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 1822a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 1838fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 1848fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 1852ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 1862ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 187b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 188b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 1892a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE) \ 190b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 191b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 1928fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 1938fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, oldC, res; \ 1942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 1958fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 1968fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 1978fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL + argR) + oldC; \ 1988fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 1998fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 2008fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2018fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 2028fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2038fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2048fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2058fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2068fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 2072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2088fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2098fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 2102ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj} 2112ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj 212b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 213b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 214df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE) \ 215b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 216b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2178fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2188fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, oldC, res; \ 2192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj oldC = CC_NDEP & X86G_CC_MASK_C; \ 2208fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = CC_DEP1; \ 2218fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = CC_DEP2 ^ oldC; \ 2228fc937421c954ff9f707254f028b1fa0410c473dsewardj res = (argL - argR) - oldC; \ 2238fc937421c954ff9f707254f028b1fa0410c473dsewardj if (oldC) \ 2248fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR; \ 2258fc937421c954ff9f707254f028b1fa0410c473dsewardj else \ 2268fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 2278fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2288fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2298fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2308fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2318fc937421c954ff9f707254f028b1fa0410c473dsewardj of = lshift((argL ^ argR) & (argL ^ res), \ 2322a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 12 - DATA_BITS) & X86G_CC_MASK_O; \ 2338fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2348fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 235a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 236a238471814bd386aeb58a76718b41e68b1a794b2sewardj 237b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 238b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 239df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE) \ 240b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 241b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2428fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2438fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = 0; \ 2448fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 2458fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; \ 2468fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 2478fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 2488fc937421c954ff9f707254f028b1fa0410c473dsewardj of = 0; \ 2498fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2508fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 251a238471814bd386aeb58a76718b41e68b1a794b2sewardj} 252a238471814bd386aeb58a76718b41e68b1a794b2sewardj 253b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 254b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 255df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_INC(DATA_BITS,DATA_UTYPE) \ 256b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 257b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2588fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2598fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 2608fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2618fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res - 1; \ 2628fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2648fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2658fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2668fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2678fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2688fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) == SIGN_MASK) << 11; \ 2698fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2708fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 27189050e58e7bee40892662fe94231aefc33768cf5sewardj} 27289050e58e7bee40892662fe94231aefc33768cf5sewardj 273b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 274b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 275df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE) \ 276b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 277b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2788fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 2798fc937421c954ff9f707254f028b1fa0410c473dsewardj Int argL, argR, res; \ 2808fc937421c954ff9f707254f028b1fa0410c473dsewardj res = CC_DEP1; \ 2818fc937421c954ff9f707254f028b1fa0410c473dsewardj argL = res + 1; \ 2828fc937421c954ff9f707254f028b1fa0410c473dsewardj argR = 1; \ 2832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = CC_NDEP & X86G_CC_MASK_C; \ 2848fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)res]; \ 2858fc937421c954ff9f707254f028b1fa0410c473dsewardj af = (res ^ argL ^ argR) & 0x10; \ 2868fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 2878fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 2888fc937421c954ff9f707254f028b1fa0410c473dsewardj of = ((res & DATA_MASK) \ 2898fc937421c954ff9f707254f028b1fa0410c473dsewardj == ((UInt)SIGN_MASK - 1)) << 11; \ 2908fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 2918fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 29289050e58e7bee40892662fe94231aefc33768cf5sewardj} 29389050e58e7bee40892662fe94231aefc33768cf5sewardj 294b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 295b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 296df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE) \ 297b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 298b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 2998fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (CC_DEP2 >> (DATA_BITS - 1)) & X86G_CC_MASK_C; \ 3018fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3028fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3038fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3048fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3058fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3088fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3098fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3105f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3115f6303579435ddb8315e11c2f02c904b978782a0sewardj 312b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 313b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3142a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE) \ 315b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 316b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3178fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3188fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = CC_DEP2 & 1; \ 3198fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)CC_DEP1]; \ 3208fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3218fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 3228fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 3238fc937421c954ff9f707254f028b1fa0410c473dsewardj /* of is defined if shift count == 1 */ \ 3242a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 3252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_O; \ 3268fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3278fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3285f6303579435ddb8315e11c2f02c904b978782a0sewardj} 3295f6303579435ddb8315e11c2f02c904b978782a0sewardj 330b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 331b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3328ee2de1f5f72c13120f59c0ca6ac8291219123dfsewardj/* ROL: cf' = lsb(result). of' = msb(result) ^ lsb(result). */ 3332a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 334df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE) \ 335b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 336b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3378fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int fl \ 3382a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & CC_DEP1) \ 3402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3428fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11))); \ 3438fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3448fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3458c7f1abe9e022f6382634efea09c9cac89ec6336sewardj} 3468c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 347b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 348b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3491813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj/* ROR: cf' = msb(result). of' = msb(result) ^ msb-1(result). */ 3502a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */ 351df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE) \ 352b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{ \ 353b9c5cf639b3b21b972599d27207a033afc76ef67sewardj PREAMBLE(DATA_BITS); \ 3548fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int fl \ 3552a9ad023890d3b34cf45e429df2a8ae88b419128sewardj = (CC_NDEP & ~(X86G_CC_MASK_O | X86G_CC_MASK_C)) \ 3562a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1))) \ 3572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | (X86G_CC_MASK_O & (lshift(CC_DEP1, \ 3582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj 11-(DATA_BITS-1)) \ 3598fc937421c954ff9f707254f028b1fa0410c473dsewardj ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1))); \ 3608fc937421c954ff9f707254f028b1fa0410c473dsewardj return fl; \ 3618fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 3621813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj} 3631813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 364b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 365b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3664a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_UMUL(DATA_BITS, DATA_UTYPE, NARROWtoU, \ 3674a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE, NARROWto2U) \ 3682a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 3692a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 3708fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3718fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_UTYPE hi; \ 3724a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_UTYPE lo \ 3734a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ 3744a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_UTYPE)CC_DEP2) ); \ 3754a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_U2TYPE rr \ 3764a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2U( \ 3774a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ 3784a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ 3794a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ 3808fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != 0); \ 3818fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 3828fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 3838fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 3848fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 3858fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 3868fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 3878fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 38856296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj} 38956296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj 390b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/ 391b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 3924a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ 3934a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE, NARROWto2S) \ 3942a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{ \ 3952a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj PREAMBLE(DATA_BITS); \ 3968fc937421c954ff9f707254f028b1fa0410c473dsewardj { Int cf, pf, af, zf, sf, of; \ 3978fc937421c954ff9f707254f028b1fa0410c473dsewardj DATA_STYPE hi; \ 3984a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_STYPE lo \ 3994a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWtoS( ((DATA_STYPE)CC_DEP1) \ 4004a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_STYPE)CC_DEP2) ); \ 4014a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj DATA_S2TYPE rr \ 4024a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj = NARROWto2S( \ 4034a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ 4044a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ 4054a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ 4068fc937421c954ff9f707254f028b1fa0410c473dsewardj cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ 4078fc937421c954ff9f707254f028b1fa0410c473dsewardj pf = parity_table[(UChar)lo]; \ 4088fc937421c954ff9f707254f028b1fa0410c473dsewardj af = 0; /* undefined */ \ 4098fc937421c954ff9f707254f028b1fa0410c473dsewardj zf = (lo == 0) << 6; \ 4108fc937421c954ff9f707254f028b1fa0410c473dsewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 4118fc937421c954ff9f707254f028b1fa0410c473dsewardj of = cf << 11; \ 4128fc937421c954ff9f707254f028b1fa0410c473dsewardj return cf | pf | af | zf | sf | of; \ 4138fc937421c954ff9f707254f028b1fa0410c473dsewardj } \ 4147ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj} 415741153c4301023a420ab45b8a10b8e1bac968822sewardj 41636ca51378f8851635df814230fa23f2c409b9eddsewardj 41784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#if PROFILE_EFLAGS 41884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 4199eab588e223e52b1e7b710ff1c0da7b032ab2837sewardjstatic Bool initted = False; 420893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 421893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, fast route */ 422893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_fast[X86G_CC_OP_NUMBER]; 423893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* C flag, slow route */ 424893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tabc_slow[X86G_CC_OP_NUMBER]; 425893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* table for calculate_cond */ 426893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt tab_cond[X86G_CC_OP_NUMBER][16]; 427893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* total entry counts for calc_all, calc_c, calc_cond. */ 42884ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_all = 0; 42984ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_c = 0; 430893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic UInt n_calc_cond = 0; 431893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 432893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond))) 433893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 43484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 43584ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void showCounts ( void ) 43684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 43784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 43884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Char ch; 439a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", 440893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all, n_calc_cond, n_calc_c); 441893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 442893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" 44384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj " S NS P NP L NL LE NLE\n"); 444893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" -----------------------------------------------------" 44584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj "----------------------------------------\n"); 4462a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 44784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 44884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = ' '; 44993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 0) 45093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'B'; 45193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj if (op > 0 && (op-1) % 3 == 1) 45293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj ch = 'W'; 45384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (op > 0 && (op-1) % 3 == 2) 45484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ch = 'L'; 45584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 45684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("%2d%c: ", op, ch); 457a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_slow[op]); 458a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("%6u ", tabc_fast[op]); 45984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) { 460893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int n = tab_cond[op][co]; 46184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 1000) { 46284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %3dK", n / 1000); 46384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else 46484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj if (n >= 0) { 465893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf(" %3d ", n ); 46684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } else { 46784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 46884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 46984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 47084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 47184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 47284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 47384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 47484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 47584ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void initCounts ( void ) 47684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 47784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int op, co; 47884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj initted = True; 4792a9ad023890d3b34cf45e429df2a8ae88b419128sewardj for (op = 0; op < X86G_CC_OP_NUMBER; op++) { 480893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[op] = tabc_slow[op] = 0; 48184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (co = 0; co < 16; co++) 482893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[op][co] = 0; 48384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 48484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 48584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 48684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#endif /* PROFILE_EFLAGS */ 48784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 488893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 4899aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 490893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. 491893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Worker function, not directly called from generated code. */ 492893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic 493893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all_WRK ( UInt cc_op, 494893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1_formal, 495893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2_formal, 496893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep_formal ) 49736ca51378f8851635df814230fa23f2c409b9eddsewardj{ 49836ca51378f8851635df814230fa23f2c409b9eddsewardj switch (cc_op) { 4992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_COPY: 5002a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj return cc_dep1_formal 5012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & (X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 5022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P); 50314731f22bf7759d6d23383ca870ac89d9581f1e9sewardj 5042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); 5052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); 5062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); 507a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); 5092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); 5102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); 511a238471814bd386aeb58a76718b41e68b1a794b2sewardj 5122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); 5132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); 5142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); 515afc5787e1c4b8e9678669577cf57ac509c6cd6b5sewardj 5162a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); 5172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); 5182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); 519741153c4301023a420ab45b8a10b8e1bac968822sewardj 5202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); 5212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); 5222a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); 5235f6303579435ddb8315e11c2f02c904b978782a0sewardj 5242a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); 5252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); 5262a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); 5271813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5282a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); 5292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); 5302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); 5318c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5322a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); 5332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); 5342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); 5358c7f1abe9e022f6382634efea09c9cac89ec6336sewardj 5362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); 5372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); 5382a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); 5391813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj 5402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); 5412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); 5422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); 543750f407b6be1aac303964a219acf0a6de8b8c4dasewardj 5442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); 5452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); 5462a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); 5477ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj 5484a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, 5494a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UShort, toUShort ); 5504a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, 5514a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj UInt, toUInt ); 5524a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, 5534a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj ULong, idULong ); 5544a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj 5554a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, 5564a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Short, toUShort ); 5574a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, 5584a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Int, toUInt ); 5594a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj case X86G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, 5604a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj Long, idULong ); 561741153c4301023a420ab45b8a10b8e1bac968822sewardj 56236ca51378f8851635df814230fa23f2c409b9eddsewardj default: 56336ca51378f8851635df814230fa23f2c409b9eddsewardj /* shouldn't really make these calls from generated code */ 564893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("x86g_calculate_eflags_all_WRK(X86)" 565a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj "( %u, 0x%x, 0x%x, 0x%x )\n", 5662a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); 567893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_eflags_all_WRK(X86)"); 56836ca51378f8851635df814230fa23f2c409b9eddsewardj } 56936ca51378f8851635df814230fa23f2c409b9eddsewardj} 57036ca51378f8851635df814230fa23f2c409b9eddsewardj 571b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 5729aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 573893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Calculate all the 6 flags from the supplied thunk parameters. */ 574893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt x86g_calculate_eflags_all ( UInt cc_op, 575893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep1, 576893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_dep2, 577893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt cc_ndep ) 578893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 579893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 580893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 581893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_all++; 582893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 583893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 584893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 585893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_calculate_eflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep ); 586893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 587893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 588893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 589893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 590b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/* Calculate just the carry flag from the supplied thunk parameters. */ 59103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(3) 5922a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_eflags_c ( UInt cc_op, 5932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 5942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 5952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 59636ca51378f8851635df814230fa23f2c409b9eddsewardj{ 597893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if PROFILE_EFLAGS 598893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 599893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj n_calc_c++; 600893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]++; 601893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 602893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 603893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 6049eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj /* Fast-case some common ones. */ 60543c46951628d616290f7245c3af2f9a652180806sewardj switch (cc_op) { 6062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICL: 6072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICW: 6082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_LOGICB: 60943c46951628d616290f7245c3af2f9a652180806sewardj return 0; 6102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBL: 61193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)cc_dep1) < ((UInt)cc_dep2) 6122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 613893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj case X86G_CC_OP_SUBW: 614893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) 615893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ? X86G_CC_MASK_C : 0; 6162a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_SUBB: 61793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) 6182a9ad023890d3b34cf45e429df2a8ae88b419128sewardj ? X86G_CC_MASK_C : 0; 619e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj case X86G_CC_OP_INCL: 6202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86G_CC_OP_DECL: 621e9ba4328f2afb94bc8474e9a7205e50ed9ac73fcsewardj return cc_ndep & X86G_CC_MASK_C; 62243c46951628d616290f7245c3af2f9a652180806sewardj default: 62343c46951628d616290f7245c3af2f9a652180806sewardj break; 62443c46951628d616290f7245c3af2f9a652180806sewardj } 6259eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj 62684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 627893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_fast[cc_op]--; 628893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tabc_slow[cc_op]++; 62984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 630893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 631893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return x86g_calculate_eflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) 6322a9ad023890d3b34cf45e429df2a8ae88b419128sewardj & X86G_CC_MASK_C; 63336ca51378f8851635df814230fa23f2c409b9eddsewardj} 63436ca51378f8851635df814230fa23f2c409b9eddsewardj 63536ca51378f8851635df814230fa23f2c409b9eddsewardj 6369aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 63784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* returns 1 or 0 */ 6382a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_condition ( UInt/*X86Condcode*/ cond, 6392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_op, 6402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep1, 6412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_dep2, 6422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj UInt cc_ndep ) 6432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{ 644893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK(cc_op, cc_dep1, 645893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2, cc_ndep); 64684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt of,sf,zf,cf,pf; 64784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj UInt inv = cond & 1; 64884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 64984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if PROFILE_EFLAGS 650893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (!initted) initCounts(); 651893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj tab_cond[cc_op][cond]++; 65284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj n_calc_cond++; 653893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (SHOW_COUNTS_NOW) showCounts(); 65484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 65584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 65684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj switch (cond) { 6572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNO: 6582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondO: /* OF == 1 */ 6592a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 66084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ of); 66184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6622a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNZ: 6632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondZ: /* ZF == 1 */ 6642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 66584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ zf); 66684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNB: 6682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondB: /* CF == 1 */ 6692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 67084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ cf); 67184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 67284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6732a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNBE: 6742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondBE: /* (CF or ZF) == 1 */ 6752a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = eflags >> X86G_CC_SHIFT_C; 6762a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 67784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (cf | zf)); 67884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 67984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6802a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNS: 6812a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondS: /* SF == 1 */ 6822a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 68384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ sf); 68484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNP: 6862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondP: /* PF == 1 */ 6872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj pf = eflags >> X86G_CC_SHIFT_P; 68884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ pf); 68984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNL: 6912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondL: /* (SF xor OF) == 1 */ 6922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 6932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 69484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ (sf ^ of)); 69584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 69684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 6972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondNLE: 6982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj case X86CondLE: /* ((SF xor OF) or ZF) == 1 */ 6992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj sf = eflags >> X86G_CC_SHIFT_S; 7002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj of = eflags >> X86G_CC_SHIFT_O; 7012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj zf = eflags >> X86G_CC_SHIFT_Z; 70284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return 1 & (inv ^ ((sf ^ of) | zf)); 70384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj break; 70484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 70584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj default: 70684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* shouldn't really make these calls from generated code */ 707a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj vex_printf("x86g_calculate_condition( %u, %u, 0x%x, 0x%x, 0x%x )\n", 7082a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); 709893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vpanic("x86g_calculate_condition"); 71084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 71184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 71284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 71384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 714893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 715893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjUInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state ) 716893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt eflags = x86g_calculate_eflags_all_WRK( 718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP, 719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1, 720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2, 721893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP 722893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 723893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt dflag = vex_state->guest_DFLAG; 724893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(dflag == 1 || dflag == 0xFFFFFFFF); 725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (dflag == 0xFFFFFFFF) 726893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<10); 727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_state->guest_IDFLAG == 1) 728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj eflags |= (1<<21); 7296d26984a0df6a7d20b658bac6edf869eb872cca3sewardj if (vex_state->guest_ACFLAG == 1) 7306d26984a0df6a7d20b658bac6edf869eb872cca3sewardj eflags |= (1<<18); 731893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return eflags; 733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 735f32d5a5dd44a6d490c901949114d86441c24ef92sewardj/* VISIBLE TO LIBVEX CLIENT */ 736f32d5a5dd44a6d490c901949114d86441c24ef92sewardjvoid 737f32d5a5dd44a6d490c901949114d86441c24ef92sewardjLibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag, 738f32d5a5dd44a6d490c901949114d86441c24ef92sewardj /*MOD*/VexGuestX86State* vex_state ) 739f32d5a5dd44a6d490c901949114d86441c24ef92sewardj{ 740f32d5a5dd44a6d490c901949114d86441c24ef92sewardj UInt oszacp = x86g_calculate_eflags_all_WRK( 741f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_OP, 742f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP1, 743f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP2, 744f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_NDEP 745f32d5a5dd44a6d490c901949114d86441c24ef92sewardj ); 746f32d5a5dd44a6d490c901949114d86441c24ef92sewardj if (new_carry_flag & 1) { 747f32d5a5dd44a6d490c901949114d86441c24ef92sewardj oszacp |= X86G_CC_MASK_C; 748f32d5a5dd44a6d490c901949114d86441c24ef92sewardj } else { 749f32d5a5dd44a6d490c901949114d86441c24ef92sewardj oszacp &= ~X86G_CC_MASK_C; 750f32d5a5dd44a6d490c901949114d86441c24ef92sewardj } 751f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_OP = X86G_CC_OP_COPY; 752f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP1 = oszacp; 753f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_DEP2 = 0; 754f32d5a5dd44a6d490c901949114d86441c24ef92sewardj vex_state->guest_CC_NDEP = 0; 755f32d5a5dd44a6d490c901949114d86441c24ef92sewardj} 756f32d5a5dd44a6d490c901949114d86441c24ef92sewardj 757893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 758893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 759893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags translation-time function specialisers. ---*/ 760893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- These help iropt specialise calls the above run-time ---*/ 761893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- %eflags functions. ---*/ 762893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 763893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 76484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Used by the optimiser to try specialisations. Returns an 76584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj equivalent expression, or NULL if none. */ 76684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 767908854045e8ebf1495663bb50801c32d6f729bbesewardjstatic inline Bool isU32 ( IRExpr* e, UInt n ) 76884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 769a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return 770a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj toBool( e->tag == Iex_Const 771a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->tag == Ico_U32 772a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && e->Iex.Const.con->Ico.U32 == n ); 77384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 77484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 775be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardjIRExpr* guest_x86_spechelper ( HChar* function_name, 776be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRExpr** args, 777be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRStmt** precedingStmts, 778be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj Int n_precedingStmts ) 77984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{ 78084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 78184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 78284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 7834afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 78484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 78584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj Int i, arity = 0; 78684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; args[i]; i++) 78784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj arity++; 78884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# if 0 78984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("spec request:\n"); 79084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" %s ", function_name); 79184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj for (i = 0; i < arity; i++) { 79284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf(" "); 79384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj ppIRExpr(args[i]); 79484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 79584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n"); 79684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# endif 79793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 7983835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj /* --------- specialising "x86g_calculate_condition" --------- */ 79993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj 8003835288ac63bb755c0e1d2f3142a13416dcb64c6sewardj if (vex_streq(function_name, "x86g_calculate_condition")) { 80184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* specialise calls to above "calculate condition" function */ 802a8415ffe6c6f0e73519301a55026a4071c701fd1sewardj IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2; 80393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj vassert(arity == 5); 80493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cond = args[0]; 80593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_op = args[1]; 80693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep1 = args[2]; 80793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj cc_dep2 = args[3]; 80884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 809d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- ADDL ----------------*/ 810d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 8112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_ADDL) && isU32(cond, X86CondZ)) { 812d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* long add, then Z --> test (dst+src == 0) */ 813d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 814d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, 815d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_Add32, cc_dep1, cc_dep2), 816d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 817d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 818d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 81946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBL ----------------*/ 82046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 8212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondZ)) { 82246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then Z --> test dst==src */ 82384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 82493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, cc_dep1, cc_dep2)); 82546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 82666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNZ)) { 82766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long sub/cmp, then NZ --> test dst!=src */ 82866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32, 82966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj binop(Iop_CmpNE32, cc_dep1, cc_dep2)); 83066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 83166f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 8322a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondL)) { 83346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then L (signed less than) 83446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <s src */ 83546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 83693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLT32S, cc_dep1, cc_dep2)); 83746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8388a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNL)) { 8398a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NL (signed greater than or equal) 8408a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <s src) */ 8418a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8428a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8438a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32S, cc_dep1, cc_dep2)), 8448a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8458a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8468a81970fd71af3fa5725b85c65c7540a441071bfsewardj 8472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondLE)) { 84846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then LE (signed less than or equal) 84946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=s src */ 85046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 85193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32S, cc_dep1, cc_dep2)); 85246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8532eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNLE)) { 854c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* long sub/cmp, then NLE (signed not less than or equal) 8552eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj --> test dst >s src 8562eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj --> test !(dst <=s src) */ 8572eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj return binop(Iop_Xor32, 8582eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj unop(Iop_1Uto32, 8592eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj binop(Iop_CmpLE32S, cc_dep1, cc_dep2)), 8602eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj mkU32(1)); 8612eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj } 8622eb9ffadd7f9dd2b0273ee6c4554615df8502e2fsewardj 8632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondBE)) { 86446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then BE (unsigned less than or equal) 86546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <=u src */ 86646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 86793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpLE32U, cc_dep1, cc_dep2)); 86846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj } 8698a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNBE)) { 8708a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then BE (unsigned greater than) 8718a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <=u src) */ 8728a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8738a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8748a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLE32U, cc_dep1, cc_dep2)), 8758a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8768a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8778a81970fd71af3fa5725b85c65c7540a441071bfsewardj 8782a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondB)) { 87946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* long sub/cmp, then B (unsigned less than) 88046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj --> test dst <u src */ 88146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj return unop(Iop_1Uto32, 882e664ec4b9f27ed7d7ca87a2d4188fd479059351csewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 88384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 8848a81970fd71af3fa5725b85c65c7540a441071bfsewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNB)) { 8858a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NB (unsigned greater than or equal) 8868a81970fd71af3fa5725b85c65c7540a441071bfsewardj --> test !(dst <u src) */ 8878a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 8888a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 8898a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)), 8908a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 8918a81970fd71af3fa5725b85c65c7540a441071bfsewardj } 8928a81970fd71af3fa5725b85c65c7540a441071bfsewardj 893e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)) { 8948a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then S (negative) --> test (dst-src <s 0) */ 895e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return unop(Iop_1Uto32, 896e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_CmpLT32S, 897e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Sub32, cc_dep1, cc_dep2), 898e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(0))); 899e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 9001ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNS)) { 9018a81970fd71af3fa5725b85c65c7540a441071bfsewardj /* long sub/cmp, then NS (not negative) --> test !(dst-src <s 0) */ 9028a81970fd71af3fa5725b85c65c7540a441071bfsewardj return binop(Iop_Xor32, 9038a81970fd71af3fa5725b85c65c7540a441071bfsewardj unop(Iop_1Uto32, 9048a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_CmpLT32S, 9058a81970fd71af3fa5725b85c65c7540a441071bfsewardj binop(Iop_Sub32, cc_dep1, cc_dep2), 9068a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(0))), 9078a81970fd71af3fa5725b85c65c7540a441071bfsewardj mkU32(1)); 9081ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj } 9091ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj 91046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBW ----------------*/ 91146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 9122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondZ)) { 913c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* word sub/cmp, then Z --> test dst==src */ 914b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 915b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ16, 9167e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep1), 9177e6644c38b3e0148ff95c2f6f4667f54148b611esewardj unop(Iop_32to16,cc_dep2))); 918b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 919beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondNZ)) { 920beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj /* word sub/cmp, then NZ --> test dst!=src */ 921beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj return unop(Iop_1Uto32, 922beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj binop(Iop_CmpNE16, 923beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_32to16,cc_dep1), 924beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_32to16,cc_dep2))); 925beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj } 926b9c5cf639b3b21b972599d27207a033afc76ef67sewardj 92746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- SUBB ----------------*/ 9287e6644c38b3e0148ff95c2f6f4667f54148b611esewardj 9292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondZ)) { 930b9c5cf639b3b21b972599d27207a033afc76ef67sewardj /* byte sub/cmp, then Z --> test dst==src */ 93184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 932b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpEQ8, 93393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 93493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 93584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 9362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNZ)) { 9377e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* byte sub/cmp, then NZ --> test dst!=src */ 93884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 939b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpNE8, 94093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep1), 94193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj unop(Iop_32to8,cc_dep2))); 942b9c5cf639b3b21b972599d27207a033afc76ef67sewardj } 94322419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 9442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNBE)) { 945c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* byte sub/cmp, then NBE (unsigned greater than) 946dc12d39f7112dd57bae91b1f87963d0acaa2e71asewardj --> test src <u dst */ 9477e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj /* Note, args are opposite way round from the usual */ 948b9c5cf639b3b21b972599d27207a033afc76ef67sewardj return unop(Iop_1Uto32, 949b9c5cf639b3b21b972599d27207a033afc76ef67sewardj binop(Iop_CmpLT32U, 9507e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)), 9517e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)))); 95284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 95384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 954908854045e8ebf1495663bb50801c32d6f729bbesewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondS) 955908854045e8ebf1495663bb50801c32d6f729bbesewardj && isU32(cc_dep2, 0)) { 956c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* byte sub/cmp of zero, then S --> test (dst-0 <s 0) 957c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj --> test dst <s 0 958c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj --> (UInt)dst[7] 959908854045e8ebf1495663bb50801c32d6f729bbesewardj This is yet another scheme by which gcc figures out if the 960908854045e8ebf1495663bb50801c32d6f729bbesewardj top bit of a byte is 1 or 0. See also LOGICB/CondS below. */ 961908854045e8ebf1495663bb50801c32d6f729bbesewardj /* Note: isU32(cc_dep2, 0) is correct, even though this is 962908854045e8ebf1495663bb50801c32d6f729bbesewardj for an 8-bit comparison, since the args to the helper 963908854045e8ebf1495663bb50801c32d6f729bbesewardj function are always U32s. */ 964908854045e8ebf1495663bb50801c32d6f729bbesewardj return binop(Iop_And32, 965908854045e8ebf1495663bb50801c32d6f729bbesewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 966908854045e8ebf1495663bb50801c32d6f729bbesewardj mkU32(1)); 967908854045e8ebf1495663bb50801c32d6f729bbesewardj } 9689a3431c38a2e435c58a5e027943f50fa35c2369csewardj if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNS) 9699a3431c38a2e435c58a5e027943f50fa35c2369csewardj && isU32(cc_dep2, 0)) { 9709a3431c38a2e435c58a5e027943f50fa35c2369csewardj /* byte sub/cmp of zero, then NS --> test !(dst-0 <s 0) 9719a3431c38a2e435c58a5e027943f50fa35c2369csewardj --> test !(dst <s 0) 9729a3431c38a2e435c58a5e027943f50fa35c2369csewardj --> (UInt) !dst[7] 9739a3431c38a2e435c58a5e027943f50fa35c2369csewardj */ 9749a3431c38a2e435c58a5e027943f50fa35c2369csewardj return binop(Iop_Xor32, 9759a3431c38a2e435c58a5e027943f50fa35c2369csewardj binop(Iop_And32, 9769a3431c38a2e435c58a5e027943f50fa35c2369csewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 9779a3431c38a2e435c58a5e027943f50fa35c2369csewardj mkU32(1)), 9789a3431c38a2e435c58a5e027943f50fa35c2369csewardj mkU32(1)); 9799a3431c38a2e435c58a5e027943f50fa35c2369csewardj } 9809a3431c38a2e435c58a5e027943f50fa35c2369csewardj 98146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICL ----------------*/ 98246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj 9832a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondZ)) { 98484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then Z --> test dst==0 */ 98593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 98684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 987b83767e0691bcd985a0f4986e42e013585db3e55sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNZ)) { 988b83767e0691bcd985a0f4986e42e013585db3e55sewardj /* long and/or/xor, then NZ --> test dst!=0 */ 989b83767e0691bcd985a0f4986e42e013585db3e55sewardj return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0))); 990b83767e0691bcd985a0f4986e42e013585db3e55sewardj } 991b83767e0691bcd985a0f4986e42e013585db3e55sewardj 9922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondLE)) { 99384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* long and/or/xor, then LE 99484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj This is pretty subtle. LOGIC sets SF and ZF according to the 99584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj result and makes OF be zero. LE computes (SZ ^ OF) | ZF, but 99684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj OF is zero, so this reduces to SZ | ZF -- which will be 1 iff 99784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj the result is <=signed 0. Hence ... 99884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj */ 99993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpLE32S, cc_dep1, mkU32(0))); 100084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 100184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 100266f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondBE)) { 100366f7a54d5425853debcb5fe77be1021f0c2b6620sewardj /* long and/or/xor, then BE 100466f7a54d5425853debcb5fe77be1021f0c2b6620sewardj LOGIC sets ZF according to the result and makes CF be zero. 100566f7a54d5425853debcb5fe77be1021f0c2b6620sewardj BE computes (CF | ZF), but CF is zero, so this reduces ZF 100666f7a54d5425853debcb5fe77be1021f0c2b6620sewardj -- which will be 1 iff the result is zero. Hence ... 100766f7a54d5425853debcb5fe77be1021f0c2b6620sewardj */ 100866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 100966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj } 101066f7a54d5425853debcb5fe77be1021f0c2b6620sewardj 101154be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) { 101254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* see comment below for (LOGICB, CondS) */ 101354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* long and/or/xor, then S --> (UInt)result[31] */ 101454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 101554be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(31)), 101654be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 101754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 1018275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNS)) { 1019275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* see comment below for (LOGICB, CondNS) */ 1020275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* long and/or/xor, then S --> (UInt) ~ result[31] */ 1021275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return binop(Iop_Xor32, 1022275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_And32, 1023275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shr32,cc_dep1,mkU8(31)), 1024275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)), 1025275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)); 1026275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 102754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 1028d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- LOGICW ----------------*/ 1029d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 10302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) { 1031c5fd97216fa0f530828d517a5db46b64f5ae986fsewardj /* word and/or/xor, then Z --> test dst==0 */ 1032d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32, 1033d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(0xFFFF)), 1034d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj mkU32(0))); 1035d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 1036d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 103754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondS)) { 103854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* see comment below for (LOGICB, CondS) */ 103954be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* word and/or/xor, then S --> (UInt)result[15] */ 104054be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 104154be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(15)), 104254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 104354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 104454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 104546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- LOGICB ----------------*/ 104684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 10472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) { 104846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /* byte and/or/xor, then Z --> test dst==0 */ 104984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return unop(Iop_1Uto32, 105093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(255)), 105146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj mkU32(0))); 105284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 1053275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNZ)) { 1054275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* byte and/or/xor, then Z --> test dst!=0 */ 1055275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* b9ac9: 84 c0 test %al,%al 1056275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj b9acb: 75 0d jne b9ada */ 1057275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return unop(Iop_1Uto32, 1058275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_CmpNE32, binop(Iop_And32,cc_dep1,mkU32(255)), 1059275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(0))); 1060275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 1061275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 106254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondS)) { 106354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* this is an idiom gcc sometimes uses to find out if the top 106454be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj bit of a byte register is set: eg testb %al,%al; js .. 106554be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj Since it just depends on the top bit of the byte, extract 106654be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj that bit and explicitly get rid of all the rest. This 106754be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj helps memcheck avoid false positives in the case where any 106854be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj of the other bits in the byte are undefined. */ 106954be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj /* byte and/or/xor, then S --> (UInt)result[7] */ 107054be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj return binop(Iop_And32, 107154be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 107254be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj mkU32(1)); 107354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj } 1074275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNS)) { 1075275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* ditto, for negation-of-S. */ 1076275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* byte and/or/xor, then S --> (UInt) ~ result[7] */ 1077275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return binop(Iop_Xor32, 1078275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_And32, 1079275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shr32,cc_dep1,mkU8(7)), 1080275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)), 1081275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(1)); 1082275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 108354be8dd43bc6a509a1aab87a5d77cec8a61cd894sewardj 108446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj /*---------------- DECL ----------------*/ 1085af991dede2815b7570828b9d9174cf989e636254sewardj 10862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondZ)) { 108784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj /* dec L, then Z --> test dst == 0 */ 108893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 108984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 109022419b8f4f2c0104549ca9954f68e190b911d1a0sewardj 10912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondS)) { 1092fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj /* dec L, then S --> compare DST <s 0 */ 10937e6644c38b3e0148ff95c2f6f4667f54148b611esewardj return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0))); 1094fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj } 1095275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 109632d615b76c65938d815fe529e690a7f79a24a4ecsewardj /*---------------- DECW ----------------*/ 109732d615b76c65938d815fe529e690a7f79a24a4ecsewardj 109832d615b76c65938d815fe529e690a7f79a24a4ecsewardj if (isU32(cc_op, X86G_CC_OP_DECW) && isU32(cond, X86CondZ)) { 109932d615b76c65938d815fe529e690a7f79a24a4ecsewardj /* dec W, then Z --> test dst == 0 */ 110032d615b76c65938d815fe529e690a7f79a24a4ecsewardj return unop(Iop_1Uto32, 110132d615b76c65938d815fe529e690a7f79a24a4ecsewardj binop(Iop_CmpEQ32, 110232d615b76c65938d815fe529e690a7f79a24a4ecsewardj binop(Iop_Shl32,cc_dep1,mkU8(16)), 110332d615b76c65938d815fe529e690a7f79a24a4ecsewardj mkU32(0))); 110432d615b76c65938d815fe529e690a7f79a24a4ecsewardj } 110532d615b76c65938d815fe529e690a7f79a24a4ecsewardj 1106275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /*---------------- INCW ----------------*/ 1107275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj 1108275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj if (isU32(cc_op, X86G_CC_OP_INCW) && isU32(cond, X86CondZ)) { 1109275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* This rewrite helps memcheck on 'incw %ax ; je ...'. */ 1110275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj /* inc W, then Z --> test dst == 0 */ 1111275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj return unop(Iop_1Uto32, 1112275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_CmpEQ32, 1113275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj binop(Iop_Shl32,cc_dep1,mkU8(16)), 1114275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj mkU32(0))); 1115275ccdf49c33fc3efb2cbebe2bb74c8dff30fcddsewardj } 1116fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj 1117d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /*---------------- SHRL ----------------*/ 1118d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 11192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) { 1120d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj /* SHRL, then Z --> test dep1 == 0 */ 1121d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 1122d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj } 1123d8e2dbf8298ebf9d8d512d24f56966685bc51faasewardj 11244afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /*---------------- COPY ----------------*/ 11254afab82eb869f21ccabc3efb5b93f31a5c343956sewardj /* This can happen, as a result of x87 FP compares: "fcom ... ; 11264afab82eb869f21ccabc3efb5b93f31a5c343956sewardj fnstsw %ax ; sahf ; jbe" for example. */ 11274afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 112866f7a54d5425853debcb5fe77be1021f0c2b6620sewardj if (isU32(cc_op, X86G_CC_OP_COPY) && 112966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj (isU32(cond, X86CondBE) || isU32(cond, X86CondNBE))) { 1130c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then BE --> extract C and Z from dep1, and test 1131c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj (C or Z) == 1. */ 1132c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then NBE --> extract C and Z from dep1, and test 1133c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj (C or Z) == 0. */ 113466f7a54d5425853debcb5fe77be1021f0c2b6620sewardj UInt nnn = isU32(cond, X86CondBE) ? 1 : 0; 11354afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 11364afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 11374afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 11384afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 113966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj Iop_CmpEQ32, 11404afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11414afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 11424afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11434afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_Or32, 11444afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 11454afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)) 11464afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 11474afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 11484afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 114966f7a54d5425853debcb5fe77be1021f0c2b6620sewardj mkU32(nnn) 11504afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 11514afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 11524afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 11534afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 11541ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 11551ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj && (isU32(cond, X86CondB) || isU32(cond, X86CondNB))) { 1156e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then B --> extract C from dep1, and test (C == 1). */ 1157e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then NB --> extract C from dep1, and test (C == 0). */ 1158e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj UInt nnn = isU32(cond, X86CondB) ? 1 : 0; 11594afab82eb869f21ccabc3efb5b93f31a5c343956sewardj return 11604afab82eb869f21ccabc3efb5b93f31a5c343956sewardj unop( 11614afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_1Uto32, 11624afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 1163e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_CmpEQ32, 11644afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop( 11654afab82eb869f21ccabc3efb5b93f31a5c343956sewardj Iop_And32, 11664afab82eb869f21ccabc3efb5b93f31a5c343956sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 11674afab82eb869f21ccabc3efb5b93f31a5c343956sewardj mkU32(1) 11684afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ), 1169e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(nnn) 1170e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ) 1171e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ); 1172e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj } 1173e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj 11741ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 11751ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj && (isU32(cond, X86CondZ) || isU32(cond, X86CondNZ))) { 1176e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */ 11771ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */ 11781ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj UInt nnn = isU32(cond, X86CondZ) ? 1 : 0; 1179e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj return 1180e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj unop( 1181e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_1Uto32, 1182e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 11831ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj Iop_CmpEQ32, 1184e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop( 1185e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj Iop_And32, 1186e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)), 1187e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj mkU32(1) 1188e51ae9f5a25e952d0e98bd90c26a9ed74770215esewardj ), 11891ee3e18f5fed89dd9c07c7362aabead931c1ea19sewardj mkU32(nnn) 11904afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ) 11914afab82eb869f21ccabc3efb5b93f31a5c343956sewardj ); 11924afab82eb869f21ccabc3efb5b93f31a5c343956sewardj } 11934afab82eb869f21ccabc3efb5b93f31a5c343956sewardj 1194c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj if (isU32(cc_op, X86G_CC_OP_COPY) 1195c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj && (isU32(cond, X86CondP) || isU32(cond, X86CondNP))) { 1196c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj /* COPY, then P --> extract P from dep1, and test (P == 1). */ 1197c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj /* COPY, then NP --> extract P from dep1, and test (P == 0). */ 1198c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj UInt nnn = isU32(cond, X86CondP) ? 1 : 0; 1199c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj return 1200c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj unop( 1201c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj Iop_1Uto32, 1202c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop( 1203c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj Iop_CmpEQ32, 1204c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop( 1205c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj Iop_And32, 1206c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_P)), 1207c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj mkU32(1) 1208c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ), 1209c7be3eb57d2dc65ee00c6011d0ea8c8a1dc57b79sewardj mkU32(nnn) 1210c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ) 1211c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj ); 1212c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj } 1213c45aa52e4f9bf0ba1ac748cd761c4bdc3051e408sewardj 121484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 121584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 121684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 1217893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_c" --------- */ 1218893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1219893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_c")) { 1220893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_c" function */ 1221893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1222893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1223893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1224893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 1225893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep2 = args[2]; 1226893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_ndep = args[3]; 1227893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1228893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBL)) { 1229893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1230893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1231893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, cc_dep1, cc_dep2)); 1232893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1233893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_SUBB)) { 1234893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* C after sub denotes unsigned less than */ 1235893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return unop(Iop_1Uto32, 1236893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_CmpLT32U, 1237893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep1,mkU32(0xFF)), 1238893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_And32,cc_dep2,mkU32(0xFF)))); 1239893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1240893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_LOGICL) 1241893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICW) 1242893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj || isU32(cc_op, X86G_CC_OP_LOGICB)) { 1243893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after logic is zero */ 1244893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return mkU32(0); 1245893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1246893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_DECL) || isU32(cc_op, X86G_CC_OP_INCL)) { 1247893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */ 1248893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return cc_ndep; 1249893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1250893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1251893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* cflag after COPY is stored in DEP1. */ 1252893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1253893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1254893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1255893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)), 1256893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(1) 1257893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1258893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1259174c7709cb81c9358d4264a8109e37404338445fsewardj if (isU32(cc_op, X86G_CC_OP_ADDL)) { 1260174c7709cb81c9358d4264a8109e37404338445fsewardj /* C after add denotes sum <u either arg */ 1261174c7709cb81c9358d4264a8109e37404338445fsewardj return unop(Iop_1Uto32, 1262174c7709cb81c9358d4264a8109e37404338445fsewardj binop(Iop_CmpLT32U, 1263174c7709cb81c9358d4264a8109e37404338445fsewardj binop(Iop_Add32, cc_dep1, cc_dep2), 1264174c7709cb81c9358d4264a8109e37404338445fsewardj cc_dep1)); 1265174c7709cb81c9358d4264a8109e37404338445fsewardj } 1266ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // ATC, requires verification, no test case known 1267ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj //if (isU32(cc_op, X86G_CC_OP_SMULL)) { 1268ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // /* C after signed widening multiply denotes the case where 1269ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // the top half of the result isn't simply the sign extension 1270ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // of the bottom half (iow the result doesn't fit completely 1271ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // in the bottom half). Hence: 1272ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // C = hi-half(dep1 x dep2) != lo-half(dep1 x dep2) >>s 31 1273ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // where 'x' denotes signed widening multiply.*/ 1274ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // return 1275ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // unop(Iop_1Uto32, 1276ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_CmpNE32, 1277ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // unop(Iop_64HIto32, 1278ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_MullS32, cc_dep1, cc_dep2)), 1279ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_Sar32, 1280ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj // binop(Iop_Mul32, cc_dep1, cc_dep2), mkU8(31)) )); 1281ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj //} 1282893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# if 0 1283893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (cc_op->tag == Iex_Const) { 1284893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n"); 1285893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1286893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# endif 1287893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1288893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1289893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1290893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1291893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* --------- specialising "x86g_calculate_eflags_all" --------- */ 1292893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1293893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (vex_streq(function_name, "x86g_calculate_eflags_all")) { 1294893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* specialise calls to above "calculate_eflags_all" function */ 129540e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj IRExpr *cc_op, *cc_dep1; /*, *cc_dep2, *cc_ndep; */ 1296893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(arity == 4); 1297893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_op = args[0]; 1298893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1 = args[1]; 129940e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_dep2 = args[2]; */ 130040e144d3c4b155ab30c71f5abc90ff67391e7a87sewardj /* cc_ndep = args[3]; */ 1301893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1302893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if (isU32(cc_op, X86G_CC_OP_COPY)) { 1303893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* eflags after COPY are stored in DEP1. */ 1304893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return 1305893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj binop( 1306893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Iop_And32, 1307893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj cc_dep1, 1308893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mkU32(X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z 1309893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P) 1310893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj ); 1311893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1312893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return NULL; 1313893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1314893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 131584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef unop 131684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef binop 131784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj# undef mkU32 13184afab82eb869f21ccabc3efb5b93f31a5c343956sewardj# undef mkU8 131984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 132084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj return NULL; 132184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 132284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 132336ca51378f8851635df814230fa23f2c409b9eddsewardj 1324893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1325893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Supporting functions for x87 FPU activities. ---*/ 1326893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1327893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1328893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjstatic inline Bool host_is_little_endian ( void ) 1329893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1330893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt x = 0x76543210; 1331893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* p = (UChar*)(&x); 1332a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toBool(*p == 0x10); 1333893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1334893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 13350c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* 80 and 64-bit floating point formats: 13360c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13370c2cb623cca372a2b42b073121c7413cdaaf75besewardj 80-bit: 13380c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13390c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0-------0 zero 13400c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0X------X denormals 13410c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FFE 1X------X normals (all normals have leading 1) 13420c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10------0 infinity 13430c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 10X-----X snan 13440c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FFF 11X-----X qnan 13450c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13460c2cb623cca372a2b42b073121c7413cdaaf75besewardj S is the sign bit. For runs X----X, at least one of the Xs must be 13470c2cb623cca372a2b42b073121c7413cdaaf75besewardj nonzero. Exponent is 15 bits, fractional part is 63 bits, and 13480c2cb623cca372a2b42b073121c7413cdaaf75besewardj there is an explicitly represented leading 1, and a sign bit, 13490c2cb623cca372a2b42b073121c7413cdaaf75besewardj giving 80 in total. 13500c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13510c2cb623cca372a2b42b073121c7413cdaaf75besewardj 64-bit avoids the confusion of an explicitly represented leading 1 13520c2cb623cca372a2b42b073121c7413cdaaf75besewardj and so is simpler: 13530c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13540c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 0------0 zero 13550c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 0 X------X denormals 13560c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 1-7FE any normals 13570c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0------0 infinity 13580c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 0X-----X snan 13590c2cb623cca372a2b42b073121c7413cdaaf75besewardj S 7FF 1X-----X qnan 13600c2cb623cca372a2b42b073121c7413cdaaf75besewardj 13610c2cb623cca372a2b42b073121c7413cdaaf75besewardj Exponent is 11 bits, fractional part is 52 bits, and there is a 13620c2cb623cca372a2b42b073121c7413cdaaf75besewardj sign bit, giving 64 in total. 13630c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/ 13640c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1365893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Inspect a value and its tag, as per the x87 'FXAM' instruction. */ 13669aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 13672a9ad023890d3b34cf45e429df2a8ae88b419128sewardjUInt x86g_calculate_FXAM ( UInt tag, ULong dbl ) 1368c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj{ 1369c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Bool mantissaIsZero; 1370c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Int bexp; 1371c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar sign; 1372c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UChar* f64; 1373c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1374a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vassert(host_is_little_endian()); 1375c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1376c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */ 1377c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1378c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj f64 = (UChar*)(&dbl); 1379a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj sign = toUChar( (f64[7] >> 7) & 1 ); 1380c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1381c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* First off, if the tag indicates the register was empty, 1382c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj return 1,0,sign,1 */ 1383c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (tag == 0) { 1384c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Empty\n"); */ 1385e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 | (sign << X86G_FC_SHIFT_C1) 1386e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1387c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1388c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1389c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F); 1390c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj bexp &= 0x7FF; 1391c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1392c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj mantissaIsZero 1393a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toBool( 1394a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj (f64[6] & 0x0F) == 0 1395a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0 1396a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj ); 1397c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1398c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If both exponent and mantissa are zero, the value is zero. 1399c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,0,sign,0. */ 1400c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && mantissaIsZero) { 1401c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Zero\n"); */ 1402e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | 0 1403e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1404c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1405c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1406c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If exponent is zero but mantissa isn't, it's a denormal. 1407c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 1,1,sign,0. */ 1408c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0 && !mantissaIsZero) { 1409c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Denormal\n"); */ 1410e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return X86G_FC_MASK_C3 | X86G_FC_MASK_C2 1411e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | (sign << X86G_FC_SHIFT_C1) | 0; 1412c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1413c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1414c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa is zero, this is an infinity. 1415c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,1. */ 1416c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && mantissaIsZero) { 1417c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("Inf\n"); */ 1418e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) 1419e128ea174ede77daa2edadb3bde0b40dde06f95esewardj | X86G_FC_MASK_C0; 1420c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1421c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1422c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN. 1423c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,0,sign,1. */ 1424c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj if (bexp == 0x7FF && !mantissaIsZero) { 1425c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("NaN\n"); */ 1426e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | 0 | (sign << X86G_FC_SHIFT_C1) | X86G_FC_MASK_C0; 1427c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj } 1428c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 1429c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* Uh, ok, we give up. It must be a normal finite number. 1430c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj Return 0,1,sign,0. 1431c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj */ 1432c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj /* vex_printf("normal\n"); */ 1433e128ea174ede77daa2edadb3bde0b40dde06f95esewardj return 0 | X86G_FC_MASK_C2 | (sign << X86G_FC_SHIFT_C1) | 0; 1434c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj} 1435c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj 14360c2cb623cca372a2b42b073121c7413cdaaf75besewardj 143717442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 143817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (reads guest memory) */ 14398f40b07a47bd0fb7c6ea22dcd0e161a3ccda82ecsewardjULong x86g_dirtyhelper_loadF80le ( UInt addrU ) 144017442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 144117442fe8094d0f82266e5a05509f62cac8f7539esewardj ULong f64; 1442c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj convert_f80le_to_f64le ( (UChar*)ULong_to_Ptr(addrU), (UChar*)&f64 ); 144317442fe8094d0f82266e5a05509f62cac8f7539esewardj return f64; 144417442fe8094d0f82266e5a05509f62cac8f7539esewardj} 144517442fe8094d0f82266e5a05509f62cac8f7539esewardj 144617442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */ 144717442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (writes guest memory) */ 14488f40b07a47bd0fb7c6ea22dcd0e161a3ccda82ecsewardjvoid x86g_dirtyhelper_storeF80le ( UInt addrU, ULong f64 ) 144917442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 1450c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj convert_f64le_to_f80le( (UChar*)&f64, (UChar*)ULong_to_Ptr(addrU) ); 145117442fe8094d0f82266e5a05509f62cac8f7539esewardj} 145217442fe8094d0f82266e5a05509f62cac8f7539esewardj 14530c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14540c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 14550c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*--- The exported fns .. ---*/ 14560c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/ 14570c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14580c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Layout of the real x87 state. */ 14594017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* 13 June 05: Fpu_State and auxiliary constants was moved to 14604017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj g_generic_x87.h */ 14610c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14620c2cb623cca372a2b42b073121c7413cdaaf75besewardj 14637df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1464a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* fpucw[15:0] contains a x87 native format FPU control word. 1465d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj Extract from it the required FPROUND value and any resulting 1466d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj emulation warning, and return (warn << 32) | fpround value. 1467d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj*/ 14683bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_fldcw ( UInt fpucw ) 1469893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1470d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* Decide on a rounding mode. fpucw[11:10] holds it. */ 1471d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 1472893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj UInt rmode = (fpucw >> 10) & 3; 1473893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1474893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* Detect any required emulation warnings. */ 1475893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj VexEmWarn ew = EmWarn_NONE; 1476893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1477893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if ((fpucw & 0x3F) != 0x3F) { 1478893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unmasked exceptions! */ 1479893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87exns; 1480893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1481893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj else 1482893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj if (((fpucw >> 8) & 3) != 3) { 1483893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* unsupported precision */ 1484893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ew = EmWarn_X86_x87precision; 1485893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj } 1486893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1487d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return (((ULong)ew) << 32) | ((ULong)rmode); 1488893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1489893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1490893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj/* CLEAN HELPER */ 14917df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given fpround as an IRRoundingMode value, create a suitable x87 14927df596b1e36840e2d74c90aa55589934add61ccfsewardj native format FPU control word. */ 14933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_fpucw ( UInt fpround ) 1494893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj{ 1495d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround &= 3; 1496d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj return 0x037F | (fpround << 10); 1497893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj} 1498893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1499893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 15007df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 1501a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* mxcsr[15:0] contains a SSE native format MXCSR value. 15027df596b1e36840e2d74c90aa55589934add61ccfsewardj Extract from it the required SSEROUND value and any resulting 15037df596b1e36840e2d74c90aa55589934add61ccfsewardj emulation warning, and return (warn << 32) | sseround value. 15047df596b1e36840e2d74c90aa55589934add61ccfsewardj*/ 15053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_check_ldmxcsr ( UInt mxcsr ) 15067df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 15077df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Decide on a rounding mode. mxcsr[14:13] holds it. */ 15087df596b1e36840e2d74c90aa55589934add61ccfsewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 15097df596b1e36840e2d74c90aa55589934add61ccfsewardj UInt rmode = (mxcsr >> 13) & 3; 15107df596b1e36840e2d74c90aa55589934add61ccfsewardj 15117df596b1e36840e2d74c90aa55589934add61ccfsewardj /* Detect any required emulation warnings. */ 15127df596b1e36840e2d74c90aa55589934add61ccfsewardj VexEmWarn ew = EmWarn_NONE; 15137df596b1e36840e2d74c90aa55589934add61ccfsewardj 15147df596b1e36840e2d74c90aa55589934add61ccfsewardj if ((mxcsr & 0x1F80) != 0x1F80) { 15157df596b1e36840e2d74c90aa55589934add61ccfsewardj /* unmasked exceptions! */ 15167df596b1e36840e2d74c90aa55589934add61ccfsewardj ew = EmWarn_X86_sseExns; 15177df596b1e36840e2d74c90aa55589934add61ccfsewardj } 15187df596b1e36840e2d74c90aa55589934add61ccfsewardj else 15195edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<15)) { 15205edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* FZ is set */ 15215edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_fz; 15225edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj } 15235edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj else 15245edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj if (mxcsr & (1<<6)) { 15255edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj /* DAZ is set */ 15265edfc26d72ca8ebea2aa0443a1ed4dd218343d04sewardj ew = EmWarn_X86_daz; 15277df596b1e36840e2d74c90aa55589934add61ccfsewardj } 15287df596b1e36840e2d74c90aa55589934add61ccfsewardj 15297df596b1e36840e2d74c90aa55589934add61ccfsewardj return (((ULong)ew) << 32) | ((ULong)rmode); 15307df596b1e36840e2d74c90aa55589934add61ccfsewardj} 15317df596b1e36840e2d74c90aa55589934add61ccfsewardj 15327df596b1e36840e2d74c90aa55589934add61ccfsewardj 15337df596b1e36840e2d74c90aa55589934add61ccfsewardj/* CLEAN HELPER */ 15347df596b1e36840e2d74c90aa55589934add61ccfsewardj/* Given sseround as an IRRoundingMode value, create a suitable SSE 15357df596b1e36840e2d74c90aa55589934add61ccfsewardj native format MXCSR value. */ 15363bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt x86g_create_mxcsr ( UInt sseround ) 15377df596b1e36840e2d74c90aa55589934add61ccfsewardj{ 15387df596b1e36840e2d74c90aa55589934add61ccfsewardj sseround &= 3; 15397df596b1e36840e2d74c90aa55589934add61ccfsewardj return 0x1F80 | (sseround << 13); 15407df596b1e36840e2d74c90aa55589934add61ccfsewardj} 15417df596b1e36840e2d74c90aa55589934add61ccfsewardj 15427df596b1e36840e2d74c90aa55589934add61ccfsewardj 1543a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* CALLED FROM GENERATED CODE */ 1544a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* DIRTY HELPER (writes guest state) */ 1545a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Initialise the x87 FPU state as per 'finit'. */ 1546a0e83b06f304527e3e9aec527c344e35e7023d76sewardjvoid x86g_dirtyhelper_FINIT ( VexGuestX86State* gst ) 1547a0e83b06f304527e3e9aec527c344e35e7023d76sewardj{ 1548a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i; 1549a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FTOP = 0; 1550a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (i = 0; i < 8; i++) { 1551a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPTAG[i] = 0; /* empty */ 1552a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */ 1553a0e83b06f304527e3e9aec527c344e35e7023d76sewardj } 1554a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FPROUND = (UInt)Irrm_NEAREST; 1555a0e83b06f304527e3e9aec527c344e35e7023d76sewardj gst->guest_FC3210 = 0; 1556a0e83b06f304527e3e9aec527c344e35e7023d76sewardj} 1557a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 1558a0e83b06f304527e3e9aec527c344e35e7023d76sewardj 15597df596b1e36840e2d74c90aa55589934add61ccfsewardj/* This is used to implement both 'frstor' and 'fldenv'. The latter 15607df596b1e36840e2d74c90aa55589934add61ccfsewardj appears to differ from the former only in that the 8 FP registers 15617df596b1e36840e2d74c90aa55589934add61ccfsewardj themselves are not transferred into the guest state. */ 15627df596b1e36840e2d74c90aa55589934add61ccfsewardjstatic 156338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjVexEmWarn do_put_x87 ( Bool moveRegs, 156438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*IN*/UChar* x87_state, 156538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/VexGuestX86State* vex_state ) 15660c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1567a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int stno, preg; 15680c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tag; 1569c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1570f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 15710c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 15720c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt ftop = (x87->env[FP_ENV_STAT] >> 11) & 7; 15730c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw = x87->env[FP_ENV_TAG]; 15746e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj UInt fpucw = x87->env[FP_ENV_CTRL]; 1575c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj UInt c3210 = x87->env[FP_ENV_STAT] & 0x4700; 1576893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj VexEmWarn ew; 1577d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj UInt fpround; 1578893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj ULong pair; 15790c2cb623cca372a2b42b073121c7413cdaaf75besewardj 15800c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* Copy registers and tags */ 1581a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1582a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1583a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tag = (tagw >> (2*preg)) & 3; 15840c2cb623cca372a2b42b073121c7413cdaaf75besewardj if (tag == 3) { 15850c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1586a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* hmm, if it's empty, does it still get written? Probably 1587a0e83b06f304527e3e9aec527c344e35e7023d76sewardj safer to say it does. If we don't, memcheck could get out 1588a0e83b06f304527e3e9aec527c344e35e7023d76sewardj of sync, in that it thinks all FP registers are defined by 1589a0e83b06f304527e3e9aec527c344e35e7023d76sewardj this helper, but in reality some have not been updated. */ 15900f33861a0aaf18e89f5f24fd5bdfa39a9049dadasewardj if (moveRegs) 1591c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 1592a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 0; 15930c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 15940c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is non-empty */ 15957df596b1e36840e2d74c90aa55589934add61ccfsewardj if (moveRegs) 1596a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f80le_to_f64le( &x87->reg[10*stno], 1597a0e83b06f304527e3e9aec527c344e35e7023d76sewardj (UChar*)&vexRegs[preg] ); 1598a0e83b06f304527e3e9aec527c344e35e7023d76sewardj vexTags[preg] = 1; 15990c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16000c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16010c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16020c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* stack pointer */ 1603f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FTOP = ftop; 16040c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16053f868e5262a8d2488f41cc49058ba60c24843c3esewardj /* status word */ 1606f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj vex_state->guest_FC3210 = c3210; 1607893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1608d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj /* handle the control word, setting FPROUND and detecting any 1609893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj emulation warnings. */ 16103bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj pair = x86g_check_fldcw ( (UInt)fpucw ); 1611d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj fpround = (UInt)pair; 1612d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj ew = (VexEmWarn)(pair >> 32); 1613893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1614d01a9639811cd74b608f3d8877af4ad74d5089a7sewardj vex_state->guest_FPROUND = fpround & 3; 1615893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1616893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj /* emulation warnings --> caller */ 1617893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj return ew; 16180c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 16190c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16206e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj 1621a0e83b06f304527e3e9aec527c344e35e7023d76sewardj/* Create an x87 FPU state from the guest state, as close as 1622a0e83b06f304527e3e9aec527c344e35e7023d76sewardj we can approximate it. */ 162338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic 162438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjvoid do_get_x87 ( /*IN*/VexGuestX86State* vex_state, 162538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /*OUT*/UChar* x87_state ) 16260c2cb623cca372a2b42b073121c7413cdaaf75besewardj{ 1627a0e83b06f304527e3e9aec527c344e35e7023d76sewardj Int i, stno, preg; 16280c2cb623cca372a2b42b073121c7413cdaaf75besewardj UInt tagw; 1629c3778a2dd48ea461a4fb47e3d50877e94069fc7esewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1630f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 16310c2cb623cca372a2b42b073121c7413cdaaf75besewardj Fpu_State* x87 = (Fpu_State*)x87_state; 1632f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt ftop = vex_state->guest_FTOP; 1633f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj UInt c3210 = vex_state->guest_FC3210; 16340c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16350c2cb623cca372a2b42b073121c7413cdaaf75besewardj for (i = 0; i < 14; i++) 16360c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[i] = 0; 16370c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16380c2cb623cca372a2b42b073121c7413cdaaf75besewardj x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 1639a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_STAT] 1640a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 1641893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj x87->env[FP_ENV_CTRL] 1642a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj = toUShort(x86g_create_fpucw( vex_state->guest_FPROUND )); 16430c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1644a0e83b06f304527e3e9aec527c344e35e7023d76sewardj /* Dump the register stack in ST order. */ 16450c2cb623cca372a2b42b073121c7413cdaaf75besewardj tagw = 0; 1646a0e83b06f304527e3e9aec527c344e35e7023d76sewardj for (stno = 0; stno < 8; stno++) { 1647a0e83b06f304527e3e9aec527c344e35e7023d76sewardj preg = (stno + ftop) & 7; 1648a0e83b06f304527e3e9aec527c344e35e7023d76sewardj if (vexTags[preg] == 0) { 16490c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is empty */ 1650a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (3 << (2*preg)); 1651a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1652a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 16530c2cb623cca372a2b42b073121c7413cdaaf75besewardj } else { 16540c2cb623cca372a2b42b073121c7413cdaaf75besewardj /* register is full. */ 1655a0e83b06f304527e3e9aec527c344e35e7023d76sewardj tagw |= (0 << (2*preg)); 1656a0e83b06f304527e3e9aec527c344e35e7023d76sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1657a0e83b06f304527e3e9aec527c344e35e7023d76sewardj &x87->reg[10*stno] ); 16580c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 16590c2cb623cca372a2b42b073121c7413cdaaf75besewardj } 1660a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj x87->env[FP_ENV_TAG] = toUShort(tagw); 16610c2cb623cca372a2b42b073121c7413cdaaf75besewardj} 16620c2cb623cca372a2b42b073121c7413cdaaf75besewardj 16630c2cb623cca372a2b42b073121c7413cdaaf75besewardj 1664893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1665893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1666893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FXSAVE ( VexGuestX86State* gst, HWord addr ) 1667f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj{ 1668893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1669893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1670893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrS = (UShort*)addr; 1671893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UChar* addrC = (UChar*)addr; 1672893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj U128* xmm = (U128*)(addr + 160); 1673893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UInt mxcsr; 1674893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort fp_tags; 1675a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt summary_tags; 1676893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int r, stno; 1677893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort *srcS, *dstS; 1678f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1679893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1680893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj mxcsr = x86g_create_mxcsr( gst->guest_SSEROUND ); 168176bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1682893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Now build the proper fxsave image from the x87 image we just 1683893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj made. */ 168476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1685893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[0] = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */ 1686893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[1] = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */ 168776bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1688893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* set addrS[2] in an endian-independent way */ 1689893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags = 0; 1690893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj fp_tags = tmp.env[FP_ENV_TAG]; 1691893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (r = 0; r < 8; r++) { 1692893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj if ( ((fp_tags >> (2*r)) & 3) != 3 ) 1693893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj summary_tags |= (1 << r); 1694893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1695a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrC[4] = toUChar(summary_tags); /* FTW: tag summary byte */ 1696893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrC[5] = 0; /* pad */ 169776bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj 1698893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[3] = 0; /* FOP: fpu opcode (bogus) */ 1699893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[4] = 0; 1700893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[5] = 0; /* FPU IP (bogus) */ 1701893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[6] = 0; /* FPU IP's segment selector (bogus) (although we 1702893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj could conceivably dump %CS here) */ 1703c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1704893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[7] = 0; /* Intel reserved */ 1705c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1706893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[8] = 0; /* FPU DP (operand pointer) (bogus) */ 1707893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[9] = 0; /* FPU DP (operand pointer) (bogus) */ 1708893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[10] = 0; /* segment selector for above operand pointer; %DS 1709893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj perhaps? */ 1710893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[11] = 0; /* Intel reserved */ 1711c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 1712a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[12] = toUShort(mxcsr); /* MXCSR */ 1713a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj addrS[13] = toUShort(mxcsr >> 16); 1714893aadad7f29f7801ce26cb7575c16e90bd3767fsewardj 1715893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[14] = 0xFFFF; /* MXCSR mask (lo16); who knows what for */ 1716893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrS[15] = 0xFFFF; /* MXCSR mask (hi16); who knows what for */ 1717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Copy in the FP registers, in ST order. */ 1719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (stno = 0; stno < 8; stno++) { 1720893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj srcS = (UShort*)(&tmp.reg[10*stno]); 1721893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS = (UShort*)(&addrS[16 + 8*stno]); 1722893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[0] = srcS[0]; 1723893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[1] = srcS[1]; 1724893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[2] = srcS[2]; 1725893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[3] = srcS[3]; 1726893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[4] = srcS[4]; 1727893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[5] = 0; 1728893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[6] = 0; 1729893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj dstS[7] = 0; 1730893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj } 1731893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* That's the first 160 bytes of the image done. Now only %xmm0 1733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj .. %xmm7 remain to be copied. If the host is big-endian, these 1734893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj need to be byte-swapped. */ 1735893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vassert(host_is_little_endian()); 1736893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1737893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define COPY_U128(_dst,_src) \ 1738893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 1739893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 1740893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj while (0) 1741893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1742893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[0], gst->guest_XMM0 ); 1743893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[1], gst->guest_XMM1 ); 1744893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[2], gst->guest_XMM2 ); 1745893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[3], gst->guest_XMM3 ); 1746893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[4], gst->guest_XMM4 ); 1747893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[5], gst->guest_XMM5 ); 1748893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[6], gst->guest_XMM6 ); 1749893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj COPY_U128( xmm[7], gst->guest_XMM7 ); 1750893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1751893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef COPY_U128 1752dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj} 1753f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1754f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj 1755893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 17563800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 17573800e2d3c23c6480b0bfbaf04444d6b10628b25esewardjVexEmWarn x86g_dirtyhelper_FXRSTOR ( VexGuestX86State* gst, HWord addr ) 17583800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj{ 17593800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Fpu_State tmp; 17603800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj VexEmWarn warnX87 = EmWarn_NONE; 17613800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj VexEmWarn warnXMM = EmWarn_NONE; 17623800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* addrS = (UShort*)addr; 17633800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UChar* addrC = (UChar*)addr; 17643800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj U128* xmm = (U128*)(addr + 160); 17653800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort fp_tags; 17663800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Int r, stno, i; 17673800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17683800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Restore %xmm0 .. %xmm7. If the host is big-endian, these need 17693800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj to be byte-swapped. */ 17703800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj vassert(host_is_little_endian()); 17713800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17723800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj# define COPY_U128(_dst,_src) \ 17733800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 17743800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 17753800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj while (0) 17763800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17773800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM0, xmm[0] ); 17783800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM1, xmm[1] ); 17793800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM2, xmm[2] ); 17803800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM3, xmm[3] ); 17813800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM4, xmm[4] ); 17823800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM5, xmm[5] ); 17833800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM6, xmm[6] ); 17843800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj COPY_U128( gst->guest_XMM7, xmm[7] ); 17853800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17863800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj# undef COPY_U128 17873800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 17883800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Copy the x87 registers out of the image, into a temporary 17893800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj Fpu_State struct. */ 17900f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj 17914ff2a1aa52dbed78055deba39c14c3978d12601csewardj /* LLVM on Darwin turns the following loop into a movaps plus a 17924ff2a1aa52dbed78055deba39c14c3978d12601csewardj handful of scalar stores. This would work fine except for the 17934ff2a1aa52dbed78055deba39c14c3978d12601csewardj fact that VEX doesn't keep the stack correctly (16-) aligned for 17944ff2a1aa52dbed78055deba39c14c3978d12601csewardj the call, so it segfaults. Hence, split the loop into two 17954ff2a1aa52dbed78055deba39c14c3978d12601csewardj pieces (and pray LLVM doesn't merely glue them back together) so 17964ff2a1aa52dbed78055deba39c14c3978d12601csewardj it's composed only of scalar stores and so is alignment 17974ff2a1aa52dbed78055deba39c14c3978d12601csewardj insensitive. Of course this is a kludge of the lamest kind -- 17984ff2a1aa52dbed78055deba39c14c3978d12601csewardj VEX should be fixed properly. */ 17990f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj /* Code that seems to trigger the problem: 18000f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 14; i++) tmp.env[i] = 0; */ 18010f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 7; i++) tmp.env[i+0] = 0; 18020f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj for (i = 0; i < 7; i++) tmp.env[i+7] = 0; 18030f30dbc3c88b854cbcc42c60c5ef6ae4c57785a4sewardj 18043800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (i = 0; i < 80; i++) tmp.reg[i] = 0; 18053800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* fill in tmp.reg[0..7] */ 18063800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (stno = 0; stno < 8; stno++) { 18073800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* dstS = (UShort*)(&tmp.reg[10*stno]); 18083800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj UShort* srcS = (UShort*)(&addrS[16 + 8*stno]); 18093800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[0] = srcS[0]; 18103800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[1] = srcS[1]; 18113800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[2] = srcS[2]; 18123800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[3] = srcS[3]; 18133800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj dstS[4] = srcS[4]; 18143800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18153800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* fill in tmp.env[0..13] */ 18163800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_CTRL] = addrS[0]; /* FCW: fpu control word */ 18173800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_STAT] = addrS[1]; /* FCW: fpu status word */ 18183800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18193800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags = 0; 18203800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj for (r = 0; r < 8; r++) { 18213800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj if (addrC[4] & (1<<r)) 18223800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags |= (0 << (2*r)); /* EMPTY */ 18233800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj else 18243800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj fp_tags |= (3 << (2*r)); /* VALID -- not really precise enough. */ 18253800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18263800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj tmp.env[FP_ENV_TAG] = fp_tags; 18273800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18283800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Now write 'tmp' into the guest state. */ 18293800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj warnX87 = do_put_x87( True/*moveRegs*/, (UChar*)&tmp, gst ); 18303800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18313800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj { UInt w32 = (((UInt)addrS[12]) & 0xFFFF) 18323800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj | ((((UInt)addrS[13]) & 0xFFFF) << 16); 18333800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj ULong w64 = x86g_check_ldmxcsr( w32 ); 18343800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18353800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj warnXMM = (VexEmWarn)(w64 >> 32); 18363800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18373800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj gst->guest_SSEROUND = (UInt)w64; 18383800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj } 18393800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18403800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj /* Prefer an X87 emwarn over an XMM one, if both exist. */ 18413800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj if (warnX87 != EmWarn_NONE) 18423800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj return warnX87; 18433800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj else 18443800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj return warnXMM; 18453800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj} 18463800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18473800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj 18483800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj/* CALLED FROM GENERATED CODE */ 1849893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1850893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSAVE ( VexGuestX86State* gst, HWord addr ) 1851893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1852893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)addr ); 1853893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1854893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1855893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1856893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 1857893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State* gst, HWord addr ) 1858893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1859893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( True/*regs too*/, (UChar*)addr, gst ); 1860893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1861893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1862893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1863893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 1864893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSTENV ( VexGuestX86State* gst, HWord addr ) 1865893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1866893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Somewhat roundabout, but at least it's simple. */ 1867893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Int i; 1868893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj UShort* addrP = (UShort*)addr; 1869893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj Fpu_State tmp; 1870893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj do_get_x87( gst, (UChar*)&tmp ); 1871893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj for (i = 0; i < 14; i++) 1872893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj addrP[i] = tmp.env[i]; 1873893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1874893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1875893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */ 1876893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 1877893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr ) 1878893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 1879893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst); 1880893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 1881893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1882893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 1883893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 1884893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Misc integer helpers, including rotates and CPUID. ---*/ 1885893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 18869aebb0c3f7a7f43313786826f31402f2b733badfsewardj 18879aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 18889aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* Calculate both flags and value result for rotate right 18899aebb0c3f7a7f43313786826f31402f2b733badfsewardj through the carry bit. Result in low 32 bits, 18909aebb0c3f7a7f43313786826f31402f2b733badfsewardj new flags (OSZACP) in high 32 bits. 18919aebb0c3f7a7f43313786826f31402f2b733badfsewardj*/ 18922a9ad023890d3b34cf45e429df2a8ae88b419128sewardjULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 18939aebb0c3f7a7f43313786826f31402f2b733badfsewardj{ 18949aebb0c3f7a7f43313786826f31402f2b733badfsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 18959aebb0c3f7a7f43313786826f31402f2b733badfsewardj 18969aebb0c3f7a7f43313786826f31402f2b733badfsewardj switch (sz) { 18979aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 4: 18982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 18999aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 31) ^ cf) & 1; 19009aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19019aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19029aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = (arg >> 1) | (cf << 31); 19039aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19049aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19059aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19069aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19079aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 2: 19089aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 19092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19109aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 15) ^ cf) & 1; 19119aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19129aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19139aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7FFF) | (cf << 15); 19149aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19159aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19169aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19179aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19189aebb0c3f7a7f43313786826f31402f2b733badfsewardj case 1: 19199aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 19202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19219aebb0c3f7a7f43313786826f31402f2b733badfsewardj of = ((arg >> 7) ^ cf) & 1; 19229aebb0c3f7a7f43313786826f31402f2b733badfsewardj while (tempCOUNT > 0) { 19239aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempcf = arg & 1; 19249aebb0c3f7a7f43313786826f31402f2b733badfsewardj arg = ((arg >> 1) & 0x7F) | (cf << 7); 19259aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf = tempcf; 19269aebb0c3f7a7f43313786826f31402f2b733badfsewardj tempCOUNT--; 19279aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19289aebb0c3f7a7f43313786826f31402f2b733badfsewardj break; 19299aebb0c3f7a7f43313786826f31402f2b733badfsewardj default: 19309aebb0c3f7a7f43313786826f31402f2b733badfsewardj vpanic("calculate_RCR: invalid size"); 19319aebb0c3f7a7f43313786826f31402f2b733badfsewardj } 19329aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19339aebb0c3f7a7f43313786826f31402f2b733badfsewardj cf &= 1; 19349aebb0c3f7a7f43313786826f31402f2b733badfsewardj of &= 1; 19352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 19362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 19379aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19389aebb0c3f7a7f43313786826f31402f2b733badfsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 19399aebb0c3f7a7f43313786826f31402f2b733badfsewardj} 19409aebb0c3f7a7f43313786826f31402f2b733badfsewardj 19417cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 19422eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 19432eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* Calculate both flags and value result for rotate left 19442eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj through the carry bit. Result in low 32 bits, 19452eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj new flags (OSZACP) in high 32 bits. 19462eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj*/ 19472eef773d07df9bbc5d62c0058ae99d5511c2759dsewardjULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) 19482eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj{ 19492eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; 19502eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19512eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj switch (sz) { 19522eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 4: 19532eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19542eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19552eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 31) & 1; 19562eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = (arg << 1) | (cf & 1); 19572eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19582eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19592eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19602eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 31) ^ cf) & 1; 19612eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19622eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 2: 19632eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 19642eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19652eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19662eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 15) & 1; 19672eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFFFF & ((arg << 1) | (cf & 1)); 19682eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19692eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19702eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19712eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 15) ^ cf) & 1; 19722eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19732eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj case 1: 19742eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 19752eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; 19762eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj while (tempCOUNT > 0) { 19772eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempcf = (arg >> 7) & 1; 19782eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj arg = 0xFF & ((arg << 1) | (cf & 1)); 19792eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf = tempcf; 19802eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj tempCOUNT--; 19812eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19822eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of = ((arg >> 7) ^ cf) & 1; 19832eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj break; 19842eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj default: 19852eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj vpanic("calculate_RCL: invalid size"); 19862eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj } 19872eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19882eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj cf &= 1; 19892eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj of &= 1; 19902eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); 19912eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); 19922eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19932eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj return (((ULong)eflags_in) << 32) | ((ULong)arg); 19942eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj} 19952eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19962eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj 19978edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 19988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* Calculate both flags and value result for DAA/DAS/AAA/AAS. 19998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj AX value in low half of arg, OSZACP in upper half. 20008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj See guest-x86/toIR.c usage point for details. 20018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj*/ 20028edc36b45e95a7ec9879a25b80390129f1d334c1sewardjstatic UInt calc_parity_8bit ( UInt w32 ) { 20038edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt i; 20048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt p = 1; 20058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj for (i = 0; i < 8; i++) 20068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj p ^= (1 & (w32 >> i)); 20078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj return p; 20088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj} 20098edc36b45e95a7ec9879a25b80390129f1d334c1sewardjUInt x86g_calculate_daa_das_aaa_aas ( UInt flags_and_AX, UInt opcode ) 20108edc36b45e95a7ec9879a25b80390129f1d334c1sewardj{ 20118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_AL = (flags_and_AX >> 0) & 0xFF; 20128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_AH = (flags_and_AX >> 8) & 0xFF; 20138edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_O = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1; 20148edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_S = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1; 20158edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_Z = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1; 20168edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_A = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1; 20178edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_C = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1; 20188edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt r_P = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1; 20198edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt result = 0; 20208edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 20218edc36b45e95a7ec9879a25b80390129f1d334c1sewardj switch (opcode) { 20228edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x27: { /* DAA */ 20238edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_AL = r_AL; 20248edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_C = r_C; 20258edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20268edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20278edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 6; 20288edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = old_C; 20298edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (r_AL >= 0x100) r_C = 1; 20308edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20318edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20328edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20338edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20348edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (old_AL > 0x99 || old_C == 1) { 20358edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 0x60; 20368edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20378edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20388edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20398edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20408edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O is undefined. S Z and P are set according to the 20418edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result. */ 20428edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL &= 0xFF; 20438edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = 0; /* let's say */ 20448edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_S = (r_AL & 0x80) ? 1 : 0; 20458edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_Z = (r_AL == 0) ? 1 : 0; 20468edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_P = calc_parity_8bit( r_AL ); 20478edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20488edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20498edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x2F: { /* DAS */ 20508edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_AL = r_AL; 20518edc36b45e95a7ec9879a25b80390129f1d334c1sewardj UInt old_C = r_C; 20528edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20538edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20548edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool borrow = r_AL < 6; 20558edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 6; 20568edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = old_C; 20578edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (borrow) r_C = 1; 20588edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20598edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20608edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20618edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20628edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if (old_AL > 0x99 || old_C == 1) { 20638edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 0x60; 20648edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20658edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20668edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* Intel docs are wrong: r_C = 0; */ 20678edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20688edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O is undefined. S Z and P are set according to the 20698edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result. */ 20708edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL &= 0xFF; 20718edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = 0; /* let's say */ 20728edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_S = (r_AL & 0x80) ? 1 : 0; 20738edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_Z = (r_AL == 0) ? 1 : 0; 20748edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_P = calc_parity_8bit( r_AL ); 20758edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20768edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20778edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x37: { /* AAA */ 20788edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool nudge = r_AL > 0xF9; 20798edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20808edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL + 6; 20818edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AH = r_AH + 1 + (nudge ? 1 : 0); 20828edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 20838edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 20848edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 20858edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 20868edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 20878edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 20888edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 20898edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20908edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O S Z and P are undefined. */ 20918edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = r_S = r_Z = r_P = 0; /* let's say */ 20928edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 20938edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 20948edc36b45e95a7ec9879a25b80390129f1d334c1sewardj case 0x3F: { /* AAS */ 20958edc36b45e95a7ec9879a25b80390129f1d334c1sewardj Bool nudge = r_AL < 0x06; 20968edc36b45e95a7ec9879a25b80390129f1d334c1sewardj if ((r_AL & 0xF) > 9 || r_A == 1) { 20978edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL - 6; 20988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AH = r_AH - 1 - (nudge ? 1 : 0); 20998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 1; 21008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 1; 21018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 21028edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } else { 21038edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_A = 0; 21048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_C = 0; 21058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_AL = r_AL & 0xF; 21068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj /* O S Z and P are undefined. */ 21088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj r_O = r_S = r_Z = r_P = 0; /* let's say */ 21098edc36b45e95a7ec9879a25b80390129f1d334c1sewardj break; 21108edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj default: 21128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj vassert(0); 21138edc36b45e95a7ec9879a25b80390129f1d334c1sewardj } 21148edc36b45e95a7ec9879a25b80390129f1d334c1sewardj result = ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) ) 21158edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) ) 21168edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) ) 21178edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) ) 21188edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) ) 21198edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) ) 21208edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_AH & 0xFF) << 8 ) 21218edc36b45e95a7ec9879a25b80390129f1d334c1sewardj | ( (r_AL & 0xFF) << 0 ); 21228edc36b45e95a7ec9879a25b80390129f1d334c1sewardj return result; 21238edc36b45e95a7ec9879a25b80390129f1d334c1sewardj} 21248edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 2125321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardjUInt x86g_calculate_aad_aam ( UInt flags_and_AX, UInt opcode ) 2126321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj{ 2127321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_AL = (flags_and_AX >> 0) & 0xFF; 2128321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_AH = (flags_and_AX >> 8) & 0xFF; 2129321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_O = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1; 2130321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_S = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1; 2131321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_Z = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1; 2132321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_A = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1; 2133321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_C = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1; 2134321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt r_P = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1; 2135321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj UInt result = 0; 2136321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2137321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj switch (opcode) { 2138321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj case 0xD4: { /* AAM */ 2139321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AH = r_AL / 10; 2140321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AL = r_AL % 10; 2141321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj break; 2142321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2143321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj case 0xD5: { /* AAD */ 2144321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AL = ((r_AH * 10) + r_AL) & 0xff; 2145321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_AH = 0; 2146321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj break; 2147321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2148321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj default: 2149321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj vassert(0); 2150321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj } 2151321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2152321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_O = 0; /* let's say (undefined) */ 2153321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_C = 0; /* let's say (undefined) */ 2154321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_A = 0; /* let's say (undefined) */ 2155321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_S = (r_AL & 0x80) ? 1 : 0; 2156321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_Z = (r_AL == 0) ? 1 : 0; 2157321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj r_P = calc_parity_8bit( r_AL ); 2158321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 2159321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj result = ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) ) 2160321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) ) 2161321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) ) 2162321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) ) 2163321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) ) 2164321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) ) 2165321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_AH & 0xFF) << 8 ) 2166321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj | ( (r_AL & 0xFF) << 0 ); 2167321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj return result; 2168321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj} 2169321bbbf4a200e69496eb0a48506d3b67a1cdbbdbsewardj 21708edc36b45e95a7ec9879a25b80390129f1d334c1sewardj 21717cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* CALLED FROM GENERATED CODE */ 21724ed6429074bf94661586d751fbecac530f5e8156sewardj/* DIRTY HELPER (non-referentially-transparent) */ 21734ed6429074bf94661586d751fbecac530f5e8156sewardj/* Horrible hack. On non-x86 platforms, return 1. */ 21744ed6429074bf94661586d751fbecac530f5e8156sewardjULong x86g_dirtyhelper_RDTSC ( void ) 21754ed6429074bf94661586d751fbecac530f5e8156sewardj{ 21764ed6429074bf94661586d751fbecac530f5e8156sewardj# if defined(__i386__) 21774ed6429074bf94661586d751fbecac530f5e8156sewardj ULong res; 21784ed6429074bf94661586d751fbecac530f5e8156sewardj __asm__ __volatile__("rdtsc" : "=A" (res)); 21794ed6429074bf94661586d751fbecac530f5e8156sewardj return res; 21804ed6429074bf94661586d751fbecac530f5e8156sewardj# else 21814ed6429074bf94661586d751fbecac530f5e8156sewardj return 1ULL; 21824ed6429074bf94661586d751fbecac530f5e8156sewardj# endif 21834ed6429074bf94661586d751fbecac530f5e8156sewardj} 21844ed6429074bf94661586d751fbecac530f5e8156sewardj 21854ed6429074bf94661586d751fbecac530f5e8156sewardj 21864ed6429074bf94661586d751fbecac530f5e8156sewardj/* CALLED FROM GENERATED CODE */ 21877cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* DIRTY HELPER (modifies guest state) */ 21884ba6ed0799fcf768e3fb9627fabc52fb1d6c2a6csewardj/* Claim to be a P55C (Intel Pentium/MMX) */ 21899df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* st ) 21907cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj{ 21919df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 21929df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 21939df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x1; 21949df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 21959df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 21969df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 21979df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 21989df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 21999df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x543; 22009df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x0; 22019df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x0; 22029df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x8001bf; 22039df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22049df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 22059df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 22069df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 22079df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* CALLED FROM GENERATED CODE */ 22089df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* DIRTY HELPER (modifies guest state) */ 22099df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* Claim to be the following SSE1-capable CPU: 22109df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 22119df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu family : 6 22129df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model : 11 22139df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj model name : Intel(R) Pentium(R) III CPU family 1133MHz 22149df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj stepping : 1 22159df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cpu MHz : 1131.013 22169df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj cache size : 512 KB 22179df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 22189df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st ) 22199df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 22209df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 22219df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 0: 22229df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x00000002; 22239df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x756e6547; 22249df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x6c65746e; 22259df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x49656e69; 22269df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22279df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj case 1: 22289df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x000006b1; 22299df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000004; 22309df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 22319df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0383fbff; 22329df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22339df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj default: 22349df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EAX = 0x03020101; 22359df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EBX = 0x00000000; 22369df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_ECX = 0x00000000; 22379df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj st->guest_EDX = 0x0c040883; 22389df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 22399df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj } 22409df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj} 22419df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj 2242150c9cddb753ad4dc38f43484144523174d38b02sewardj/* Claim to be the following SSSE3-capable CPU (2 x ...): 22439df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj vendor_id : GenuineIntel 2244150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu family : 6 2245150c9cddb753ad4dc38f43484144523174d38b02sewardj model : 15 2246150c9cddb753ad4dc38f43484144523174d38b02sewardj model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz 2247150c9cddb753ad4dc38f43484144523174d38b02sewardj stepping : 6 2248150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu MHz : 2394.000 2249150c9cddb753ad4dc38f43484144523174d38b02sewardj cache size : 4096 KB 2250150c9cddb753ad4dc38f43484144523174d38b02sewardj physical id : 0 2251150c9cddb753ad4dc38f43484144523174d38b02sewardj siblings : 2 2252150c9cddb753ad4dc38f43484144523174d38b02sewardj core id : 0 2253150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu cores : 2 2254150c9cddb753ad4dc38f43484144523174d38b02sewardj fpu : yes 2255150c9cddb753ad4dc38f43484144523174d38b02sewardj fpu_exception : yes 2256150c9cddb753ad4dc38f43484144523174d38b02sewardj cpuid level : 10 2257150c9cddb753ad4dc38f43484144523174d38b02sewardj wp : yes 2258150c9cddb753ad4dc38f43484144523174d38b02sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2259150c9cddb753ad4dc38f43484144523174d38b02sewardj mtrr pge mca cmov pat pse36 clflush dts acpi 2260150c9cddb753ad4dc38f43484144523174d38b02sewardj mmx fxsr sse sse2 ss ht tm syscall nx lm 2261150c9cddb753ad4dc38f43484144523174d38b02sewardj constant_tsc pni monitor ds_cpl vmx est tm2 2262150c9cddb753ad4dc38f43484144523174d38b02sewardj cx16 xtpr lahf_lm 2263150c9cddb753ad4dc38f43484144523174d38b02sewardj bogomips : 4798.78 2264150c9cddb753ad4dc38f43484144523174d38b02sewardj clflush size : 64 2265150c9cddb753ad4dc38f43484144523174d38b02sewardj cache_alignment : 64 2266150c9cddb753ad4dc38f43484144523174d38b02sewardj address sizes : 36 bits physical, 48 bits virtual 2267150c9cddb753ad4dc38f43484144523174d38b02sewardj power management: 22689df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/ 22699df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) 22709df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{ 2271150c9cddb753ad4dc38f43484144523174d38b02sewardj# define SET_ABCD(_a,_b,_c,_d) \ 2272150c9cddb753ad4dc38f43484144523174d38b02sewardj do { st->guest_EAX = (UInt)(_a); \ 2273150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_EBX = (UInt)(_b); \ 2274150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_ECX = (UInt)(_c); \ 2275150c9cddb753ad4dc38f43484144523174d38b02sewardj st->guest_EDX = (UInt)(_d); \ 2276150c9cddb753ad4dc38f43484144523174d38b02sewardj } while (0) 2277150c9cddb753ad4dc38f43484144523174d38b02sewardj 22789df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj switch (st->guest_EAX) { 2279150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000000: 2280150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69); 22819df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 2282150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000001: 2283150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x000006f6, 0x00020800, 0x0000e3bd, 0xbfebfbff); 22849df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj break; 2285150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000002: 2286150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x05b0b101, 0x005657f0, 0x00000000, 0x2cb43049); 2287150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2288150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000003: 2289150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2290150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 229132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000004: { 229232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj switch (st->guest_ECX) { 229332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, 229432bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 229532bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, 229632bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 229732bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, 229832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000fff, 0x00000001); break; 229932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj default: SET_ABCD(0x00000000, 0x00000000, 230032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000000, 0x00000000); break; 230132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2302150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 230332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2304150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000005: 2305150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); 2306150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2307150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000006: 2308150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000001, 0x00000002, 0x00000001, 0x00000000); 2309150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2310150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000007: 2311150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2312150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2313150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000008: 2314150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000400, 0x00000000, 0x00000000, 0x00000000); 2315150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2316150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000009: 2317150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2318150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2319150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x0000000a: 232032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj unhandled_eax_value: 2321150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); 2322150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2323150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000000: 2324150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2325150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2326150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000001: 2327150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x20100000); 2328150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2329150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000002: 2330150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 2331150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2332150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000003: 2333150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x43203229, 0x20205550, 0x20202020, 0x20202020); 2334150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2335150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000004: 2336150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x30303636, 0x20402020, 0x30342e32, 0x007a4847); 2337150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2338150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000005: 2339150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2340150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2341150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000006: 2342150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x10008040, 0x00000000); 2343150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2344150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000007: 2345150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2346150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2347150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000008: 2348150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2349150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 235032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj default: 235132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj goto unhandled_eax_value; 23527cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj } 2353150c9cddb753ad4dc38f43484144523174d38b02sewardj# undef SET_ABCD 23547cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj} 23557cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj 2356464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 2357d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */ 2358d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2359d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack. On non-x86 platforms, return 0. */ 2360d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjUInt x86g_dirtyhelper_IN ( UInt portno, UInt sz/*1,2 or 4*/ ) 2361d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{ 2362d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# if defined(__i386__) 2363d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj UInt r = 0; 2364d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj portno &= 0xFFFF; 2365d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj switch (sz) { 2366d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 4: 2367d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inl %w1,%0" 2368d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2369d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2370d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 2: 2371d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inw %w1,%w0" 2372d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2373d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2374d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 1: 2375d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("movl $0,%%eax; inb %w1,%b0" 2376d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : "=a" (r) : "Nd" (portno)); 2377d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2378d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj default: 2379d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2380d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj } 2381d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj return r; 2382d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# else 2383d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj return 0; 2384d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# endif 2385d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj} 2386d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2387d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2388d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */ 2389d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2390d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack. On non-x86 platforms, do nothing. */ 2391d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjvoid x86g_dirtyhelper_OUT ( UInt portno, UInt data, UInt sz/*1,2 or 4*/ ) 2392d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{ 2393d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# if defined(__i386__) 2394d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj portno &= 0xFFFF; 2395d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj switch (sz) { 2396d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 4: 2397d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outl %0, %w1" 2398d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2399d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2400d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 2: 2401d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outw %w0, %w1" 2402d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2403d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2404d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj case 1: 2405d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj __asm__ __volatile__("outb %b0, %w1" 2406d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj : : "a" (data), "Nd" (portno)); 2407d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2408d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj default: 2409d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj break; 2410d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj } 2411d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# else 24125e55f492bb4e0d6cca529a31653d8682fbc5a6dasewardj /* do nothing */ 2413d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj# endif 2414d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj} 2415d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2416b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* CALLED FROM GENERATED CODE */ 2417b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* DIRTY HELPER (non-referentially-transparent) */ 2418b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* Horrible hack. On non-x86 platforms, do nothing. */ 2419b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* op = 0: call the native SGDT instruction. 2420b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj op = 1: call the native SIDT instruction. 2421b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj*/ 2422b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardjvoid x86g_dirtyhelper_SxDT ( void *address, UInt op ) { 2423b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# if defined(__i386__) 2424b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj switch (op) { 2425b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 0: 2426b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory"); 2427b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 2428b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 1: 2429b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory"); 2430b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 2431b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj default: 2432b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj vpanic("x86g_dirtyhelper_SxDT"); 2433b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj } 2434b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# else 2435b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj /* do nothing */ 2436b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj UChar* p = (UChar*)address; 2437b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0; 2438b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# endif 2439b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj} 2440d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj 2441893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2442893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for MMX/SSE/SSE2. ---*/ 2443893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2444464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 244538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar abdU8 ( UChar xx, UChar yy ) { 2446a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(xx>yy ? xx-yy : yy-xx); 244738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj} 2448464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 244938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) { 2450464efa446b2db97115d3e5f04af5db3464cc0e93sewardj return (((ULong)w1) << 32) | ((ULong)w0); 2451464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2452464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 245338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_3 ( ULong w64 ) { 2454a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2455a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32 >> 16); 2456464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 245738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_2 ( ULong w64 ) { 2458a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2459a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(hi32); 2460464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 246138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_1 ( ULong w64 ) { 2462a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2463a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32 >> 16); 2464464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 246538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_0 ( ULong w64 ) { 2466a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2467a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUShort(lo32); 2468464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2469464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 247038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_7 ( ULong w64 ) { 2471a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2472a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 24); 2473464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 247438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_6 ( ULong w64 ) { 2475a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2476a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 16); 2477464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 247838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_5 ( ULong w64 ) { 2479a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2480a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 8); 2481464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 248238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_4 ( ULong w64 ) { 2483a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt hi32 = toUInt(w64 >> 32); 2484a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(hi32 >> 0); 2485464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 248638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_3 ( ULong w64 ) { 2487a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2488a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 24); 2489464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 249038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_2 ( ULong w64 ) { 2491a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2492a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 16); 2493464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 249438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_1 ( ULong w64 ) { 2495a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2496a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 8); 2497464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 249838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_0 ( ULong w64 ) { 2499a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj UInt lo32 = toUInt(w64); 2500a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj return toUChar(lo32 >> 0); 2501464efa446b2db97115d3e5f04af5db3464cc0e93sewardj} 2502464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 250338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 250438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) 25054340dac5c2cede4962868e6da5b73282da2bc465sewardj{ 25064340dac5c2cede4962868e6da5b73282da2bc465sewardj return 25074340dac5c2cede4962868e6da5b73282da2bc465sewardj mk32x2( 25084340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) 25094340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), 25104340dac5c2cede4962868e6da5b73282da2bc465sewardj (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) 25114340dac5c2cede4962868e6da5b73282da2bc465sewardj + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) 25124340dac5c2cede4962868e6da5b73282da2bc465sewardj ); 25134340dac5c2cede4962868e6da5b73282da2bc465sewardj} 25144340dac5c2cede4962868e6da5b73282da2bc465sewardj 251538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 251638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjUInt x86g_calculate_mmx_pmovmskb ( ULong xx ) 2517b54520819b40c3fe907725b56bcd8db5112c0b9asewardj{ 2518b54520819b40c3fe907725b56bcd8db5112c0b9asewardj UInt r = 0; 2519b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (64-1))) r |= (1<<7); 2520b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (56-1))) r |= (1<<6); 2521b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (48-1))) r |= (1<<5); 2522b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (40-1))) r |= (1<<4); 2523b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (32-1))) r |= (1<<3); 2524b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (24-1))) r |= (1<<2); 2525b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << (16-1))) r |= (1<<1); 2526b54520819b40c3fe907725b56bcd8db5112c0b9asewardj if (xx & (1ULL << ( 8-1))) r |= (1<<0); 2527b54520819b40c3fe907725b56bcd8db5112c0b9asewardj return r; 2528b54520819b40c3fe907725b56bcd8db5112c0b9asewardj} 2529b54520819b40c3fe907725b56bcd8db5112c0b9asewardj 253038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 253138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy ) 25320bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj{ 25330bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj UInt t = 0; 25340bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); 25350bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); 25360bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); 25370bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); 25380bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 25390bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 25400bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 25410bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 25420bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj t &= 0xFFFF; 25430bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj return (ULong)t; 25440bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj} 25450bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj 254638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 2547e5854d6d470f21677ec84f71d09129434b044246sewardjUInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo ) 2548e5854d6d470f21677ec84f71d09129434b044246sewardj{ 254938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj UInt rHi8 = x86g_calculate_mmx_pmovmskb ( w64hi ); 255038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj UInt rLo8 = x86g_calculate_mmx_pmovmskb ( w64lo ); 2551e5854d6d470f21677ec84f71d09129434b044246sewardj return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF); 2552e5854d6d470f21677ec84f71d09129434b044246sewardj} 2553e5854d6d470f21677ec84f71d09129434b044246sewardj 2554464efa446b2db97115d3e5f04af5db3464cc0e93sewardj 2555893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2556893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with segment overrides. ---*/ 2557893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 25583bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25593bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 25603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_base ( VexGuestX86SegDescr* ent ) 25613bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 25623bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.BaseLow; 25633bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt mid = 0xFF & (UInt)ent->LdtEnt.Bits.BaseMid; 25643bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xFF & (UInt)ent->LdtEnt.Bits.BaseHi; 25653bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (hi << 24) | (mid << 16) | lo; 25663bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 25673bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25683bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline 25693bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_limit ( VexGuestX86SegDescr* ent ) 25703bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 25713bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt lo = 0xFFFF & (UInt)ent->LdtEnt.Bits.LimitLow; 25723bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt hi = 0xF & (UInt)ent->LdtEnt.Bits.LimitHi; 25733bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt limit = (hi << 16) | lo; 25743bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ent->LdtEnt.Bits.Granularity) 25753bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = (limit << 12) | 0xFFF; 25763bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return limit; 25773bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 25783bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 257938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 25803bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_use_seg_selector ( HWord ldt, HWord gdt, 25813bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt seg_selector, UInt virtual_addr ) 25823bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{ 25833bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj UInt tiBit, base, limit; 25843bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj VexGuestX86SegDescr* the_descrs; 25853bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25863bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj Bool verboze = False; 25873bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25883bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* If this isn't true, we're in Big Trouble. */ 25893bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(8 == sizeof(VexGuestX86SegDescr)); 25903bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25913bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 25923bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 25933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "seg_selector = 0x%x, vaddr = 0x%x\n", 25943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector, virtual_addr); 25953bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 25963bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for wildly invalid selector. */ 25973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector & ~0xFFFF) 25983bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 25993bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector &= 0x0000FFFF; 26013bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Sanity check the segment selector. Ensure that RPL=11b (least 26033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj privilege). This forms the bottom 2 bits of the selector. */ 26043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if ((seg_selector & 3) != 3) 26053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26073bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Extract the TI bit (0 means GDT, 1 means LDT) */ 26083bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj tiBit = (seg_selector >> 2) & 1; 26093bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26103bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Convert the segment selector onto a table index */ 26113bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj seg_selector >>= 3; 26123bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vassert(seg_selector >= 0 && seg_selector < 8192); 26133bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26143bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (tiBit == 0) { 26153bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26163bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* GDT access. */ 26173bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do we actually have a GDT to look at? */ 26183bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (gdt == 0) 26193bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26203bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26213bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Check for access to non-existent entry. */ 26223bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_GDT_NENT) 26233bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26243bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26253bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)gdt; 26263bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 26273bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 26283bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26293bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } else { 26303bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26313bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* All the same stuff, except for the LDT. */ 26323bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (ldt == 0) 26333bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26343bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26353bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (seg_selector >= VEX_GUEST_X86_LDT_NENT) 26363bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26373bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26383bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj the_descrs = (VexGuestX86SegDescr*)ldt; 26393bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base = get_segdescr_base (&the_descrs[seg_selector]); 26403bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit = get_segdescr_limit(&the_descrs[seg_selector]); 26413bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26423bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj } 26433bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26443bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* Do the limit check. Note, this check is just slightly too 26453bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj slack. Really it should be "if (virtual_addr + size - 1 >= 26463bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj limit)," but we don't have the size info to hand. Getting it 26473bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj could be significantly complex. */ 26483bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (virtual_addr >= limit) 26493bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj goto bad; 26503bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26513bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj if (verboze) 26523bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj vex_printf("x86h_use_seg_selector: " 26533bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj "base = 0x%x, addr = 0x%x\n", 26543bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj base, base + virtual_addr); 26553bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26563bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj /* High 32 bits are zero, indicating success. */ 26573bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return (ULong)( ((UInt)virtual_addr) + base ); 26583bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26593bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj bad: 26603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj return 1ULL << 32; 26613bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj} 26623bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 26633bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 2664893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2665893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with, and describing, ---*/ 2666893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- guest state as a whole. ---*/ 2667893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/ 2668893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2669893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Initialise the entire x86 guest state. */ 2670893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */ 2671893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state ) 2672893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{ 2673893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EAX = 0; 2674893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ECX = 0; 2675893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDX = 0; 2676893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBX = 0; 2677893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESP = 0; 2678893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EBP = 0; 2679893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ESI = 0; 2680893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EDI = 0; 2681893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2682893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_OP = X86G_CC_OP_COPY; 2683893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP1 = 0; 2684893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_DEP2 = 0; 2685893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CC_NDEP = 0; 2686893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DFLAG = 1; /* forwards */ 2687893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_IDFLAG = 0; 26886d26984a0df6a7d20b658bac6edf869eb872cca3sewardj vex_state->guest_ACFLAG = 0; 2689893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2690893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EIP = 0; 2691893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2692893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialise the simulated FPU */ 2693893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj x86g_dirtyhelper_FINIT( vex_state ); 2694893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2695893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj /* Initialse the SSE state. */ 2696893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# define SSEZERO(_xmm) _xmm[0]=_xmm[1]=_xmm[2]=_xmm[3] = 0; 2697893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2698893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SSEROUND = (UInt)Irrm_NEAREST; 2699893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM0); 2700893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM1); 2701893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM2); 2702893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM3); 2703893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM4); 2704893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM5); 2705893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM6); 2706893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj SSEZERO(vex_state->guest_XMM7); 2707893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2708893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj# undef SSEZERO 2709893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2710893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_CS = 0; 2711893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_DS = 0; 2712893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_ES = 0; 2713893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_FS = 0; 2714893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GS = 0; 2715893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_SS = 0; 2716893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_LDT = 0; 2717893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_GDT = 0; 2718893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 2719893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj vex_state->guest_EMWARN = EmWarn_NONE; 27201f126c5c092801acfc1ac968d2f1a37dde334bccsewardj 2721bfceb089644ce9eee882bae5cec5902be4831cacsewardj /* SSE2 has a 'clflush' cache-line-invalidator which uses these. */ 27221f126c5c092801acfc1ac968d2f1a37dde334bccsewardj vex_state->guest_TISTART = 0; 27231f126c5c092801acfc1ac968d2f1a37dde334bccsewardj vex_state->guest_TILEN = 0; 2724ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj 2725d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_NRADDR = 0; 2726d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_SC_CLASS = 0; 2727e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->guest_IP_AT_SYSCALL = 0; 2728e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj 2729e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->padding1 = 0; 2730e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->padding2 = 0; 2731e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->padding3 = 0; 2732893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj} 2733893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj 27348d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27358d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/* Figure out if any part of the guest state contained in minoff 27368d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj .. maxoff requires precise memory exceptions. If in doubt return 27378d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj True (but this is generates significantly slower code). 27388d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27394cca75cb48776ceda40e8e305232d85f62021804sewardj By default we enforce precise exns for guest %ESP, %EBP and %EIP 27404cca75cb48776ceda40e8e305232d85f62021804sewardj only. These are the minimum needed to extract correct stack 27414cca75cb48776ceda40e8e305232d85f62021804sewardj backtraces from x86 code. 27428d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj*/ 27438d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardjBool guest_x86_state_requires_precise_mem_exns ( Int minoff, 27448d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int maxoff) 27458d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj{ 27464cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_min = offsetof(VexGuestX86State, guest_EBP); 27474cca75cb48776ceda40e8e305232d85f62021804sewardj Int ebp_max = ebp_min + 4 - 1; 27488d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_min = offsetof(VexGuestX86State, guest_ESP); 27498d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int esp_max = esp_min + 4 - 1; 27508d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_min = offsetof(VexGuestX86State, guest_EIP); 27518d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj Int eip_max = eip_min + 4 - 1; 27528d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27534cca75cb48776ceda40e8e305232d85f62021804sewardj if (maxoff < ebp_min || minoff > ebp_max) { 27544cca75cb48776ceda40e8e305232d85f62021804sewardj /* no overlap with ebp */ 27554cca75cb48776ceda40e8e305232d85f62021804sewardj } else { 27564cca75cb48776ceda40e8e305232d85f62021804sewardj return True; 27574cca75cb48776ceda40e8e305232d85f62021804sewardj } 27584cca75cb48776ceda40e8e305232d85f62021804sewardj 27598d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj if (maxoff < esp_min || minoff > esp_max) { 2760eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* no overlap with esp */ 27618d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2762eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 27638d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 27648d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27658d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj if (maxoff < eip_min || minoff > eip_max) { 2766eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* no overlap with eip */ 27678d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } else { 2768eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj return True; 27698d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 27708d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27718d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj return False; 27728d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj} 27738d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 27748d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 2775eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj#define ALWAYSDEFD(field) \ 2776eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj { offsetof(VexGuestX86State, field), \ 2777eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj (sizeof ((VexGuestX86State*)0)->field) } 2778eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2779eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardjVexGuestLayout 278049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj x86guest_layout 2781eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj = { 2782eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Total size of the guest state, in bytes. */ 2783eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .total_sizeB = sizeof(VexGuestX86State), 2784eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2785eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe the stack pointer. */ 2786eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .offset_SP = offsetof(VexGuestX86State,guest_ESP), 2787eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj .sizeof_SP = 4, 2788eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2789a203330aad67bc3e52ca1395a55e94ef9a091223sewardj /* Describe the frame pointer. */ 2790a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .offset_FP = offsetof(VexGuestX86State,guest_EBP), 2791a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .sizeof_FP = 4, 2792a203330aad67bc3e52ca1395a55e94ef9a091223sewardj 2793cf7879021370aabcccb1a9347244fcc7d5680141sewardj /* Describe the instruction pointer. */ 2794cf7879021370aabcccb1a9347244fcc7d5680141sewardj .offset_IP = offsetof(VexGuestX86State,guest_EIP), 2795cf7879021370aabcccb1a9347244fcc7d5680141sewardj .sizeof_IP = 4, 2796eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 2797eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj /* Describe any sections to be regarded by Memcheck as 2798eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj 'always-defined'. */ 2799e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj .n_alwaysDefd = 24, 28003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj 28012a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj /* flags thunk: OP and NDEP are always defd, whereas DEP1 28022a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj and DEP2 have to be tracked. See detailed comment in 28032a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj gdefs.h on meaning of thunk fields. */ 28048fc937421c954ff9f707254f028b1fa0410c473dsewardj .alwaysDefd 28058fc937421c954ff9f707254f028b1fa0410c473dsewardj = { /* 0 */ ALWAYSDEFD(guest_CC_OP), 28068fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), 28078fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 2 */ ALWAYSDEFD(guest_DFLAG), 28088fc937421c954ff9f707254f028b1fa0410c473dsewardj /* 3 */ ALWAYSDEFD(guest_IDFLAG), 28096d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 4 */ ALWAYSDEFD(guest_ACFLAG), 28106d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 5 */ ALWAYSDEFD(guest_EIP), 28116d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 6 */ ALWAYSDEFD(guest_FTOP), 28126d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 7 */ ALWAYSDEFD(guest_FPTAG), 28136d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 8 */ ALWAYSDEFD(guest_FPROUND), 28146d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 9 */ ALWAYSDEFD(guest_FC3210), 28156d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 10 */ ALWAYSDEFD(guest_CS), 28166d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 11 */ ALWAYSDEFD(guest_DS), 28176d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 12 */ ALWAYSDEFD(guest_ES), 28186d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 13 */ ALWAYSDEFD(guest_FS), 28196d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 14 */ ALWAYSDEFD(guest_GS), 28206d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 15 */ ALWAYSDEFD(guest_SS), 28216d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 16 */ ALWAYSDEFD(guest_LDT), 28226d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 17 */ ALWAYSDEFD(guest_GDT), 28236d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 18 */ ALWAYSDEFD(guest_EMWARN), 28246d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 19 */ ALWAYSDEFD(guest_SSEROUND), 28256d26984a0df6a7d20b658bac6edf869eb872cca3sewardj /* 20 */ ALWAYSDEFD(guest_TISTART), 2826e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 21 */ ALWAYSDEFD(guest_TILEN), 2827e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 22 */ ALWAYSDEFD(guest_SC_CLASS), 2828e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 23 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) 28298fc937421c954ff9f707254f028b1fa0410c473dsewardj } 2830eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj }; 283149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 283249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj 283336ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2834cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end guest_x86_helpers.c ---*/ 283536ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/ 2836