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