guest_x86_helpers.c revision 7e5b7cdbfa65376488d58e4e6d8f13d974f7a8bc
136ca51378f8851635df814230fa23f2c409b9eddsewardj
236ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
336ca51378f8851635df814230fa23f2c409b9eddsewardj/*---                                                         ---*/
4c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- This file (guest-x86/ghelpers.c) is                     ---*/
536ca51378f8851635df814230fa23f2c409b9eddsewardj/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
636ca51378f8851635df814230fa23f2c409b9eddsewardj/*---                                                         ---*/
736ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
836ca51378f8851635df814230fa23f2c409b9eddsewardj
936ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_basictypes.h"
100c2cb623cca372a2b42b073121c7413cdaaf75besewardj#include "libvex_guest_x86.h"
1136ca51378f8851635df814230fa23f2c409b9eddsewardj#include "libvex_ir.h"
1249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj#include "libvex.h"
13c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj
14c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "main/vex_util.h"
15c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj#include "guest-x86/gdefs.h"
1636ca51378f8851635df814230fa23f2c409b9eddsewardj
17c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
1836ca51378f8851635df814230fa23f2c409b9eddsewardj/* This file contains helper functions for x86 guest code.
1936ca51378f8851635df814230fa23f2c409b9eddsewardj   Calls to these functions are generated by the back end.
2036ca51378f8851635df814230fa23f2c409b9eddsewardj   These calls are of course in the host machine code and
2136ca51378f8851635df814230fa23f2c409b9eddsewardj   this file will be compiled to host machine code, so that
2236ca51378f8851635df814230fa23f2c409b9eddsewardj   all makes sense.
2336ca51378f8851635df814230fa23f2c409b9eddsewardj
2436ca51378f8851635df814230fa23f2c409b9eddsewardj   Only change the signatures of these helper functions very
2536ca51378f8851635df814230fa23f2c409b9eddsewardj   carefully.  If you change the signature here, you'll have to change
2636ca51378f8851635df814230fa23f2c409b9eddsewardj   the parameters passed to it in the IR calls constructed by
2789050e58e7bee40892662fe94231aefc33768cf5sewardj   x86toIR.c.
2889050e58e7bee40892662fe94231aefc33768cf5sewardj
2989050e58e7bee40892662fe94231aefc33768cf5sewardj   Some of this code/logic is derived from QEMU, which is copyright
3089050e58e7bee40892662fe94231aefc33768cf5sewardj   Fabrice Bellard, licensed under the LGPL.  It is used with
3189050e58e7bee40892662fe94231aefc33768cf5sewardj   permission.
3236ca51378f8851635df814230fa23f2c409b9eddsewardj*/
3336ca51378f8851635df814230fa23f2c409b9eddsewardj
3484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Set to 1 to get detailed profiling info about use of the flag
3584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   machinery. */
3684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#define PROFILE_EFLAGS 0
3784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
3884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
39d44bc6e6692dfb0881dcc249bd4ba3d8f8e97fcasewardjstatic const UChar parity_table[256] = {
409aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
419aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
429aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
439aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
449aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
459aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
469aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
479aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
489aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
499aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
509aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
519aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
529aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
539aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
549aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
559aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
569aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
579aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
589aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
599aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
609aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
619aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
629aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
639aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
649aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
659aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
669aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
679aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
689aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
699aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
709aebb0c3f7a7f43313786826f31402f2b733badfsewardj    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
719aebb0c3f7a7f43313786826f31402f2b733badfsewardj    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
7214731f22bf7759d6d23383ca870ac89d9581f1e9sewardj};
7314731f22bf7759d6d23383ca870ac89d9581f1e9sewardj
7414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj/* n must be a constant to be efficient */
75df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardjinline static Int lshift ( Int x, Int n )
7614731f22bf7759d6d23383ca870ac89d9581f1e9sewardj{
77df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   if (n >= 0)
78df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj      return x << n;
79df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   else
80df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj      return x >> (-n);
8114731f22bf7759d6d23383ca870ac89d9581f1e9sewardj}
8214731f22bf7759d6d23383ca870ac89d9581f1e9sewardj
8314731f22bf7759d6d23383ca870ac89d9581f1e9sewardj
84b9c5cf639b3b21b972599d27207a033afc76ef67sewardj#define PREAMBLE(__data_bits)					\
85df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   /* const */ UInt DATA_MASK 					\
86b9c5cf639b3b21b972599d27207a033afc76ef67sewardj      = __data_bits==8 ? 0xFF 					\
87b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                       : (__data_bits==16 ? 0xFFFF 		\
88b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                                          : 0xFFFFFFFF); 	\
89df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   /* const */ UInt SIGN_MASK = 1 << (__data_bits - 1);		\
902a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   /* const */ UInt CC_DEP1 = cc_dep1_formal;			\
912a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   /* const */ UInt CC_DEP2 = cc_dep2_formal;			\
922a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   /* const */ UInt CC_NDEP = cc_ndep_formal;			\
932a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   /* Four bogus assignments, which hopefully gcc can     */	\
94df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   /* optimise away, and which stop it complaining about  */	\
95df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   /* unused variables.                                   */	\
96df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   SIGN_MASK = SIGN_MASK;					\
97df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj   DATA_MASK = DATA_MASK;					\
982a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   CC_DEP2 = CC_DEP2;						\
992a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   CC_NDEP = CC_NDEP;
100df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj
10114731f22bf7759d6d23383ca870ac89d9581f1e9sewardj
102b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
103b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
104df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE)			\
105b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
106b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
107948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
108948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int argL, argR, res;						\
1092a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = CC_DEP1;						\
1102a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argR = CC_DEP2;						\
1112a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = argL + argR;						\
112948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   cf = (DATA_UTYPE)res < (DATA_UTYPE)argL;			\
113948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   pf = parity_table[(UChar)res];				\
114948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   af = (res ^ argL ^ argR) & 0x10;				\
115948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
116948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
117948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   of = lshift((argL ^ argR ^ -1) & (argL ^ res), 		\
1189aebb0c3f7a7f43313786826f31402f2b733badfsewardj               12 - DATA_BITS) & CC_MASK_O;			\
119b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
1202ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj}
1212ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj
122b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
123b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
1242a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE)			\
125b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
126b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
127948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
128948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int argL, argR, res;						\
1292a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = CC_DEP1;						\
1302a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argR = CC_DEP2;						\
1312a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = argL - argR;						\
1322a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR;			\
133948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   pf = parity_table[(UChar)res];				\
134948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   af = (res ^ argL ^ argR) & 0x10;				\
135948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
136948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
1372a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = lshift((argL ^ argR) & (argL ^ res),	 		\
1382a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj               12 - DATA_BITS) & CC_MASK_O; 			\
139b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
1402ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj}
1412ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj
142b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
143b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
1442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE)			\
145b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
146b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
147948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
1482a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int argL, argR, oldC, res;		       			\
1492a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   oldC = CC_NDEP & CC_MASK_C;					\
1502a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = CC_DEP1;						\
1512a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argR = CC_DEP2 ^ oldC;	       				\
1522a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = (argL + argR) + oldC;					\
1532a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   if (oldC)							\
1542a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL;			\
1552a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   else								\
1562a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      cf = (DATA_UTYPE)res < (DATA_UTYPE)argL;			\
157948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   pf = parity_table[(UChar)res];				\
158948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   af = (res ^ argL ^ argR) & 0x10;				\
159948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
160948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
1612a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = lshift((argL ^ argR ^ -1) & (argL ^ res), 		\
1622a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                12 - DATA_BITS) & CC_MASK_O;			\
163b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
1642ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj}
1652ef5f2a829433c4ca17f33e1bf993cf16b9e347dsewardj
166b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
167b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
168df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE)			\
169b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
170b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
171948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
1722a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int argL, argR, oldC, res;		       			\
1732a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   oldC = CC_NDEP & CC_MASK_C;					\
1742a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = CC_DEP1;						\
1752a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argR = CC_DEP2 ^ oldC;	       				\
1762a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = (argL - argR) - oldC;					\
1772a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   if (oldC)							\
1782a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR;		\
1792a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   else								\
1802a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR;			\
181948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   pf = parity_table[(UChar)res];				\
182948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   af = (res ^ argL ^ argR) & 0x10;				\
183948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
184948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
185948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   of = lshift((argL ^ argR) & (argL ^ res), 			\
1869aebb0c3f7a7f43313786826f31402f2b733badfsewardj               12 - DATA_BITS) & CC_MASK_O;			\
187b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
188a238471814bd386aeb58a76718b41e68b1a794b2sewardj}
189a238471814bd386aeb58a76718b41e68b1a794b2sewardj
190b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
191b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
192df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE)			\
193b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
194b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
195948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
196b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   cf = 0;							\
1972a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)CC_DEP1];				\
198b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   af = 0;							\
1992a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;			\
2002a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;			\
201b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   of = 0;							\
202b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
203a238471814bd386aeb58a76718b41e68b1a794b2sewardj}
204a238471814bd386aeb58a76718b41e68b1a794b2sewardj
205b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
206b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
207df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_INC(DATA_BITS,DATA_UTYPE)			\
208b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
209b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
210948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
2112a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int argL, argR, res;						\
2122a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = CC_DEP1;						\
2132a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = res - 1;						\
214948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   argR = 1;							\
2152a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = CC_NDEP & CC_MASK_C;					\
2162a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)res];				\
2172a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   af = (res ^ argL ^ argR) & 0x10;				\
2182a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
2192a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
2202a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = ((res & DATA_MASK) == SIGN_MASK) << 11;			\
221b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
22289050e58e7bee40892662fe94231aefc33768cf5sewardj}
22389050e58e7bee40892662fe94231aefc33768cf5sewardj
224b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
225b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
226df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE)			\
227b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
228b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
229948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
2302a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int argL, argR, res;						\
2312a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   res  = CC_DEP1;						\
2322a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   argL = res + 1;						\
233948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   argR = 1;							\
2342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = CC_NDEP & CC_MASK_C;					\
2352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)res];				\
2362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   af = (res ^ argL ^ argR) & 0x10;				\
2372a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = ((DATA_UTYPE)res == 0) << 6;				\
2382a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(res, 8 - DATA_BITS) & 0x80;			\
2392a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = ((res & DATA_MASK) 					\
240d44bc6e6692dfb0881dcc249bd4ba3d8f8e97fcasewardj        == ((UInt)SIGN_MASK - 1)) << 11;			\
241b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
24289050e58e7bee40892662fe94231aefc33768cf5sewardj}
24389050e58e7bee40892662fe94231aefc33768cf5sewardj
244b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
245b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
246df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE)			\
247b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
248b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
249948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
2502a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = (CC_DEP2 >> (DATA_BITS - 1)) & CC_MASK_C;		\
2512a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)CC_DEP1];				\
252b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   af = 0; /* undefined */					\
2532a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;			\
2542a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;			\
255b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   /* of is defined if shift count == 1 */			\
2562a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) & CC_MASK_O;	\
257b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
2585f6303579435ddb8315e11c2f02c904b978782a0sewardj}
2595f6303579435ddb8315e11c2f02c904b978782a0sewardj
260b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
261b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
2622a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE)			\
263b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
264b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);  					\
265948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int cf, pf, af, zf, sf, of;					\
2662a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = CC_DEP2 & 1;						\
2672a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)CC_DEP1];				\
268b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   af = 0; /* undefined */					\
2692a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;			\
2702a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;			\
271b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   /* of is defined if shift count == 1 */			\
2722a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) & CC_MASK_O;	\
273b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return cf | pf | af | zf | sf | of;				\
2745f6303579435ddb8315e11c2f02c904b978782a0sewardj}
2755f6303579435ddb8315e11c2f02c904b978782a0sewardj
276b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
277b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
2788ee2de1f5f72c13120f59c0ca6ac8291219123dfsewardj/* ROL: cf' = lsb(result).  of' = msb(result) ^ lsb(result). */
2792a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */
280df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE)			\
281b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
282b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
283948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int fl 							\
2842a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      = (CC_NDEP & ~(CC_MASK_O | CC_MASK_C))			\
2852a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj        | (CC_MASK_C & CC_DEP1)					\
2862a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj        | (CC_MASK_O & (lshift(CC_DEP1, 11-(DATA_BITS-1)) 	\
2872a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                   ^ lshift(CC_DEP1, 11)));			\
288b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return fl;							\
2898c7f1abe9e022f6382634efea09c9cac89ec6336sewardj}
2908c7f1abe9e022f6382634efea09c9cac89ec6336sewardj
291b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
292b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
2931813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj/* ROR: cf' = msb(result).  of' = msb(result) ^ msb-1(result). */
2942a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj/* DEP1 = result, NDEP = old flags */
295df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE)			\
296b9c5cf639b3b21b972599d27207a033afc76ef67sewardj{								\
297b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   PREAMBLE(DATA_BITS);						\
298948d48be23eca9df7b9d33be5dca499affb7cb3asewardj   Int fl 							\
2992a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      = (CC_NDEP & ~(CC_MASK_O | CC_MASK_C))			\
3002a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj        | (CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1)))		\
3012a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj        | (CC_MASK_O & (lshift(CC_DEP1, 11-(DATA_BITS-1)) 	\
3022a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                   ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1)));	\
303b9c5cf639b3b21b972599d27207a033afc76ef67sewardj   return fl;							\
3041813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj}
3051813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj
306b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
307b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
3082a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE,DATA_U2TYPE)          \
3092a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{                                                               \
3102a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   PREAMBLE(DATA_BITS);                                         \
3112a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int cf, pf, af, zf, sf, of;                                  \
3122a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_UTYPE  hi;                                              \
3132a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_UTYPE  lo = ((DATA_UTYPE)CC_DEP1)                       \
3142a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    * ((DATA_UTYPE)CC_DEP2);                    \
3152a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_U2TYPE rr = ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1))        \
3162a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2));     \
3172a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   hi = (DATA_UTYPE)(rr >>/*u*/ DATA_BITS);                     \
3182a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = (hi != 0);                                              \
3192a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)lo];                                \
3202a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   af = 0; /* undefined */                                      \
3212a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = (lo == 0) << 6;                                         \
3222a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                       \
3232a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = cf << 11;                                               \
3242a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   return cf | pf | af | zf | sf | of;                          \
32556296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj}
32656296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj
327b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/*-------------------------------------------------------------*/
328b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
3292a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE,DATA_S2TYPE)          \
3302a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj{                                                               \
3312a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   PREAMBLE(DATA_BITS);                                         \
3322a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   Int cf, pf, af, zf, sf, of;                                  \
3332a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_STYPE  hi;                                              \
3342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_STYPE  lo = ((DATA_STYPE)CC_DEP1)                       \
3352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    * ((DATA_STYPE)CC_DEP2);                    \
3362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   DATA_S2TYPE rr = ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1))        \
3372a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2));     \
3382a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   hi = (DATA_STYPE)(rr >>/*s*/ DATA_BITS);                     \
3392a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   cf = (hi != (lo >>/*s*/ (DATA_BITS-1)));                     \
3402a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   pf = parity_table[(UChar)lo];                                \
3412a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   af = 0; /* undefined */                                      \
3422a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   zf = (lo == 0) << 6;                                         \
3432a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                       \
3442a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   of = cf << 11;                                               \
3452a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   return cf | pf | af | zf | sf | of;                          \
3467ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj}
347741153c4301023a420ab45b8a10b8e1bac968822sewardj
34836ca51378f8851635df814230fa23f2c409b9eddsewardj
34984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#if PROFILE_EFLAGS
35084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
35184ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt tabc[CC_OP_NUMBER];
35284ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt tab[CC_OP_NUMBER][16];
3539eab588e223e52b1e7b710ff1c0da7b032ab2837sewardjstatic Bool initted     = False;
35484ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_cond = 0;
35584ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_all  = 0;
35684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic UInt n_calc_c    = 0;
35784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
35884ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void showCounts ( void )
35984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
36084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   Int op, co;
36184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   Char ch;
3629eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj   vex_printf("\nALL=%d  COND=%d   C=%d\n",
36384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj              n_calc_all-n_calc_cond-n_calc_c, n_calc_cond, n_calc_c);
36484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("      CARRY    O   NO    B   NB    Z   NZ   BE  NBE"
36584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj              "    S   NS    P   NP    L   NL   LE  NLE\n");
36684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("     ----------------------------------------------"
36784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj              "----------------------------------------\n");
36884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   for (op = 0; op < CC_OP_NUMBER; op++) {
36984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
37084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      ch = ' ';
37193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      if (op > 0 && (op-1) % 3 == 0)
37293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         ch = 'B';
37393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      if (op > 0 && (op-1) % 3 == 1)
37493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         ch = 'W';
37584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (op > 0 && (op-1) % 3 == 2)
37684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         ch = 'L';
37784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
37884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      vex_printf("%2d%c: ", op, ch);
37984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      vex_printf("%6d ", tabc[op]);
38084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      for (co = 0; co < 16; co++) {
38184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         Int n = tab[op][co];
38284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         if (n >= 1000) {
38384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            vex_printf(" %3dK", n / 1000);
38484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         } else
38584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         if (n >= 0) {
38684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj           vex_printf(" %3d ", n );
38784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         } else {
38884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            vex_printf("     ");
38984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         }
39084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
39184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      vex_printf("\n");
39284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
39384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("\n");
39484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj}
39584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
39684ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic void initCounts ( void )
39784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
39884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   Int op, co;
39984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   initted = True;
40084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   for (op = 0; op < CC_OP_NUMBER; op++) {
40184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      tabc[op] = 0;
40284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      for (co = 0; co < 16; co++)
40384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         tab[op][co] = 0;
40484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
40584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj}
40684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
40784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#endif /* PROFILE_EFLAGS */
40884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
4099aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
410b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/* Calculate all the 6 flags from the supplied thunk parameters. */
4112a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardjUInt calculate_eflags_all ( UInt cc_op,
4122a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                            UInt cc_dep1_formal,
4132a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                            UInt cc_dep2_formal,
4142a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                            UInt cc_ndep_formal )
41536ca51378f8851635df814230fa23f2c409b9eddsewardj{
41684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  if PROFILE_EFLAGS
41784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   n_calc_all++;
41884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  endif
41936ca51378f8851635df814230fa23f2c409b9eddsewardj   switch (cc_op) {
4201813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj      case CC_OP_COPY:
4212a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj         return cc_dep1_formal
422df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj                & (CC_MASK_O | CC_MASK_S | CC_MASK_Z
423df22c1c8b9c7fb712e6471a391d2615c48afaa6dsewardj                   | CC_MASK_A | CC_MASK_C | CC_MASK_P);
42414731f22bf7759d6d23383ca870ac89d9581f1e9sewardj
4258c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ADDB:   ACTIONS_ADD( 8,  UChar  );
426a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_ADDW:   ACTIONS_ADD( 16, UShort );
4278c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ADDL:   ACTIONS_ADD( 32, UInt   );
428a238471814bd386aeb58a76718b41e68b1a794b2sewardj
4298c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ADCB:   ACTIONS_ADC( 8,  UChar  );
430a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_ADCW:   ACTIONS_ADC( 16, UShort );
4318c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ADCL:   ACTIONS_ADC( 32, UInt   );
432a238471814bd386aeb58a76718b41e68b1a794b2sewardj
4338c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SUBB:   ACTIONS_SUB(  8, UChar  );
434a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_SUBW:   ACTIONS_SUB( 16, UShort );
4358c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SUBL:   ACTIONS_SUB( 32, UInt   );
436afc5787e1c4b8e9678669577cf57ac509c6cd6b5sewardj
4378c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SBBB:   ACTIONS_SBB(  8, UChar  );
438a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_SBBW:   ACTIONS_SBB( 16, UShort );
4398c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SBBL:   ACTIONS_SBB( 32, UInt   );
440741153c4301023a420ab45b8a10b8e1bac968822sewardj
4418c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_LOGICB: ACTIONS_LOGIC(  8, UChar  );
442a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort );
4438c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt   );
4445f6303579435ddb8315e11c2f02c904b978782a0sewardj
4458c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_INCB:   ACTIONS_INC(  8, UChar  );
446a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_INCW:   ACTIONS_INC( 16, UShort );
4478c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_INCL:   ACTIONS_INC( 32, UInt   );
4481813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj
4498c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_DECB:   ACTIONS_DEC(  8, UChar  );
450a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_DECW:   ACTIONS_DEC( 16, UShort );
4518c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_DECL:   ACTIONS_DEC( 32, UInt   );
4528c7f1abe9e022f6382634efea09c9cac89ec6336sewardj
4538c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SHLB:   ACTIONS_SHL(  8, UChar  );
4548c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SHLW:   ACTIONS_SHL( 16, UShort );
4558c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_SHLL:   ACTIONS_SHL( 32, UInt   );
4568c7f1abe9e022f6382634efea09c9cac89ec6336sewardj
4572a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SHRB:   ACTIONS_SHR(  8, UChar  );
4582a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SHRW:   ACTIONS_SHR( 16, UShort );
4592a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SHRL:   ACTIONS_SHR( 32, UInt   );
4601813dbeb912870e9a544cae17a3fadbf8d2b0d55sewardj
4618c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ROLB:   ACTIONS_ROL(  8, UChar  );
4628c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ROLW:   ACTIONS_ROL( 16, UShort );
4638c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_ROLL:   ACTIONS_ROL( 32, UInt   );
464750f407b6be1aac303964a219acf0a6de8b8c4dasewardj
4658c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_RORB:   ACTIONS_ROR(  8, UChar  );
466a238471814bd386aeb58a76718b41e68b1a794b2sewardj      case CC_OP_RORW:   ACTIONS_ROR( 16, UShort );
4678c7f1abe9e022f6382634efea09c9cac89ec6336sewardj      case CC_OP_RORL:   ACTIONS_ROR( 32, UInt   );
4687ed2295459ac5e788a98dd5570fef0d4645c27d4sewardj
4692a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_UMULB:  ACTIONS_UMUL(  8, UChar,  UShort );
4702a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_UMULW:  ACTIONS_UMUL( 16, UShort, UInt   );
4712a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_UMULL:  ACTIONS_UMUL( 32, UInt,   ULong  );
47256296d80c9e15ec59eebecf1c3aea9ebd4dac115sewardj
4732a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SMULB:  ACTIONS_SMUL(  8, Char,   Short );
4742a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SMULW:  ACTIONS_SMUL( 16, Short,  Int   );
4752a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj      case CC_OP_SMULL:  ACTIONS_SMUL( 32, Int,    Long  );
476741153c4301023a420ab45b8a10b8e1bac968822sewardj
47736ca51378f8851635df814230fa23f2c409b9eddsewardj      default:
47836ca51378f8851635df814230fa23f2c409b9eddsewardj         /* shouldn't really make these calls from generated code */
4792a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj         vex_printf("calculate_eflags_all( %d, 0x%x, 0x%x, 0x%x )\n",
4802a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal );
48136ca51378f8851635df814230fa23f2c409b9eddsewardj         vpanic("calculate_eflags_all");
48236ca51378f8851635df814230fa23f2c409b9eddsewardj   }
48336ca51378f8851635df814230fa23f2c409b9eddsewardj}
48436ca51378f8851635df814230fa23f2c409b9eddsewardj
485b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
4869aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
487b9c5cf639b3b21b972599d27207a033afc76ef67sewardj/* Calculate just the carry flag from the supplied thunk parameters. */
4882a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardjUInt calculate_eflags_c ( UInt cc_op,
4892a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                          UInt cc_dep1,
4902a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                          UInt cc_dep2,
4912a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                          UInt cc_ndep )
49236ca51378f8851635df814230fa23f2c409b9eddsewardj{
4939eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj   /* Fast-case some common ones. */
49443c46951628d616290f7245c3af2f9a652180806sewardj   switch (cc_op) {
49543c46951628d616290f7245c3af2f9a652180806sewardj      case CC_OP_LOGICL: case CC_OP_LOGICW: case CC_OP_LOGICB:
49643c46951628d616290f7245c3af2f9a652180806sewardj         return 0;
49743c46951628d616290f7245c3af2f9a652180806sewardj      case CC_OP_SUBL:
49893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return ((UInt)cc_dep1) < ((UInt)cc_dep2)
49993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                   ? CC_MASK_C : 0;
50093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#if 0
50193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      case CC_OP_SUBB:
50293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF))
50343c46951628d616290f7245c3af2f9a652180806sewardj                   ? CC_MASK_C : 0;
50493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#endif
50593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#if 0
50693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      case CC_OP_DECL:
50793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return cc_src;
50843c46951628d616290f7245c3af2f9a652180806sewardj      case CC_OP_ADDL:
50943c46951628d616290f7245c3af2f9a652180806sewardj         return ( ((UInt)cc_src + (UInt)cc_dst) < ((UInt)cc_src) )
51043c46951628d616290f7245c3af2f9a652180806sewardj                   ? CC_MASK_C : 0;
51143c46951628d616290f7245c3af2f9a652180806sewardj      case CC_OP_SUBB:
51243c46951628d616290f7245c3af2f9a652180806sewardj         return ( ((UInt)(cc_src & 0xFF)) > ((UInt)(cc_dst & 0xFF)) )
51343c46951628d616290f7245c3af2f9a652180806sewardj                   ? CC_MASK_C : 0;
514948d48be23eca9df7b9d33be5dca499affb7cb3asewardj#endif
51543c46951628d616290f7245c3af2f9a652180806sewardj      default:
51643c46951628d616290f7245c3af2f9a652180806sewardj         break;
51743c46951628d616290f7245c3af2f9a652180806sewardj   }
5189eab588e223e52b1e7b710ff1c0da7b032ab2837sewardj
51984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  if PROFILE_EFLAGS
52084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   if (!initted)
52184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      initCounts();
52284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   tabc[cc_op]++;
52384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
52484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   n_calc_c++;
52584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  endif
5262a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   return calculate_eflags_all(cc_op,cc_dep1,cc_dep2,cc_ndep) & CC_MASK_C;
52736ca51378f8851635df814230fa23f2c409b9eddsewardj}
52836ca51378f8851635df814230fa23f2c409b9eddsewardj
52936ca51378f8851635df814230fa23f2c409b9eddsewardj
5309aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
53184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* returns 1 or 0 */
53284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/*static*/ UInt calculate_condition ( UInt/*Condcode*/ cond,
5332a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                                      UInt cc_op,
5342a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                                      UInt cc_dep1,
5352a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                                      UInt cc_dep2,
5362a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                                      UInt cc_ndep )
53784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
5382a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   UInt eflags = calculate_eflags_all(cc_op, cc_dep1, cc_dep2, cc_ndep);
53984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   UInt of,sf,zf,cf,pf;
54084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   UInt inv = cond & 1;
54184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
54284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  if PROFILE_EFLAGS
54384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   if (!initted)
54484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj     initCounts();
54584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
54684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   tab[cc_op][cond]++;
54784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   n_calc_cond++;
54884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
54993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj   if (0 == ((n_calc_all+n_calc_c) & 0x7FFFF)) showCounts();
55084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  endif
55184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
55284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   switch (cond) {
55384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNO:
55484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondO: /* OF == 1 */
55584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         of = eflags >> CC_SHIFT_O;
55684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ of);
55784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
55884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNZ:
55984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondZ: /* ZF == 1 */
56084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         zf = eflags >> CC_SHIFT_Z;
56184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ zf);
56284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
56384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNB:
56484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondB: /* CF == 1 */
56584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         cf = eflags >> CC_SHIFT_C;
56684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ cf);
56784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         break;
56884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
56984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNBE:
57084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondBE: /* (CF or ZF) == 1 */
57184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         cf = eflags >> CC_SHIFT_C;
57284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         zf = eflags >> CC_SHIFT_Z;
57384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ (cf | zf));
57484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         break;
57584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
57684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNS:
57784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondS: /* SF == 1 */
57884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         sf = eflags >> CC_SHIFT_S;
57984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ sf);
58084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
58184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNP:
58284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondP: /* PF == 1 */
58384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         pf = eflags >> CC_SHIFT_P;
58484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ pf);
58584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
58684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNL:
58784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondL: /* (SF xor OF) == 1 */
58884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         sf = eflags >> CC_SHIFT_S;
58984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         of = eflags >> CC_SHIFT_O;
59084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ (sf ^ of));
59184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         break;
59284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
59384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondNLE:
59484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      case CondLE: /* ((SF xor OF) or ZF)  == 1 */
59584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         sf = eflags >> CC_SHIFT_S;
59684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         of = eflags >> CC_SHIFT_O;
59784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         zf = eflags >> CC_SHIFT_Z;
59884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return 1 & (inv ^ ((sf ^ of) | zf));
59984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         break;
60084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
60184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      default:
60284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* shouldn't really make these calls from generated code */
6032a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj         vex_printf("calculate_condition( %d, %d, 0x%x, 0x%x, 0x%x )\n",
6042a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    cond, cc_op, cc_dep1, cc_dep2, cc_ndep );
60584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         vpanic("calculate_condition");
60684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
60784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj}
60884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
60984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
61084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj/* Used by the optimiser to try specialisations.  Returns an
61184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   equivalent expression, or NULL if none. */
61284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
61384ff0657940e62f38e618ea18bac6f27ce0e741fsewardjstatic Bool isU32 ( IRExpr* e, UInt n )
61484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
61584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   return e->tag == Iex_Const
61684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj          && e->Iex.Const.con->tag == Ico_U32
61784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj          && e->Iex.Const.con->Ico.U32 == n;
61884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj}
61984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
62084ff0657940e62f38e618ea18bac6f27ce0e741fsewardjIRExpr* x86guest_spechelper ( Char* function_name,
62184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj                              IRExpr** args )
62284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
62384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  define unop(_op,_a1) IRExpr_Unop((_op),(_a1))
62484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2))
62584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  define mkU32(_n) IRExpr_Const(IRConst_U32(_n))
62684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
62784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   Int i, arity = 0;
62884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   for (i = 0; args[i]; i++)
62984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      arity++;
63084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  if 0
63184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("spec request:\n");
63284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("   %s  ", function_name);
63384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   for (i = 0; i < arity; i++) {
63484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      vex_printf("  ");
63584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      ppIRExpr(args[i]);
63684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
63784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   vex_printf("\n");
63884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  endif
63993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj
64093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj   /* --------- specialising "calculate_eflags_c" --------- */
64193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj
64284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   if (vex_streq(function_name, "calculate_eflags_c")) {
64384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      /* specialise calls to above "calculate_eflags_c" function */
64493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;
64593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      vassert(arity == 4);
64693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_op   = args[0];
64793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_dep1 = args[1];
64893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_dep2 = args[2];
64993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_ndep = args[3];
65084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
65193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      if (isU32(cc_op, CC_OP_SUBL)) {
65293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         /* C after sub denotes unsigned less than */
65393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return unop(Iop_1Uto32,
65493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpLT32U, cc_dep1, cc_dep2));
65593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      }
65684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_LOGICL)) {
65784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* cflag after logic is zero */
65884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return mkU32(0);
65984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
66084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_DECL) || isU32(cc_op, CC_OP_INCL)) {
66184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* If the thunk is dec or inc, the cflag is supplied as CC_SRC. */
66293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return cc_dep1;
66384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
66484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#     if 0
66584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (cc_op->tag == Iex_Const) {
66684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");
66784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
66884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#     endif
66984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
67084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      return NULL;
67184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
67284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
67393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj   /* --------- specialising "calculate_condition" --------- */
67493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj
67584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   if (vex_streq(function_name, "calculate_condition")) {
67684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      /* specialise calls to above "calculate condition" function */
67793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;
67893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      vassert(arity == 5);
67993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cond    = args[0];
68093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_op   = args[1];
68193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_dep1 = args[2];
68293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_dep2 = args[3];
68393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj      cc_ndep = args[4];
68484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
68546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- SUBL ----------------*/
68646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
68746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_SUBL) && isU32(cond, CondZ)) {
68846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* long sub/cmp, then Z --> test dst==src */
68984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return unop(Iop_1Uto32,
69093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpEQ32, cc_dep1, cc_dep2));
69146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      }
69246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
69346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_SUBL) && isU32(cond, CondL)) {
69446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* long sub/cmp, then L (signed less than)
69546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj            --> test dst <s src */
69646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         return unop(Iop_1Uto32,
69793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpLT32S, cc_dep1, cc_dep2));
69846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      }
69946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
70046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_SUBL) && isU32(cond, CondLE)) {
70146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* long sub/cmp, then LE (signed less than or equal)
70246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj            --> test dst <=s src */
70346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         return unop(Iop_1Uto32,
70493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpLE32S, cc_dep1, cc_dep2));
70546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      }
70646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
70746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_SUBL) && isU32(cond, CondBE)) {
70846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* long sub/cmp, then BE (unsigned less than or equal)
70946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj            --> test dst <=u src */
71046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         return unop(Iop_1Uto32,
71193d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpLE32U, cc_dep1, cc_dep2));
71246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      }
71393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#if 0
71446ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_SUBL) && isU32(cond, CondB)) {
71546ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* long sub/cmp, then B (unsigned less than)
71646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj            --> test dst <u src */
71746ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         return unop(Iop_1Uto32,
71846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj                     binop(Iop_CmpLT32U, cc_dst, cc_src));
71984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
72084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
72146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- SUBW ----------------*/
72246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
723b9c5cf639b3b21b972599d27207a033afc76ef67sewardj      if (isU32(cc_op, CC_OP_SUBW) && isU32(cond, CondZ)) {
724b9c5cf639b3b21b972599d27207a033afc76ef67sewardj         /* byte sub/cmp, then Z --> test dst==src */
725b9c5cf639b3b21b972599d27207a033afc76ef67sewardj         return unop(Iop_1Uto32,
726b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                     binop(Iop_CmpEQ16,
727b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                           unop(Iop_32to16,cc_dst),
728b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                           unop(Iop_32to16,cc_src)));
729b9c5cf639b3b21b972599d27207a033afc76ef67sewardj      }
730b9c5cf639b3b21b972599d27207a033afc76ef67sewardj
73146ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- SUBB ----------------*/
73293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#endif
73384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_SUBB) && isU32(cond, CondZ)) {
734b9c5cf639b3b21b972599d27207a033afc76ef67sewardj         /* byte sub/cmp, then Z --> test dst==src */
73584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return unop(Iop_1Uto32,
736b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                     binop(Iop_CmpEQ8,
73793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                           unop(Iop_32to8,cc_dep1),
73893d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                           unop(Iop_32to8,cc_dep2)));
73984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
74084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
74184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_SUBB) && isU32(cond, CondNZ)) {
7427e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj         /* byte sub/cmp, then NZ --> test dst!=src */
74384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return unop(Iop_1Uto32,
744b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                     binop(Iop_CmpNE8,
74593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                           unop(Iop_32to8,cc_dep1),
74693d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                           unop(Iop_32to8,cc_dep2)));
747b9c5cf639b3b21b972599d27207a033afc76ef67sewardj      }
748b9c5cf639b3b21b972599d27207a033afc76ef67sewardj      if (isU32(cc_op, CC_OP_SUBB) && isU32(cond, CondNBE)) {
749b9c5cf639b3b21b972599d27207a033afc76ef67sewardj         /* long sub/cmp, then NBE (unsigned greater than)
750b9c5cf639b3b21b972599d27207a033afc76ef67sewardj            --> test src <=u dst */
7517e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj         /* Note, args are opposite way round from the usual */
752b9c5cf639b3b21b972599d27207a033afc76ef67sewardj         return unop(Iop_1Uto32,
753b9c5cf639b3b21b972599d27207a033afc76ef67sewardj                     binop(Iop_CmpLT32U,
7547e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj                           binop(Iop_And32,cc_dep2,mkU32(0xFF)),
7557e5b7cdbfa65376488d58e4e6d8f13d974f7a8bcsewardj			   binop(Iop_And32,cc_dep1,mkU32(0xFF))));
75684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
75784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
75846ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- LOGICL ----------------*/
75946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj
76084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_LOGICL) && isU32(cond, CondZ)) {
76184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* long and/or/xor, then Z --> test dst==0 */
76293d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
76384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
76493d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#if 0
765fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj      if (isU32(cc_op, CC_OP_LOGICL) && isU32(cond, CondS)) {
766fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj         /* long and/or/xor, then S --> test dst <s 0 */
767fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj         return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dst, mkU32(0)));
768fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj      }
76993d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#endif
77084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_LOGICL) && isU32(cond, CondLE)) {
77184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* long and/or/xor, then LE
77284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            This is pretty subtle.  LOGIC sets SF and ZF according to the
77384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            result and makes OF be zero.  LE computes (SZ ^ OF) | ZF, but
77484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            OF is zero, so this reduces to SZ | ZF -- which will be 1 iff
77584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj            the result is <=signed 0.  Hence ...
77684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         */
77793d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return unop(Iop_1Uto32,binop(Iop_CmpLE32S, cc_dep1, mkU32(0)));
77884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
77984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
78046ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- LOGICB ----------------*/
78184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
78246ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      if (isU32(cc_op, CC_OP_LOGICB) && isU32(cond, CondZ)) {
78346ccb51aff085d180120d310c0be2fe6c86e1b65sewardj         /* byte and/or/xor, then Z --> test dst==0 */
78484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         return unop(Iop_1Uto32,
78593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj                     binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(255)),
78646ccb51aff085d180120d310c0be2fe6c86e1b65sewardj                                        mkU32(0)));
78784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
78884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
78946ccb51aff085d180120d310c0be2fe6c86e1b65sewardj      /*---------------- DECL ----------------*/
790af991dede2815b7570828b9d9174cf989e636254sewardj
79184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      if (isU32(cc_op, CC_OP_DECL) && isU32(cond, CondZ)) {
79284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj         /* dec L, then Z --> test dst == 0 */
79393d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj         return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
79484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      }
79593d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#if 0
796fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj      if (isU32(cc_op, CC_OP_DECL) && isU32(cond, CondS)) {
797fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj         /* dec L, then S --> compare DST <s 0 */
798fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj         return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dst, mkU32(0)));
799fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj      }
80093d96e91167fc72c5ec1b8d615cd0f96674110b0sewardj#endif
801fae2ca7ef81549a4b28235618317d4352ca32ac2sewardj
80284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj      return NULL;
80384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   }
80484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
80584ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  undef unop
80684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  undef binop
80784ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#  undef mkU32
80884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
80984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj   return NULL;
81084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj}
81184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj
81236ca51378f8851635df814230fa23f2c409b9eddsewardj
8130c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*-----------------------------------------------------------*/
8140c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*--- Utility functions for x87 FPU conversions.          ---*/
8150c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*-----------------------------------------------------------*/
8160c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8170c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8180c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* 80 and 64-bit floating point formats:
8190c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8200c2cb623cca372a2b42b073121c7413cdaaf75besewardj   80-bit:
8210c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8220c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  0       0-------0      zero
8230c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  0       0X------X      denormals
8240c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  1-7FFE  1X------X      normals (all normals have leading 1)
8250c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FFF    10------0      infinity
8260c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FFF    10X-----X      snan
8270c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FFF    11X-----X      qnan
8280c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8290c2cb623cca372a2b42b073121c7413cdaaf75besewardj   S is the sign bit.  For runs X----X, at least one of the Xs must be
8300c2cb623cca372a2b42b073121c7413cdaaf75besewardj   nonzero.  Exponent is 15 bits, fractional part is 63 bits, and
8310c2cb623cca372a2b42b073121c7413cdaaf75besewardj   there is an explicitly represented leading 1, and a sign bit,
8320c2cb623cca372a2b42b073121c7413cdaaf75besewardj   giving 80 in total.
8330c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8340c2cb623cca372a2b42b073121c7413cdaaf75besewardj   64-bit avoids the confusion of an explicitly represented leading 1
8350c2cb623cca372a2b42b073121c7413cdaaf75besewardj   and so is simpler:
8360c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8370c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  0      0------0   zero
8380c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  0      X------X   denormals
8390c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  1-7FE  any        normals
8400c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FF    0------0   infinity
8410c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FF    0X-----X   snan
8420c2cb623cca372a2b42b073121c7413cdaaf75besewardj    S  7FF    1X-----X   qnan
8430c2cb623cca372a2b42b073121c7413cdaaf75besewardj
8440c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Exponent is 11 bits, fractional part is 52 bits, and there is a
8450c2cb623cca372a2b42b073121c7413cdaaf75besewardj   sign bit, giving 64 in total.
8460c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/
8470c2cb623cca372a2b42b073121c7413cdaaf75besewardj
848c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardjstatic inline Bool host_is_little_endian ( void )
849c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj{
850c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UInt x = 0x76543210;
851c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UChar* p = (UChar*)(&x);
852c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   return (*p == 0x10);
853c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj}
854c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
8559aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
8568ea867b06de73d909c29e243407713c291c8414esewardjUInt calculate_FXAM ( UInt tag, ULong dbl )
857c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj{
858c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   Bool   mantissaIsZero;
859c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   Int    bexp;
860c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UChar  sign;
861c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UInt   c1;
862c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UChar* f64;
863c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
864f5e36670bf70ac2d23f6336d7f46889bf996cfdfsewardj   if (!host_is_little_endian()) {
865c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      vassert(0);
866c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
867c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
868c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */
869c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
870c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   f64  = (UChar*)(&dbl);
871c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   sign = (f64[7] >> 7) & 1;
872c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
873c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* First off, if the tag indicates the register was empty,
874c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return 1,0,sign,1 */
875c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   if (tag == 0) {
876c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      /* vex_printf("Empty\n"); */
877c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return FC_MASK_C3 | 0 | sign | FC_MASK_C0;
878c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
879c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
880c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F);
881c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   bexp &= 0x7FF;
882c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
883c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   c1 = ((UInt)sign) << 9;
884c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
885c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   mantissaIsZero
886c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      = (f64[6] & 0x0F) == 0
887c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj        && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0;
888c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
889c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* If both exponent and mantissa are zero, the value is zero.
890c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      Return 1,0,sign,0. */
891c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   if (bexp == 0 && mantissaIsZero) {
892c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      /* vex_printf("Zero\n"); */
893c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return FC_MASK_C3 | 0 | sign | 0;
894c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
895c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
896c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* If exponent is zero but mantissa isn't, it's a denormal.
897c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      Return 1,1,sign,0. */
898c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   if (bexp == 0 && !mantissaIsZero) {
899c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      /* vex_printf("Denormal\n"); */
900c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return FC_MASK_C3 | FC_MASK_C2 | sign | 0;
901c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
902c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
903c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* If the exponent is 7FF and the mantissa is zero, this is an infinity.
904c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      Return 0,1,sign,1. */
905c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   if (bexp == 0x7FF && mantissaIsZero) {
906c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      /* vex_printf("Inf\n"); */
907c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return 0 | FC_MASK_C2 | sign | FC_MASK_C0;
908c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
909c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
910c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN.
911c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      Return 0,0,sign,1. */
912c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   if (bexp == 0x7FF && !mantissaIsZero) {
913c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      /* vex_printf("NaN\n"); */
914c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      return 0 | 0 | sign | FC_MASK_C0;
915c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   }
916c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
917c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* Uh, ok, we give up.  It must be a normal finite number.
918c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj      Return 0,1,sign,0.
919c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   */
920c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   /* vex_printf("normal\n"); */
921c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   return 0 | FC_MASK_C2 | sign | 0;
922c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj}
923c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj
9240c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9250c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Convert a IEEE754 double (64-bit) into an x87 extended double
9260c2cb623cca372a2b42b073121c7413cdaaf75besewardj   (80-bit), mimicing the hardware fairly closely.  Both numbers are
9270c2cb623cca372a2b42b073121c7413cdaaf75besewardj   stored little-endian.  Limitations, all of which could be fixed,
9280c2cb623cca372a2b42b073121c7413cdaaf75besewardj   given some level of hassle:
9290c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9300c2cb623cca372a2b42b073121c7413cdaaf75besewardj   * Does not handle double precision denormals.  As a result, values
9310c2cb623cca372a2b42b073121c7413cdaaf75besewardj     with magnitudes less than 1e-308 are flushed to zero when they
9320c2cb623cca372a2b42b073121c7413cdaaf75besewardj     need not be.
9330c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9340c2cb623cca372a2b42b073121c7413cdaaf75besewardj   * Identity of NaNs is not preserved.
9350c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9360c2cb623cca372a2b42b073121c7413cdaaf75besewardj   See comments in the code for more details.
9370c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/
9380c2cb623cca372a2b42b073121c7413cdaaf75besewardjstatic void convert_f64le_to_f80le ( /*IN*/UChar* f64, /*OUT*/UChar* f80 )
9390c2cb623cca372a2b42b073121c7413cdaaf75besewardj{
9400c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Bool  isInf;
9410c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Int   bexp;
9420c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UChar sign;
9430c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9440c2cb623cca372a2b42b073121c7413cdaaf75besewardj   sign = (f64[7] >> 7) & 1;
9450c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F);
9460c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp &= 0x7FF;
9470c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9480c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* If the exponent is zero, either we have a zero or a denormal.
9490c2cb623cca372a2b42b073121c7413cdaaf75besewardj      Produce a zero.  This is a hack in that it forces denormals to
9500c2cb623cca372a2b42b073121c7413cdaaf75besewardj      zero.  Could do better. */
9510c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp == 0) {
9520c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f80[9] = sign << 7;
9530c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f80[8] = f80[7] = f80[6] = f80[5] = f80[4]
9540c2cb623cca372a2b42b073121c7413cdaaf75besewardj             = f80[3] = f80[2] = f80[1] = f80[0] = 0;
9550c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
9560c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
9570c2cb623cca372a2b42b073121c7413cdaaf75besewardj
9580c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* If the exponent is 7FF, this is either an Infinity, a SNaN or
9590c2cb623cca372a2b42b073121c7413cdaaf75besewardj      QNaN, as determined by examining bits 51:0, thus:
9600c2cb623cca372a2b42b073121c7413cdaaf75besewardj          0  ... 0    Inf
9610c2cb623cca372a2b42b073121c7413cdaaf75besewardj          0X ... X    SNaN
9620c2cb623cca372a2b42b073121c7413cdaaf75besewardj          1X ... X    QNaN
9630c2cb623cca372a2b42b073121c7413cdaaf75besewardj      where at least one of the Xs is not zero.
9640c2cb623cca372a2b42b073121c7413cdaaf75besewardj   */
9650c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp == 0x7FF) {
9660c2cb623cca372a2b42b073121c7413cdaaf75besewardj      isInf = (f64[6] & 0x0F) == 0
9670c2cb623cca372a2b42b073121c7413cdaaf75besewardj              && f64[5] == 0 && f64[4] == 0 && f64[3] == 0
9680c2cb623cca372a2b42b073121c7413cdaaf75besewardj              && f64[2] == 0 && f64[1] == 0 && f64[0] == 0;
9690c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (isInf) {
9700c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* Produce an appropriately signed infinity:
9710c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (15)  1  0--0 (63)
9720c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
9730c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[9] = (sign << 7) | 0x7F;
9740c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[8] = 0xFF;
9750c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[7] = 0x80;
9760c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[6] = f80[5] = f80[4] = f80[3]
9770c2cb623cca372a2b42b073121c7413cdaaf75besewardj                = f80[2] = f80[1] = f80[0] = 0;
9780c2cb623cca372a2b42b073121c7413cdaaf75besewardj         return;
9790c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
9800c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* So it's either a QNaN or SNaN.  Distinguish by considering
9810c2cb623cca372a2b42b073121c7413cdaaf75besewardj         bit 51.  Note, this destroys all the trailing bits
9820c2cb623cca372a2b42b073121c7413cdaaf75besewardj         (identity?) of the NaN.  IEEE754 doesn't require preserving
9830c2cb623cca372a2b42b073121c7413cdaaf75besewardj         these (it only requires that there be one QNaN value and one
9840c2cb623cca372a2b42b073121c7413cdaaf75besewardj         SNaN value), but x87 does seem to have some ability to
9850c2cb623cca372a2b42b073121c7413cdaaf75besewardj         preserve them.  Anyway, here, the NaN's identity is
9860c2cb623cca372a2b42b073121c7413cdaaf75besewardj         destroyed.  Could be improved. */
9870c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (f64[6] & 8) {
9880c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* QNaN.  Make a QNaN:
9890c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (15)  1  1--1 (63)
9900c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
9910c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[9] = (sign << 7) | 0x7F;
9920c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[8] = 0xFF;
9930c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[7] = 0xFF;
9940c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[6] = f80[5] = f80[4] = f80[3]
9950c2cb623cca372a2b42b073121c7413cdaaf75besewardj                = f80[2] = f80[1] = f80[0] = 0xFF;
9960c2cb623cca372a2b42b073121c7413cdaaf75besewardj      } else {
9970c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* SNaN.  Make a SNaN:
9980c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (15)  0  1--1 (63)
9990c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
10000c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[9] = (sign << 7) | 0x7F;
10010c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[8] = 0xFF;
10020c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[7] = 0x7F;
10030c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f80[6] = f80[5] = f80[4] = f80[3]
10040c2cb623cca372a2b42b073121c7413cdaaf75besewardj                = f80[2] = f80[1] = f80[0] = 0xFF;
10050c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
10060c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
10070c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
10080c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10090c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* It's not a zero, denormal, infinity or nan.  So it must be a
10100c2cb623cca372a2b42b073121c7413cdaaf75besewardj      normalised number.  Rebias the exponent and build the new
10110c2cb623cca372a2b42b073121c7413cdaaf75besewardj      number.  */
10120c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp += (16383 - 1023);
10130c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10140c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[9] = (sign << 7) | ((bexp >> 8) & 0xFF);
10150c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[8] = bexp & 0xFF;
10160c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[7] = (1 << 7) | ((f64[6] << 3) & 0x78) | ((f64[5] >> 5) & 7);
10170c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[6] = ((f64[5] << 3) & 0xF8) | ((f64[4] >> 5) & 7);
10180c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[5] = ((f64[4] << 3) & 0xF8) | ((f64[3] >> 5) & 7);
10190c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[4] = ((f64[3] << 3) & 0xF8) | ((f64[2] >> 5) & 7);
10200c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[3] = ((f64[2] << 3) & 0xF8) | ((f64[1] >> 5) & 7);
10210c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[2] = ((f64[1] << 3) & 0xF8) | ((f64[0] >> 5) & 7);
10220c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[1] = ((f64[0] << 3) & 0xF8);
10230c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f80[0] = 0;
10240c2cb623cca372a2b42b073121c7413cdaaf75besewardj}
10250c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10260c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10270c2cb623cca372a2b42b073121c7413cdaaf75besewardj/////////////////////////////////////////////////////////////////
10280c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10290c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Convert a x87 extended double (80-bit) into an IEEE 754 double
10300c2cb623cca372a2b42b073121c7413cdaaf75besewardj   (64-bit), mimicing the hardware fairly closely.  Both numbers are
10310c2cb623cca372a2b42b073121c7413cdaaf75besewardj   stored little-endian.  Limitations, all of which could be fixed,
10320c2cb623cca372a2b42b073121c7413cdaaf75besewardj   given some level of hassle:
10330c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10340c2cb623cca372a2b42b073121c7413cdaaf75besewardj   * Does not create double precision denormals.  As a result, values
10350c2cb623cca372a2b42b073121c7413cdaaf75besewardj     with magnitudes less than 1e-308 are flushed to zero when they
10360c2cb623cca372a2b42b073121c7413cdaaf75besewardj     need not be.
10370c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10380c2cb623cca372a2b42b073121c7413cdaaf75besewardj   * Rounding following truncation could be a bit better.
10390c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10400c2cb623cca372a2b42b073121c7413cdaaf75besewardj   * Identity of NaNs is not preserved.
10410c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10420c2cb623cca372a2b42b073121c7413cdaaf75besewardj   See comments in the code for more details.
10430c2cb623cca372a2b42b073121c7413cdaaf75besewardj*/
10440c2cb623cca372a2b42b073121c7413cdaaf75besewardjstatic void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 )
10450c2cb623cca372a2b42b073121c7413cdaaf75besewardj{
10460c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Bool  isInf;
10470c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Int   bexp;
10480c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UChar sign;
10490c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10500c2cb623cca372a2b42b073121c7413cdaaf75besewardj   sign = (f80[9] >> 7) & 1;
10510c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp = (((UInt)f80[9]) << 8) | (UInt)f80[8];
10520c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp &= 0x7FFF;
10530c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10540c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* If the exponent is zero, either we have a zero or a denormal.
10550c2cb623cca372a2b42b073121c7413cdaaf75besewardj      But an extended precision denormal becomes a double precision
10560c2cb623cca372a2b42b073121c7413cdaaf75besewardj      zero, so in either case, just produce the appropriately signed
10570c2cb623cca372a2b42b073121c7413cdaaf75besewardj      zero. */
10580c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp == 0) {
10590c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[7] = sign << 7;
10600c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[6] = f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;
10610c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
10620c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
10630c2cb623cca372a2b42b073121c7413cdaaf75besewardj
10640c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* If the exponent is 7FFF, this is either an Infinity, a SNaN or
10650c2cb623cca372a2b42b073121c7413cdaaf75besewardj      QNaN, as determined by examining bits 62:0, thus:
10660c2cb623cca372a2b42b073121c7413cdaaf75besewardj          0  ... 0    Inf
10670c2cb623cca372a2b42b073121c7413cdaaf75besewardj          0X ... X    SNaN
10680c2cb623cca372a2b42b073121c7413cdaaf75besewardj          1X ... X    QNaN
10690c2cb623cca372a2b42b073121c7413cdaaf75besewardj      where at least one of the Xs is not zero.
10700c2cb623cca372a2b42b073121c7413cdaaf75besewardj   */
10710c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp == 0x7FFF) {
10720c2cb623cca372a2b42b073121c7413cdaaf75besewardj      isInf = (f80[7] & 0x7F) == 0
10730c2cb623cca372a2b42b073121c7413cdaaf75besewardj              && f80[6] == 0 && f80[5] == 0 && f80[4] == 0
10740c2cb623cca372a2b42b073121c7413cdaaf75besewardj              && f80[3] == 0 && f80[2] == 0 && f80[1] == 0 && f80[0] == 0;
10750c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (isInf) {
10760c2cb623cca372a2b42b073121c7413cdaaf75besewardj         if (0 == (f80[7] & 0x80))
10770c2cb623cca372a2b42b073121c7413cdaaf75besewardj            goto wierd_NaN;
10780c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* Produce an appropriately signed infinity:
10790c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (11)  0--0 (52)
10800c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
10810c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[7] = (sign << 7) | 0x7F;
10820c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[6] = 0xF0;
10830c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;
10840c2cb623cca372a2b42b073121c7413cdaaf75besewardj         return;
10850c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
10860c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* So it's either a QNaN or SNaN.  Distinguish by considering
10870c2cb623cca372a2b42b073121c7413cdaaf75besewardj         bit 62.  Note, this destroys all the trailing bits
10880c2cb623cca372a2b42b073121c7413cdaaf75besewardj         (identity?) of the NaN.  IEEE754 doesn't require preserving
10890c2cb623cca372a2b42b073121c7413cdaaf75besewardj         these (it only requires that there be one QNaN value and one
10900c2cb623cca372a2b42b073121c7413cdaaf75besewardj         SNaN value), but x87 does seem to have some ability to
10910c2cb623cca372a2b42b073121c7413cdaaf75besewardj         preserve them.  Anyway, here, the NaN's identity is
10920c2cb623cca372a2b42b073121c7413cdaaf75besewardj         destroyed.  Could be improved. */
10930c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (f80[8] & 0x40) {
10940c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* QNaN.  Make a QNaN:
10950c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (11)  1  1--1 (51)
10960c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
10970c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[7] = (sign << 7) | 0x7F;
10980c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[6] = 0xFF;
10990c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0xFF;
11000c2cb623cca372a2b42b073121c7413cdaaf75besewardj      } else {
11010c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* SNaN.  Make a SNaN:
11020c2cb623cca372a2b42b073121c7413cdaaf75besewardj            S 1--1 (11)  0  1--1 (51)
11030c2cb623cca372a2b42b073121c7413cdaaf75besewardj         */
11040c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[7] = (sign << 7) | 0x7F;
11050c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[6] = 0xF7;
11060c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0xFF;
11070c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
11080c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
11090c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
11100c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11110c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* If it's not a Zero, NaN or Inf, and the integer part (bit 62) is
11120c2cb623cca372a2b42b073121c7413cdaaf75besewardj      zero, the x87 FPU appears to consider the number denormalised
11130c2cb623cca372a2b42b073121c7413cdaaf75besewardj      and converts it to a QNaN. */
11140c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (0 == (f80[7] & 0x80)) {
11150c2cb623cca372a2b42b073121c7413cdaaf75besewardj      wierd_NaN:
11160c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* Strange hardware QNaN:
11170c2cb623cca372a2b42b073121c7413cdaaf75besewardj         S 1--1 (11)  1  0--0 (51)
11180c2cb623cca372a2b42b073121c7413cdaaf75besewardj      */
11190c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* On a PIII, these QNaNs always appear with sign==1.  I have
11200c2cb623cca372a2b42b073121c7413cdaaf75besewardj         no idea why. */
11210c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[7] = (1 /*sign*/ << 7) | 0x7F;
11220c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[6] = 0xF8;
11230c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;
11240c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
11250c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
11260c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11270c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* It's not a zero, denormal, infinity or nan.  So it must be a
11280c2cb623cca372a2b42b073121c7413cdaaf75besewardj      normalised number.  Rebias the exponent and consider. */
11290c2cb623cca372a2b42b073121c7413cdaaf75besewardj   bexp -= (16383 - 1023);
11300c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp >= 0x7FF) {
11310c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* It's too big for a double.  Construct an infinity. */
11320c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[7] = (sign << 7) | 0x7F;
11330c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[6] = 0xF0;
11340c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;
11350c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
11360c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
11370c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11380c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (bexp < 0) {
11390c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* It's too small for a double.  Construct a zero.  Note, this
11400c2cb623cca372a2b42b073121c7413cdaaf75besewardj      is a kludge since we could conceivably create a
11410c2cb623cca372a2b42b073121c7413cdaaf75besewardj      denormalised number for bexp in -1 to -51, but we don't
11420c2cb623cca372a2b42b073121c7413cdaaf75besewardj      bother.  This means the conversion flushes values
11430c2cb623cca372a2b42b073121c7413cdaaf75besewardj      approximately in the range 1e-309 to 1e-324 ish to zero
11440c2cb623cca372a2b42b073121c7413cdaaf75besewardj      when it doesn't actually need to.  This could be
11450c2cb623cca372a2b42b073121c7413cdaaf75besewardj      improved. */
11460c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[7] = sign << 7;
11470c2cb623cca372a2b42b073121c7413cdaaf75besewardj      f64[6] = f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;
11480c2cb623cca372a2b42b073121c7413cdaaf75besewardj      return;
11490c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
11500c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11510c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* Ok, it's a normalised number which is representable as a double.
11520c2cb623cca372a2b42b073121c7413cdaaf75besewardj      Copy the exponent and mantissa into place. */
11530c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /*
11540c2cb623cca372a2b42b073121c7413cdaaf75besewardj   for (i = 0; i < 52; i++)
11550c2cb623cca372a2b42b073121c7413cdaaf75besewardj      write_bit_array ( f64,
11560c2cb623cca372a2b42b073121c7413cdaaf75besewardj                        i,
11570c2cb623cca372a2b42b073121c7413cdaaf75besewardj                        read_bit_array ( f80, i+11 ) );
11580c2cb623cca372a2b42b073121c7413cdaaf75besewardj   */
11590c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[0] = (f80[1] >> 3) | (f80[2] << 5);
11600c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[1] = (f80[2] >> 3) | (f80[3] << 5);
11610c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[2] = (f80[3] >> 3) | (f80[4] << 5);
11620c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[3] = (f80[4] >> 3) | (f80[5] << 5);
11630c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[4] = (f80[5] >> 3) | (f80[6] << 5);
11640c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[5] = (f80[6] >> 3) | (f80[7] << 5);
11650c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11660c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[6] = ((bexp << 4) & 0xF0) | ((f80[7] >> 3) & 0x0F);
11670c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11680c2cb623cca372a2b42b073121c7413cdaaf75besewardj   f64[7] = (sign << 7) | ((bexp >> 4) & 0x7F);
11690c2cb623cca372a2b42b073121c7413cdaaf75besewardj
11700c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* Now consider any rounding that needs to happen as a result of
11710c2cb623cca372a2b42b073121c7413cdaaf75besewardj      truncating the mantissa. */
11720c2cb623cca372a2b42b073121c7413cdaaf75besewardj   if (f80[1] & 4) /* read_bit_array(f80, 10) == 1) */ {
11730c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* Round upwards.  This is a kludge.  Once in every 64k
11740c2cb623cca372a2b42b073121c7413cdaaf75besewardj         roundings (statistically) the bottom two bytes are both 0xFF
11750c2cb623cca372a2b42b073121c7413cdaaf75besewardj         and so we don't round at all.  Could be improved. */
11760c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (f64[0] != 0xFF) {
11770c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[0]++;
11780c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
11790c2cb623cca372a2b42b073121c7413cdaaf75besewardj      else
11800c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (f64[0] == 0xFF && f64[1] != 0xFF) {
11810c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[0] = 0;
11820c2cb623cca372a2b42b073121c7413cdaaf75besewardj         f64[1]++;
11830c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
11840c2cb623cca372a2b42b073121c7413cdaaf75besewardj      /* else we don't round, but we should. */
11850c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
11860c2cb623cca372a2b42b073121c7413cdaaf75besewardj}
11870c2cb623cca372a2b42b073121c7413cdaaf75besewardj
118817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */
118917442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (reads guest memory) */
11908ea867b06de73d909c29e243407713c291c8414esewardjULong loadF80le ( UInt addrU )
119117442fe8094d0f82266e5a05509f62cac8f7539esewardj{
119217442fe8094d0f82266e5a05509f62cac8f7539esewardj   ULong f64;
119317442fe8094d0f82266e5a05509f62cac8f7539esewardj   convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 );
119417442fe8094d0f82266e5a05509f62cac8f7539esewardj   return f64;
119517442fe8094d0f82266e5a05509f62cac8f7539esewardj}
119617442fe8094d0f82266e5a05509f62cac8f7539esewardj
119717442fe8094d0f82266e5a05509f62cac8f7539esewardj/* CALLED FROM GENERATED CODE */
119817442fe8094d0f82266e5a05509f62cac8f7539esewardj/* DIRTY HELPER (writes guest memory) */
11998ea867b06de73d909c29e243407713c291c8414esewardjvoid storeF80le ( UInt addrU, ULong f64 )
120017442fe8094d0f82266e5a05509f62cac8f7539esewardj{
120117442fe8094d0f82266e5a05509f62cac8f7539esewardj   convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU );
120217442fe8094d0f82266e5a05509f62cac8f7539esewardj}
120317442fe8094d0f82266e5a05509f62cac8f7539esewardj
12040c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12050c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/
12060c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*--- The exported fns ..                    ---*/
12070c2cb623cca372a2b42b073121c7413cdaaf75besewardj/*----------------------------------------------*/
12080c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12090c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Layout of the real x87 state. */
12100c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12110c2cb623cca372a2b42b073121c7413cdaaf75besewardjtypedef
12120c2cb623cca372a2b42b073121c7413cdaaf75besewardj   struct {
12130c2cb623cca372a2b42b073121c7413cdaaf75besewardj      UShort env[14];
12140c2cb623cca372a2b42b073121c7413cdaaf75besewardj      UChar  reg[80];
12150c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
12160c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Fpu_State;
12170c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12180c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* Offsets, in 16-bit ints, into the FPU environment (env) area. */
12190c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_CTRL   0
12200c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_STAT   2
12210c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_TAG    4
12220c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_IP     6 /* and 7 */
12230c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_CS     8
12240c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_OPOFF  10 /* and 11 */
12250c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_ENV_OPSEL  12
12260c2cb623cca372a2b42b073121c7413cdaaf75besewardj#define FP_REG(ii)    (10*(7-(ii)))
12270c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12280c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12290c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* VISIBLE TO LIBVEX CLIENT */
123076bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardjvoid LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
123176bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj                               /*OUT*/VexGuestX86State* vex_state )
12320c2cb623cca372a2b42b073121c7413cdaaf75besewardj{
12330c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Int        r;
12340c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UInt       tag;
1235f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   Double*    vexRegs = (Double*)(&vex_state->guest_FPREG[0]);
1236f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);
12370c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Fpu_State* x87     = (Fpu_State*)x87_state;
12380c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UInt       ftop    = (x87->env[FP_ENV_STAT] >> 11) & 7;
12390c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UInt       tagw    = x87->env[FP_ENV_TAG];
12406e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj   UInt       fpucw   = x87->env[FP_ENV_CTRL];
1241c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   UInt       c3210   = x87->env[FP_ENV_STAT] & 0x4700;
12420c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12430c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* Copy registers and tags */
12440c2cb623cca372a2b42b073121c7413cdaaf75besewardj   for (r = 0; r < 8; r++) {
12450c2cb623cca372a2b42b073121c7413cdaaf75besewardj      tag = (tagw >> (2*r)) & 3;
12460c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (tag == 3) {
12470c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* register is empty */
12480c2cb623cca372a2b42b073121c7413cdaaf75besewardj         vexRegs[r] = 0.0;
12490c2cb623cca372a2b42b073121c7413cdaaf75besewardj         vexTags[r] = 0;
12500c2cb623cca372a2b42b073121c7413cdaaf75besewardj      } else {
12510c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* register is non-empty */
12520c2cb623cca372a2b42b073121c7413cdaaf75besewardj         convert_f80le_to_f64le( &x87->reg[FP_REG(r)], (UChar*)&vexRegs[r] );
12530c2cb623cca372a2b42b073121c7413cdaaf75besewardj         vexTags[r] = 1;
12540c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
12550c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
12560c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12570c2cb623cca372a2b42b073121c7413cdaaf75besewardj   /* stack pointer */
1258f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   vex_state->guest_FTOP = ftop;
12590c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12606e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj   /* control word */
1261f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   vex_state->guest_FPUCW = fpucw;
12623f868e5262a8d2488f41cc49058ba60c24843c3esewardj
12633f868e5262a8d2488f41cc49058ba60c24843c3esewardj   /* status word */
1264f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   vex_state->guest_FC3210 = c3210;
12650c2cb623cca372a2b42b073121c7413cdaaf75besewardj}
12660c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12676e0dbda4f7ea53dd29996d4d429d3c5c92ee3640sewardj
12680c2cb623cca372a2b42b073121c7413cdaaf75besewardj/* VISIBLE TO LIBVEX CLIENT */
126976bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardjvoid LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
127076bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj                               /*OUT*/UChar* x87_state )
12710c2cb623cca372a2b42b073121c7413cdaaf75besewardj{
12720c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Int        i, r;
12730c2cb623cca372a2b42b073121c7413cdaaf75besewardj   UInt       tagw;
1274f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   Double*    vexRegs = (Double*)(&vex_state->guest_FPREG[0]);
1275f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);
12760c2cb623cca372a2b42b073121c7413cdaaf75besewardj   Fpu_State* x87     = (Fpu_State*)x87_state;
1277f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UInt       ftop    = vex_state->guest_FTOP;
1278f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UInt       c3210   = vex_state->guest_FC3210;
12790c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12800c2cb623cca372a2b42b073121c7413cdaaf75besewardj   for (i = 0; i < 14; i++)
12810c2cb623cca372a2b42b073121c7413cdaaf75besewardj      x87->env[i] = 0;
12820c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12830c2cb623cca372a2b42b073121c7413cdaaf75besewardj   x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF;
1284f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   x87->env[FP_ENV_CTRL] = (UShort)( vex_state->guest_FPUCW );
1285c4be80c5f03eda35da5d9f2aeba90f27a2015b93sewardj   x87->env[FP_ENV_STAT] = ((ftop & 7) << 11) | (c3210 & 0x4700);
12860c2cb623cca372a2b42b073121c7413cdaaf75besewardj
12870c2cb623cca372a2b42b073121c7413cdaaf75besewardj   tagw = 0;
12880c2cb623cca372a2b42b073121c7413cdaaf75besewardj   for (r = 0; r < 8; r++) {
12890c2cb623cca372a2b42b073121c7413cdaaf75besewardj      if (vexTags[r] == 0) {
12900c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* register is empty */
12910c2cb623cca372a2b42b073121c7413cdaaf75besewardj         tagw |= (3 << (2*r));
12920c2cb623cca372a2b42b073121c7413cdaaf75besewardj         convert_f64le_to_f80le( (UChar*)&vexRegs[r], &x87->reg[FP_REG(r)] );
12930c2cb623cca372a2b42b073121c7413cdaaf75besewardj      } else {
12940c2cb623cca372a2b42b073121c7413cdaaf75besewardj         /* register is full. */
12950c2cb623cca372a2b42b073121c7413cdaaf75besewardj         tagw |= (0 << (2*r));
12960c2cb623cca372a2b42b073121c7413cdaaf75besewardj         convert_f64le_to_f80le( (UChar*)&vexRegs[r],  &x87->reg[FP_REG(r)] );
12970c2cb623cca372a2b42b073121c7413cdaaf75besewardj      }
12980c2cb623cca372a2b42b073121c7413cdaaf75besewardj   }
12990c2cb623cca372a2b42b073121c7413cdaaf75besewardj   x87->env[FP_ENV_TAG] = tagw;
13000c2cb623cca372a2b42b073121c7413cdaaf75besewardj}
13010c2cb623cca372a2b42b073121c7413cdaaf75besewardj
13020c2cb623cca372a2b42b073121c7413cdaaf75besewardj
1303f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj/* VISIBLE TO LIBVEX CLIENT */
130476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardjvoid LibVEX_GuestX86_put_eflags ( UInt eflags_native,
130576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj                                  /*OUT*/VexGuestX86State* vex_state )
1306f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj{
1307f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   vex_state->guest_DFLAG
1308f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj      = (eflags_native & (1<<10)) ? 0xFFFFFFFF : 0x00000001;
1309006a6a2f15f48f705895a516d4883e8f8142e910sewardj   vex_state->guest_IDFLAG
1310006a6a2f15f48f705895a516d4883e8f8142e910sewardj      = (eflags_native & (1<<21)) ? 1 : 0;
1311f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1312f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   /* Mask out everything except O S Z A C P. */
1313f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   eflags_native
1314f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj      &= (CC_MASK_C | CC_MASK_P | CC_MASK_A
1315f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj          | CC_MASK_Z | CC_MASK_S | CC_MASK_O);
1316f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
13172a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_OP   = CC_OP_COPY;
13182a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_DEP1 = eflags_native;
13192a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_DEP2 = 0;
13202a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_NDEP = 0; /* unnecessary paranoia */
1321f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj}
1322f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1323f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1324f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj/* VISIBLE TO LIBVEX CLIENT */
132576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardjUInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state )
1326f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj{
1327f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UInt eflags = calculate_eflags_all(
1328f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj                    vex_state->guest_CC_OP,
13292a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    vex_state->guest_CC_DEP1,
13302a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    vex_state->guest_CC_DEP2,
13312a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj                    vex_state->guest_CC_NDEP
1332f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj                 );
1333f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   UInt dflag = vex_state->guest_DFLAG;
1334f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   vassert(dflag == 1 || dflag == 0xFFFFFFFF);
1335f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   if (dflag == 0xFFFFFFFF)
1336f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj      eflags |= (1<<10);
1337006a6a2f15f48f705895a516d4883e8f8142e910sewardj   if (vex_state->guest_IDFLAG == 1)
1338006a6a2f15f48f705895a516d4883e8f8142e910sewardj      eflags |= (1<<21);
1339f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1340f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj   return eflags;
1341f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj}
1342f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1343dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj/* VISIBLE TO LIBVEX CLIENT */
134476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardjvoid LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
1345dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj{
1346dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj   Int i;
134776bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj
134876bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EAX = 0;
134976bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_ECX = 0;
135076bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EDX = 0;
135176bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EBX = 0;
135276bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_ESP = 0;
135376bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EBP = 0;
135476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_ESI = 0;
135576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EDI = 0;
135676bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj
13572a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_OP   = CC_OP_COPY;
13582a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_DEP1 = 0;
13592a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_DEP2 = 0;
13602a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_CC_NDEP = 0;
13612a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_DFLAG   = 1; /* forwards */
13622a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj   vex_state->guest_IDFLAG  = 0;
136376bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj
136476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_EIP = 0;
136576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj
136676bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_FTOP = 0;
1367dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj   for (i = 0; i < 8; i++) {
1368dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj      vex_state->guest_FPTAG[i] = 0; /* empty */
1369dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj      vex_state->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */
1370dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj   }
1371dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj   /* The default setting: all fp exceptions masked, rounding to
1372dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj      nearest, precision to 64 bits */
1373dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj   vex_state->guest_FPUCW = 0x03F7;
137476bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_FC3210 = 0;
137576bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj
137676bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_CS = 0;
137776bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_DS = 0;
137876bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_ES = 0;
137976bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_FS = 0;
138076bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_GS = 0;
138176bdc805d2e3104009118cb0a2adf3ecff45e2a3sewardj   vex_state->guest_SS = 0;
1382dda7a4c98be4c7c6f11eab4e1cad6ab275aed79csewardj}
1383f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
1384f6dc3ce7df8154569748530c20b31c44f60ab6f8sewardj
13859aebb0c3f7a7f43313786826f31402f2b733badfsewardj/*----------------------------------------------*/
13869aebb0c3f7a7f43313786826f31402f2b733badfsewardj/*--- Misc integer helpers                   ---*/
13879aebb0c3f7a7f43313786826f31402f2b733badfsewardj/*----------------------------------------------*/
13889aebb0c3f7a7f43313786826f31402f2b733badfsewardj
13899aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
13909aebb0c3f7a7f43313786826f31402f2b733badfsewardj/* Calculate both flags and value result for rotate right
13919aebb0c3f7a7f43313786826f31402f2b733badfsewardj   through the carry bit.  Result in low 32 bits,
13929aebb0c3f7a7f43313786826f31402f2b733badfsewardj   new flags (OSZACP) in high 32 bits.
13939aebb0c3f7a7f43313786826f31402f2b733badfsewardj*/
13948ea867b06de73d909c29e243407713c291c8414esewardjULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
13959aebb0c3f7a7f43313786826f31402f2b733badfsewardj{
13969aebb0c3f7a7f43313786826f31402f2b733badfsewardj   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;
13979aebb0c3f7a7f43313786826f31402f2b733badfsewardj
13989aebb0c3f7a7f43313786826f31402f2b733badfsewardj   switch (sz) {
13999aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 4:
14009aebb0c3f7a7f43313786826f31402f2b733badfsewardj         cf        = (eflags_in >> CC_SHIFT_C) & 1;
14019aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 31) ^ cf) & 1;
14029aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
14039aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
14049aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = (arg >> 1) | (cf << 31);
14059aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
14069aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
14079aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
14089aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
14099aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 2:
14109aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT >= 17) tempCOUNT -= 17;
14119aebb0c3f7a7f43313786826f31402f2b733badfsewardj         cf        = (eflags_in >> CC_SHIFT_C) & 1;
14129aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 15) ^ cf) & 1;
14139aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
14149aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
14159aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = ((arg >> 1) & 0x7FFF) | (cf << 15);
14169aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
14179aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
14189aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
14199aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
14209aebb0c3f7a7f43313786826f31402f2b733badfsewardj      case 1:
14219aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT >= 9) tempCOUNT -= 9;
14229aebb0c3f7a7f43313786826f31402f2b733badfsewardj         cf        = (eflags_in >> CC_SHIFT_C) & 1;
14239aebb0c3f7a7f43313786826f31402f2b733badfsewardj         of        = ((arg >> 7) ^ cf) & 1;
14249aebb0c3f7a7f43313786826f31402f2b733badfsewardj         while (tempCOUNT > 0) {
14259aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempcf = arg & 1;
14269aebb0c3f7a7f43313786826f31402f2b733badfsewardj            arg    = ((arg >> 1) & 0x7F) | (cf << 7);
14279aebb0c3f7a7f43313786826f31402f2b733badfsewardj            cf     = tempcf;
14289aebb0c3f7a7f43313786826f31402f2b733badfsewardj            tempCOUNT--;
14299aebb0c3f7a7f43313786826f31402f2b733badfsewardj         }
14309aebb0c3f7a7f43313786826f31402f2b733badfsewardj         break;
14319aebb0c3f7a7f43313786826f31402f2b733badfsewardj      default:
14329aebb0c3f7a7f43313786826f31402f2b733badfsewardj         vpanic("calculate_RCR: invalid size");
14339aebb0c3f7a7f43313786826f31402f2b733badfsewardj   }
14349aebb0c3f7a7f43313786826f31402f2b733badfsewardj
14359aebb0c3f7a7f43313786826f31402f2b733badfsewardj   cf &= 1;
14369aebb0c3f7a7f43313786826f31402f2b733badfsewardj   of &= 1;
14379aebb0c3f7a7f43313786826f31402f2b733badfsewardj   eflags_in &= ~(CC_MASK_C | CC_MASK_O);
14389aebb0c3f7a7f43313786826f31402f2b733badfsewardj   eflags_in |= (cf << CC_SHIFT_C) | (of << CC_SHIFT_O);
14399aebb0c3f7a7f43313786826f31402f2b733badfsewardj
14409aebb0c3f7a7f43313786826f31402f2b733badfsewardj   return (((ULong)eflags_in) << 32) | ((ULong)arg);
14419aebb0c3f7a7f43313786826f31402f2b733badfsewardj}
14429aebb0c3f7a7f43313786826f31402f2b733badfsewardj
14437cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj
14447cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* CALLED FROM GENERATED CODE */
14457cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* DIRTY HELPER (modifies guest state) */
14467cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj/* Claim to be a P54C P133 (pre-MMX Pentium) */
14478ea867b06de73d909c29e243407713c291c8414esewardjvoid dirtyhelper_CPUID ( VexGuestX86State* st )
14487cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj{
14497cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj   if (st->guest_EAX == 0) {
14507cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EAX = 0x1;
14517cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EBX = 0x756e6547;
14527cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_ECX = 0x6c65746e;
14537cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EDX = 0x49656e69;
14547cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj   } else {
14557cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EAX = 0x52b;
14567cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EBX = 0x0;
14577cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_ECX = 0x0;
14587cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj      st->guest_EDX = 0x1bf;
14597cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj   }
14607cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj}
14617cb49d78b0f97c1f83ac95a02f4d044a4dd3f194sewardj
14628d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/*-----------------------------------------------------------*/
14638d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/*--- Describing the x86 guest state, for the benefit     ---*/
14648d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/*--- of iropt and instrumenters.                         ---*/
14658d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/*-----------------------------------------------------------*/
14668d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14678d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj/* Figure out if any part of the guest state contained in minoff
14688d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   .. maxoff requires precise memory exceptions.  If in doubt return
14698d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   True (but this is generates significantly slower code).
14708d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14718d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   We enforce precise exns for guest %ESP and %EIP only.
14728d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj*/
14738d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardjBool guest_x86_state_requires_precise_mem_exns ( Int minoff,
14748d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj                                                 Int maxoff)
14758d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj{
14768d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int esp_min = offsetof(VexGuestX86State, guest_ESP);
14778d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int esp_max = esp_min + 4 - 1;
14788d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int eip_min = offsetof(VexGuestX86State, guest_EIP);
14798d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   Int eip_max = eip_min + 4 - 1;
14808d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14818d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   if (maxoff < esp_min || minoff > esp_max) {
1482eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      /* no overlap with esp */
14838d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   } else {
1484eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      return True;
14858d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   }
14868d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14878d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   if (maxoff < eip_min || minoff > eip_max) {
1488eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      /* no overlap with eip */
14898d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   } else {
1490eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      return True;
14918d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   }
14928d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14938d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj   return False;
14948d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj}
14958d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
14968d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj
1497eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj#define ALWAYSDEFD(field)                           \
1498eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj    { offsetof(VexGuestX86State, field),            \
1499eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      (sizeof ((VexGuestX86State*)0)->field) }
1500eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
1501eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardjVexGuestLayout
150249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj   x86guest_layout
1503eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj      = {
1504eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Total size of the guest state, in bytes. */
1505eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .total_sizeB = sizeof(VexGuestX86State),
1506eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
1507eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Describe the stack pointer. */
1508eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .offset_SP = offsetof(VexGuestX86State,guest_ESP),
1509eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .sizeof_SP = 4,
1510eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
1511cf7879021370aabcccb1a9347244fcc7d5680141sewardj          /* Describe the instruction pointer. */
1512cf7879021370aabcccb1a9347244fcc7d5680141sewardj          .offset_IP = offsetof(VexGuestX86State,guest_EIP),
1513cf7879021370aabcccb1a9347244fcc7d5680141sewardj          .sizeof_IP = 4,
1514eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj
1515eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          /* Describe any sections to be regarded by Memcheck as
1516eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj             'always-defined'. */
1517948d48be23eca9df7b9d33be5dca499affb7cb3asewardj          .n_alwaysDefd = 15,
15182a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj          /* flags thunk: OP and NDEP are always defd, whereas DEP1
15192a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj             and DEP2 have to be tracked.  See detailed comment in
15202a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj             gdefs.h on meaning of thunk fields. */
1521eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj          .alwaysDefd[0]  = ALWAYSDEFD(guest_CC_OP),
15222a2ba8b72b4e467292c33cec23dee90cbf078e5dsewardj          .alwaysDefd[1]  = ALWAYSDEFD(guest_CC_NDEP),
1523b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj
1524b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[2]  = ALWAYSDEFD(guest_DFLAG),
1525b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[3]  = ALWAYSDEFD(guest_IDFLAG),
1526b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[4]  = ALWAYSDEFD(guest_EIP),
1527b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[5]  = ALWAYSDEFD(guest_FTOP),
1528b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[6]  = ALWAYSDEFD(guest_FPTAG),
1529b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[7]  = ALWAYSDEFD(guest_FPUCW),
1530b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[8]  = ALWAYSDEFD(guest_FC3210),
1531b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[9]  = ALWAYSDEFD(guest_CS),
1532b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[10] = ALWAYSDEFD(guest_DS),
1533b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[11] = ALWAYSDEFD(guest_ES),
1534b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[12] = ALWAYSDEFD(guest_FS),
1535b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[13] = ALWAYSDEFD(guest_GS),
1536b128ebeda55b4a4ab172131b24db0c7abeca28fdsewardj          .alwaysDefd[14] = ALWAYSDEFD(guest_SS)
1537eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj        };
153849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
153949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj
154036ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
1541c0ee2edb4563c90bc8f1a83a09984a1fda86d1d3sewardj/*--- end                                guest-x86/ghelpers.c ---*/
154236ca51378f8851635df814230fa23f2c409b9eddsewardj/*---------------------------------------------------------------*/
1543