guest_x86_helpers.c revision be9179130bdfb61d0e03ecb32eced8dd5c7bfc74
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
10752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Copyright (C) 2004-2010 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. */
591893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj__attribute((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. */
17903800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   for (i = 0; i < 14; i++) tmp.env[i] = 0;
17913800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   for (i = 0; i < 80; i++) tmp.reg[i] = 0;
17923800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   /* fill in tmp.reg[0..7] */
17933800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   for (stno = 0; stno < 8; stno++) {
17943800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      UShort* dstS = (UShort*)(&tmp.reg[10*stno]);
17953800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      UShort* srcS = (UShort*)(&addrS[16 + 8*stno]);
17963800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      dstS[0] = srcS[0];
17973800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      dstS[1] = srcS[1];
17983800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      dstS[2] = srcS[2];
17993800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      dstS[3] = srcS[3];
18003800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      dstS[4] = srcS[4];
18013800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   }
18023800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   /* fill in tmp.env[0..13] */
18033800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   tmp.env[FP_ENV_CTRL] = addrS[0]; /* FCW: fpu control word */
18043800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   tmp.env[FP_ENV_STAT] = addrS[1]; /* FCW: fpu status word */
18053800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18063800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   fp_tags = 0;
18073800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   for (r = 0; r < 8; r++) {
18083800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      if (addrC[4] & (1<<r))
18093800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj         fp_tags |= (0 << (2*r)); /* EMPTY */
18103800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      else
18113800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj         fp_tags |= (3 << (2*r)); /* VALID -- not really precise enough. */
18123800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   }
18133800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   tmp.env[FP_ENV_TAG] = fp_tags;
18143800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18153800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   /* Now write 'tmp' into the guest state. */
18163800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   warnX87 = do_put_x87( True/*moveRegs*/, (UChar*)&tmp, gst );
18173800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18183800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   { UInt w32 = (((UInt)addrS[12]) & 0xFFFF)
18193800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj                | ((((UInt)addrS[13]) & 0xFFFF) << 16);
18203800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj     ULong w64 = x86g_check_ldmxcsr( w32 );
18213800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18223800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj     warnXMM = (VexEmWarn)(w64 >> 32);
18233800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18243800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj     gst->guest_SSEROUND = (UInt)w64;
18253800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   }
18263800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18273800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   /* Prefer an X87 emwarn over an XMM one, if both exist. */
18283800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   if (warnX87 != EmWarn_NONE)
18293800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      return warnX87;
18303800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj   else
18313800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj      return warnXMM;
18323800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj}
18333800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18343800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj
18353800e2d3c23c6480b0bfbaf04444d6b10628b25esewardj/* CALLED FROM GENERATED CODE */
1836893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */
1837893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSAVE ( VexGuestX86State* gst, HWord addr )
1838893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{
1839893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   do_get_x87( gst, (UChar*)addr );
1840893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj}
1841893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
1842893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */
1843893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */
1844893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State* gst, HWord addr )
1845893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{
1846893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   return do_put_x87( True/*regs too*/, (UChar*)addr, gst );
1847893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj}
1848893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
1849893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */
1850893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */
1851893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid x86g_dirtyhelper_FSTENV ( VexGuestX86State* gst, HWord addr )
1852893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{
1853893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   /* Somewhat roundabout, but at least it's simple. */
1854893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   Int       i;
1855893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   UShort*   addrP = (UShort*)addr;
1856893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   Fpu_State tmp;
1857893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   do_get_x87( gst, (UChar*)&tmp );
1858893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   for (i = 0; i < 14; i++)
1859893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj      addrP[i] = tmp.env[i];
1860893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj}
1861893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
1862893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* CALLED FROM GENERATED CODE */
1863893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */
1864893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjVexEmWarn x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr )
1865893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{
1866893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst);
1867893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj}
1868893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
1869893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
1870893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
1871893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Misc integer helpers, including rotates and CPUID.      ---*/
1872893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
18739aebb0c3f7a7f43313786826f31402f2b733badfsewardj
18749aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
18759aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* Calculate both flags and value result for rotate right
18769aebb0c3f7a7f43313786826f31402f2b733badfsewardj   through the carry bit.  Result in low 32 bits,
18779aebb0c3f7a7f43313786826f31402f2b733badfsewardj   new flags (OSZACP) in high 32 bits.
18789aebb0c3f7a7f43313786826f31402f2b733badfsewardj*/
18792a9ad023890d3b34cf45e429df2a8ae88b419128sewardjULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
18809aebb0c3f7a7f43313786826f31402f2b733badfsewardj{
18819aebb0c3f7a7f43313786826f31402f2b733badfsewardj   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;
18829aebb0c3f7a7f43313786826f31402f2b733badfsewardj
18839aebb0c3f7a7f43313786826f31402f2b733badfsewardj   switch (sz) {
18849aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 4:
18852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;
18869aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 31) ^ cf) & 1;
18879aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
18889aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
18899aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = (arg >> 1) | (cf << 31);
18909aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
18919aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
18929aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
18939aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
18949aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 2:
18959aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT >= 17) tempCOUNT -= 17;
18962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;
18979aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 15) ^ cf) & 1;
18989aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
18999aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
19009aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = ((arg >> 1) & 0x7FFF) | (cf << 15);
19019aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
19029aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
19039aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
19049aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
19059aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 1:
19069aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT >= 9) tempCOUNT -= 9;
19072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj         cf        = (eflags_in >> X86G_CC_SHIFT_C) & 1;
19089aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 7) ^ cf) & 1;
19099aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
19109aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
19119aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = ((arg >> 1) & 0x7F) | (cf << 7);
19129aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
19139aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
19149aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
19159aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
19169aebb0c3f7a7f43313786826f31402f2b733badfsewardj      default:
19179aebb0c3f7a7f43313786826f31402f2b733badfsewardj         vpanic("calculate_RCR: invalid size");
19189aebb0c3f7a7f43313786826f31402f2b733badfsewardj   }
19199aebb0c3f7a7f43313786826f31402f2b733badfsewardj
19209aebb0c3f7a7f43313786826f31402f2b733badfsewardj   cf &= 1;
19219aebb0c3f7a7f43313786826f31402f2b733badfsewardj   of &= 1;
19222a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O);
19232a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O);
19249aebb0c3f7a7f43313786826f31402f2b733badfsewardj
19259aebb0c3f7a7f43313786826f31402f2b733badfsewardj   return (((ULong)eflags_in) << 32) | ((ULong)arg);
19269aebb0c3f7a7f43313786826f31402f2b733badfsewardj}
19279aebb0c3f7a7f43313786826f31402f2b733badfsewardj
19287cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj
19292eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
19302eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj/* Calculate both flags and value result for rotate left
19312eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   through the carry bit.  Result in low 32 bits,
19322eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   new flags (OSZACP) in high 32 bits.
19332eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj*/
19342eef773d07df9bbc5d62c0058ae99d5511c2759dsewardjULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
19352eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj{
19362eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;
19372eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj
19382eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   switch (sz) {
19392eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj      case 4:
19402eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
19412eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         while (tempCOUNT > 0) {
19422eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempcf = (arg >> 31) & 1;
19432eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            arg    = (arg << 1) | (cf & 1);
19442eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            cf     = tempcf;
19452eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempCOUNT--;
19462eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         }
19472eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         of = ((arg >> 31) ^ cf) & 1;
19482eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         break;
19492eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj      case 2:
19502eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         while (tempCOUNT >= 17) tempCOUNT -= 17;
19512eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
19522eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         while (tempCOUNT > 0) {
19532eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempcf = (arg >> 15) & 1;
19542eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            arg    = 0xFFFF & ((arg << 1) | (cf & 1));
19552eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            cf     = tempcf;
19562eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempCOUNT--;
19572eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         }
19582eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         of = ((arg >> 15) ^ cf) & 1;
19592eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         break;
19602eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj      case 1:
19612eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         while (tempCOUNT >= 9) tempCOUNT -= 9;
19622eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
19632eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         while (tempCOUNT > 0) {
19642eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempcf = (arg >> 7) & 1;
19652eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            arg    = 0xFF & ((arg << 1) | (cf & 1));
19662eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            cf     = tempcf;
19672eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj            tempCOUNT--;
19682eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         }
19692eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         of = ((arg >> 7) ^ cf) & 1;
19702eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         break;
19712eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj      default:
19722eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj         vpanic("calculate_RCL: invalid size");
19732eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   }
19742eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj
19752eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   cf &= 1;
19762eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   of &= 1;
19772eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O);
19782eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O);
19792eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj
19802eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj   return (((ULong)eflags_in) << 32) | ((ULong)arg);
19812eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj}
19822eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj
19832eef773d07df9bbc5d62c0058ae99d5511c2759dsewardj
19848edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
19858edc36b45e95a7ec9879a25b80390129f1d334c1sewardj/* Calculate both flags and value result for DAA/DAS/AAA/AAS.
19868edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   AX value in low half of arg, OSZACP in upper half.
19878edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   See guest-x86/toIR.c usage point for details.
19888edc36b45e95a7ec9879a25b80390129f1d334c1sewardj*/
19898edc36b45e95a7ec9879a25b80390129f1d334c1sewardjstatic UInt calc_parity_8bit ( UInt w32 ) {
19908edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt i;
19918edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt p = 1;
19928edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   for (i = 0; i < 8; i++)
19938edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      p ^= (1 & (w32 >> i));
19948edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   return p;
19958edc36b45e95a7ec9879a25b80390129f1d334c1sewardj}
19968edc36b45e95a7ec9879a25b80390129f1d334c1sewardjUInt x86g_calculate_daa_das_aaa_aas ( UInt flags_and_AX, UInt opcode )
19978edc36b45e95a7ec9879a25b80390129f1d334c1sewardj{
19988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_AL = (flags_and_AX >> 0) & 0xFF;
19998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_AH = (flags_and_AX >> 8) & 0xFF;
20008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_O  = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1;
20018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_S  = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1;
20028edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_Z  = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1;
20038edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_A  = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1;
20048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_C  = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1;
20058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt r_P  = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1;
20068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   UInt result = 0;
20078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj
20088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   switch (opcode) {
20098edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      case 0x27: { /* DAA */
20108edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         UInt old_AL = r_AL;
20118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         UInt old_C  = r_C;
20128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_C = 0;
20138edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if ((r_AL & 0xF) > 9 || r_A == 1) {
20148edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL + 6;
20158edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = old_C;
20168edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            if (r_AL >= 0x100) r_C = 1;
20178edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A = 1;
20188edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20198edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A = 0;
20208edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20218edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if (old_AL > 0x99 || old_C == 1) {
20228edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL + 0x60;
20238edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 1;
20248edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20258edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C = 0;
20268edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20278edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         /* O is undefined.  S Z and P are set according to the
20288edc36b45e95a7ec9879a25b80390129f1d334c1sewardj	    result. */
20298edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_AL &= 0xFF;
20308edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_O = 0; /* let's say */
20318edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_S = (r_AL & 0x80) ? 1 : 0;
20328edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_Z = (r_AL == 0) ? 1 : 0;
20338edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_P = calc_parity_8bit( r_AL );
20348edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         break;
20358edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      }
20368edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      case 0x2F: { /* DAS */
20378edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         UInt old_AL = r_AL;
20388edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         UInt old_C  = r_C;
20398edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_C = 0;
20408edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if ((r_AL & 0xF) > 9 || r_A == 1) {
20418edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            Bool borrow = r_AL < 6;
20428edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL - 6;
20438edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = old_C;
20448edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            if (borrow) r_C = 1;
20458edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A = 1;
20468edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20478edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A = 0;
20488edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20498edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if (old_AL > 0x99 || old_C == 1) {
20508edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL - 0x60;
20518edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 1;
20528edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20538edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            /* Intel docs are wrong: r_C = 0; */
20548edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20558edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         /* O is undefined.  S Z and P are set according to the
20568edc36b45e95a7ec9879a25b80390129f1d334c1sewardj	    result. */
20578edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_AL &= 0xFF;
20588edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_O = 0; /* let's say */
20598edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_S = (r_AL & 0x80) ? 1 : 0;
20608edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_Z = (r_AL == 0) ? 1 : 0;
20618edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_P = calc_parity_8bit( r_AL );
20628edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         break;
20638edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      }
20648edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      case 0x37: { /* AAA */
20658edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         Bool nudge = r_AL > 0xF9;
20668edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if ((r_AL & 0xF) > 9 || r_A == 1) {
20678edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL + 6;
20688edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AH = r_AH + 1 + (nudge ? 1 : 0);
20698edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A  = 1;
20708edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 1;
20718edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL & 0xF;
20728edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20738edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A  = 0;
20748edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 0;
20758edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL & 0xF;
20768edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20778edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         /* O S Z and P are undefined. */
20788edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_O = r_S = r_Z = r_P = 0; /* let's say */
20798edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         break;
20808edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      }
20818edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      case 0x3F: { /* AAS */
20828edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         Bool nudge = r_AL < 0x06;
20838edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         if ((r_AL & 0xF) > 9 || r_A == 1) {
20848edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL - 6;
20858edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AH = r_AH - 1 - (nudge ? 1 : 0);
20868edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A  = 1;
20878edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 1;
20888edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL & 0xF;
20898edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         } else {
20908edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_A  = 0;
20918edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_C  = 0;
20928edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            r_AL = r_AL & 0xF;
20938edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         }
20948edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         /* O S Z and P are undefined. */
20958edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         r_O = r_S = r_Z = r_P = 0; /* let's say */
20968edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         break;
20978edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      }
20988edc36b45e95a7ec9879a25b80390129f1d334c1sewardj      default:
20998edc36b45e95a7ec9879a25b80390129f1d334c1sewardj         vassert(0);
21008edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   }
21018edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   result =   ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) )
21028edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) )
21038edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) )
21048edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) )
21058edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) )
21068edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) )
21078edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_AH & 0xFF) << 8 )
21088edc36b45e95a7ec9879a25b80390129f1d334c1sewardj            | ( (r_AL & 0xFF) << 0 );
21098edc36b45e95a7ec9879a25b80390129f1d334c1sewardj   return result;
21108edc36b45e95a7ec9879a25b80390129f1d334c1sewardj}
21118edc36b45e95a7ec9879a25b80390129f1d334c1sewardj
21128edc36b45e95a7ec9879a25b80390129f1d334c1sewardj
21137cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* CALLED FROM GENERATED CODE */
21144ed6429074bf94661586d751fbecac530f5e8156sewardj/* DIRTY HELPER (non-referentially-transparent) */
21154ed6429074bf94661586d751fbecac530f5e8156sewardj/* Horrible hack.  On non-x86 platforms, return 1. */
21164ed6429074bf94661586d751fbecac530f5e8156sewardjULong x86g_dirtyhelper_RDTSC ( void )
21174ed6429074bf94661586d751fbecac530f5e8156sewardj{
21184ed6429074bf94661586d751fbecac530f5e8156sewardj#  if defined(__i386__)
21194ed6429074bf94661586d751fbecac530f5e8156sewardj   ULong res;
21204ed6429074bf94661586d751fbecac530f5e8156sewardj   __asm__ __volatile__("rdtsc" : "=A" (res));
21214ed6429074bf94661586d751fbecac530f5e8156sewardj   return res;
21224ed6429074bf94661586d751fbecac530f5e8156sewardj#  else
21234ed6429074bf94661586d751fbecac530f5e8156sewardj   return 1ULL;
21244ed6429074bf94661586d751fbecac530f5e8156sewardj#  endif
21254ed6429074bf94661586d751fbecac530f5e8156sewardj}
21264ed6429074bf94661586d751fbecac530f5e8156sewardj
21274ed6429074bf94661586d751fbecac530f5e8156sewardj
21284ed6429074bf94661586d751fbecac530f5e8156sewardj/* CALLED FROM GENERATED CODE */
21297cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* DIRTY HELPER (modifies guest state) */
21304ba6ed0799fcf768e3fb9627fabc52fb1d6c2a6csewardj/* Claim to be a P55C (Intel Pentium/MMX) */
21319df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* st )
21327cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj{
21339df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   switch (st->guest_EAX) {
21349df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      case 0:
21359df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EAX = 0x1;
21369df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EBX = 0x756e6547;
21379df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_ECX = 0x6c65746e;
21389df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EDX = 0x49656e69;
21399df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
21409df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      default:
21419df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EAX = 0x543;
21429df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EBX = 0x0;
21439df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_ECX = 0x0;
21449df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EDX = 0x8001bf;
21459df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
21469df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   }
21479df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj}
21489df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj
21499df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* CALLED FROM GENERATED CODE */
21509df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* DIRTY HELPER (modifies guest state) */
21519df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj/* Claim to be the following SSE1-capable CPU:
21529df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   vendor_id       : GenuineIntel
21539df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   cpu family      : 6
21549df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   model           : 11
21559df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   model name      : Intel(R) Pentium(R) III CPU family      1133MHz
21569df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   stepping        : 1
21579df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   cpu MHz         : 1131.013
21589df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   cache size      : 512 KB
21599df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/
21609df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st )
21619df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{
21629df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   switch (st->guest_EAX) {
21639df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      case 0:
21649df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EAX = 0x00000002;
21659df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EBX = 0x756e6547;
21669df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_ECX = 0x6c65746e;
21679df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EDX = 0x49656e69;
21689df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
21699df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      case 1:
21709df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EAX = 0x000006b1;
21719df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EBX = 0x00000004;
21729df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_ECX = 0x00000000;
21739df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EDX = 0x0383fbff;
21749df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
21759df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj      default:
21769df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EAX = 0x03020101;
21779df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EBX = 0x00000000;
21789df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_ECX = 0x00000000;
21799df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         st->guest_EDX = 0x0c040883;
21809df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
21819df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   }
21829df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj}
21839df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj
2184150c9cddb753ad4dc38f43484144523174d38b02sewardj/* Claim to be the following SSSE3-capable CPU (2 x ...):
21859df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   vendor_id       : GenuineIntel
2186150c9cddb753ad4dc38f43484144523174d38b02sewardj   cpu family      : 6
2187150c9cddb753ad4dc38f43484144523174d38b02sewardj   model           : 15
2188150c9cddb753ad4dc38f43484144523174d38b02sewardj   model name      : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
2189150c9cddb753ad4dc38f43484144523174d38b02sewardj   stepping        : 6
2190150c9cddb753ad4dc38f43484144523174d38b02sewardj   cpu MHz         : 2394.000
2191150c9cddb753ad4dc38f43484144523174d38b02sewardj   cache size      : 4096 KB
2192150c9cddb753ad4dc38f43484144523174d38b02sewardj   physical id     : 0
2193150c9cddb753ad4dc38f43484144523174d38b02sewardj   siblings        : 2
2194150c9cddb753ad4dc38f43484144523174d38b02sewardj   core id         : 0
2195150c9cddb753ad4dc38f43484144523174d38b02sewardj   cpu cores       : 2
2196150c9cddb753ad4dc38f43484144523174d38b02sewardj   fpu             : yes
2197150c9cddb753ad4dc38f43484144523174d38b02sewardj   fpu_exception   : yes
2198150c9cddb753ad4dc38f43484144523174d38b02sewardj   cpuid level     : 10
2199150c9cddb753ad4dc38f43484144523174d38b02sewardj   wp              : yes
2200150c9cddb753ad4dc38f43484144523174d38b02sewardj   flags           : fpu vme de pse tsc msr pae mce cx8 apic sep
2201150c9cddb753ad4dc38f43484144523174d38b02sewardj                     mtrr pge mca cmov pat pse36 clflush dts acpi
2202150c9cddb753ad4dc38f43484144523174d38b02sewardj                     mmx fxsr sse sse2 ss ht tm syscall nx lm
2203150c9cddb753ad4dc38f43484144523174d38b02sewardj                     constant_tsc pni monitor ds_cpl vmx est tm2
2204150c9cddb753ad4dc38f43484144523174d38b02sewardj                     cx16 xtpr lahf_lm
2205150c9cddb753ad4dc38f43484144523174d38b02sewardj   bogomips        : 4798.78
2206150c9cddb753ad4dc38f43484144523174d38b02sewardj   clflush size    : 64
2207150c9cddb753ad4dc38f43484144523174d38b02sewardj   cache_alignment : 64
2208150c9cddb753ad4dc38f43484144523174d38b02sewardj   address sizes   : 36 bits physical, 48 bits virtual
2209150c9cddb753ad4dc38f43484144523174d38b02sewardj   power management:
22109df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj*/
22119df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardjvoid x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st )
22129df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj{
2213150c9cddb753ad4dc38f43484144523174d38b02sewardj#  define SET_ABCD(_a,_b,_c,_d)               \
2214150c9cddb753ad4dc38f43484144523174d38b02sewardj      do { st->guest_EAX = (UInt)(_a);        \
2215150c9cddb753ad4dc38f43484144523174d38b02sewardj           st->guest_EBX = (UInt)(_b);        \
2216150c9cddb753ad4dc38f43484144523174d38b02sewardj           st->guest_ECX = (UInt)(_c);        \
2217150c9cddb753ad4dc38f43484144523174d38b02sewardj           st->guest_EDX = (UInt)(_d);        \
2218150c9cddb753ad4dc38f43484144523174d38b02sewardj      } while (0)
2219150c9cddb753ad4dc38f43484144523174d38b02sewardj
22209df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj   switch (st->guest_EAX) {
2221150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000000:
2222150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69);
22239df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
2224150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000001:
2225150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x000006f6, 0x00020800, 0x0000e3bd, 0xbfebfbff);
22269df271d97c0f79a58a8eabdcfbe6f8bf4d17876asewardj         break;
2227150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000002:
2228150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x05b0b101, 0x005657f0, 0x00000000, 0x2cb43049);
2229150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2230150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000003:
2231150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
2232150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
223332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj      case 0x00000004: {
223432bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj         switch (st->guest_ECX) {
223532bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj            case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f,
223632bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj                                      0x0000003f, 0x00000001); break;
223732bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj            case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f,
223832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj                                      0x0000003f, 0x00000001); break;
223932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj            case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f,
224032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj                                      0x00000fff, 0x00000001); break;
224132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj            default:         SET_ABCD(0x00000000, 0x00000000,
224232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj                                      0x00000000, 0x00000000); break;
224332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj         }
2244150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
224532bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj      }
2246150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000005:
2247150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020);
2248150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2249150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000006:
2250150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000001, 0x00000002, 0x00000001, 0x00000000);
2251150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2252150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000007:
2253150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
2254150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2255150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000008:
2256150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000400, 0x00000000, 0x00000000, 0x00000000);
2257150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2258150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x00000009:
2259150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
2260150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2261150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x0000000a:
226232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj      unhandled_eax_value:
2263150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000);
2264150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2265150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000000:
2266150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000);
2267150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2268150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000001:
2269150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x20100000);
2270150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2271150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000002:
2272150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865);
2273150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2274150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000003:
2275150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x43203229, 0x20205550, 0x20202020, 0x20202020);
2276150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2277150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000004:
2278150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x30303636, 0x20402020, 0x30342e32, 0x007a4847);
2279150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2280150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000005:
2281150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
2282150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2283150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000006:
2284150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x10008040, 0x00000000);
2285150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2286150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000007:
2287150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
2288150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
2289150c9cddb753ad4dc38f43484144523174d38b02sewardj      case 0x80000008:
2290150c9cddb753ad4dc38f43484144523174d38b02sewardj         SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000);
2291150c9cddb753ad4dc38f43484144523174d38b02sewardj         break;
229232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj      default:
229332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj         goto unhandled_eax_value;
22947cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj   }
2295150c9cddb753ad4dc38f43484144523174d38b02sewardj#  undef SET_ABCD
22967cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj}
22977cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj
2298464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
2299d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */
2300d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */
2301d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack.  On non-x86 platforms, return 0. */
2302d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjUInt x86g_dirtyhelper_IN ( UInt portno, UInt sz/*1,2 or 4*/ )
2303d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{
2304d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  if defined(__i386__)
2305d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   UInt r = 0;
2306d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   portno &= 0xFFFF;
2307d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   switch (sz) {
2308d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 4:
2309d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("movl $0,%%eax; inl %w1,%0"
2310d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : "=a" (r) : "Nd" (portno));
2311d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2312d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 2:
2313d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("movl $0,%%eax; inw %w1,%w0"
2314d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : "=a" (r) : "Nd" (portno));
2315d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2316d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 1:
2317d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("movl $0,%%eax; inb %w1,%b0"
2318d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : "=a" (r) : "Nd" (portno));
2319d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2320d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      default:
2321d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         break;
2322d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   }
2323d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   return r;
2324d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  else
2325d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   return 0;
2326d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  endif
2327d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj}
2328d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj
2329d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj
2330d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* CALLED FROM GENERATED CODE */
2331d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* DIRTY HELPER (non-referentially-transparent) */
2332d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj/* Horrible hack.  On non-x86 platforms, do nothing. */
2333d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardjvoid x86g_dirtyhelper_OUT ( UInt portno, UInt data, UInt sz/*1,2 or 4*/ )
2334d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj{
2335d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  if defined(__i386__)
2336d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   portno &= 0xFFFF;
2337d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   switch (sz) {
2338d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 4:
2339d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("outl %0, %w1"
2340d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : : "a" (data), "Nd" (portno));
2341d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2342d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 2:
2343d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("outw %w0, %w1"
2344d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : : "a" (data), "Nd" (portno));
2345d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2346d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      case 1:
2347d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         __asm__ __volatile__("outb %b0, %w1"
2348d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj                              : : "a" (data), "Nd" (portno));
2349d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj	 break;
2350d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj      default:
2351d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj         break;
2352d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj   }
2353d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  else
23545e55f492bb4e0d6cca529a31653d8682fbc5a6dasewardj   /* do nothing */
2355d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj#  endif
2356d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj}
2357d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj
2358b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* CALLED FROM GENERATED CODE */
2359b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* DIRTY HELPER (non-referentially-transparent) */
2360b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* Horrible hack.  On non-x86 platforms, do nothing. */
2361b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* op = 0: call the native SGDT instruction.
2362b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   op = 1: call the native SIDT instruction.
2363b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj*/
2364b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardjvoid x86g_dirtyhelper_SxDT ( void *address, UInt op ) {
2365b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj#  if defined(__i386__)
2366b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   switch (op) {
2367b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj      case 0:
2368b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj         __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory");
2369b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj         break;
2370b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj      case 1:
2371b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj         __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory");
2372b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj         break;
2373b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj      default:
2374b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj         vpanic("x86g_dirtyhelper_SxDT");
2375b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   }
2376b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj#  else
2377b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   /* do nothing */
2378b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   UChar* p = (UChar*)address;
2379b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj   p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0;
2380b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj#  endif
2381b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj}
2382d14c5702cd2a0b15a66119ec1a6d68e4840a0dd5sewardj
2383893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
2384893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for MMX/SSE/SSE2.                               ---*/
2385893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
2386464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
238738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar abdU8 ( UChar xx, UChar yy ) {
2388a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(xx>yy ? xx-yy : yy-xx);
238938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj}
2390464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
239138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) {
2392464efa446b2db97115d3e5f04af5db3464cc0e93sewardj   return (((ULong)w1) << 32) | ((ULong)w0);
2393464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
2394464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
239538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_3 ( ULong w64 ) {
2396a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2397a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUShort(hi32 >> 16);
2398464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
239938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_2 ( ULong w64 ) {
2400a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2401a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUShort(hi32);
2402464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
240338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_1 ( ULong w64 ) {
2404a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2405a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUShort(lo32 >> 16);
2406464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
240738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UShort sel16x4_0 ( ULong w64 ) {
2408a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2409a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUShort(lo32);
2410464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
2411464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
241238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_7 ( ULong w64 ) {
2413a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2414a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(hi32 >> 24);
2415464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
241638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_6 ( ULong w64 ) {
2417a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2418a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(hi32 >> 16);
2419464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
242038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_5 ( ULong w64 ) {
2421a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2422a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(hi32 >> 8);
2423464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
242438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_4 ( ULong w64 ) {
2425a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt hi32 = toUInt(w64 >> 32);
2426a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(hi32 >> 0);
2427464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
242838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_3 ( ULong w64 ) {
2429a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2430a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(lo32 >> 24);
2431464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
243238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_2 ( ULong w64 ) {
2433a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2434a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(lo32 >> 16);
2435464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
243638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_1 ( ULong w64 ) {
2437a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2438a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(lo32 >> 8);
2439464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
244038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic inline UChar sel8x8_0 ( ULong w64 ) {
2441a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   UInt lo32 = toUInt(w64);
2442a4b4be4e6d9bfaf4149b99b59069b61651915102sewardj   return toUChar(lo32 >> 0);
2443464efa446b2db97115d3e5f04af5db3464cc0e93sewardj}
2444464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
244538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
244638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_pmaddwd ( ULong xx, ULong yy )
24474340dac5c2cede4962868e6da5b73282da2bc465sewardj{
24484340dac5c2cede4962868e6da5b73282da2bc465sewardj   return
24494340dac5c2cede4962868e6da5b73282da2bc465sewardj      mk32x2(
24504340dac5c2cede4962868e6da5b73282da2bc465sewardj         (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy)))
24514340dac5c2cede4962868e6da5b73282da2bc465sewardj            + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))),
24524340dac5c2cede4962868e6da5b73282da2bc465sewardj         (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy)))
24534340dac5c2cede4962868e6da5b73282da2bc465sewardj            + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy)))
24544340dac5c2cede4962868e6da5b73282da2bc465sewardj      );
24554340dac5c2cede4962868e6da5b73282da2bc465sewardj}
24564340dac5c2cede4962868e6da5b73282da2bc465sewardj
245738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
245838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjUInt x86g_calculate_mmx_pmovmskb ( ULong xx )
2459b54520819b40c3fe907725b56bcd8db5112c0b9asewardj{
2460b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   UInt r = 0;
2461b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (64-1))) r |= (1<<7);
2462b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (56-1))) r |= (1<<6);
2463b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (48-1))) r |= (1<<5);
2464b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (40-1))) r |= (1<<4);
2465b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (32-1))) r |= (1<<3);
2466b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (24-1))) r |= (1<<2);
2467b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << (16-1))) r |= (1<<1);
2468b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   if (xx & (1ULL << ( 8-1))) r |= (1<<0);
2469b54520819b40c3fe907725b56bcd8db5112c0b9asewardj   return r;
2470b54520819b40c3fe907725b56bcd8db5112c0b9asewardj}
2471b54520819b40c3fe907725b56bcd8db5112c0b9asewardj
247238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
247338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy )
24740bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj{
24750bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   UInt t = 0;
24760bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) );
24770bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) );
24780bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) );
24790bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) );
24800bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) );
24810bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) );
24820bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) );
24830bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) );
24840bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   t &= 0xFFFF;
24850bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj   return (ULong)t;
24860bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj}
24870bd7ce6ae95b61bd9781f6a70f0132681a7b6387sewardj
248838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
2489e5854d6d470f21677ec84f71d09129434b044246sewardjUInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo )
2490e5854d6d470f21677ec84f71d09129434b044246sewardj{
249138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj   UInt rHi8 = x86g_calculate_mmx_pmovmskb ( w64hi );
249238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj   UInt rLo8 = x86g_calculate_mmx_pmovmskb ( w64lo );
2493e5854d6d470f21677ec84f71d09129434b044246sewardj   return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF);
2494e5854d6d470f21677ec84f71d09129434b044246sewardj}
2495e5854d6d470f21677ec84f71d09129434b044246sewardj
2496464efa446b2db97115d3e5f04af5db3464cc0e93sewardj
2497893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
2498893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with segment overrides.             ---*/
2499893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
25003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25013bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline
25023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_base ( VexGuestX86SegDescr* ent )
25033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{
25043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   UInt lo  = 0xFFFF & (UInt)ent->LdtEnt.Bits.BaseLow;
25053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   UInt mid =   0xFF & (UInt)ent->LdtEnt.Bits.BaseMid;
25063bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   UInt hi  =   0xFF & (UInt)ent->LdtEnt.Bits.BaseHi;
25073bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   return (hi << 24) | (mid << 16) | lo;
25083bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj}
25093bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25103bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjstatic inline
25113bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjUInt get_segdescr_limit ( VexGuestX86SegDescr* ent )
25123bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{
25133bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj    UInt lo    = 0xFFFF & (UInt)ent->LdtEnt.Bits.LimitLow;
25143bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj    UInt hi    =    0xF & (UInt)ent->LdtEnt.Bits.LimitHi;
25153bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj    UInt limit = (hi << 16) | lo;
25163bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj    if (ent->LdtEnt.Bits.Granularity)
25173bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj       limit = (limit << 12) | 0xFFF;
25183bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj    return limit;
25193bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj}
25203bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
252138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
25223bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardjULong x86g_use_seg_selector ( HWord ldt, HWord gdt,
25233bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj                              UInt seg_selector, UInt virtual_addr )
25243bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj{
25253bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   UInt tiBit, base, limit;
25263bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   VexGuestX86SegDescr* the_descrs;
25273bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25283bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   Bool verboze = False;
25293bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25303bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* If this isn't true, we're in Big Trouble. */
25313bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   vassert(8 == sizeof(VexGuestX86SegDescr));
25323bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25333bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if (verboze)
25343bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      vex_printf("x86h_use_seg_selector: "
25353bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj                 "seg_selector = 0x%x, vaddr = 0x%x\n",
25363bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj                 seg_selector, virtual_addr);
25373bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25383bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* Check for wildly invalid selector. */
25393bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if (seg_selector & ~0xFFFF)
25403bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      goto bad;
25413bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25423bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   seg_selector &= 0x0000FFFF;
25433bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25443bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* Sanity check the segment selector.  Ensure that RPL=11b (least
25453bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      privilege).  This forms the bottom 2 bits of the selector. */
25463bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if ((seg_selector & 3) != 3)
25473bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      goto bad;
25483bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25493bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* Extract the TI bit (0 means GDT, 1 means LDT) */
25503bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   tiBit = (seg_selector >> 2) & 1;
25513bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25523bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* Convert the segment selector onto a table index */
25533bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   seg_selector >>= 3;
25543bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   vassert(seg_selector >= 0 && seg_selector < 8192);
25553bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25563bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if (tiBit == 0) {
25573bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25583bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      /* GDT access. */
25593bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      /* Do we actually have a GDT to look at? */
25603bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      if (gdt == 0)
25613bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj         goto bad;
25623bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25633bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      /* Check for access to non-existent entry. */
25643bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      if (seg_selector >= VEX_GUEST_X86_GDT_NENT)
25653bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj         goto bad;
25663bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25673bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      the_descrs = (VexGuestX86SegDescr*)gdt;
25683bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      base  = get_segdescr_base (&the_descrs[seg_selector]);
25693bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      limit = get_segdescr_limit(&the_descrs[seg_selector]);
25703bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25713bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   } else {
25723bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25733bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      /* All the same stuff, except for the LDT. */
25743bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      if (ldt == 0)
25753bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj         goto bad;
25763bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25773bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      if (seg_selector >= VEX_GUEST_X86_LDT_NENT)
25783bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj         goto bad;
25793bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25803bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      the_descrs = (VexGuestX86SegDescr*)ldt;
25813bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      base  = get_segdescr_base (&the_descrs[seg_selector]);
25823bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      limit = get_segdescr_limit(&the_descrs[seg_selector]);
25833bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25843bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   }
25853bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25863bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* Do the limit check.  Note, this check is just slightly too
25873bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      slack.  Really it should be "if (virtual_addr + size - 1 >=
25883bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      limit)," but we don't have the size info to hand.  Getting it
25893bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      could be significantly complex.  */
25903bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if (virtual_addr >= limit)
25913bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      goto bad;
25923bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25933bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   if (verboze)
25943bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj      vex_printf("x86h_use_seg_selector: "
25953bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj                 "base = 0x%x, addr = 0x%x\n",
25963bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj                 base, base + virtual_addr);
25973bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
25983bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   /* High 32 bits are zero, indicating success. */
25993bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   return (ULong)( ((UInt)virtual_addr) + base );
26003bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
26013bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj bad:
26023bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj   return 1ULL << 32;
26033bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj}
26043bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
26053bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
2606893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
2607893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- Helpers for dealing with, and describing,               ---*/
2608893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*--- guest state as a whole.                                 ---*/
2609893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/*---------------------------------------------------------------*/
2610893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2611893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* Initialise the entire x86 guest state. */
2612893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj/* VISIBLE TO LIBVEX CLIENT */
2613893a3302cc943e2ad1db421a8e6a753f82f532a7sewardjvoid LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
2614893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj{
2615893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EAX = 0;
2616893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_ECX = 0;
2617893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EDX = 0;
2618893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EBX = 0;
2619893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_ESP = 0;
2620893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EBP = 0;
2621893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_ESI = 0;
2622893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EDI = 0;
2623893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2624893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_CC_OP   = X86G_CC_OP_COPY;
2625893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_CC_DEP1 = 0;
2626893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_CC_DEP2 = 0;
2627893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_CC_NDEP = 0;
2628893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_DFLAG   = 1; /* forwards */
2629893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_IDFLAG  = 0;
26306d26984a0df6a7d20b658bac6edf869eb872cca3sewardj   vex_state->guest_ACFLAG  = 0;
2631893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2632893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EIP = 0;
2633893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2634893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   /* Initialise the simulated FPU */
2635893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   x86g_dirtyhelper_FINIT( vex_state );
2636893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2637893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   /* Initialse the SSE state. */
2638893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj#  define SSEZERO(_xmm) _xmm[0]=_xmm[1]=_xmm[2]=_xmm[3] = 0;
2639893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2640893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_SSEROUND = (UInt)Irrm_NEAREST;
2641893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM0);
2642893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM1);
2643893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM2);
2644893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM3);
2645893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM4);
2646893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM5);
2647893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM6);
2648893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   SSEZERO(vex_state->guest_XMM7);
2649893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2650893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj#  undef SSEZERO
2651893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2652893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_CS  = 0;
2653893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_DS  = 0;
2654893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_ES  = 0;
2655893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_FS  = 0;
2656893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_GS  = 0;
2657893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_SS  = 0;
2658893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_LDT = 0;
2659893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_GDT = 0;
2660893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
2661893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj   vex_state->guest_EMWARN = EmWarn_NONE;
26621f126c5c092801acfc1ac968d2f1a37dde334bccsewardj
2663bfceb089644ce9eee882bae5cec5902be4831cacsewardj   /* SSE2 has a 'clflush' cache-line-invalidator which uses these. */
26641f126c5c092801acfc1ac968d2f1a37dde334bccsewardj   vex_state->guest_TISTART = 0;
26651f126c5c092801acfc1ac968d2f1a37dde334bccsewardj   vex_state->guest_TILEN   = 0;
2666ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj
2667d660d41d4174e44f284bad3264601662ed68d4a1sewardj   vex_state->guest_NRADDR   = 0;
2668d660d41d4174e44f284bad3264601662ed68d4a1sewardj   vex_state->guest_SC_CLASS = 0;
2669e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   vex_state->guest_IP_AT_SYSCALL = 0;
2670e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj
2671e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   vex_state->padding1 = 0;
2672e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   vex_state->padding2 = 0;
2673e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj   vex_state->padding3 = 0;
2674893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj}
2675893a3302cc943e2ad1db421a8e6a753f82f532a7sewardj
26768d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
26778d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/* Figure out if any part of the guest state contained in minoff
26788d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   .. maxoff requires precise memory exceptions.  If in doubt return
26798d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   True (but this is generates significantly slower code).
26808d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
26814cca75cb48776ceda40e8e305232d85f62021804sewardj   By default we enforce precise exns for guest %ESP, %EBP and %EIP
26824cca75cb48776ceda40e8e305232d85f62021804sewardj   only.  These are the minimum needed to extract correct stack
26834cca75cb48776ceda40e8e305232d85f62021804sewardj   backtraces from x86 code.
26848d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj*/
26858d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardjBool guest_x86_state_requires_precise_mem_exns ( Int minoff,
26868d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj                                                 Int maxoff)
26878d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj{
26884cca75cb48776ceda40e8e305232d85f62021804sewardj   Int ebp_min = offsetof(VexGuestX86State, guest_EBP);
26894cca75cb48776ceda40e8e305232d85f62021804sewardj   Int ebp_max = ebp_min + 4 - 1;
26908d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int esp_min = offsetof(VexGuestX86State, guest_ESP);
26918d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int esp_max = esp_min + 4 - 1;
26928d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int eip_min = offsetof(VexGuestX86State, guest_EIP);
26938d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int eip_max = eip_min + 4 - 1;
26948d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
26954cca75cb48776ceda40e8e305232d85f62021804sewardj   if (maxoff < ebp_min || minoff > ebp_max) {
26964cca75cb48776ceda40e8e305232d85f62021804sewardj      /* no overlap with ebp */
26974cca75cb48776ceda40e8e305232d85f62021804sewardj   } else {
26984cca75cb48776ceda40e8e305232d85f62021804sewardj      return True;
26994cca75cb48776ceda40e8e305232d85f62021804sewardj   }
27004cca75cb48776ceda40e8e305232d85f62021804sewardj
27018d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   if (maxoff < esp_min || minoff > esp_max) {
2702eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      /* no overlap with esp */
27038d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   } else {
2704eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      return True;
27058d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   }
27068d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
27078d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   if (maxoff < eip_min || minoff > eip_max) {
2708eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      /* no overlap with eip */
27098d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   } else {
2710eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      return True;
27118d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   }
27128d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
27138d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   return False;
27148d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj}
27158d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
27168d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
2717eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj#define ALWAYSDEFD(field)                           \
2718eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj    { offsetof(VexGuestX86State, field),            \
2719eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      (sizeof ((VexGuestX86State*)0)->field) }
2720eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
2721eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardjVexGuestLayout
272249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   x86guest_layout
2723eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      = {
2724eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Total size of the guest state, in bytes. */
2725eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .total_sizeB = sizeof(VexGuestX86State),
2726eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
2727eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Describe the stack pointer. */
2728eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .offset_SP = offsetof(VexGuestX86State,guest_ESP),
2729eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .sizeof_SP = 4,
2730eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
2731a203330aad67bc3e52ca1395a55e94ef9a091223sewardj          /* Describe the frame pointer. */
2732a203330aad67bc3e52ca1395a55e94ef9a091223sewardj          .offset_FP = offsetof(VexGuestX86State,guest_EBP),
2733a203330aad67bc3e52ca1395a55e94ef9a091223sewardj          .sizeof_FP = 4,
2734a203330aad67bc3e52ca1395a55e94ef9a091223sewardj
2735cf7879021370aabcccb1a9347244fcc7d5680141sewardj          /* Describe the instruction pointer. */
2736cf7879021370aabcccb1a9347244fcc7d5680141sewardj          .offset_IP = offsetof(VexGuestX86State,guest_EIP),
2737cf7879021370aabcccb1a9347244fcc7d5680141sewardj          .sizeof_IP = 4,
2738eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
2739eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Describe any sections to be regarded by Memcheck as
2740eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj             'always-defined'. */
2741e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj          .n_alwaysDefd = 24,
27423bd6f3ee3f38fe11f302dd41b2781c7bbc0f201csewardj
27432a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj          /* flags thunk: OP and NDEP are always defd, whereas DEP1
27442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj             and DEP2 have to be tracked.  See detailed comment in
27452a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj             gdefs.h on meaning of thunk fields. */
27468fc937421c954ff9f707254f028b1fa0410c473dsewardj          .alwaysDefd
27478fc937421c954ff9f707254f028b1fa0410c473dsewardj             = { /*  0 */ ALWAYSDEFD(guest_CC_OP),
27488fc937421c954ff9f707254f028b1fa0410c473dsewardj                 /*  1 */ ALWAYSDEFD(guest_CC_NDEP),
27498fc937421c954ff9f707254f028b1fa0410c473dsewardj                 /*  2 */ ALWAYSDEFD(guest_DFLAG),
27508fc937421c954ff9f707254f028b1fa0410c473dsewardj                 /*  3 */ ALWAYSDEFD(guest_IDFLAG),
27516d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  4 */ ALWAYSDEFD(guest_ACFLAG),
27526d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  5 */ ALWAYSDEFD(guest_EIP),
27536d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  6 */ ALWAYSDEFD(guest_FTOP),
27546d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  7 */ ALWAYSDEFD(guest_FPTAG),
27556d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  8 */ ALWAYSDEFD(guest_FPROUND),
27566d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /*  9 */ ALWAYSDEFD(guest_FC3210),
27576d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 10 */ ALWAYSDEFD(guest_CS),
27586d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 11 */ ALWAYSDEFD(guest_DS),
27596d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 12 */ ALWAYSDEFD(guest_ES),
27606d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 13 */ ALWAYSDEFD(guest_FS),
27616d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 14 */ ALWAYSDEFD(guest_GS),
27626d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 15 */ ALWAYSDEFD(guest_SS),
27636d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 16 */ ALWAYSDEFD(guest_LDT),
27646d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 17 */ ALWAYSDEFD(guest_GDT),
27656d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 18 */ ALWAYSDEFD(guest_EMWARN),
27666d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 19 */ ALWAYSDEFD(guest_SSEROUND),
27676d26984a0df6a7d20b658bac6edf869eb872cca3sewardj                 /* 20 */ ALWAYSDEFD(guest_TISTART),
2768e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj                 /* 21 */ ALWAYSDEFD(guest_TILEN),
2769e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj                 /* 22 */ ALWAYSDEFD(guest_SC_CLASS),
2770e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj                 /* 23 */ ALWAYSDEFD(guest_IP_AT_SYSCALL)
27718fc937421c954ff9f707254f028b1fa0410c473dsewardj               }
2772eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj        };
277349651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
277449651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
277536ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
2776cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                 guest_x86_helpers.c ---*/
277736ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
2778