19c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 29c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn/*---------------------------------------------------------------*/ 3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin guest_amd64_helpers.c ---*/ 49c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn/*---------------------------------------------------------------*/ 59c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 69c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn/* 7752f90673ebbb6b2f55fc5e46606dea371313713sewardj This file is part of Valgrind, a dynamic binary instrumentation 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj framework. 99c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2004-2017 OpenWorks LLP 11752f90673ebbb6b2f55fc5e46606dea371313713sewardj info@open-works.net 129c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 13752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is free software; you can redistribute it and/or 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj modify it under the terms of the GNU General Public License as 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj published by the Free Software Foundation; either version 2 of the 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj License, or (at your option) any later version. 179c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 18752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is distributed in the hope that it will be useful, but 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj General Public License for more details. 22752f90673ebbb6b2f55fc5e46606dea371313713sewardj 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj You should have received a copy of the GNU General Public License 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj along with this program; if not, write to the Free Software 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 02110-1301, USA. 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 28752f90673ebbb6b2f55fc5e46606dea371313713sewardj The GNU General Public License is contained in the file COPYING. 299c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 309c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn Neither the names of the U.S. Department of Energy nor the 319c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn University of California nor the names of its contributors may be 329c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn used to endorse or promote products derived from this software 339c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn without prior written permission. 349c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn*/ 359c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 369c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn#include "libvex_basictypes.h" 3733b024301d2311965cc68dc4cc900f3d0fdd8085florian#include "libvex_emnote.h" 389c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn#include "libvex_guest_amd64.h" 399c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn#include "libvex_ir.h" 409c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn#include "libvex.h" 419c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 436c46befd9eb90c1b6e739926c1fa335cba75bf46philippe#include "main_globals.h" 44cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h" 45cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_amd64_defs.h" 46cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_x87.h" 4744d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 48f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 49f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* This file contains helper functions for amd64 guest code. 50f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Calls to these functions are generated by the back end. 51f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj These calls are of course in the host machine code and 52f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj this file will be compiled to host machine code, so that 53f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj all makes sense. 54f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 55f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Only change the signatures of these helper functions very 56f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj carefully. If you change the signature here, you'll have to change 57f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj the parameters passed to it in the IR calls constructed by 58f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj guest-amd64/toIR.c. 59f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 60f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj The convention used is that all functions called from generated 61f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj code are named amd64g_<something>, and any function whose name lacks 62f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj that prefix is not called from generated code. Note that some 63f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj LibVEX_* functions can however be called by VEX's client, but that 64f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj is not the same as calling them from VEX-generated code. 65f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj*/ 66f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 67f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 68f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* Set to 1 to get detailed profiling info about use of the flag 69f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj machinery. */ 70f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define PROFILE_RFLAGS 0 71f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 72f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 73f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 74f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- %rflags run-time helpers. ---*/ 75f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 76f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 771a01e65f9993d97095c2af463e98674a091834casewardj/* Do 64x64 -> 128 signed/unsigned multiplies, for computing flags 781a01e65f9993d97095c2af463e98674a091834casewardj after imulq/mulq. */ 791a01e65f9993d97095c2af463e98674a091834casewardj 801a01e65f9993d97095c2af463e98674a091834casewardjstatic void mullS64 ( Long u, Long v, Long* rHi, Long* rLo ) 811a01e65f9993d97095c2af463e98674a091834casewardj{ 82095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj const Long halfMask = 0xFFFFFFFFLL; 831a01e65f9993d97095c2af463e98674a091834casewardj ULong u0, v0, w0; 841a01e65f9993d97095c2af463e98674a091834casewardj Long u1, v1, w1, w2, t; 85095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj u0 = u & halfMask; 861a01e65f9993d97095c2af463e98674a091834casewardj u1 = u >> 32; 87095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj v0 = v & halfMask; 881a01e65f9993d97095c2af463e98674a091834casewardj v1 = v >> 32; 891a01e65f9993d97095c2af463e98674a091834casewardj w0 = u0 * v0; 901a01e65f9993d97095c2af463e98674a091834casewardj t = u1 * v0 + (w0 >> 32); 91095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj w1 = t & halfMask; 921a01e65f9993d97095c2af463e98674a091834casewardj w2 = t >> 32; 931a01e65f9993d97095c2af463e98674a091834casewardj w1 = u0 * v1 + w1; 941a01e65f9993d97095c2af463e98674a091834casewardj *rHi = u1 * v1 + w2 + (w1 >> 32); 95095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj *rLo = (Long)((ULong)u * (ULong)v); 961a01e65f9993d97095c2af463e98674a091834casewardj} 971a01e65f9993d97095c2af463e98674a091834casewardj 981a01e65f9993d97095c2af463e98674a091834casewardjstatic void mullU64 ( ULong u, ULong v, ULong* rHi, ULong* rLo ) 991a01e65f9993d97095c2af463e98674a091834casewardj{ 100095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj const ULong halfMask = 0xFFFFFFFFULL; 1011a01e65f9993d97095c2af463e98674a091834casewardj ULong u0, v0, w0; 1021a01e65f9993d97095c2af463e98674a091834casewardj ULong u1, v1, w1,w2,t; 103095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj u0 = u & halfMask; 1041a01e65f9993d97095c2af463e98674a091834casewardj u1 = u >> 32; 105095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj v0 = v & halfMask; 1061a01e65f9993d97095c2af463e98674a091834casewardj v1 = v >> 32; 1071a01e65f9993d97095c2af463e98674a091834casewardj w0 = u0 * v0; 1081a01e65f9993d97095c2af463e98674a091834casewardj t = u1 * v0 + (w0 >> 32); 109095b4cbfbf9c7c88a66da949cc4cfc8888caae8dsewardj w1 = t & halfMask; 1101a01e65f9993d97095c2af463e98674a091834casewardj w2 = t >> 32; 1111a01e65f9993d97095c2af463e98674a091834casewardj w1 = u0 * v1 + w1; 1121a01e65f9993d97095c2af463e98674a091834casewardj *rHi = u1 * v1 + w2 + (w1 >> 32); 1131a01e65f9993d97095c2af463e98674a091834casewardj *rLo = u * v; 1141a01e65f9993d97095c2af463e98674a091834casewardj} 1151a01e65f9993d97095c2af463e98674a091834casewardj 1161a01e65f9993d97095c2af463e98674a091834casewardj 117f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic const UChar parity_table[256] = { 118f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 119f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 120f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 121f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 122f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 123f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 124f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 125f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 126f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 127f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 128f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 129f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 130f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 131f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 132f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 133f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 134f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 135f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 136f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 137f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 138f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 139f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 140f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 141f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 142f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 143f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 144f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 145f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 146f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 147f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 148f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 149f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 150f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj}; 151f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 1524a6f3844a29aebc9774ab0d71418421c14ba9c41sewardj/* generalised left-shifter */ 1531fa7b8031dea649db2f3b99b407d5a9a036dacdasewardjstatic inline Long lshift ( Long x, Int n ) 154f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 155f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (n >= 0) 156108e03fcb0a4ef42164235b1988aa540aa1e5298florian return (ULong)x << n; 157f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj else 158f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return x >> (-n); 159f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 160f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 1611fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj/* identity on ULong */ 1621fa7b8031dea649db2f3b99b407d5a9a036dacdasewardjstatic inline ULong idULong ( ULong x ) 1631fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj{ 1641fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj return x; 1651fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj} 1661fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj 167f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 168f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define PREAMBLE(__data_bits) \ 169f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* const */ ULong DATA_MASK \ 170f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj = __data_bits==8 \ 171f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ? 0xFFULL \ 172f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj : (__data_bits==16 \ 173f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ? 0xFFFFULL \ 174f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj : (__data_bits==32 \ 175f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ? 0xFFFFFFFFULL \ 176f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj : 0xFFFFFFFFFFFFFFFFULL)); \ 177f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* const */ ULong SIGN_MASK = 1ULL << (__data_bits - 1); \ 178f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* const */ ULong CC_DEP1 = cc_dep1_formal; \ 179f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* const */ ULong CC_DEP2 = cc_dep2_formal; \ 180f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* const */ ULong CC_NDEP = cc_ndep_formal; \ 181f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* Four bogus assignments, which hopefully gcc can */ \ 182f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* optimise away, and which stop it complaining about */ \ 183f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* unused variables. */ \ 184f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj SIGN_MASK = SIGN_MASK; \ 185f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj DATA_MASK = DATA_MASK; \ 186f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj CC_DEP2 = CC_DEP2; \ 187f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj CC_NDEP = CC_NDEP; 188f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 189f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 190f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 191f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 192f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE) \ 193f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 194f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 195108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 196108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, res; \ 197f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = CC_DEP1; \ 198f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = CC_DEP2; \ 199f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = argL + argR; \ 200f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 201f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 202f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 203f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 204f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 205f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 206f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 207f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 208f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 209f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 210f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 211f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 212f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 213f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE) \ 214f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 215f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 216108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 217108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, res; \ 218f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = CC_DEP1; \ 219f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = CC_DEP2; \ 220f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = argL - argR; \ 221f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 222f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 223f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 224f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 225f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 226f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift((argL ^ argR) & (argL ^ res), \ 227f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 228f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 229f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 230f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 231f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 232f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 233f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 234f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE) \ 235f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 236f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 237108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 238108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, oldC, res; \ 239f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj oldC = CC_NDEP & AMD64G_CC_MASK_C; \ 240f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = CC_DEP1; \ 241f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = CC_DEP2 ^ oldC; \ 242f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = (argL + argR) + oldC; \ 243f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (oldC) \ 244f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 245f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj else \ 246f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 247f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 248f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 249f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 250f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 251f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 252f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 253f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 254f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 255f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 256f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 257f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 258f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 259f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE) \ 260f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 261f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 262108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 263108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, oldC, res; \ 264f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj oldC = CC_NDEP & AMD64G_CC_MASK_C; \ 265f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = CC_DEP1; \ 266f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = CC_DEP2 ^ oldC; \ 267f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = (argL - argR) - oldC; \ 268f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (oldC) \ 269f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR; \ 270f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj else \ 271f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 272f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 273f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 274f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 275f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 276f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift((argL ^ argR) & (argL ^ res), \ 277f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 278f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 279f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 280f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 281f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 282f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 283f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 284f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE) \ 285f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 286f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 287108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 288f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = 0; \ 289f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)CC_DEP1]; \ 290f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = 0; \ 291f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 292f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 293f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = 0; \ 294f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 295f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 296f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 297f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 298f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 299f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 300f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_INC(DATA_BITS,DATA_UTYPE) \ 301f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 302f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 303108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 304108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, res; \ 305f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = CC_DEP1; \ 306f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = res - 1; \ 307f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = 1; \ 308f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = CC_NDEP & AMD64G_CC_MASK_C; \ 309f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 310f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 311f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 312f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 313f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = ((res & DATA_MASK) == SIGN_MASK) << 11; \ 314f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 315f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 316f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 317f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 318f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 319f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 320f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE) \ 321f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 322f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 323108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 324108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong argL, argR, res; \ 325f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj res = CC_DEP1; \ 326f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argL = res + 1; \ 327f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj argR = 1; \ 328f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = CC_NDEP & AMD64G_CC_MASK_C; \ 329f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)res]; \ 330f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = (res ^ argL ^ argR) & 0x10; \ 331f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)res == 0) << 6; \ 332f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 333f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = ((res & DATA_MASK) \ 334f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj == ((ULong)SIGN_MASK - 1)) << 11; \ 335f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 336f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 337f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 338f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 339f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 340f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 341f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE) \ 342f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 343f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 344108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 345f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (CC_DEP2 >> (DATA_BITS - 1)) & AMD64G_CC_MASK_C; \ 346f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)CC_DEP1]; \ 347f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = 0; /* undefined */ \ 348f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 349f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 350f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* of is defined if shift count == 1 */ \ 351f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 352f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj & AMD64G_CC_MASK_O; \ 353f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 354f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 355f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 356f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 357f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 358f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 359f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE) \ 360f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 361f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 362108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 363f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = CC_DEP2 & 1; \ 364f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)CC_DEP1]; \ 365f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = 0; /* undefined */ \ 366f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 367f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 368f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* of is defined if shift count == 1 */ \ 369f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 370f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj & AMD64G_CC_MASK_O; \ 371f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 372f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 373f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 374f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 375f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 376f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 377f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* ROL: cf' = lsb(result). of' = msb(result) ^ lsb(result). */ 378f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* DEP1 = result, NDEP = old flags */ 379f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE) \ 380f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 381f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 382108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong fl \ 383f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj = (CC_NDEP & ~(AMD64G_CC_MASK_O | AMD64G_CC_MASK_C)) \ 3847de0d3c800437fbd82c59d57d156f4823d67609fsewardj | (AMD64G_CC_MASK_C & CC_DEP1) \ 385f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj | (AMD64G_CC_MASK_O & (lshift(CC_DEP1, \ 386f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 11-(DATA_BITS-1)) \ 387f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ^ lshift(CC_DEP1, 11))); \ 388f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return fl; \ 389f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 390f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 391f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 392f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 393f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 394f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* ROR: cf' = msb(result). of' = msb(result) ^ msb-1(result). */ 395f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* DEP1 = result, NDEP = old flags */ 396f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE) \ 397f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 398f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 399108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong fl \ 400f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj = (CC_NDEP & ~(AMD64G_CC_MASK_O | AMD64G_CC_MASK_C)) \ 401f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj | (AMD64G_CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1))) \ 402f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj | (AMD64G_CC_MASK_O & (lshift(CC_DEP1, \ 403f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 11-(DATA_BITS-1)) \ 404f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1))); \ 405f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return fl; \ 406f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 407f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 408f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 409f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 410f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4111fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj#define ACTIONS_UMUL(DATA_BITS, DATA_UTYPE, NARROWtoU, \ 4121fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_U2TYPE, NARROWto2U) \ 413f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 414f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 415108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 416f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj DATA_UTYPE hi; \ 4171fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_UTYPE lo \ 4181fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ 4191fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj * ((DATA_UTYPE)CC_DEP2) ); \ 4201fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_U2TYPE rr \ 4211fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj = NARROWto2U( \ 4221fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ 4231fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ 4241fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ 425f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (hi != 0); \ 426f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)lo]; \ 427f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = 0; /* undefined */ \ 428f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = (lo == 0) << 6; \ 429f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 430f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = cf << 11; \ 431f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 432f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 433f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 434f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 435f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*-------------------------------------------------------------*/ 436f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4371fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ 4381fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_S2TYPE, NARROWto2S) \ 439f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ \ 440f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj PREAMBLE(DATA_BITS); \ 441108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 442f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj DATA_STYPE hi; \ 4431fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_STYPE lo \ 44445f8de626643cea67d0741f2b8a0b33dc69cbf84florian = NARROWtoS( ((DATA_S2TYPE)(DATA_STYPE)CC_DEP1) \ 44545f8de626643cea67d0741f2b8a0b33dc69cbf84florian * ((DATA_S2TYPE)(DATA_STYPE)CC_DEP2) ); \ 4461fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj DATA_S2TYPE rr \ 4471fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj = NARROWto2S( \ 4481fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ 4491fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ 4501fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ 451f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ 452f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = parity_table[(UChar)lo]; \ 453f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj af = 0; /* undefined */ \ 454f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = (lo == 0) << 6; \ 455f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 456f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = cf << 11; \ 457f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cf | pf | af | zf | sf | of; \ 458f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } \ 459f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 460f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4611a01e65f9993d97095c2af463e98674a091834casewardj/*-------------------------------------------------------------*/ 4621a01e65f9993d97095c2af463e98674a091834casewardj 4631a01e65f9993d97095c2af463e98674a091834casewardj#define ACTIONS_UMULQ \ 4641a01e65f9993d97095c2af463e98674a091834casewardj{ \ 4651a01e65f9993d97095c2af463e98674a091834casewardj PREAMBLE(64); \ 466108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 4671a01e65f9993d97095c2af463e98674a091834casewardj ULong lo, hi; \ 4681a01e65f9993d97095c2af463e98674a091834casewardj mullU64( (ULong)CC_DEP1, (ULong)CC_DEP2, &hi, &lo ); \ 4691a01e65f9993d97095c2af463e98674a091834casewardj cf = (hi != 0); \ 4701a01e65f9993d97095c2af463e98674a091834casewardj pf = parity_table[(UChar)lo]; \ 4711a01e65f9993d97095c2af463e98674a091834casewardj af = 0; /* undefined */ \ 4721a01e65f9993d97095c2af463e98674a091834casewardj zf = (lo == 0) << 6; \ 4731a01e65f9993d97095c2af463e98674a091834casewardj sf = lshift(lo, 8 - 64) & 0x80; \ 4741a01e65f9993d97095c2af463e98674a091834casewardj of = cf << 11; \ 4751a01e65f9993d97095c2af463e98674a091834casewardj return cf | pf | af | zf | sf | of; \ 4761a01e65f9993d97095c2af463e98674a091834casewardj } \ 4771a01e65f9993d97095c2af463e98674a091834casewardj} 4781a01e65f9993d97095c2af463e98674a091834casewardj 4791a01e65f9993d97095c2af463e98674a091834casewardj/*-------------------------------------------------------------*/ 4801a01e65f9993d97095c2af463e98674a091834casewardj 4811a01e65f9993d97095c2af463e98674a091834casewardj#define ACTIONS_SMULQ \ 4821a01e65f9993d97095c2af463e98674a091834casewardj{ \ 4831a01e65f9993d97095c2af463e98674a091834casewardj PREAMBLE(64); \ 484108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 4851a01e65f9993d97095c2af463e98674a091834casewardj Long lo, hi; \ 4861a01e65f9993d97095c2af463e98674a091834casewardj mullS64( (Long)CC_DEP1, (Long)CC_DEP2, &hi, &lo ); \ 4871a01e65f9993d97095c2af463e98674a091834casewardj cf = (hi != (lo >>/*s*/ (64-1))); \ 4881a01e65f9993d97095c2af463e98674a091834casewardj pf = parity_table[(UChar)lo]; \ 4891a01e65f9993d97095c2af463e98674a091834casewardj af = 0; /* undefined */ \ 4901a01e65f9993d97095c2af463e98674a091834casewardj zf = (lo == 0) << 6; \ 4911a01e65f9993d97095c2af463e98674a091834casewardj sf = lshift(lo, 8 - 64) & 0x80; \ 4921a01e65f9993d97095c2af463e98674a091834casewardj of = cf << 11; \ 4931a01e65f9993d97095c2af463e98674a091834casewardj return cf | pf | af | zf | sf | of; \ 4941a01e65f9993d97095c2af463e98674a091834casewardj } \ 4951a01e65f9993d97095c2af463e98674a091834casewardj} 4961a01e65f9993d97095c2af463e98674a091834casewardj 497cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/*-------------------------------------------------------------*/ 498cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 499cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj#define ACTIONS_ANDN(DATA_BITS,DATA_UTYPE) \ 500cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ \ 501cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj PREAMBLE(DATA_BITS); \ 502108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 503cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj cf = 0; \ 504cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj pf = 0; \ 505cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj af = 0; \ 506cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 507cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 508cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj of = 0; \ 509cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return cf | pf | af | zf | sf | of; \ 510cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } \ 511cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 512cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 513cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/*-------------------------------------------------------------*/ 514cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 515cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj#define ACTIONS_BLSI(DATA_BITS,DATA_UTYPE) \ 516cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ \ 517cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj PREAMBLE(DATA_BITS); \ 518108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 519cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj cf = ((DATA_UTYPE)CC_DEP2 != 0); \ 520cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj pf = 0; \ 521cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj af = 0; \ 522cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 523cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 524cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj of = 0; \ 525cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return cf | pf | af | zf | sf | of; \ 526cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } \ 527cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 528cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 529cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/*-------------------------------------------------------------*/ 530cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 531cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj#define ACTIONS_BLSMSK(DATA_BITS,DATA_UTYPE) \ 532cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ \ 533cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj PREAMBLE(DATA_BITS); \ 534cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj { Long cf, pf, af, zf, sf, of; \ 535cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj cf = ((DATA_UTYPE)CC_DEP2 == 0); \ 536cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj pf = 0; \ 537cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj af = 0; \ 538cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj zf = 0; \ 539cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 540cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj of = 0; \ 541cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return cf | pf | af | zf | sf | of; \ 542cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } \ 543cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 544cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 545cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/*-------------------------------------------------------------*/ 546cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 547cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj#define ACTIONS_BLSR(DATA_BITS,DATA_UTYPE) \ 548cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ \ 549cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj PREAMBLE(DATA_BITS); \ 550108e03fcb0a4ef42164235b1988aa540aa1e5298florian { ULong cf, pf, af, zf, sf, of; \ 551cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj cf = ((DATA_UTYPE)CC_DEP2 == 0); \ 552cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj pf = 0; \ 553cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj af = 0; \ 554cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 555cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 556cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj of = 0; \ 557cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return cf | pf | af | zf | sf | of; \ 558cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } \ 559cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 560cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 561cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/*-------------------------------------------------------------*/ 562cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 563ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#define ACTIONS_ADX(DATA_BITS,DATA_UTYPE,FLAGNAME) \ 564ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes{ \ 565ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes PREAMBLE(DATA_BITS); \ 566ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes { ULong ocf; /* o or c */ \ 567ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes ULong argL, argR, oldOC, res; \ 568ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes oldOC = (CC_NDEP >> AMD64G_CC_SHIFT_##FLAGNAME) & 1; \ 569ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes argL = CC_DEP1; \ 570ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes argR = CC_DEP2 ^ oldOC; \ 571ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes res = (argL + argR) + oldOC; \ 572ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (oldOC) \ 573ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes ocf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 574ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes else \ 575ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes ocf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 576ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return (CC_NDEP & ~AMD64G_CC_MASK_##FLAGNAME) \ 577ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes | (ocf << AMD64G_CC_SHIFT_##FLAGNAME); \ 578ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } \ 579ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes} 580ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 581ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes/*-------------------------------------------------------------*/ 582ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 583f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 5841fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj#if PROFILE_RFLAGS 585f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 586f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic Bool initted = False; 587f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 588f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* C flag, fast route */ 589f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt tabc_fast[AMD64G_CC_OP_NUMBER]; 590f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* C flag, slow route */ 591f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt tabc_slow[AMD64G_CC_OP_NUMBER]; 592f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* table for calculate_cond */ 593f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt tab_cond[AMD64G_CC_OP_NUMBER][16]; 594f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* total entry counts for calc_all, calc_c, calc_cond. */ 595f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt n_calc_all = 0; 596f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt n_calc_c = 0; 597f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic UInt n_calc_cond = 0; 598f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 599f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond))) 600f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 601f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 602f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic void showCounts ( void ) 603f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 604f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Int op, co; 6055df8ab0739ec95e8de9d9f43fa0e68b3e7125554florian HChar ch; 6061fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", 607f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj n_calc_all, n_calc_cond, n_calc_c); 608f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 609f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" 610f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj " S NS P NP L NL LE NLE\n"); 611f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf(" -----------------------------------------------------" 612f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj "----------------------------------------\n"); 613f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj for (op = 0; op < AMD64G_CC_OP_NUMBER; op++) { 614f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 615f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ch = ' '; 6160354035b9222b1d6e37172ac2a70b19c816df025sewardj if (op > 0 && (op-1) % 4 == 0) 617f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ch = 'B'; 6180354035b9222b1d6e37172ac2a70b19c816df025sewardj if (op > 0 && (op-1) % 4 == 1) 619f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ch = 'W'; 6200354035b9222b1d6e37172ac2a70b19c816df025sewardj if (op > 0 && (op-1) % 4 == 2) 621f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ch = 'L'; 6220354035b9222b1d6e37172ac2a70b19c816df025sewardj if (op > 0 && (op-1) % 4 == 3) 6230354035b9222b1d6e37172ac2a70b19c816df025sewardj ch = 'Q'; 624f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 625f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf("%2d%c: ", op, ch); 6261fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj vex_printf("%6u ", tabc_slow[op]); 6271fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj vex_printf("%6u ", tabc_fast[op]); 628f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj for (co = 0; co < 16; co++) { 629f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Int n = tab_cond[op][co]; 630f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (n >= 1000) { 631f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf(" %3dK", n / 1000); 632f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } else 633f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (n >= 0) { 634f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf(" %3d ", n ); 635f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } else { 636f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf(" "); 637f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 638f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 639f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf("\n"); 640f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 641f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf("\n"); 642f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 643f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 644f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic void initCounts ( void ) 645f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 646f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Int op, co; 647f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj initted = True; 648f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj for (op = 0; op < AMD64G_CC_OP_NUMBER; op++) { 649f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tabc_fast[op] = tabc_slow[op] = 0; 650f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj for (co = 0; co < 16; co++) 651f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tab_cond[op][co] = 0; 652f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 653f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 654f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 6551fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj#endif /* PROFILE_RFLAGS */ 656f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 657f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 658f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 659f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* Calculate all the 6 flags from the supplied thunk parameters. 660f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj Worker function, not directly called from generated code. */ 661f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjstatic 662f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjULong amd64g_calculate_rflags_all_WRK ( ULong cc_op, 663f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep1_formal, 664f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep2_formal, 665f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_ndep_formal ) 666118b23eb9e0d86e8d0f7e1a347134ec00ae5f821sewardj{ 667f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj switch (cc_op) { 668f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_COPY: 669f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return cc_dep1_formal 670f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj & (AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z 671f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P); 672f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 673f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); 674f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); 675f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); 676d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case AMD64G_CC_OP_ADDQ: ACTIONS_ADD( 64, ULong ); 677f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 678f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); 679f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); 680f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); 68185520e44c14bebadea604ba9ba32113b55988227sewardj case AMD64G_CC_OP_ADCQ: ACTIONS_ADC( 64, ULong ); 682f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 683f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); 684f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); 685f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); 686f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SUBQ: ACTIONS_SUB( 64, ULong ); 687f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 688f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); 689f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); 690f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); 69185520e44c14bebadea604ba9ba32113b55988227sewardj case AMD64G_CC_OP_SBBQ: ACTIONS_SBB( 64, ULong ); 692f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 693f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); 694f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); 695f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); 696f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICQ: ACTIONS_LOGIC( 64, ULong ); 697f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 698f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); 699f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); 700f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); 7017de0d3c800437fbd82c59d57d156f4823d67609fsewardj case AMD64G_CC_OP_INCQ: ACTIONS_INC( 64, ULong ); 702f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 703f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); 704f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); 705f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); 7067de0d3c800437fbd82c59d57d156f4823d67609fsewardj case AMD64G_CC_OP_DECQ: ACTIONS_DEC( 64, ULong ); 707f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 708f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); 709f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); 710f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); 7117de0d3c800437fbd82c59d57d156f4823d67609fsewardj case AMD64G_CC_OP_SHLQ: ACTIONS_SHL( 64, ULong ); 712f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 713f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); 714f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); 715f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); 716a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj case AMD64G_CC_OP_SHRQ: ACTIONS_SHR( 64, ULong ); 717f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 718f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); 719f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); 720f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); 72185520e44c14bebadea604ba9ba32113b55988227sewardj case AMD64G_CC_OP_ROLQ: ACTIONS_ROL( 64, ULong ); 722f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 723f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); 724f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); 725f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); 72685520e44c14bebadea604ba9ba32113b55988227sewardj case AMD64G_CC_OP_RORQ: ACTIONS_ROR( 64, ULong ); 727f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 7281fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, 7291fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj UShort, toUShort ); 7301fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, 7311fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj UInt, toUInt ); 7321fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, 7331fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj ULong, idULong ); 7341fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj 7358bdb89a30baf14230e483916deaf1eaaf92d3d34sewardj case AMD64G_CC_OP_UMULQ: ACTIONS_UMULQ; 7368bdb89a30baf14230e483916deaf1eaaf92d3d34sewardj 7371fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, 7381fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj Short, toUShort ); 7391fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, 7401fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj Int, toUInt ); 7411fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj case AMD64G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, 7421fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj Long, idULong ); 743f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 7441a01e65f9993d97095c2af463e98674a091834casewardj case AMD64G_CC_OP_SMULQ: ACTIONS_SMULQ; 745f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 746cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_ANDN32: ACTIONS_ANDN( 32, UInt ); 747cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_ANDN64: ACTIONS_ANDN( 64, ULong ); 748cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 749cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSI32: ACTIONS_BLSI( 32, UInt ); 750cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSI64: ACTIONS_BLSI( 64, ULong ); 751cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 752cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSMSK32: ACTIONS_BLSMSK( 32, UInt ); 753cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSMSK64: ACTIONS_BLSMSK( 64, ULong ); 754cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 755cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSR32: ACTIONS_BLSR( 32, UInt ); 756cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj case AMD64G_CC_OP_BLSR64: ACTIONS_BLSR( 64, ULong ); 757cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 758ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case AMD64G_CC_OP_ADCX32: ACTIONS_ADX( 32, UInt, C ); 759ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case AMD64G_CC_OP_ADCX64: ACTIONS_ADX( 64, ULong, C ); 760ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 761ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case AMD64G_CC_OP_ADOX32: ACTIONS_ADX( 32, UInt, O ); 762ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case AMD64G_CC_OP_ADOX64: ACTIONS_ADX( 64, ULong, O ); 763ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 764f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj default: 765f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* shouldn't really make these calls from generated code */ 766f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf("amd64g_calculate_rflags_all_WRK(AMD64)" 7671fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj "( %llu, 0x%llx, 0x%llx, 0x%llx )\n", 768f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); 769f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vpanic("amd64g_calculate_rflags_all_WRK(AMD64)"); 770f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 771f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 772f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 773f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 774f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 775f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* Calculate all the 6 flags from the supplied thunk parameters. */ 776f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjULong amd64g_calculate_rflags_all ( ULong cc_op, 777f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep1, 778f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep2, 779f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_ndep ) 780f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 7811fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj# if PROFILE_RFLAGS 782f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (!initted) initCounts(); 783f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj n_calc_all++; 784f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (SHOW_COUNTS_NOW) showCounts(); 785f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# endif 786f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 787f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj amd64g_calculate_rflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep ); 788f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 789f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 790f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 791f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 792f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* Calculate just the carry flag from the supplied thunk parameters. */ 793f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjULong amd64g_calculate_rflags_c ( ULong cc_op, 794f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep1, 795f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep2, 796f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_ndep ) 797f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 7981fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj# if PROFILE_RFLAGS 799f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (!initted) initCounts(); 800f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj n_calc_c++; 801f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tabc_fast[cc_op]++; 802f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (SHOW_COUNTS_NOW) showCounts(); 803f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# endif 804f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 805f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* Fast-case some common ones. */ 806f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj switch (cc_op) { 8077fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj case AMD64G_CC_OP_COPY: 8087fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj return (cc_dep1 >> AMD64G_CC_SHIFT_C) & 1; 8090354035b9222b1d6e37172ac2a70b19c816df025sewardj case AMD64G_CC_OP_LOGICQ: 810f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICL: 811f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICW: 812f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64G_CC_OP_LOGICB: 813f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 0; 8140354035b9222b1d6e37172ac2a70b19c816df025sewardj // case AMD64G_CC_OP_SUBL: 8150354035b9222b1d6e37172ac2a70b19c816df025sewardj // return ((UInt)cc_dep1) < ((UInt)cc_dep2) 8160354035b9222b1d6e37172ac2a70b19c816df025sewardj // ? AMD64G_CC_MASK_C : 0; 8170354035b9222b1d6e37172ac2a70b19c816df025sewardj // case AMD64G_CC_OP_SUBW: 8180354035b9222b1d6e37172ac2a70b19c816df025sewardj // return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) 8190354035b9222b1d6e37172ac2a70b19c816df025sewardj // ? AMD64G_CC_MASK_C : 0; 8200354035b9222b1d6e37172ac2a70b19c816df025sewardj // case AMD64G_CC_OP_SUBB: 8210354035b9222b1d6e37172ac2a70b19c816df025sewardj // return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) 8220354035b9222b1d6e37172ac2a70b19c816df025sewardj // ? AMD64G_CC_MASK_C : 0; 8230354035b9222b1d6e37172ac2a70b19c816df025sewardj // case AMD64G_CC_OP_INCL: 8240354035b9222b1d6e37172ac2a70b19c816df025sewardj // case AMD64G_CC_OP_DECL: 8250354035b9222b1d6e37172ac2a70b19c816df025sewardj // return cc_ndep & AMD64G_CC_MASK_C; 826f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj default: 827f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj break; 828f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 829f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 8301fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj# if PROFILE_RFLAGS 831f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tabc_fast[cc_op]--; 832f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tabc_slow[cc_op]++; 833f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# endif 834f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 835f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return amd64g_calculate_rflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) 836f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj & AMD64G_CC_MASK_C; 837118b23eb9e0d86e8d0f7e1a347134ec00ae5f821sewardj} 838118b23eb9e0d86e8d0f7e1a347134ec00ae5f821sewardj 839118b23eb9e0d86e8d0f7e1a347134ec00ae5f821sewardj 840f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 841f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* returns 1 or 0 */ 842f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjULong amd64g_calculate_condition ( ULong/*AMD64Condcode*/ cond, 843f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_op, 844f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep1, 845f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_dep2, 846f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong cc_ndep ) 847df0e002ac9be60d99aef2e2cfc1801d5d734ae9bsewardj{ 848f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong rflags = amd64g_calculate_rflags_all_WRK(cc_op, cc_dep1, 849f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cc_dep2, cc_ndep); 850f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong of,sf,zf,cf,pf; 851f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong inv = cond & 1; 852f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 8531fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj# if PROFILE_RFLAGS 854f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (!initted) initCounts(); 855f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj tab_cond[cc_op][cond]++; 856f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj n_calc_cond++; 857f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj if (SHOW_COUNTS_NOW) showCounts(); 858f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# endif 859f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 860f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj switch (cond) { 861f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNO: 862f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondO: /* OF == 1 */ 863f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = rflags >> AMD64G_CC_SHIFT_O; 864f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ of); 865f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 866f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNZ: 867f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondZ: /* ZF == 1 */ 868f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = rflags >> AMD64G_CC_SHIFT_Z; 869f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ zf); 870f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 871f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNB: 872f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondB: /* CF == 1 */ 873f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = rflags >> AMD64G_CC_SHIFT_C; 874f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ cf); 875f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj break; 876f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 877f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNBE: 878f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondBE: /* (CF or ZF) == 1 */ 879f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cf = rflags >> AMD64G_CC_SHIFT_C; 880f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = rflags >> AMD64G_CC_SHIFT_Z; 881f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ (cf | zf)); 882f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj break; 883f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 884f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNS: 885f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondS: /* SF == 1 */ 886f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = rflags >> AMD64G_CC_SHIFT_S; 887f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ sf); 888f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 889f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNP: 890f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondP: /* PF == 1 */ 891f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj pf = rflags >> AMD64G_CC_SHIFT_P; 892f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ pf); 893f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 894f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNL: 895f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondL: /* (SF xor OF) == 1 */ 896f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = rflags >> AMD64G_CC_SHIFT_S; 897f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = rflags >> AMD64G_CC_SHIFT_O; 898f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ (sf ^ of)); 899f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj break; 900f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 901f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondNLE: 902f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj case AMD64CondLE: /* ((SF xor OF) or ZF) == 1 */ 903f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj sf = rflags >> AMD64G_CC_SHIFT_S; 904f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj of = rflags >> AMD64G_CC_SHIFT_O; 905f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj zf = rflags >> AMD64G_CC_SHIFT_Z; 906f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return 1 & (inv ^ ((sf ^ of) | zf)); 907f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj break; 908f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 909f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj default: 910f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj /* shouldn't really make these calls from generated code */ 911f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_printf("amd64g_calculate_condition" 9121fa7b8031dea649db2f3b99b407d5a9a036dacdasewardj "( %llu, %llu, 0x%llx, 0x%llx, 0x%llx )\n", 913f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); 914f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vpanic("amd64g_calculate_condition"); 915f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj } 916df0e002ac9be60d99aef2e2cfc1801d5d734ae9bsewardj} 91744d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 918f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 919f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* VISIBLE TO LIBVEX CLIENT */ 920efa834abaded25c8aff2f3923e476ef7cc1d0396florianULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state ) 921354e5c6a228cbd811c1267adda79509500da158esewardj{ 922f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ULong rflags = amd64g_calculate_rflags_all_WRK( 923f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_OP, 924f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_DEP1, 925f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_DEP2, 926f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_NDEP 927f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj ); 9287de0d3c800437fbd82c59d57d156f4823d67609fsewardj Long dflag = vex_state->guest_DFLAG; 9297de0d3c800437fbd82c59d57d156f4823d67609fsewardj vassert(dflag == 1 || dflag == -1); 9307de0d3c800437fbd82c59d57d156f4823d67609fsewardj if (dflag == -1) 931f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj rflags |= (1<<10); 93285520e44c14bebadea604ba9ba32113b55988227sewardj if (vex_state->guest_IDFLAG == 1) 93385520e44c14bebadea604ba9ba32113b55988227sewardj rflags |= (1<<21); 9345e120aaf7b9e659ecbc641dc1e20e40b2219618esewardj if (vex_state->guest_ACFLAG == 1) 9355e120aaf7b9e659ecbc641dc1e20e40b2219618esewardj rflags |= (1<<18); 9365e120aaf7b9e659ecbc641dc1e20e40b2219618esewardj 937f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return rflags; 938354e5c6a228cbd811c1267adda79509500da158esewardj} 939f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 940d660d41d4174e44f284bad3264601662ed68d4a1sewardj/* VISIBLE TO LIBVEX CLIENT */ 941d660d41d4174e44f284bad3264601662ed68d4a1sewardjvoid 9423e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardjLibVEX_GuestAMD64_put_rflags ( ULong rflags, 9433e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj /*MOD*/VexGuestAMD64State* vex_state ) 9443e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj{ 9453e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj /* D flag */ 9463e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj if (rflags & AMD64G_CC_MASK_D) { 9473e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_DFLAG = -1; 9483e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj rflags &= ~AMD64G_CC_MASK_D; 9493e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj } 9503e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj else 9513e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_DFLAG = 1; 9523e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj 9533e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj /* ID flag */ 9543e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj if (rflags & AMD64G_CC_MASK_ID) { 9553e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_IDFLAG = 1; 9563e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj rflags &= ~AMD64G_CC_MASK_ID; 9573e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj } 9583e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj else 9593e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_IDFLAG = 0; 9603e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj 9613e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj /* AC flag */ 9623e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj if (rflags & AMD64G_CC_MASK_AC) { 9633e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_ACFLAG = 1; 9643e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj rflags &= ~AMD64G_CC_MASK_AC; 9653e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj } 9663e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj else 9673e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_ACFLAG = 0; 9683e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj 9693e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj UInt cc_mask = AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z | 9703e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P; 9713e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_CC_OP = AMD64G_CC_OP_COPY; 9723e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_CC_DEP1 = rflags & cc_mask; 9733e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_CC_DEP2 = 0; 9743e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj vex_state->guest_CC_NDEP = 0; 9753e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj} 9763e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj 9773e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj/* VISIBLE TO LIBVEX CLIENT */ 9783e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardjvoid 979d660d41d4174e44f284bad3264601662ed68d4a1sewardjLibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag, 980d660d41d4174e44f284bad3264601662ed68d4a1sewardj /*MOD*/VexGuestAMD64State* vex_state ) 981d660d41d4174e44f284bad3264601662ed68d4a1sewardj{ 982d660d41d4174e44f284bad3264601662ed68d4a1sewardj ULong oszacp = amd64g_calculate_rflags_all_WRK( 983d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_OP, 984d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_DEP1, 985d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_DEP2, 986d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_NDEP 987d660d41d4174e44f284bad3264601662ed68d4a1sewardj ); 988d660d41d4174e44f284bad3264601662ed68d4a1sewardj if (new_carry_flag & 1) { 989d660d41d4174e44f284bad3264601662ed68d4a1sewardj oszacp |= AMD64G_CC_MASK_C; 990d660d41d4174e44f284bad3264601662ed68d4a1sewardj } else { 991d660d41d4174e44f284bad3264601662ed68d4a1sewardj oszacp &= ~AMD64G_CC_MASK_C; 992d660d41d4174e44f284bad3264601662ed68d4a1sewardj } 993d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_OP = AMD64G_CC_OP_COPY; 994d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_DEP1 = oszacp; 995d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_DEP2 = 0; 996d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_CC_NDEP = 0; 997d660d41d4174e44f284bad3264601662ed68d4a1sewardj} 998d660d41d4174e44f284bad3264601662ed68d4a1sewardj 999f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 1000f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 1001f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- %rflags translation-time function specialisers. ---*/ 1002f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- These help iropt specialise calls the above run-time ---*/ 1003f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- %rflags functions. ---*/ 1004f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 1005354e5c6a228cbd811c1267adda79509500da158esewardj 10060354035b9222b1d6e37172ac2a70b19c816df025sewardj/* Used by the optimiser to try specialisations. Returns an 10070354035b9222b1d6e37172ac2a70b19c816df025sewardj equivalent expression, or NULL if none. */ 10080354035b9222b1d6e37172ac2a70b19c816df025sewardj 10090354035b9222b1d6e37172ac2a70b19c816df025sewardjstatic Bool isU64 ( IRExpr* e, ULong n ) 10100354035b9222b1d6e37172ac2a70b19c816df025sewardj{ 101165b17c682ad74b2b0d1d6011a0ec847d25fc96a8sewardj return toBool( e->tag == Iex_Const 101265b17c682ad74b2b0d1d6011a0ec847d25fc96a8sewardj && e->Iex.Const.con->tag == Ico_U64 101365b17c682ad74b2b0d1d6011a0ec847d25fc96a8sewardj && e->Iex.Const.con->Ico.U64 == n ); 10140354035b9222b1d6e37172ac2a70b19c816df025sewardj} 1015354e5c6a228cbd811c1267adda79509500da158esewardj 10161ff4756e1731485e6bf3cd96717cd8398daec1f2florianIRExpr* guest_amd64_spechelper ( const HChar* function_name, 1017be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRExpr** args, 1018be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRStmt** precedingStmts, 1019be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj Int n_precedingStmts ) 102044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj{ 10210354035b9222b1d6e37172ac2a70b19c816df025sewardj# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 10220354035b9222b1d6e37172ac2a70b19c816df025sewardj# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 10230354035b9222b1d6e37172ac2a70b19c816df025sewardj# define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) 10249cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj# define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 10250354035b9222b1d6e37172ac2a70b19c816df025sewardj# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 10260354035b9222b1d6e37172ac2a70b19c816df025sewardj 10270354035b9222b1d6e37172ac2a70b19c816df025sewardj Int i, arity = 0; 10280354035b9222b1d6e37172ac2a70b19c816df025sewardj for (i = 0; args[i]; i++) 10290354035b9222b1d6e37172ac2a70b19c816df025sewardj arity++; 10300354035b9222b1d6e37172ac2a70b19c816df025sewardj# if 0 10310354035b9222b1d6e37172ac2a70b19c816df025sewardj vex_printf("spec request:\n"); 10320354035b9222b1d6e37172ac2a70b19c816df025sewardj vex_printf(" %s ", function_name); 10330354035b9222b1d6e37172ac2a70b19c816df025sewardj for (i = 0; i < arity; i++) { 10340354035b9222b1d6e37172ac2a70b19c816df025sewardj vex_printf(" "); 10350354035b9222b1d6e37172ac2a70b19c816df025sewardj ppIRExpr(args[i]); 10360354035b9222b1d6e37172ac2a70b19c816df025sewardj } 10370354035b9222b1d6e37172ac2a70b19c816df025sewardj vex_printf("\n"); 10380354035b9222b1d6e37172ac2a70b19c816df025sewardj# endif 10390354035b9222b1d6e37172ac2a70b19c816df025sewardj 10400354035b9222b1d6e37172ac2a70b19c816df025sewardj /* --------- specialising "amd64g_calculate_condition" --------- */ 10410354035b9222b1d6e37172ac2a70b19c816df025sewardj 10420354035b9222b1d6e37172ac2a70b19c816df025sewardj if (vex_streq(function_name, "amd64g_calculate_condition")) { 10430354035b9222b1d6e37172ac2a70b19c816df025sewardj /* specialise calls to above "calculate condition" function */ 10440354035b9222b1d6e37172ac2a70b19c816df025sewardj IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2; 10450354035b9222b1d6e37172ac2a70b19c816df025sewardj vassert(arity == 5); 10460354035b9222b1d6e37172ac2a70b19c816df025sewardj cond = args[0]; 10470354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_op = args[1]; 10480354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_dep1 = args[2]; 10490354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_dep2 = args[3]; 10500354035b9222b1d6e37172ac2a70b19c816df025sewardj 1051db261e489a4302789faccbfc17b96182051c8c3asewardj /*---------------- ADDQ ----------------*/ 1052db261e489a4302789faccbfc17b96182051c8c3asewardj 1053db261e489a4302789faccbfc17b96182051c8c3asewardj if (isU64(cc_op, AMD64G_CC_OP_ADDQ) && isU64(cond, AMD64CondZ)) { 1054db261e489a4302789faccbfc17b96182051c8c3asewardj /* long long add, then Z --> test (dst+src == 0) */ 1055db261e489a4302789faccbfc17b96182051c8c3asewardj return unop(Iop_1Uto64, 1056db261e489a4302789faccbfc17b96182051c8c3asewardj binop(Iop_CmpEQ64, 1057db261e489a4302789faccbfc17b96182051c8c3asewardj binop(Iop_Add64, cc_dep1, cc_dep2), 1058db261e489a4302789faccbfc17b96182051c8c3asewardj mkU64(0))); 1059db261e489a4302789faccbfc17b96182051c8c3asewardj } 10600354035b9222b1d6e37172ac2a70b19c816df025sewardj 1061aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /*---------------- ADDL ----------------*/ 1062aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1063aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_ADDL) && isU64(cond, AMD64CondO)) { 1064aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* This is very commonly generated by Javascript JITs, for 1065aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj the idiom "do a 32-bit add and jump to out-of-line code if 1066aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj an overflow occurs". */ 1067aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long add, then O (overflow) 1068aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dep1 ^ dep2 ^ -1) & (dep1 ^ (dep1 + dep2)))[31] 1069aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (((dep1 ^ dep2 ^ -1) & (dep1 ^ (dep1 +64 dep2))) >>u 31) & 1 1070aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (((not(dep1 ^ dep2)) & (dep1 ^ (dep1 +64 dep2))) >>u 31) & 1 1071aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj */ 1072aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep1)); 1073aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep2)); 1074aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return 1075aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1076aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shr64, 1077aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1078aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj unop(Iop_Not64, 1079aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, cc_dep1, cc_dep2)), 1080aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, 1081aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj cc_dep1, 1082aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Add64, cc_dep1, cc_dep2))), 1083aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(31)), 1084aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)); 1085aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1086aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1087aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 10884b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /*---------------- SUBQ ----------------*/ 10894b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj 1090aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 0, */ 1091aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondO)) { 1092aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long long sub/cmp, then O (overflow) 1093aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dep1 ^ dep2) & (dep1 ^ (dep1 - dep2)))[63] 1094aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dep1 ^ dep2) & (dep1 ^ (dep1 - dep2))) >>u 63 1095aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj */ 1096aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep1)); 1097aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep2)); 1098aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return binop(Iop_Shr64, 1099aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1100aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, cc_dep1, cc_dep2), 1101aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, 1102aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj cc_dep1, 1103aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2))), 1104d937bebf71808133be12831f57f47e8fd022ab91mjw mkU8(63)); 1105aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1106aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNO)) { 1107aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* No action. Never yet found a test case. */ 1108aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1109aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1110edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 2, 3 */ 11114b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondB)) { 11124b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /* long long sub/cmp, then B (unsigned less than) 11134b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj --> test dst <u src */ 11144b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj return unop(Iop_1Uto64, 11154b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 11164b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj } 1117a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNB)) { 1118a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj /* long long sub/cmp, then NB (unsigned greater than or equal) 1119a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj --> test src <=u dst */ 1120a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj /* Note, args are opposite way round from the usual */ 1121a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj return unop(Iop_1Uto64, 1122a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 1123a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj } 1124a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj 1125edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 4, 5 */ 1126edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondZ)) { 1127edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long long sub/cmp, then Z --> test dst==src */ 11283cfd1f038f2f8457f63f2731ed5a53d4544f52absewardj return unop(Iop_1Uto64, 1129edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpEQ64,cc_dep1,cc_dep2)); 1130edccb443be188091d51d7ecd984ce75e649adb16sewardj } 1131edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNZ)) { 1132edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long long sub/cmp, then NZ --> test dst!=src */ 1133edccb443be188091d51d7ecd984ce75e649adb16sewardj return unop(Iop_1Uto64, 1134edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpNE64,cc_dep1,cc_dep2)); 11353cfd1f038f2f8457f63f2731ed5a53d4544f52absewardj } 11363cfd1f038f2f8457f63f2731ed5a53d4544f52absewardj 1137edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 6, 7 */ 1138a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondBE)) { 1139a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj /* long long sub/cmp, then BE (unsigned less than or equal) 1140a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj --> test dst <=u src */ 1141a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj return unop(Iop_1Uto64, 1142a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 1143a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj } 11443a05a1543f99be21e75ed7136c45bf1a24594822sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNBE)) { 11453a05a1543f99be21e75ed7136c45bf1a24594822sewardj /* long long sub/cmp, then NBE (unsigned greater than) 11463a05a1543f99be21e75ed7136c45bf1a24594822sewardj --> test !(dst <=u src) */ 11473a05a1543f99be21e75ed7136c45bf1a24594822sewardj return binop(Iop_Xor64, 11483a05a1543f99be21e75ed7136c45bf1a24594822sewardj unop(Iop_1Uto64, 11493a05a1543f99be21e75ed7136c45bf1a24594822sewardj binop(Iop_CmpLE64U, cc_dep1, cc_dep2)), 11503a05a1543f99be21e75ed7136c45bf1a24594822sewardj mkU64(1)); 11513a05a1543f99be21e75ed7136c45bf1a24594822sewardj } 1152a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj 1153aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 8, 9 */ 1154aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondS)) { 1155aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long long sub/cmp, then S (negative) 1156aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (dst-src)[63] 1157aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (dst-src) >>u 63 */ 1158aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return binop(Iop_Shr64, 1159aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2), 1160aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(63)); 1161aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1162aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNS)) { 1163aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long long sub/cmp, then NS (not negative) 1164aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (dst-src)[63] ^ 1 1165aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dst-src) >>u 63) ^ 1 */ 1166aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return binop(Iop_Xor64, 1167aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shr64, 1168aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2), 1169aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(63)), 1170aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)); 1171aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1172aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1173aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 12, 13 */ 1174edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondL)) { 1175edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long long sub/cmp, then L (signed less than) 1176edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test dst <s src */ 1177db261e489a4302789faccbfc17b96182051c8c3asewardj return unop(Iop_1Uto64, 1178edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLT64S, cc_dep1, cc_dep2)); 1179a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj } 1180aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNL)) { 1181aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long long sub/cmp, then NL (signed greater than or equal) 1182aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test dst >=s src 1183aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test src <=s dst */ 1184aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return unop(Iop_1Uto64, 1185aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_CmpLE64S, cc_dep2, cc_dep1)); 1186aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1187edccb443be188091d51d7ecd984ce75e649adb16sewardj 1188aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 14, 15 */ 1189aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondLE)) { 1190aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long long sub/cmp, then LE (signed less than or equal) 1191aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test dst <=s src */ 1192aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return unop(Iop_1Uto64, 1193aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_CmpLE64S, cc_dep1, cc_dep2)); 1194aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1195edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNLE)) { 1196edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then NLE (signed greater than) 1197edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test !(dst <=s src) 1198edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test (dst >s src) 1199edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test (src <s dst) */ 1200a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj return unop(Iop_1Uto64, 1201edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLT64S, cc_dep2, cc_dep1)); 1202edccb443be188091d51d7ecd984ce75e649adb16sewardj 1203db261e489a4302789faccbfc17b96182051c8c3asewardj } 1204db261e489a4302789faccbfc17b96182051c8c3asewardj 1205edccb443be188091d51d7ecd984ce75e649adb16sewardj /*---------------- SUBL ----------------*/ 1206edccb443be188091d51d7ecd984ce75e649adb16sewardj 1207aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 0, */ 1208aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondO)) { 1209aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* This is very commonly generated by Javascript JITs, for 1210aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj the idiom "do a 32-bit subtract and jump to out-of-line 1211aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj code if an overflow occurs". */ 1212aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long sub/cmp, then O (overflow) 1213aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dep1 ^ dep2) & (dep1 ^ (dep1 - dep2)))[31] 1214aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (((dep1 ^ dep2) & (dep1 ^ (dep1 -64 dep2))) >>u 31) & 1 1215aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj */ 1216aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep1)); 1217aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj vassert(isIRAtom(cc_dep2)); 1218aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return 1219aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1220aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shr64, 1221aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1222aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, cc_dep1, cc_dep2), 1223aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Xor64, 1224aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj cc_dep1, 1225aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2))), 1226aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(31)), 1227aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)); 1228aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1229aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNO)) { 1230aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* No action. Never yet found a test case. */ 1231aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1232aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1233aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 2, 3 */ 1234edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondB)) { 1235edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then B (unsigned less than) 1236edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test dst <u src */ 12376d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 1238edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLT32U, 12399cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 12409cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep2))); 12410354035b9222b1d6e37172ac2a70b19c816df025sewardj } 1242aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNB)) { 1243aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long sub/cmp, then NB (unsigned greater than or equal) 1244aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test src <=u dst */ 1245aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* Note, args are opposite way round from the usual */ 1246aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return unop(Iop_1Uto64, 1247aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_CmpLE32U, 1248aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj unop(Iop_64to32, cc_dep2), 1249aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj unop(Iop_64to32, cc_dep1))); 1250aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 12510354035b9222b1d6e37172ac2a70b19c816df025sewardj 1252edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 4, 5 */ 1253edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondZ)) { 1254edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then Z --> test dst==src */ 12556d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 1256edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpEQ32, 12579cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 12589cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep2))); 12590354035b9222b1d6e37172ac2a70b19c816df025sewardj } 1260edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNZ)) { 1261edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then NZ --> test dst!=src */ 1262ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj return unop(Iop_1Uto64, 1263edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpNE32, 1264edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep1), 1265edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep2))); 1266ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj } 12670354035b9222b1d6e37172ac2a70b19c816df025sewardj 1268edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 6, 7 */ 1269a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondBE)) { 1270a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj /* long sub/cmp, then BE (unsigned less than or equal) 1271a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj --> test dst <=u src */ 1272a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj return unop(Iop_1Uto64, 12739cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpLE32U, 12749cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 12759cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep2))); 1276a9e4a80f0533c83cebca31070135d9506d5ae4c7sewardj } 127732d615b76c65938d815fe529e690a7f79a24a4ecsewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNBE)) { 127832d615b76c65938d815fe529e690a7f79a24a4ecsewardj /* long sub/cmp, then NBE (unsigned greater than) 127932d615b76c65938d815fe529e690a7f79a24a4ecsewardj --> test src <u dst */ 128032d615b76c65938d815fe529e690a7f79a24a4ecsewardj /* Note, args are opposite way round from the usual */ 128132d615b76c65938d815fe529e690a7f79a24a4ecsewardj return unop(Iop_1Uto64, 12829cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpLT32U, 12839cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep2), 12849cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1))); 128532d615b76c65938d815fe529e690a7f79a24a4ecsewardj } 12860354035b9222b1d6e37172ac2a70b19c816df025sewardj 1287aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 8, 9 */ 12883b09235486a95b746c7aeca7fe7e21f3271fd489sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondS)) { 1289aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long sub/cmp, then S (negative) 1290aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (dst-src)[31] 1291aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> ((dst -64 src) >>u 31) & 1 1292aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj Pointless to narrow the args to 32 bit before the subtract. */ 1293aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return binop(Iop_And64, 1294aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shr64, 1295aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2), 1296aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(31)), 1297aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)); 1298aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1299aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNS)) { 1300aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long sub/cmp, then NS (not negative) 1301aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (dst-src)[31] ^ 1 1302aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> (((dst -64 src) >>u 31) & 1) ^ 1 1303aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj Pointless to narrow the args to 32 bit before the subtract. */ 1304aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return binop(Iop_Xor64, 1305aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_And64, 1306aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shr64, 1307aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Sub64, cc_dep1, cc_dep2), 1308aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU8(31)), 1309aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)), 1310aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj mkU64(1)); 13113b09235486a95b746c7aeca7fe7e21f3271fd489sewardj } 13123b09235486a95b746c7aeca7fe7e21f3271fd489sewardj 1313aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* 12, 13 */ 1314edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondL)) { 1315edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then L (signed less than) 1316edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test dst <s src */ 1317e430418063e237ff914c91ecb0d32ac0dd14587asewardj return unop(Iop_1Uto64, 1318edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLT32S, 1319e430418063e237ff914c91ecb0d32ac0dd14587asewardj unop(Iop_64to32, cc_dep1), 1320e430418063e237ff914c91ecb0d32ac0dd14587asewardj unop(Iop_64to32, cc_dep2))); 1321e430418063e237ff914c91ecb0d32ac0dd14587asewardj } 1322aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNL)) { 1323aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* long sub/cmp, then NL (signed greater than or equal) 1324aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test dst >=s src 1325aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test src <=s dst */ 1326aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return unop(Iop_1Uto64, 1327aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_CmpLE32S, 1328aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj unop(Iop_64to32, cc_dep2), 1329aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj unop(Iop_64to32, cc_dep1))); 1330aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1331e430418063e237ff914c91ecb0d32ac0dd14587asewardj 1332edccb443be188091d51d7ecd984ce75e649adb16sewardj /* 14, 15 */ 1333edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondLE)) { 1334edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then LE (signed less than or equal) 1335edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test dst <=s src */ 1336edccb443be188091d51d7ecd984ce75e649adb16sewardj return unop(Iop_1Uto64, 1337edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLE32S, 1338edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep1), 1339edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep2))); 1340edccb443be188091d51d7ecd984ce75e649adb16sewardj 1341edccb443be188091d51d7ecd984ce75e649adb16sewardj } 1342edccb443be188091d51d7ecd984ce75e649adb16sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNLE)) { 1343edccb443be188091d51d7ecd984ce75e649adb16sewardj /* long sub/cmp, then NLE (signed greater than) 1344edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test !(dst <=s src) 1345edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test (dst >s src) 1346edccb443be188091d51d7ecd984ce75e649adb16sewardj --> test (src <s dst) */ 1347edccb443be188091d51d7ecd984ce75e649adb16sewardj return unop(Iop_1Uto64, 1348edccb443be188091d51d7ecd984ce75e649adb16sewardj binop(Iop_CmpLT32S, 1349edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep2), 1350edccb443be188091d51d7ecd984ce75e649adb16sewardj unop(Iop_64to32, cc_dep1))); 1351edccb443be188091d51d7ecd984ce75e649adb16sewardj 1352edccb443be188091d51d7ecd984ce75e649adb16sewardj } 1353edccb443be188091d51d7ecd984ce75e649adb16sewardj 13540354035b9222b1d6e37172ac2a70b19c816df025sewardj /*---------------- SUBW ----------------*/ 13550354035b9222b1d6e37172ac2a70b19c816df025sewardj 135666a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 4, 5 */ 1357a82b476f778a599ece9d9001d51b6a024d4657dasewardj if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondZ)) { 1358a82b476f778a599ece9d9001d51b6a024d4657dasewardj /* word sub/cmp, then Z --> test dst==src */ 1359a82b476f778a599ece9d9001d51b6a024d4657dasewardj return unop(Iop_1Uto64, 1360a82b476f778a599ece9d9001d51b6a024d4657dasewardj binop(Iop_CmpEQ16, 1361a82b476f778a599ece9d9001d51b6a024d4657dasewardj unop(Iop_64to16,cc_dep1), 1362a82b476f778a599ece9d9001d51b6a024d4657dasewardj unop(Iop_64to16,cc_dep2))); 1363a82b476f778a599ece9d9001d51b6a024d4657dasewardj } 1364beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondNZ)) { 1365beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj /* word sub/cmp, then NZ --> test dst!=src */ 1366beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj return unop(Iop_1Uto64, 1367beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj binop(Iop_CmpNE16, 1368beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_64to16,cc_dep1), 1369beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj unop(Iop_64to16,cc_dep2))); 1370beb5291313fcd91543dd19c76a9e04d8b0e94af9sewardj } 13710354035b9222b1d6e37172ac2a70b19c816df025sewardj 137266a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 6, */ 1373aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondBE)) { 1374aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj /* word sub/cmp, then BE (unsigned less than or equal) 1375aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj --> test dst <=u src */ 1376aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj return unop(Iop_1Uto64, 1377aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_CmpLE64U, 1378aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shl64, cc_dep1, mkU8(48)), 1379aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj binop(Iop_Shl64, cc_dep2, mkU8(48)))); 1380aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj } 1381aedb8595d3c44725ba4397263731e4a14f4d4b70sewardj 1382ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* 8, 9 */ 1383ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondS) 1384ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && isU64(cc_dep2, 0)) { 1385ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* word sub/cmp of zero, then S --> test (dst-0 <s 0) 1386ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes --> test dst <s 0 1387ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes --> (ULong)dst[15] 1388ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes This is yet another scheme by which clang figures out if the 1389ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes top bit of a word is 1 or 0. See also LOGICB/CondS below. */ 1390ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Note: isU64(cc_dep2, 0) is correct, even though this is 1391ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes for an 16-bit comparison, since the args to the helper 1392ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes function are always U64s. */ 1393ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return binop(Iop_And64, 1394ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_Shr64,cc_dep1,mkU8(15)), 1395ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes mkU64(1)); 1396ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1397ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondNS) 1398ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && isU64(cc_dep2, 0)) { 1399ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* word sub/cmp of zero, then NS --> test !(dst-0 <s 0) 1400ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes --> test !(dst <s 0) 1401ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes --> (ULong) !dst[15] 1402ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes */ 1403ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return binop(Iop_Xor64, 1404ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_And64, 1405ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_Shr64,cc_dep1,mkU8(15)), 1406ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes mkU64(1)), 1407ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes mkU64(1)); 1408ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1409ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 141066a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 14, */ 14113f81c4e65a102d0c74857d221921d6d8882fdb33sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondLE)) { 14123be608db7407faffb476302dfd34d4b82e13c26csewardj /* word sub/cmp, then LE (signed less than or equal) 14133f81c4e65a102d0c74857d221921d6d8882fdb33sewardj --> test dst <=s src */ 14143f81c4e65a102d0c74857d221921d6d8882fdb33sewardj return unop(Iop_1Uto64, 14153f81c4e65a102d0c74857d221921d6d8882fdb33sewardj binop(Iop_CmpLE64S, 14163f81c4e65a102d0c74857d221921d6d8882fdb33sewardj binop(Iop_Shl64,cc_dep1,mkU8(48)), 14173f81c4e65a102d0c74857d221921d6d8882fdb33sewardj binop(Iop_Shl64,cc_dep2,mkU8(48)))); 14183f81c4e65a102d0c74857d221921d6d8882fdb33sewardj 14193f81c4e65a102d0c74857d221921d6d8882fdb33sewardj } 14203f81c4e65a102d0c74857d221921d6d8882fdb33sewardj 14210354035b9222b1d6e37172ac2a70b19c816df025sewardj /*---------------- SUBB ----------------*/ 14220354035b9222b1d6e37172ac2a70b19c816df025sewardj 142366a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 2, 3 */ 142466a5e810b05fbe4473bf5babb5446c20091b4602sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondB)) { 142566a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* byte sub/cmp, then B (unsigned less than) 142666a5e810b05fbe4473bf5babb5446c20091b4602sewardj --> test dst <u src */ 142766a5e810b05fbe4473bf5babb5446c20091b4602sewardj return unop(Iop_1Uto64, 142866a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_CmpLT64U, 142966a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_And64, cc_dep1, mkU64(0xFF)), 143066a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_And64, cc_dep2, mkU64(0xFF)))); 143166a5e810b05fbe4473bf5babb5446c20091b4602sewardj } 143266a5e810b05fbe4473bf5babb5446c20091b4602sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNB)) { 143366a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* byte sub/cmp, then NB (unsigned greater than or equal) 143466a5e810b05fbe4473bf5babb5446c20091b4602sewardj --> test src <=u dst */ 143566a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* Note, args are opposite way round from the usual */ 143666a5e810b05fbe4473bf5babb5446c20091b4602sewardj return unop(Iop_1Uto64, 143766a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_CmpLE64U, 143866a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_And64, cc_dep2, mkU64(0xFF)), 143966a5e810b05fbe4473bf5babb5446c20091b4602sewardj binop(Iop_And64, cc_dep1, mkU64(0xFF)))); 144066a5e810b05fbe4473bf5babb5446c20091b4602sewardj } 144166a5e810b05fbe4473bf5babb5446c20091b4602sewardj 144266a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 4, 5 */ 14430354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondZ)) { 14440354035b9222b1d6e37172ac2a70b19c816df025sewardj /* byte sub/cmp, then Z --> test dst==src */ 14456d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 14460354035b9222b1d6e37172ac2a70b19c816df025sewardj binop(Iop_CmpEQ8, 14476d709a9a67687e446d25838deccd1698bfb3d273sewardj unop(Iop_64to8,cc_dep1), 14486d709a9a67687e446d25838deccd1698bfb3d273sewardj unop(Iop_64to8,cc_dep2))); 14490354035b9222b1d6e37172ac2a70b19c816df025sewardj } 145032d615b76c65938d815fe529e690a7f79a24a4ecsewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNZ)) { 145132d615b76c65938d815fe529e690a7f79a24a4ecsewardj /* byte sub/cmp, then NZ --> test dst!=src */ 145232d615b76c65938d815fe529e690a7f79a24a4ecsewardj return unop(Iop_1Uto64, 145332d615b76c65938d815fe529e690a7f79a24a4ecsewardj binop(Iop_CmpNE8, 145432d615b76c65938d815fe529e690a7f79a24a4ecsewardj unop(Iop_64to8,cc_dep1), 145532d615b76c65938d815fe529e690a7f79a24a4ecsewardj unop(Iop_64to8,cc_dep2))); 145632d615b76c65938d815fe529e690a7f79a24a4ecsewardj } 145732d615b76c65938d815fe529e690a7f79a24a4ecsewardj 145866a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 6, */ 1459e430418063e237ff914c91ecb0d32ac0dd14587asewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondBE)) { 1460e430418063e237ff914c91ecb0d32ac0dd14587asewardj /* byte sub/cmp, then BE (unsigned less than or equal) 1461e430418063e237ff914c91ecb0d32ac0dd14587asewardj --> test dst <=u src */ 1462e430418063e237ff914c91ecb0d32ac0dd14587asewardj return unop(Iop_1Uto64, 1463e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_CmpLE64U, 1464e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_And64, cc_dep1, mkU64(0xFF)), 1465e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_And64, cc_dep2, mkU64(0xFF)))); 1466e430418063e237ff914c91ecb0d32ac0dd14587asewardj } 1467e430418063e237ff914c91ecb0d32ac0dd14587asewardj 146866a5e810b05fbe4473bf5babb5446c20091b4602sewardj /* 8, 9 */ 14693be608db7407faffb476302dfd34d4b82e13c26csewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondS) 14703be608db7407faffb476302dfd34d4b82e13c26csewardj && isU64(cc_dep2, 0)) { 14713be608db7407faffb476302dfd34d4b82e13c26csewardj /* byte sub/cmp of zero, then S --> test (dst-0 <s 0) 14723be608db7407faffb476302dfd34d4b82e13c26csewardj --> test dst <s 0 14733be608db7407faffb476302dfd34d4b82e13c26csewardj --> (ULong)dst[7] 14743be608db7407faffb476302dfd34d4b82e13c26csewardj This is yet another scheme by which gcc figures out if the 14753be608db7407faffb476302dfd34d4b82e13c26csewardj top bit of a byte is 1 or 0. See also LOGICB/CondS below. */ 14763be608db7407faffb476302dfd34d4b82e13c26csewardj /* Note: isU64(cc_dep2, 0) is correct, even though this is 14773be608db7407faffb476302dfd34d4b82e13c26csewardj for an 8-bit comparison, since the args to the helper 14783be608db7407faffb476302dfd34d4b82e13c26csewardj function are always U64s. */ 14793be608db7407faffb476302dfd34d4b82e13c26csewardj return binop(Iop_And64, 14803be608db7407faffb476302dfd34d4b82e13c26csewardj binop(Iop_Shr64,cc_dep1,mkU8(7)), 14813be608db7407faffb476302dfd34d4b82e13c26csewardj mkU64(1)); 14823be608db7407faffb476302dfd34d4b82e13c26csewardj } 1483cd538b445c0489aae317dabf2425698435c9a1f3sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNS) 1484cd538b445c0489aae317dabf2425698435c9a1f3sewardj && isU64(cc_dep2, 0)) { 1485cd538b445c0489aae317dabf2425698435c9a1f3sewardj /* byte sub/cmp of zero, then NS --> test !(dst-0 <s 0) 1486cd538b445c0489aae317dabf2425698435c9a1f3sewardj --> test !(dst <s 0) 1487cd538b445c0489aae317dabf2425698435c9a1f3sewardj --> (ULong) !dst[7] 1488cd538b445c0489aae317dabf2425698435c9a1f3sewardj */ 1489cd538b445c0489aae317dabf2425698435c9a1f3sewardj return binop(Iop_Xor64, 1490cd538b445c0489aae317dabf2425698435c9a1f3sewardj binop(Iop_And64, 1491cd538b445c0489aae317dabf2425698435c9a1f3sewardj binop(Iop_Shr64,cc_dep1,mkU8(7)), 1492cd538b445c0489aae317dabf2425698435c9a1f3sewardj mkU64(1)), 1493cd538b445c0489aae317dabf2425698435c9a1f3sewardj mkU64(1)); 1494cd538b445c0489aae317dabf2425698435c9a1f3sewardj } 14953be608db7407faffb476302dfd34d4b82e13c26csewardj 14964b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /*---------------- LOGICQ ----------------*/ 14974b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj 14984b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondZ)) { 14994b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /* long long and/or/xor, then Z --> test dst==0 */ 15004b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj return unop(Iop_1Uto64, 15014b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 15024b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj } 15030cd7473678993cbd9a3f8ba01089221af3becb74sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondNZ)) { 15040cd7473678993cbd9a3f8ba01089221af3becb74sewardj /* long long and/or/xor, then NZ --> test dst!=0 */ 15050cd7473678993cbd9a3f8ba01089221af3becb74sewardj return unop(Iop_1Uto64, 15060cd7473678993cbd9a3f8ba01089221af3becb74sewardj binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 15070cd7473678993cbd9a3f8ba01089221af3becb74sewardj } 15084b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj 150977fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondL)) { 151077fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj /* long long and/or/xor, then L 151177fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj LOGIC sets SF and ZF according to the 151277fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj result and makes OF be zero. L computes SF ^ OF, but 151377fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj OF is zero, so this reduces to SF -- which will be 1 iff 151477fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj the result is < signed 0. Hence ... 151577fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj */ 151677fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj return unop(Iop_1Uto64, 151777fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj binop(Iop_CmpLT64S, 151877fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj cc_dep1, 151977fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj mkU64(0))); 152077fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj } 152177fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj 15220354035b9222b1d6e37172ac2a70b19c816df025sewardj /*---------------- LOGICL ----------------*/ 15230354035b9222b1d6e37172ac2a70b19c816df025sewardj 15240354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondZ)) { 15250354035b9222b1d6e37172ac2a70b19c816df025sewardj /* long and/or/xor, then Z --> test dst==0 */ 15266d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 15279cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpEQ32, 15289cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 15299cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mkU32(0))); 1530005b4ef5a50535516154e60fa65b3420fe4eed35sewardj } 1531005b4ef5a50535516154e60fa65b3420fe4eed35sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondNZ)) { 1532005b4ef5a50535516154e60fa65b3420fe4eed35sewardj /* long and/or/xor, then NZ --> test dst!=0 */ 1533005b4ef5a50535516154e60fa65b3420fe4eed35sewardj return unop(Iop_1Uto64, 15349cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpNE32, 15359cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 15369cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mkU32(0))); 15370354035b9222b1d6e37172ac2a70b19c816df025sewardj } 15380354035b9222b1d6e37172ac2a70b19c816df025sewardj 15390354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondLE)) { 15400354035b9222b1d6e37172ac2a70b19c816df025sewardj /* long and/or/xor, then LE 15410354035b9222b1d6e37172ac2a70b19c816df025sewardj This is pretty subtle. LOGIC sets SF and ZF according to the 154277fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj result and makes OF be zero. LE computes (SF ^ OF) | ZF, but 154377fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj OF is zero, so this reduces to SF | ZF -- which will be 1 iff 15440354035b9222b1d6e37172ac2a70b19c816df025sewardj the result is <=signed 0. Hence ... 15450354035b9222b1d6e37172ac2a70b19c816df025sewardj */ 15466d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 15479cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpLE32S, 15489cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 15499cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mkU32(0))); 15500354035b9222b1d6e37172ac2a70b19c816df025sewardj } 15510354035b9222b1d6e37172ac2a70b19c816df025sewardj 1552e430418063e237ff914c91ecb0d32ac0dd14587asewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondS)) { 1553e430418063e237ff914c91ecb0d32ac0dd14587asewardj /* long and/or/xor, then S --> (ULong)result[31] */ 1554e430418063e237ff914c91ecb0d32ac0dd14587asewardj return binop(Iop_And64, 1555e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_Shr64, cc_dep1, mkU8(31)), 1556e430418063e237ff914c91ecb0d32ac0dd14587asewardj mkU64(1)); 1557e430418063e237ff914c91ecb0d32ac0dd14587asewardj } 1558e430418063e237ff914c91ecb0d32ac0dd14587asewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondNS)) { 1559e430418063e237ff914c91ecb0d32ac0dd14587asewardj /* long and/or/xor, then S --> (ULong) ~ result[31] */ 1560e430418063e237ff914c91ecb0d32ac0dd14587asewardj return binop(Iop_Xor64, 1561e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_And64, 1562e430418063e237ff914c91ecb0d32ac0dd14587asewardj binop(Iop_Shr64, cc_dep1, mkU8(31)), 1563e430418063e237ff914c91ecb0d32ac0dd14587asewardj mkU64(1)), 1564e430418063e237ff914c91ecb0d32ac0dd14587asewardj mkU64(1)); 1565e430418063e237ff914c91ecb0d32ac0dd14587asewardj } 1566e430418063e237ff914c91ecb0d32ac0dd14587asewardj 156761acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj /*---------------- LOGICW ----------------*/ 156861acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj 156961acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICW) && isU64(cond, AMD64CondZ)) { 157061acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj /* word and/or/xor, then Z --> test dst==0 */ 157161acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj return unop(Iop_1Uto64, 157261acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj binop(Iop_CmpEQ64, 157361acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj binop(Iop_And64, cc_dep1, mkU64(0xFFFF)), 157461acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj mkU64(0))); 157561acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj } 157661acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICW) && isU64(cond, AMD64CondNZ)) { 157761acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj /* word and/or/xor, then NZ --> test dst!=0 */ 157861acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj return unop(Iop_1Uto64, 157961acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj binop(Iop_CmpNE64, 158061acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj binop(Iop_And64, cc_dep1, mkU64(0xFFFF)), 158161acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj mkU64(0))); 158261acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj } 158361acf4ca755d2d2b2632a4fb31b4fc21e681c5f6sewardj 15844b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /*---------------- LOGICB ----------------*/ 15854b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj 15864b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondZ)) { 15874b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj /* byte and/or/xor, then Z --> test dst==0 */ 15884b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj return unop(Iop_1Uto64, 15894b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj binop(Iop_CmpEQ64, binop(Iop_And64,cc_dep1,mkU64(255)), 15904b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj mkU64(0))); 1591ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj } 1592ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondNZ)) { 1593ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj /* byte and/or/xor, then NZ --> test dst!=0 */ 1594ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj return unop(Iop_1Uto64, 1595ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj binop(Iop_CmpNE64, binop(Iop_And64,cc_dep1,mkU64(255)), 1596ff6b34ac26070c47e55803e61f8ae5554ddcac27sewardj mkU64(0))); 15974b06a0b4ad062b86e43431d82ab514d6dc68407fsewardj } 15983f81c4e65a102d0c74857d221921d6d8882fdb33sewardj 1599346d9a198e8db67114d158e97e33072bf737bc25sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondS)) { 1600346d9a198e8db67114d158e97e33072bf737bc25sewardj /* this is an idiom gcc sometimes uses to find out if the top 1601346d9a198e8db67114d158e97e33072bf737bc25sewardj bit of a byte register is set: eg testb %al,%al; js .. 1602346d9a198e8db67114d158e97e33072bf737bc25sewardj Since it just depends on the top bit of the byte, extract 1603346d9a198e8db67114d158e97e33072bf737bc25sewardj that bit and explicitly get rid of all the rest. This 1604346d9a198e8db67114d158e97e33072bf737bc25sewardj helps memcheck avoid false positives in the case where any 1605346d9a198e8db67114d158e97e33072bf737bc25sewardj of the other bits in the byte are undefined. */ 1606346d9a198e8db67114d158e97e33072bf737bc25sewardj /* byte and/or/xor, then S --> (UInt)result[7] */ 1607346d9a198e8db67114d158e97e33072bf737bc25sewardj return binop(Iop_And64, 1608346d9a198e8db67114d158e97e33072bf737bc25sewardj binop(Iop_Shr64,cc_dep1,mkU8(7)), 1609346d9a198e8db67114d158e97e33072bf737bc25sewardj mkU64(1)); 1610346d9a198e8db67114d158e97e33072bf737bc25sewardj } 1611a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondNS)) { 1612a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj /* byte and/or/xor, then NS --> (UInt)!result[7] */ 1613a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj return binop(Iop_Xor64, 1614a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj binop(Iop_And64, 1615a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj binop(Iop_Shr64,cc_dep1,mkU8(7)), 1616a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj mkU64(1)), 1617a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj mkU64(1)); 1618a6d08098f8291c52a2f08d70812805f9b47f6d7csewardj } 1619346d9a198e8db67114d158e97e33072bf737bc25sewardj 16203f81c4e65a102d0c74857d221921d6d8882fdb33sewardj /*---------------- INCB ----------------*/ 16213f81c4e65a102d0c74857d221921d6d8882fdb33sewardj 16223f81c4e65a102d0c74857d221921d6d8882fdb33sewardj if (isU64(cc_op, AMD64G_CC_OP_INCB) && isU64(cond, AMD64CondLE)) { 16234df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj /* 8-bit inc, then LE --> sign bit of the arg */ 16244df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj return binop(Iop_And64, 16254df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj binop(Iop_Shr64, 16264df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj binop(Iop_Sub64, cc_dep1, mkU64(1)), 16274df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj mkU8(7)), 16284df975ffbe2c0aad9b64f547d84bde40c3c11171sewardj mkU64(1)); 16293f81c4e65a102d0c74857d221921d6d8882fdb33sewardj } 16303f81c4e65a102d0c74857d221921d6d8882fdb33sewardj 16317784bd257254f55f4b5cebbcb70d5974fb12e808sewardj /*---------------- INCW ----------------*/ 16327784bd257254f55f4b5cebbcb70d5974fb12e808sewardj 16337784bd257254f55f4b5cebbcb70d5974fb12e808sewardj if (isU64(cc_op, AMD64G_CC_OP_INCW) && isU64(cond, AMD64CondZ)) { 16347784bd257254f55f4b5cebbcb70d5974fb12e808sewardj /* 16-bit inc, then Z --> test dst == 0 */ 16357784bd257254f55f4b5cebbcb70d5974fb12e808sewardj return unop(Iop_1Uto64, 16367784bd257254f55f4b5cebbcb70d5974fb12e808sewardj binop(Iop_CmpEQ64, 16377784bd257254f55f4b5cebbcb70d5974fb12e808sewardj binop(Iop_Shl64,cc_dep1,mkU8(48)), 16387784bd257254f55f4b5cebbcb70d5974fb12e808sewardj mkU64(0))); 16397784bd257254f55f4b5cebbcb70d5974fb12e808sewardj } 16407784bd257254f55f4b5cebbcb70d5974fb12e808sewardj 164177fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj /*---------------- DECL ----------------*/ 164277fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj 164377fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj if (isU64(cc_op, AMD64G_CC_OP_DECL) && isU64(cond, AMD64CondZ)) { 164477fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj /* dec L, then Z --> test dst == 0 */ 164577fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj return unop(Iop_1Uto64, 16469cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpEQ32, 16479cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 16489cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mkU32(0))); 164977fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj } 165077fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj 1651b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj /*---------------- DECW ----------------*/ 1652b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj 1653b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj if (isU64(cc_op, AMD64G_CC_OP_DECW) && isU64(cond, AMD64CondNZ)) { 1654b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj /* 16-bit dec, then NZ --> test dst != 0 */ 1655b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj return unop(Iop_1Uto64, 1656b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj binop(Iop_CmpNE64, 1657b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj binop(Iop_Shl64,cc_dep1,mkU8(48)), 1658b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj mkU64(0))); 1659b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj } 1660b6d02ea14a70600fda60851f1b12a81661bd5c24sewardj 1661ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /*---------------- SHRQ ----------------*/ 1662ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 1663ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondZ)) { 1664ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* SHRQ, then Z --> test dep1 == 0 */ 1665ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return unop(Iop_1Uto64, 1666ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 1667ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1668ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNZ)) { 1669ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* SHRQ, then NZ --> test dep1 != 0 */ 1670ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return unop(Iop_1Uto64, 1671ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 1672ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1673ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 1674a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /*---------------- SHRL ----------------*/ 1675a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 1676a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SHRL) && isU64(cond, AMD64CondZ)) { 1677a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* SHRL, then Z --> test dep1 == 0 */ 1678a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return unop(Iop_1Uto64, 1679a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1), 1680a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes mkU32(0))); 1681a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1682ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_SHRL) && isU64(cond, AMD64CondNZ)) { 1683ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* SHRL, then NZ --> test dep1 != 0 */ 1684ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return unop(Iop_1Uto64, 1685ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_CmpNE32, unop(Iop_64to32, cc_dep1), 1686ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes mkU32(0))); 1687ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1688a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 16897fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj /*---------------- COPY ----------------*/ 16907fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj /* This can happen, as a result of amd64 FP compares: "comisd ... ; 16917fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj jbe" for example. */ 16927fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj 16937fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj if (isU64(cc_op, AMD64G_CC_OP_COPY) && 16947fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj (isU64(cond, AMD64CondBE) || isU64(cond, AMD64CondNBE))) { 16957fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj /* COPY, then BE --> extract C and Z from dep1, and test (C 16967fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj or Z == 1). */ 16977fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj /* COPY, then NBE --> extract C and Z from dep1, and test (C 16987fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj or Z == 0). */ 16997fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj ULong nnn = isU64(cond, AMD64CondBE) ? 1 : 0; 17007fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj return 17017fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj unop( 17027fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj Iop_1Uto64, 17037fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj binop( 17047fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj Iop_CmpEQ64, 17057fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj binop( 17067fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj Iop_And64, 17077fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj binop( 17087fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj Iop_Or64, 17097fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_C)), 17107fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_Z)) 17117fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj ), 17127fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj mkU64(1) 17137fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj ), 17147fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj mkU64(nnn) 17157fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj ) 17167fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj ); 17177fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj } 17187fc494b1b2abc210ee4b7a82d43f6a084a869022sewardj 17199f05a64b6443485d0f9156ca75230c53381ce163sewardj if (isU64(cc_op, AMD64G_CC_OP_COPY) && isU64(cond, AMD64CondB)) { 17209f05a64b6443485d0f9156ca75230c53381ce163sewardj /* COPY, then B --> extract C dep1, and test (C == 1). */ 17219f05a64b6443485d0f9156ca75230c53381ce163sewardj return 17229f05a64b6443485d0f9156ca75230c53381ce163sewardj unop( 17239f05a64b6443485d0f9156ca75230c53381ce163sewardj Iop_1Uto64, 17249f05a64b6443485d0f9156ca75230c53381ce163sewardj binop( 17259f05a64b6443485d0f9156ca75230c53381ce163sewardj Iop_CmpNE64, 17269f05a64b6443485d0f9156ca75230c53381ce163sewardj binop( 17279f05a64b6443485d0f9156ca75230c53381ce163sewardj Iop_And64, 17289f05a64b6443485d0f9156ca75230c53381ce163sewardj binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_C)), 17299f05a64b6443485d0f9156ca75230c53381ce163sewardj mkU64(1) 17309f05a64b6443485d0f9156ca75230c53381ce163sewardj ), 17319f05a64b6443485d0f9156ca75230c53381ce163sewardj mkU64(0) 17329f05a64b6443485d0f9156ca75230c53381ce163sewardj ) 17339f05a64b6443485d0f9156ca75230c53381ce163sewardj ); 17349f05a64b6443485d0f9156ca75230c53381ce163sewardj } 17350354035b9222b1d6e37172ac2a70b19c816df025sewardj 1736b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj if (isU64(cc_op, AMD64G_CC_OP_COPY) 1737b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj && (isU64(cond, AMD64CondZ) || isU64(cond, AMD64CondNZ))) { 1738b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */ 1739b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */ 1740b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj UInt nnn = isU64(cond, AMD64CondZ) ? 1 : 0; 1741b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj return 1742b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj unop( 1743b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_1Uto64, 1744b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop( 1745b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_CmpEQ64, 1746b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop( 1747b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_And64, 1748b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_Z)), 1749b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj mkU64(1) 1750b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ), 1751b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj mkU64(nnn) 1752b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ) 1753b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ); 1754b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj } 1755b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj 1756b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj if (isU64(cc_op, AMD64G_CC_OP_COPY) && isU64(cond, AMD64CondP)) { 1757b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj /* COPY, then P --> extract P from dep1, and test (P == 1). */ 1758b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj return 1759b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj unop( 1760b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_1Uto64, 1761b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop( 1762b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_CmpNE64, 1763b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop( 1764b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj Iop_And64, 1765b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_P)), 1766b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj mkU64(1) 1767b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ), 1768b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj mkU64(0) 1769b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ) 1770b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj ); 1771b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj } 1772b235e5b6613f6e4e00c0e50f2062d30cc99d9434sewardj 17730354035b9222b1d6e37172ac2a70b19c816df025sewardj return NULL; 17740354035b9222b1d6e37172ac2a70b19c816df025sewardj } 17750354035b9222b1d6e37172ac2a70b19c816df025sewardj 17760354035b9222b1d6e37172ac2a70b19c816df025sewardj /* --------- specialising "amd64g_calculate_rflags_c" --------- */ 17770354035b9222b1d6e37172ac2a70b19c816df025sewardj 17780354035b9222b1d6e37172ac2a70b19c816df025sewardj if (vex_streq(function_name, "amd64g_calculate_rflags_c")) { 17790354035b9222b1d6e37172ac2a70b19c816df025sewardj /* specialise calls to above "calculate_rflags_c" function */ 17800354035b9222b1d6e37172ac2a70b19c816df025sewardj IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 17810354035b9222b1d6e37172ac2a70b19c816df025sewardj vassert(arity == 4); 17820354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_op = args[0]; 17830354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_dep1 = args[1]; 17840354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_dep2 = args[2]; 17850354035b9222b1d6e37172ac2a70b19c816df025sewardj cc_ndep = args[3]; 17860354035b9222b1d6e37172ac2a70b19c816df025sewardj 178777fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBQ)) { 178877fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj /* C after sub denotes unsigned less than */ 178977fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj return unop(Iop_1Uto64, 179077fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj binop(Iop_CmpLT64U, 179177fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj cc_dep1, 179277fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj cc_dep2)); 179377fd8467f1c25c2873ece6e3328d8ebf3afebb12sewardj } 17940354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBL)) { 17950354035b9222b1d6e37172ac2a70b19c816df025sewardj /* C after sub denotes unsigned less than */ 17966d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 17979cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj binop(Iop_CmpLT32U, 17989cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep1), 17999cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj unop(Iop_64to32, cc_dep2))); 18000354035b9222b1d6e37172ac2a70b19c816df025sewardj } 18010354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_SUBB)) { 18020354035b9222b1d6e37172ac2a70b19c816df025sewardj /* C after sub denotes unsigned less than */ 18036d709a9a67687e446d25838deccd1698bfb3d273sewardj return unop(Iop_1Uto64, 18040354035b9222b1d6e37172ac2a70b19c816df025sewardj binop(Iop_CmpLT64U, 18050354035b9222b1d6e37172ac2a70b19c816df025sewardj binop(Iop_And64,cc_dep1,mkU64(0xFF)), 18066d709a9a67687e446d25838deccd1698bfb3d273sewardj binop(Iop_And64,cc_dep2,mkU64(0xFF)))); 18070354035b9222b1d6e37172ac2a70b19c816df025sewardj } 1808ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_ADDQ)) { 1809ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* C after add denotes sum <u either arg */ 1810ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return unop(Iop_1Uto64, 1811ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_CmpLT64U, 1812ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_Add64, cc_dep1, cc_dep2), 1813ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes cc_dep1)); 1814ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 1815ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (isU64(cc_op, AMD64G_CC_OP_ADDL)) { 1816ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* C after add denotes sum <u either arg */ 1817ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return unop(Iop_1Uto64, 1818ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes binop(Iop_CmpLT32U, 1819ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes unop(Iop_64to32, binop(Iop_Add64, cc_dep1, cc_dep2)), 1820ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes unop(Iop_64to32, cc_dep1))); 1821ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 18220354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) 18230354035b9222b1d6e37172ac2a70b19c816df025sewardj || isU64(cc_op, AMD64G_CC_OP_LOGICL) 18240354035b9222b1d6e37172ac2a70b19c816df025sewardj || isU64(cc_op, AMD64G_CC_OP_LOGICW) 18250354035b9222b1d6e37172ac2a70b19c816df025sewardj || isU64(cc_op, AMD64G_CC_OP_LOGICB)) { 18260354035b9222b1d6e37172ac2a70b19c816df025sewardj /* cflag after logic is zero */ 18270354035b9222b1d6e37172ac2a70b19c816df025sewardj return mkU64(0); 18280354035b9222b1d6e37172ac2a70b19c816df025sewardj } 18290354035b9222b1d6e37172ac2a70b19c816df025sewardj if (isU64(cc_op, AMD64G_CC_OP_DECL) || isU64(cc_op, AMD64G_CC_OP_INCL) 18300354035b9222b1d6e37172ac2a70b19c816df025sewardj || isU64(cc_op, AMD64G_CC_OP_DECQ) || isU64(cc_op, AMD64G_CC_OP_INCQ)) { 18310354035b9222b1d6e37172ac2a70b19c816df025sewardj /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */ 18320354035b9222b1d6e37172ac2a70b19c816df025sewardj return cc_ndep; 18330354035b9222b1d6e37172ac2a70b19c816df025sewardj } 18347784bd257254f55f4b5cebbcb70d5974fb12e808sewardj 18357784bd257254f55f4b5cebbcb70d5974fb12e808sewardj# if 0 18367784bd257254f55f4b5cebbcb70d5974fb12e808sewardj if (cc_op->tag == Iex_Const) { 18377784bd257254f55f4b5cebbcb70d5974fb12e808sewardj vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n"); 18387784bd257254f55f4b5cebbcb70d5974fb12e808sewardj } 18397784bd257254f55f4b5cebbcb70d5974fb12e808sewardj# endif 18400354035b9222b1d6e37172ac2a70b19c816df025sewardj 18410354035b9222b1d6e37172ac2a70b19c816df025sewardj return NULL; 18420354035b9222b1d6e37172ac2a70b19c816df025sewardj } 18430354035b9222b1d6e37172ac2a70b19c816df025sewardj 1844f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# undef unop 1845f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# undef binop 18460354035b9222b1d6e37172ac2a70b19c816df025sewardj# undef mkU64 18479cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj# undef mkU32 1848f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj# undef mkU8 1849f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 1850f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj return NULL; 1851f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj} 1852f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 1853f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 18548d965316c72c2392f670dcdfa127547ec77c7e56sewardj/*---------------------------------------------------------------*/ 18558d965316c72c2392f670dcdfa127547ec77c7e56sewardj/*--- Supporting functions for x87 FPU activities. ---*/ 18568d965316c72c2392f670dcdfa127547ec77c7e56sewardj/*---------------------------------------------------------------*/ 18578d965316c72c2392f670dcdfa127547ec77c7e56sewardj 18584f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardjstatic inline Bool host_is_little_endian ( void ) 18594f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj{ 18604f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj UInt x = 0x76543210; 18614f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj UChar* p = (UChar*)(&x); 18624f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return toBool(*p == 0x10); 18634f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj} 18644f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18654f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj/* Inspect a value and its tag, as per the x87 'FXAM' instruction. */ 18664f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 18674f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardjULong amd64g_calculate_FXAM ( ULong tag, ULong dbl ) 18684f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj{ 18694f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Bool mantissaIsZero; 18704f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Int bexp; 18714f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj UChar sign; 18724f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj UChar* f64; 18734f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18744f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj vassert(host_is_little_endian()); 18754f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18764f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */ 18774f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18784f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj f64 = (UChar*)(&dbl); 18794f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj sign = toUChar( (f64[7] >> 7) & 1 ); 18804f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18814f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* First off, if the tag indicates the register was empty, 18824f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return 1,0,sign,1 */ 18834f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj if (tag == 0) { 18844f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("Empty\n"); */ 18854f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return AMD64G_FC_MASK_C3 | 0 | (sign << AMD64G_FC_SHIFT_C1) 18864f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj | AMD64G_FC_MASK_C0; 18874f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj } 18884f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18894f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F); 18904f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj bexp &= 0x7FF; 18914f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18924f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj mantissaIsZero 18934f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj = toBool( 18944f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj (f64[6] & 0x0F) == 0 18954f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0 18964f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj ); 18974f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 18984f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* If both exponent and mantissa are zero, the value is zero. 18994f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Return 1,0,sign,0. */ 19004f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj if (bexp == 0 && mantissaIsZero) { 19014f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("Zero\n"); */ 19024f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return AMD64G_FC_MASK_C3 | 0 19034f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj | (sign << AMD64G_FC_SHIFT_C1) | 0; 19044f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj } 19054f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19064f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* If exponent is zero but mantissa isn't, it's a denormal. 19074f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Return 1,1,sign,0. */ 19084f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj if (bexp == 0 && !mantissaIsZero) { 19094f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("Denormal\n"); */ 19104f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return AMD64G_FC_MASK_C3 | AMD64G_FC_MASK_C2 19114f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj | (sign << AMD64G_FC_SHIFT_C1) | 0; 19124f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj } 19134f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19144f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* If the exponent is 7FF and the mantissa is zero, this is an infinity. 19154f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Return 0,1,sign,1. */ 19164f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj if (bexp == 0x7FF && mantissaIsZero) { 19174f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("Inf\n"); */ 19184f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return 0 | AMD64G_FC_MASK_C2 | (sign << AMD64G_FC_SHIFT_C1) 19194f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj | AMD64G_FC_MASK_C0; 19204f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj } 19214f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19224f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN. 19234f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Return 0,0,sign,1. */ 19244f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj if (bexp == 0x7FF && !mantissaIsZero) { 19254f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("NaN\n"); */ 19264f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return 0 | 0 | (sign << AMD64G_FC_SHIFT_C1) | AMD64G_FC_MASK_C0; 19274f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj } 19284f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19294f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* Uh, ok, we give up. It must be a normal finite number. 19304f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj Return 0,1,sign,0. 19314f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj */ 19324f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj /* vex_printf("normal\n"); */ 19334f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj return 0 | AMD64G_FC_MASK_C2 | (sign << AMD64G_FC_SHIFT_C1) | 0; 19344f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj} 19354f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19364f9847ddc664dd58bd9e4dbcd0626747d142cd06sewardj 19375556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj/* This is used to implement both 'frstor' and 'fldenv'. The latter 19385556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj appears to differ from the former only in that the 8 FP registers 19395556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj themselves are not transferred into the guest state. */ 19405556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardjstatic 19416ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote do_put_x87 ( Bool moveRegs, 1942ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /*IN*/Fpu_State* x87_state, 19435556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /*OUT*/VexGuestAMD64State* vex_state ) 19445556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj{ 19455556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj Int stno, preg; 19465556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UInt tag; 19475556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 19485556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 1949ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes UInt ftop = (x87_state->env[FP_ENV_STAT] >> 11) & 7; 1950ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes UInt tagw = x87_state->env[FP_ENV_TAG]; 1951ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes UInt fpucw = x87_state->env[FP_ENV_CTRL]; 1952ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes UInt c3210 = x87_state->env[FP_ENV_STAT] & 0x4700; 19536ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew; 19545556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UInt fpround; 19555556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj ULong pair; 19565556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19575556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* Copy registers and tags */ 19585556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj for (stno = 0; stno < 8; stno++) { 19595556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj preg = (stno + ftop) & 7; 19605556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj tag = (tagw >> (2*preg)) & 3; 19615556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj if (tag == 3) { 19625556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* register is empty */ 19635556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* hmm, if it's empty, does it still get written? Probably 19645556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj safer to say it does. If we don't, memcheck could get out 19655556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj of sync, in that it thinks all FP registers are defined by 19665556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj this helper, but in reality some have not been updated. */ 19675556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj if (moveRegs) 19685556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 19695556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vexTags[preg] = 0; 19705556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj } else { 19715556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* register is non-empty */ 19725556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj if (moveRegs) 1973ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes convert_f80le_to_f64le( &x87_state->reg[10*stno], 19745556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj (UChar*)&vexRegs[preg] ); 19755556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vexTags[preg] = 1; 19765556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj } 19775556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj } 19785556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19795556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* stack pointer */ 19805556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vex_state->guest_FTOP = ftop; 19815556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19825556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* status word */ 19835556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vex_state->guest_FC3210 = c3210; 19845556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19855556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* handle the control word, setting FPROUND and detecting any 19865556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj emulation warnings. */ 19875556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj pair = amd64g_check_fldcw ( (ULong)fpucw ); 19889ae42a77adfcd9fef928bef3439da258b6e6f748sewardj fpround = (UInt)pair & 0xFFFFFFFFULL; 19896ef84bed9bb3af22060eb1759788034602bbcc88florian ew = (VexEmNote)(pair >> 32); 19905556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19915556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj vex_state->guest_FPROUND = fpround & 3; 19925556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19935556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* emulation warnings --> caller */ 19945556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj return ew; 19955556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj} 19965556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19975556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 19985abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj/* Create an x87 FPU state from the guest state, as close as 19995abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj we can approximate it. */ 20005abcfe66bd59f67b474d0d9e4b70b852213dd910sewardjstatic 20015abcfe66bd59f67b474d0d9e4b70b852213dd910sewardjvoid do_get_x87 ( /*IN*/VexGuestAMD64State* vex_state, 2002ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /*OUT*/Fpu_State* x87_state ) 20035abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj{ 20045abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj Int i, stno, preg; 20055abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UInt tagw; 20065abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 20075abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 20085abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UInt ftop = vex_state->guest_FTOP; 20095abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UInt c3210 = vex_state->guest_FC3210; 20105abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20115abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj for (i = 0; i < 14; i++) 2012ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes x87_state->env[i] = 0; 20135abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 2014ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes x87_state->env[1] = x87_state->env[3] = x87_state->env[5] 2015ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes = x87_state->env[13] = 0xFFFF; 2016ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes x87_state->env[FP_ENV_STAT] 20175abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 2018ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes x87_state->env[FP_ENV_CTRL] 20195abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj = toUShort(amd64g_create_fpucw( vex_state->guest_FPROUND )); 20205abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20215abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* Dump the register stack in ST order. */ 20225abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj tagw = 0; 20235abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj for (stno = 0; stno < 8; stno++) { 20245abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj preg = (stno + ftop) & 7; 20255abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj if (vexTags[preg] == 0) { 20265abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* register is empty */ 20275abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj tagw |= (3 << (2*preg)); 20285abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 2029ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes &x87_state->reg[10*stno] ); 20305abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj } else { 20315abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* register is full. */ 20325abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj tagw |= (0 << (2*preg)); 20335abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 2034ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes &x87_state->reg[10*stno] ); 20355abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj } 20365abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj } 2037ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes x87_state->env[FP_ENV_TAG] = toUShort(tagw); 20385abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj} 20395abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20405abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 204170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 204270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*--- Supporting functions for XSAVE/FXSAVE. ---*/ 204370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 204470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 204570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* CALLED FROM GENERATED CODE */ 204670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 204770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* XSAVE component 0 is the x87 FPU state. */ 204870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjvoid amd64g_dirtyhelper_XSAVE_COMPONENT_0 204970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ( VexGuestAMD64State* gst, HWord addr ) 20505abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj{ 20515abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* Derived from values obtained from 20525abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj vendor_id : AuthenticAMD 20535abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj cpu family : 15 20545abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj model : 12 20555abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj model name : AMD Athlon(tm) 64 Processor 3200+ 20565abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj stepping : 0 20575abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj cpu MHz : 2200.000 20585abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj cache size : 512 KB 20595abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj */ 20605abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* Somewhat roundabout, but at least it's simple. */ 20615abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj Fpu_State tmp; 20625abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UShort* addrS = (UShort*)addr; 20635abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UChar* addrC = (UChar*)addr; 20645abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UShort fp_tags; 20655abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UInt summary_tags; 20665abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj Int r, stno; 20675abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj UShort *srcS, *dstS; 20685abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 2069ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes do_get_x87( gst, &tmp ); 20705abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 207170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Now build the proper fxsave x87 image from the fsave x87 image 207270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj we just made. */ 20735abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20745abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[0] = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */ 20755abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[1] = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */ 20765abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20775abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* set addrS[2] in an endian-independent way */ 20785abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj summary_tags = 0; 20795abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj fp_tags = tmp.env[FP_ENV_TAG]; 20805abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj for (r = 0; r < 8; r++) { 20815abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj if ( ((fp_tags >> (2*r)) & 3) != 3 ) 20825abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj summary_tags |= (1 << r); 20835abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj } 20845abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrC[4] = toUChar(summary_tags); /* FTW: tag summary byte */ 20855abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrC[5] = 0; /* pad */ 20865abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20875abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* FOP: faulting fpu opcode. From experimentation, the real CPU 20885abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj does not write this field. (?!) */ 20895abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[3] = 0; /* BOGUS */ 20905abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20915abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* RIP (Last x87 instruction pointer). From experimentation, the 20925abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj real CPU does not write this field. (?!) */ 20935abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[4] = 0; /* BOGUS */ 20945abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[5] = 0; /* BOGUS */ 20955abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[6] = 0; /* BOGUS */ 20965abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[7] = 0; /* BOGUS */ 20975abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 20985abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* RDP (Last x87 data pointer). From experimentation, the real CPU 20995abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj does not write this field. (?!) */ 21005abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[8] = 0; /* BOGUS */ 21015abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[9] = 0; /* BOGUS */ 21025abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[10] = 0; /* BOGUS */ 21035abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj addrS[11] = 0; /* BOGUS */ 21045abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 210570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* addrS[13,12] are MXCSR -- not written */ 210670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* addrS[15,14] are MXCSR_MASK -- not written */ 21075abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 21085abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj /* Copy in the FP registers, in ST order. */ 21095abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj for (stno = 0; stno < 8; stno++) { 21105abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj srcS = (UShort*)(&tmp.reg[10*stno]); 21115abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS = (UShort*)(&addrS[16 + 8*stno]); 21125abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[0] = srcS[0]; 21135abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[1] = srcS[1]; 21145abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[2] = srcS[2]; 21155abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[3] = srcS[3]; 21165abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[4] = srcS[4]; 21175abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[5] = 0; 21185abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[6] = 0; 21195abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj dstS[7] = 0; 21205abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj } 212170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 212270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 212370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 212470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* CALLED FROM GENERATED CODE */ 212570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* DIRTY HELPER (reads guest state, writes guest mem) */ 212670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* XSAVE component 1 is the SSE state. */ 212770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjvoid amd64g_dirtyhelper_XSAVE_COMPONENT_1_EXCLUDING_XMMREGS 212870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ( VexGuestAMD64State* gst, HWord addr ) 212970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 213070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UShort* addrS = (UShort*)addr; 213170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UInt mxcsr; 213270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 213370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* The only non-register parts of the SSE state are MXCSR and 213470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj MXCSR_MASK. */ 213570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj mxcsr = amd64g_create_mxcsr( gst->guest_SSEROUND ); 213670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 213770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addrS[12] = toUShort(mxcsr); /* MXCSR */ 213870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addrS[13] = toUShort(mxcsr >> 16); 213970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 214070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addrS[14] = 0xFFFF; /* MXCSR mask (lo16) */ 214170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addrS[15] = 0x0000; /* MXCSR mask (hi16) */ 214270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 214370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 214470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 214570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* VISIBLE TO LIBVEX CLIENT */ 214670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* Do FXSAVE from the supplied VexGuestAMD64State structure and store 214770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj the result at the given address which represents a buffer of at 214870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj least 416 bytes. 214970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 215070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj This function is not called from generated code. FXSAVE is dealt 215170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj with by the amd64 front end by calling the XSAVE_COMPONENT_{0,1} 215270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj functions above plus some in-line IR. This function is merely a 215370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj convenience function for VEX's users. 215470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj*/ 215570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjvoid LibVEX_GuestAMD64_fxsave ( /*IN*/VexGuestAMD64State* gst, 215670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /*OUT*/HWord fp_state ) 215770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 215870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Do the x87 part */ 215970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj amd64g_dirtyhelper_XSAVE_COMPONENT_0(gst, fp_state); 216070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 216170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* And now the SSE part, except for the registers themselves. */ 216270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj amd64g_dirtyhelper_XSAVE_COMPONENT_1_EXCLUDING_XMMREGS(gst, fp_state); 21635abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 21643e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj /* That's the first 160 bytes of the image done. */ 216570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Now only %xmm0 .. %xmm15 remain to be copied. If the host is 216670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj big-endian, these need to be byte-swapped. */ 216770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj U128 *xmm = (U128 *)(fp_state + 160); 216870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(host_is_little_endian()); 216970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 217070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj# define COPY_U128(_dst,_src) \ 217170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 217270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 217370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj while (0) 217470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 217570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[0], gst->guest_YMM0 ); 217670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[1], gst->guest_YMM1 ); 217770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[2], gst->guest_YMM2 ); 217870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[3], gst->guest_YMM3 ); 217970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[4], gst->guest_YMM4 ); 218070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[5], gst->guest_YMM5 ); 218170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[6], gst->guest_YMM6 ); 218270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[7], gst->guest_YMM7 ); 218370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[8], gst->guest_YMM8 ); 218470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[9], gst->guest_YMM9 ); 218570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[10], gst->guest_YMM10 ); 218670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[11], gst->guest_YMM11 ); 218770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[12], gst->guest_YMM12 ); 218870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[13], gst->guest_YMM13 ); 218970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[14], gst->guest_YMM14 ); 219070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( xmm[15], gst->guest_YMM15 ); 21913e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj# undef COPY_U128 21925abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj} 21935abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 21945abcfe66bd59f67b474d0d9e4b70b852213dd910sewardj 219570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 219670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*--- Supporting functions for XRSTOR/FXRSTOR. ---*/ 219770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 219870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 219970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* CALLED FROM GENERATED CODE */ 220070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 220170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjVexEmNote amd64g_dirtyhelper_XRSTOR_COMPONENT_0 220270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ( VexGuestAMD64State* gst, HWord addr ) 22035556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj{ 22045556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj Fpu_State tmp; 22055556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UShort* addrS = (UShort*)addr; 22065556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UChar* addrC = (UChar*)addr; 22075556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UShort fp_tags; 22085556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj Int r, stno, i; 22095556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 22105556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* Copy the x87 registers out of the image, into a temporary 22115556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj Fpu_State struct. */ 22125556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj for (i = 0; i < 14; i++) tmp.env[i] = 0; 22135556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj for (i = 0; i < 80; i++) tmp.reg[i] = 0; 22145556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* fill in tmp.reg[0..7] */ 22155556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj for (stno = 0; stno < 8; stno++) { 22165556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UShort* dstS = (UShort*)(&tmp.reg[10*stno]); 22175556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj UShort* srcS = (UShort*)(&addrS[16 + 8*stno]); 22185556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj dstS[0] = srcS[0]; 22195556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj dstS[1] = srcS[1]; 22205556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj dstS[2] = srcS[2]; 22215556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj dstS[3] = srcS[3]; 22225556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj dstS[4] = srcS[4]; 22235556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj } 22245556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* fill in tmp.env[0..13] */ 22255556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj tmp.env[FP_ENV_CTRL] = addrS[0]; /* FCW: fpu control word */ 22265556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj tmp.env[FP_ENV_STAT] = addrS[1]; /* FCW: fpu status word */ 22275556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 22285556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj fp_tags = 0; 22295556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj for (r = 0; r < 8; r++) { 22305556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj if (addrC[4] & (1<<r)) 22315556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj fp_tags |= (0 << (2*r)); /* EMPTY */ 22325556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj else 22335556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj fp_tags |= (3 << (2*r)); /* VALID -- not really precise enough. */ 22345556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj } 22355556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj tmp.env[FP_ENV_TAG] = fp_tags; 22365556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 22375556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* Now write 'tmp' into the guest state. */ 2238ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes VexEmNote warnX87 = do_put_x87( True/*moveRegs*/, &tmp, gst ); 22395556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 224070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return warnX87; 224170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 22425556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 22435556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 224470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* CALLED FROM GENERATED CODE */ 224570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* DIRTY HELPER (writes guest state, reads guest mem) */ 224670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjVexEmNote amd64g_dirtyhelper_XRSTOR_COMPONENT_1_EXCLUDING_XMMREGS 224770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ( VexGuestAMD64State* gst, HWord addr ) 224870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 224970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UShort* addrS = (UShort*)addr; 225070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UInt w32 = (((UInt)addrS[12]) & 0xFFFF) 225170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj | ((((UInt)addrS[13]) & 0xFFFF) << 16); 225270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ULong w64 = amd64g_check_ldmxcsr( (ULong)w32 ); 225370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 225470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj VexEmNote warnXMM = (VexEmNote)(w64 >> 32); 225570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 225670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj gst->guest_SSEROUND = w64 & 0xFFFFFFFFULL; 225770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return warnXMM; 225870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 225970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 226070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 226170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* VISIBLE TO LIBVEX CLIENT */ 226270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* Do FXRSTOR from the supplied address and store read values to the given 226370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj VexGuestAMD64State structure. 226470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 226570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj This function is not called from generated code. FXRSTOR is dealt 226670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj with by the amd64 front end by calling the XRSTOR_COMPONENT_{0,1} 226770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj functions above plus some in-line IR. This function is merely a 226870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj convenience function for VEX's users. 226970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj*/ 227070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjVexEmNote LibVEX_GuestAMD64_fxrstor ( /*IN*/HWord fp_state, 227170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /*MOD*/VexGuestAMD64State* gst ) 227270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 227370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Restore %xmm0 .. %xmm15. If the host is big-endian, these need 227470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj to be byte-swapped. */ 227570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj U128 *xmm = (U128 *)(fp_state + 160); 227670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 227770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(host_is_little_endian()); 227870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 227970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj# define COPY_U128(_dst,_src) \ 228070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 228170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 228270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj while (0) 228370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 228470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM0, xmm[0] ); 228570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM1, xmm[1] ); 228670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM2, xmm[2] ); 228770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM3, xmm[3] ); 228870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM4, xmm[4] ); 228970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM5, xmm[5] ); 229070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM6, xmm[6] ); 229170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM7, xmm[7] ); 229270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM8, xmm[8] ); 229370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM9, xmm[9] ); 229470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM10, xmm[10] ); 229570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM11, xmm[11] ); 229670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM12, xmm[12] ); 229770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM13, xmm[13] ); 229870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM14, xmm[14] ); 229970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj COPY_U128( gst->guest_YMM15, xmm[15] ); 230070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 230170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj# undef COPY_U128 230270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 230370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj VexEmNote warnXMM 230470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj = amd64g_dirtyhelper_XRSTOR_COMPONENT_1_EXCLUDING_XMMREGS(gst, fp_state); 230570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj VexEmNote warnX87 230670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj = amd64g_dirtyhelper_XRSTOR_COMPONENT_0(gst, fp_state); 23075556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 23085556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj /* Prefer an X87 emwarn over an XMM one, if both exist. */ 23096ef84bed9bb3af22060eb1759788034602bbcc88florian if (warnX87 != EmNote_NONE) 23105556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj return warnX87; 23115556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj else 23125556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj return warnXMM; 23135556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj} 23145556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 23155556e5e2c77b722c233e3e49f915fa8c0aeba5b2sewardj 231670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 231770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*--- Supporting functions for FSAVE/FRSTOR ---*/ 231870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 23193e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj 23200585a03e90a5e6350a09e44528147e531bd77092sewardj/* DIRTY HELPER (writes guest state) */ 23218d965316c72c2392f670dcdfa127547ec77c7e56sewardj/* Initialise the x87 FPU state as per 'finit'. */ 23228d965316c72c2392f670dcdfa127547ec77c7e56sewardjvoid amd64g_dirtyhelper_FINIT ( VexGuestAMD64State* gst ) 23238d965316c72c2392f670dcdfa127547ec77c7e56sewardj{ 23248d965316c72c2392f670dcdfa127547ec77c7e56sewardj Int i; 23258d965316c72c2392f670dcdfa127547ec77c7e56sewardj gst->guest_FTOP = 0; 23268d965316c72c2392f670dcdfa127547ec77c7e56sewardj for (i = 0; i < 8; i++) { 23278d965316c72c2392f670dcdfa127547ec77c7e56sewardj gst->guest_FPTAG[i] = 0; /* empty */ 23288d965316c72c2392f670dcdfa127547ec77c7e56sewardj gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */ 23298d965316c72c2392f670dcdfa127547ec77c7e56sewardj } 23308d965316c72c2392f670dcdfa127547ec77c7e56sewardj gst->guest_FPROUND = (ULong)Irrm_NEAREST; 23318d965316c72c2392f670dcdfa127547ec77c7e56sewardj gst->guest_FC3210 = 0; 23328d965316c72c2392f670dcdfa127547ec77c7e56sewardj} 23338d965316c72c2392f670dcdfa127547ec77c7e56sewardj 2334d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 2335924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj/* CALLED FROM GENERATED CODE */ 2336924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj/* DIRTY HELPER (reads guest memory) */ 2337bdf99f06a5f44fd617c51ac80861ff07da09a50fflorianULong amd64g_dirtyhelper_loadF80le ( Addr addrU ) 2338924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj{ 2339924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj ULong f64; 2340bdf99f06a5f44fd617c51ac80861ff07da09a50fflorian convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 ); 2341924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj return f64; 2342924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj} 2343924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj 2344924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj/* CALLED FROM GENERATED CODE */ 2345924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj/* DIRTY HELPER (writes guest memory) */ 2346bdf99f06a5f44fd617c51ac80861ff07da09a50fflorianvoid amd64g_dirtyhelper_storeF80le ( Addr addrU, ULong f64 ) 2347924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj{ 2348bdf99f06a5f44fd617c51ac80861ff07da09a50fflorian convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU ); 2349924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj} 2350924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj 2351924215b14b9a8391f992b419220ffaa0b2e49ea7sewardj 2352bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* CALLED FROM GENERATED CODE */ 2353bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* CLEAN HELPER */ 2354bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* mxcsr[15:0] contains a SSE native format MXCSR value. 2355bcbb9de4726dfe62898f83578e4ec8099b710734sewardj Extract from it the required SSEROUND value and any resulting 2356bcbb9de4726dfe62898f83578e4ec8099b710734sewardj emulation warning, and return (warn << 32) | sseround value. 2357bcbb9de4726dfe62898f83578e4ec8099b710734sewardj*/ 2358bcbb9de4726dfe62898f83578e4ec8099b710734sewardjULong amd64g_check_ldmxcsr ( ULong mxcsr ) 2359bcbb9de4726dfe62898f83578e4ec8099b710734sewardj{ 2360bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* Decide on a rounding mode. mxcsr[14:13] holds it. */ 2361bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 2362bcbb9de4726dfe62898f83578e4ec8099b710734sewardj ULong rmode = (mxcsr >> 13) & 3; 2363bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2364bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* Detect any required emulation warnings. */ 23656ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew = EmNote_NONE; 2366bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2367bcbb9de4726dfe62898f83578e4ec8099b710734sewardj if ((mxcsr & 0x1F80) != 0x1F80) { 2368bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* unmasked exceptions! */ 2369bcbb9de4726dfe62898f83578e4ec8099b710734sewardj ew = EmWarn_X86_sseExns; 2370bcbb9de4726dfe62898f83578e4ec8099b710734sewardj } 2371bcbb9de4726dfe62898f83578e4ec8099b710734sewardj else 2372bcbb9de4726dfe62898f83578e4ec8099b710734sewardj if (mxcsr & (1<<15)) { 2373bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* FZ is set */ 2374bcbb9de4726dfe62898f83578e4ec8099b710734sewardj ew = EmWarn_X86_fz; 2375bcbb9de4726dfe62898f83578e4ec8099b710734sewardj } 2376bcbb9de4726dfe62898f83578e4ec8099b710734sewardj else 2377bcbb9de4726dfe62898f83578e4ec8099b710734sewardj if (mxcsr & (1<<6)) { 2378bcbb9de4726dfe62898f83578e4ec8099b710734sewardj /* DAZ is set */ 2379bcbb9de4726dfe62898f83578e4ec8099b710734sewardj ew = EmWarn_X86_daz; 2380bcbb9de4726dfe62898f83578e4ec8099b710734sewardj } 2381bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2382bcbb9de4726dfe62898f83578e4ec8099b710734sewardj return (((ULong)ew) << 32) | ((ULong)rmode); 2383bcbb9de4726dfe62898f83578e4ec8099b710734sewardj} 2384bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2385bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2386bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* CALLED FROM GENERATED CODE */ 2387bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* CLEAN HELPER */ 2388bcbb9de4726dfe62898f83578e4ec8099b710734sewardj/* Given sseround as an IRRoundingMode value, create a suitable SSE 2389bcbb9de4726dfe62898f83578e4ec8099b710734sewardj native format MXCSR value. */ 2390bcbb9de4726dfe62898f83578e4ec8099b710734sewardjULong amd64g_create_mxcsr ( ULong sseround ) 2391bcbb9de4726dfe62898f83578e4ec8099b710734sewardj{ 2392bcbb9de4726dfe62898f83578e4ec8099b710734sewardj sseround &= 3; 2393bcbb9de4726dfe62898f83578e4ec8099b710734sewardj return 0x1F80 | (sseround << 13); 2394bcbb9de4726dfe62898f83578e4ec8099b710734sewardj} 2395bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 2396bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 23975e205372f0023f11eb756ee38de40a065b0681c1sewardj/* CLEAN HELPER */ 23985e205372f0023f11eb756ee38de40a065b0681c1sewardj/* fpucw[15:0] contains a x87 native format FPU control word. 23995e205372f0023f11eb756ee38de40a065b0681c1sewardj Extract from it the required FPROUND value and any resulting 24005e205372f0023f11eb756ee38de40a065b0681c1sewardj emulation warning, and return (warn << 32) | fpround value. 24015e205372f0023f11eb756ee38de40a065b0681c1sewardj*/ 24025e205372f0023f11eb756ee38de40a065b0681c1sewardjULong amd64g_check_fldcw ( ULong fpucw ) 24035e205372f0023f11eb756ee38de40a065b0681c1sewardj{ 24045e205372f0023f11eb756ee38de40a065b0681c1sewardj /* Decide on a rounding mode. fpucw[11:10] holds it. */ 24055e205372f0023f11eb756ee38de40a065b0681c1sewardj /* NOTE, encoded exactly as per enum IRRoundingMode. */ 24065e205372f0023f11eb756ee38de40a065b0681c1sewardj ULong rmode = (fpucw >> 10) & 3; 24075e205372f0023f11eb756ee38de40a065b0681c1sewardj 24085e205372f0023f11eb756ee38de40a065b0681c1sewardj /* Detect any required emulation warnings. */ 24096ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew = EmNote_NONE; 24105e205372f0023f11eb756ee38de40a065b0681c1sewardj 24115e205372f0023f11eb756ee38de40a065b0681c1sewardj if ((fpucw & 0x3F) != 0x3F) { 24125e205372f0023f11eb756ee38de40a065b0681c1sewardj /* unmasked exceptions! */ 24135e205372f0023f11eb756ee38de40a065b0681c1sewardj ew = EmWarn_X86_x87exns; 24145e205372f0023f11eb756ee38de40a065b0681c1sewardj } 24155e205372f0023f11eb756ee38de40a065b0681c1sewardj else 24165e205372f0023f11eb756ee38de40a065b0681c1sewardj if (((fpucw >> 8) & 3) != 3) { 24175e205372f0023f11eb756ee38de40a065b0681c1sewardj /* unsupported precision */ 24185e205372f0023f11eb756ee38de40a065b0681c1sewardj ew = EmWarn_X86_x87precision; 24195e205372f0023f11eb756ee38de40a065b0681c1sewardj } 24205e205372f0023f11eb756ee38de40a065b0681c1sewardj 24215e205372f0023f11eb756ee38de40a065b0681c1sewardj return (((ULong)ew) << 32) | ((ULong)rmode); 24225e205372f0023f11eb756ee38de40a065b0681c1sewardj} 24235e205372f0023f11eb756ee38de40a065b0681c1sewardj 24245e205372f0023f11eb756ee38de40a065b0681c1sewardj 24255e205372f0023f11eb756ee38de40a065b0681c1sewardj/* CLEAN HELPER */ 24265e205372f0023f11eb756ee38de40a065b0681c1sewardj/* Given fpround as an IRRoundingMode value, create a suitable x87 24275e205372f0023f11eb756ee38de40a065b0681c1sewardj native format FPU control word. */ 24285e205372f0023f11eb756ee38de40a065b0681c1sewardjULong amd64g_create_fpucw ( ULong fpround ) 24295e205372f0023f11eb756ee38de40a065b0681c1sewardj{ 24305e205372f0023f11eb756ee38de40a065b0681c1sewardj fpround &= 3; 24315e205372f0023f11eb756ee38de40a065b0681c1sewardj return 0x037F | (fpround << 10); 24325e205372f0023f11eb756ee38de40a065b0681c1sewardj} 24335e205372f0023f11eb756ee38de40a065b0681c1sewardj 2434bcbb9de4726dfe62898f83578e4ec8099b710734sewardj 24354017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* This is used to implement 'fldenv'. 24364017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj Reads 28 bytes at x87_state[0 .. 27]. */ 24374017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* CALLED FROM GENERATED CODE */ 24384017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* DIRTY HELPER */ 24396ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote amd64g_dirtyhelper_FLDENV ( /*OUT*/VexGuestAMD64State* vex_state, 24404017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /*IN*/HWord x87_state) 24414017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj{ 2442ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return do_put_x87( False, (Fpu_State*)x87_state, vex_state ); 24434017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj} 24444017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24454017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24464017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* CALLED FROM GENERATED CODE */ 24474017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* DIRTY HELPER */ 24484017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj/* Create an x87 FPU env from the guest state, as close as we can 24494017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj approximate it. Writes 28 bytes at x87_state[0..27]. */ 24504017a3b223ee0ae98f6068e5eaaee0e3151d482asewardjvoid amd64g_dirtyhelper_FSTENV ( /*IN*/VexGuestAMD64State* vex_state, 24514017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /*OUT*/HWord x87_state ) 24524017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj{ 24534017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj Int i, stno, preg; 24544017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj UInt tagw; 24554017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 24564017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj Fpu_State* x87 = (Fpu_State*)x87_state; 24574017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj UInt ftop = vex_state->guest_FTOP; 24584017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj ULong c3210 = vex_state->guest_FC3210; 24594017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24604017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj for (i = 0; i < 14; i++) 24614017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj x87->env[i] = 0; 24624017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24634017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 24644017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj x87->env[FP_ENV_STAT] 246581d72eaa999c0ffae0f121dbd96b9b44ba67dce5sewardj = toUShort(toUInt( ((ftop & 7) << 11) | (c3210 & 0x4700) )); 24664017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj x87->env[FP_ENV_CTRL] 246781d72eaa999c0ffae0f121dbd96b9b44ba67dce5sewardj = toUShort(toUInt( amd64g_create_fpucw( vex_state->guest_FPROUND ) )); 24684017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24694017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /* Compute the x87 tag word. */ 24704017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj tagw = 0; 24714017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj for (stno = 0; stno < 8; stno++) { 24724017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj preg = (stno + ftop) & 7; 24734017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj if (vexTags[preg] == 0) { 24744017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /* register is empty */ 24754017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj tagw |= (3 << (2*preg)); 24764017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj } else { 24774017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /* register is full. */ 24784017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj tagw |= (0 << (2*preg)); 24794017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj } 24804017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj } 24814017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj x87->env[FP_ENV_TAG] = toUShort(tagw); 24824017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24834017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj /* We don't dump the x87 registers, tho. */ 24844017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj} 24854017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24864017a3b223ee0ae98f6068e5eaaee0e3151d482asewardj 24879ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* This is used to implement 'fnsave'. 24889ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Writes 108 bytes at x87_state[0 .. 107]. */ 24899ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* CALLED FROM GENERATED CODE */ 24909ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* DIRTY HELPER */ 24919ae42a77adfcd9fef928bef3439da258b6e6f748sewardjvoid amd64g_dirtyhelper_FNSAVE ( /*IN*/VexGuestAMD64State* vex_state, 24929ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /*OUT*/HWord x87_state) 24939ae42a77adfcd9fef928bef3439da258b6e6f748sewardj{ 2494ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes do_get_x87( vex_state, (Fpu_State*)x87_state ); 24959ae42a77adfcd9fef928bef3439da258b6e6f748sewardj} 24969ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 24979ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 24989ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* This is used to implement 'fnsaves'. 24999ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Writes 94 bytes at x87_state[0 .. 93]. */ 25009ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* CALLED FROM GENERATED CODE */ 25019ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* DIRTY HELPER */ 25029ae42a77adfcd9fef928bef3439da258b6e6f748sewardjvoid amd64g_dirtyhelper_FNSAVES ( /*IN*/VexGuestAMD64State* vex_state, 25039ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /*OUT*/HWord x87_state) 25049ae42a77adfcd9fef928bef3439da258b6e6f748sewardj{ 25059ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Int i, stno, preg; 25069ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt tagw; 25079ae42a77adfcd9fef928bef3439da258b6e6f748sewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 25089ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 25099ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Fpu_State_16* x87 = (Fpu_State_16*)x87_state; 25109ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt ftop = vex_state->guest_FTOP; 25119ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt c3210 = vex_state->guest_FC3210; 25129ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25139ae42a77adfcd9fef928bef3439da258b6e6f748sewardj for (i = 0; i < 7; i++) 25149ae42a77adfcd9fef928bef3439da258b6e6f748sewardj x87->env[i] = 0; 25159ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25169ae42a77adfcd9fef928bef3439da258b6e6f748sewardj x87->env[FPS_ENV_STAT] 25179ae42a77adfcd9fef928bef3439da258b6e6f748sewardj = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 25189ae42a77adfcd9fef928bef3439da258b6e6f748sewardj x87->env[FPS_ENV_CTRL] 25199ae42a77adfcd9fef928bef3439da258b6e6f748sewardj = toUShort(amd64g_create_fpucw( vex_state->guest_FPROUND )); 25209ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25219ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* Dump the register stack in ST order. */ 25229ae42a77adfcd9fef928bef3439da258b6e6f748sewardj tagw = 0; 25239ae42a77adfcd9fef928bef3439da258b6e6f748sewardj for (stno = 0; stno < 8; stno++) { 25249ae42a77adfcd9fef928bef3439da258b6e6f748sewardj preg = (stno + ftop) & 7; 25259ae42a77adfcd9fef928bef3439da258b6e6f748sewardj if (vexTags[preg] == 0) { 25269ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* register is empty */ 25279ae42a77adfcd9fef928bef3439da258b6e6f748sewardj tagw |= (3 << (2*preg)); 25289ae42a77adfcd9fef928bef3439da258b6e6f748sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 25299ae42a77adfcd9fef928bef3439da258b6e6f748sewardj &x87->reg[10*stno] ); 25309ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } else { 25319ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* register is full. */ 25329ae42a77adfcd9fef928bef3439da258b6e6f748sewardj tagw |= (0 << (2*preg)); 25339ae42a77adfcd9fef928bef3439da258b6e6f748sewardj convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 25349ae42a77adfcd9fef928bef3439da258b6e6f748sewardj &x87->reg[10*stno] ); 25359ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } 25369ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } 25379ae42a77adfcd9fef928bef3439da258b6e6f748sewardj x87->env[FPS_ENV_TAG] = toUShort(tagw); 25389ae42a77adfcd9fef928bef3439da258b6e6f748sewardj} 25399ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25409ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25419ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* This is used to implement 'frstor'. 25429ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Reads 108 bytes at x87_state[0 .. 107]. */ 25439ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* CALLED FROM GENERATED CODE */ 25449ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* DIRTY HELPER */ 25456ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote amd64g_dirtyhelper_FRSTOR ( /*OUT*/VexGuestAMD64State* vex_state, 25469ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /*IN*/HWord x87_state) 25479ae42a77adfcd9fef928bef3439da258b6e6f748sewardj{ 2548ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return do_put_x87( True, (Fpu_State*)x87_state, vex_state ); 25499ae42a77adfcd9fef928bef3439da258b6e6f748sewardj} 25509ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25519ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25529ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* This is used to implement 'frstors'. 25539ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Reads 94 bytes at x87_state[0 .. 93]. */ 25549ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* CALLED FROM GENERATED CODE */ 25559ae42a77adfcd9fef928bef3439da258b6e6f748sewardj/* DIRTY HELPER */ 25566ef84bed9bb3af22060eb1759788034602bbcc88florianVexEmNote amd64g_dirtyhelper_FRSTORS ( /*OUT*/VexGuestAMD64State* vex_state, 25579ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /*IN*/HWord x87_state) 25589ae42a77adfcd9fef928bef3439da258b6e6f748sewardj{ 25599ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Int stno, preg; 25609ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt tag; 25619ae42a77adfcd9fef928bef3439da258b6e6f748sewardj ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 25629ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 25639ae42a77adfcd9fef928bef3439da258b6e6f748sewardj Fpu_State_16* x87 = (Fpu_State_16*)x87_state; 25649ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt ftop = (x87->env[FPS_ENV_STAT] >> 11) & 7; 25659ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt tagw = x87->env[FPS_ENV_TAG]; 25669ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt fpucw = x87->env[FPS_ENV_CTRL]; 25679ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt c3210 = x87->env[FPS_ENV_STAT] & 0x4700; 25686ef84bed9bb3af22060eb1759788034602bbcc88florian VexEmNote ew; 25699ae42a77adfcd9fef928bef3439da258b6e6f748sewardj UInt fpround; 25709ae42a77adfcd9fef928bef3439da258b6e6f748sewardj ULong pair; 25719ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25729ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* Copy registers and tags */ 25739ae42a77adfcd9fef928bef3439da258b6e6f748sewardj for (stno = 0; stno < 8; stno++) { 25749ae42a77adfcd9fef928bef3439da258b6e6f748sewardj preg = (stno + ftop) & 7; 25759ae42a77adfcd9fef928bef3439da258b6e6f748sewardj tag = (tagw >> (2*preg)) & 3; 25769ae42a77adfcd9fef928bef3439da258b6e6f748sewardj if (tag == 3) { 25779ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* register is empty */ 25789ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* hmm, if it's empty, does it still get written? Probably 25799ae42a77adfcd9fef928bef3439da258b6e6f748sewardj safer to say it does. If we don't, memcheck could get out 25809ae42a77adfcd9fef928bef3439da258b6e6f748sewardj of sync, in that it thinks all FP registers are defined by 25819ae42a77adfcd9fef928bef3439da258b6e6f748sewardj this helper, but in reality some have not been updated. */ 25829ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 25839ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vexTags[preg] = 0; 25849ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } else { 25859ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* register is non-empty */ 25869ae42a77adfcd9fef928bef3439da258b6e6f748sewardj convert_f80le_to_f64le( &x87->reg[10*stno], 25879ae42a77adfcd9fef928bef3439da258b6e6f748sewardj (UChar*)&vexRegs[preg] ); 25889ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vexTags[preg] = 1; 25899ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } 25909ae42a77adfcd9fef928bef3439da258b6e6f748sewardj } 25919ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25929ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* stack pointer */ 25939ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vex_state->guest_FTOP = ftop; 25949ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25959ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* status word */ 25969ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vex_state->guest_FC3210 = c3210; 25979ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 25989ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* handle the control word, setting FPROUND and detecting any 25999ae42a77adfcd9fef928bef3439da258b6e6f748sewardj emulation warnings. */ 26009ae42a77adfcd9fef928bef3439da258b6e6f748sewardj pair = amd64g_check_fldcw ( (ULong)fpucw ); 26019ae42a77adfcd9fef928bef3439da258b6e6f748sewardj fpround = (UInt)pair & 0xFFFFFFFFULL; 26026ef84bed9bb3af22060eb1759788034602bbcc88florian ew = (VexEmNote)(pair >> 32); 26039ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 26049ae42a77adfcd9fef928bef3439da258b6e6f748sewardj vex_state->guest_FPROUND = fpround & 3; 26059ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 26069ae42a77adfcd9fef928bef3439da258b6e6f748sewardj /* emulation warnings --> caller */ 26079ae42a77adfcd9fef928bef3439da258b6e6f748sewardj return ew; 26089ae42a77adfcd9fef928bef3439da258b6e6f748sewardj} 26099ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 26109ae42a77adfcd9fef928bef3439da258b6e6f748sewardj 2611d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj/*---------------------------------------------------------------*/ 261270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*--- CPUID helpers. ---*/ 2613d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj/*---------------------------------------------------------------*/ 2614d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 2615e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj/* Claim to be the following CPU, which is probably representative of 2616e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj the lowliest (earliest) amd64 offerings. It can do neither sse3 2617e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj nor cx16. 2618e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2619e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vendor_id : AuthenticAMD 2620e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cpu family : 15 2621e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj model : 5 2622e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj model name : AMD Opteron (tm) Processor 848 2623e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj stepping : 10 2624e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cpu MHz : 1797.682 2625e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cache size : 1024 KB 2626e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj fpu : yes 2627e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj fpu_exception : yes 2628e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cpuid level : 1 2629e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj wp : yes 2630e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2631e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj mtrr pge mca cmov pat pse36 clflush mmx fxsr 2632e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj sse sse2 syscall nx mmxext lm 3dnowext 3dnow 2633e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj bogomips : 3600.62 2634e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj TLB size : 1088 4K pages 2635e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj clflush size : 64 2636e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cache_alignment : 64 2637e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj address sizes : 40 bits physical, 48 bits virtual 26381aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj power management: ts fid vid ttp 26391aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj 26401aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj 2012-Feb-21: don't claim 3dnow or 3dnowext, since in fact 26411aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj we don't support them. See #291568. 3dnow is 80000001.EDX.31 26421aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj and 3dnowext is 80000001.EDX.30. 2643e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj*/ 2644e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjvoid amd64g_dirtyhelper_CPUID_baseline ( VexGuestAMD64State* st ) 2645e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj{ 2646e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj# define SET_ABCD(_a,_b,_c,_d) \ 2647e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj do { st->guest_RAX = (ULong)(_a); \ 2648e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj st->guest_RBX = (ULong)(_b); \ 2649e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj st->guest_RCX = (ULong)(_c); \ 2650e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj st->guest_RDX = (ULong)(_d); \ 2651e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj } while (0) 2652e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2653e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj switch (0xFFFFFFFF & st->guest_RAX) { 2654e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x00000000: 2655e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000001, 0x68747541, 0x444d4163, 0x69746e65); 2656e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2657e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x00000001: 2658e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000f5a, 0x01000800, 0x00000000, 0x078bfbff); 2659e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2660e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000000: 2661e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x80000018, 0x68747541, 0x444d4163, 0x69746e65); 2662e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2663e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000001: 26641aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj /* Don't claim to support 3dnow or 3dnowext. 0xe1d3fbff is 26651aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj the original it-is-supported value that the h/w provides. 26661aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj See #291568. */ 26671aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj SET_ABCD(0x00000f5a, 0x00000505, 0x00000000, /*0xe1d3fbff*/ 26681aa3aefc284aee6a947e7f52079eb5e4e48f59acsewardj 0x21d3fbff); 2669e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2670e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000002: 2671e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x20444d41, 0x6574704f, 0x206e6f72, 0x296d7428); 2672e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2673e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000003: 2674e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x6f725020, 0x73736563, 0x3820726f, 0x00003834); 2675e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2676e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000004: 2677e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2678e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2679e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000005: 2680e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0xff08ff08, 0xff20ff20, 0x40020140, 0x40020140); 2681e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2682e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000006: 2683e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000000, 0x42004200, 0x04008140, 0x00000000); 2684e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2685e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000007: 2686e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x0000000f); 2687e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2688e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case 0x80000008: 2689e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00003028, 0x00000000, 0x00000000, 0x00000000); 2690e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2691e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj default: 2692e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2693e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 2694e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj } 2695e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj# undef SET_ABCD 2696e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj} 2697e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2698e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2699e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj/* Claim to be the following CPU (2 x ...), which is sse3 and cx16 2700e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj capable. 2701e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2702150c9cddb753ad4dc38f43484144523174d38b02sewardj vendor_id : GenuineIntel 2703150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu family : 6 2704150c9cddb753ad4dc38f43484144523174d38b02sewardj model : 15 2705150c9cddb753ad4dc38f43484144523174d38b02sewardj model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz 2706150c9cddb753ad4dc38f43484144523174d38b02sewardj stepping : 6 2707150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu MHz : 2394.000 2708150c9cddb753ad4dc38f43484144523174d38b02sewardj cache size : 4096 KB 2709150c9cddb753ad4dc38f43484144523174d38b02sewardj physical id : 0 2710150c9cddb753ad4dc38f43484144523174d38b02sewardj siblings : 2 2711150c9cddb753ad4dc38f43484144523174d38b02sewardj core id : 0 2712150c9cddb753ad4dc38f43484144523174d38b02sewardj cpu cores : 2 2713d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj fpu : yes 2714d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj fpu_exception : yes 2715150c9cddb753ad4dc38f43484144523174d38b02sewardj cpuid level : 10 2716d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj wp : yes 2717150c9cddb753ad4dc38f43484144523174d38b02sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2718150c9cddb753ad4dc38f43484144523174d38b02sewardj mtrr pge mca cmov pat pse36 clflush dts acpi 2719150c9cddb753ad4dc38f43484144523174d38b02sewardj mmx fxsr sse sse2 ss ht tm syscall nx lm 2720150c9cddb753ad4dc38f43484144523174d38b02sewardj constant_tsc pni monitor ds_cpl vmx est tm2 2721150c9cddb753ad4dc38f43484144523174d38b02sewardj cx16 xtpr lahf_lm 2722150c9cddb753ad4dc38f43484144523174d38b02sewardj bogomips : 4798.78 2723d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj clflush size : 64 2724d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj cache_alignment : 64 2725150c9cddb753ad4dc38f43484144523174d38b02sewardj address sizes : 36 bits physical, 48 bits virtual 2726150c9cddb753ad4dc38f43484144523174d38b02sewardj power management: 2727d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj*/ 2728e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjvoid amd64g_dirtyhelper_CPUID_sse3_and_cx16 ( VexGuestAMD64State* st ) 2729d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj{ 2730d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj# define SET_ABCD(_a,_b,_c,_d) \ 2731d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj do { st->guest_RAX = (ULong)(_a); \ 2732d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj st->guest_RBX = (ULong)(_b); \ 2733d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj st->guest_RCX = (ULong)(_c); \ 2734d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj st->guest_RDX = (ULong)(_d); \ 2735d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } while (0) 2736d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 2737d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj switch (0xFFFFFFFF & st->guest_RAX) { 2738150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000000: 2739150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69); 2740d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2741150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000001: 2742150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x000006f6, 0x00020800, 0x0000e3bd, 0xbfebfbff); 2743d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2744150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000002: 2745150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x05b0b101, 0x005657f0, 0x00000000, 0x2cb43049); 2746d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2747150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000003: 2748150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2749d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 275032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000004: { 275132bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj switch (0xFFFFFFFF & st->guest_RCX) { 275232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, 275332bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 275432bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, 275532bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x0000003f, 0x00000001); break; 275632bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, 275732bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000fff, 0x00000001); break; 275832bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj default: SET_ABCD(0x00000000, 0x00000000, 275932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj 0x00000000, 0x00000000); break; 276032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2761d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 276232bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj } 2763150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000005: 2764150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); 2765d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2766150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000006: 2767150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000001, 0x00000002, 0x00000001, 0x00000000); 2768d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2769150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000007: 2770150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2771d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2772150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000008: 2773150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000400, 0x00000000, 0x00000000, 0x00000000); 2774d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2775150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x00000009: 2776150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2777d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 2778150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x0000000a: 277932bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj unhandled_eax_value: 2780150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); 2781150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2782150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000000: 2783150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2784150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2785150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000001: 2786150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x20100800); 2787150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2788150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000002: 2789150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 2790150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2791150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000003: 2792150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x43203229, 0x20205550, 0x20202020, 0x20202020); 2793150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2794150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000004: 2795150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x30303636, 0x20402020, 0x30342e32, 0x007a4847); 2796150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2797150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000005: 2798150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2799150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2800150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000006: 2801150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x10008040, 0x00000000); 2802150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2803150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000007: 2804150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2805150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2806150c9cddb753ad4dc38f43484144523174d38b02sewardj case 0x80000008: 2807150c9cddb753ad4dc38f43484144523174d38b02sewardj SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2808150c9cddb753ad4dc38f43484144523174d38b02sewardj break; 2809d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj default: 281032bfd3e057bf3e0b215b1d234398b4d7791eba9asewardj goto unhandled_eax_value; 2811d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 2812d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj# undef SET_ABCD 2813d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj} 2814d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 2815d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 28160b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj/* Claim to be the following CPU (4 x ...), which is sse4.2 and cx16 28170b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj capable. 28180b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 28190b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj vendor_id : GenuineIntel 28200b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cpu family : 6 28210b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj model : 37 28220b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj model name : Intel(R) Core(TM) i5 CPU 670 @ 3.47GHz 28230b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj stepping : 2 28240b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cpu MHz : 3334.000 28250b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cache size : 4096 KB 28260b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj physical id : 0 28270b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj siblings : 4 28280b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj core id : 0 28290b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cpu cores : 2 28300b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj apicid : 0 28310b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj initial apicid : 0 28320b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj fpu : yes 28330b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj fpu_exception : yes 28340b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cpuid level : 11 28350b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj wp : yes 28360b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 28370b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj mtrr pge mca cmov pat pse36 clflush dts acpi 28380b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp 28390b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj lm constant_tsc arch_perfmon pebs bts rep_good 28400b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj xtopology nonstop_tsc aperfmperf pni pclmulqdq 28410b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 28420b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj xtpr pdcm sse4_1 sse4_2 popcnt aes lahf_lm ida 28430b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj arat tpr_shadow vnmi flexpriority ept vpid 28440b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj bogomips : 6957.57 28450b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj clflush size : 64 28460b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj cache_alignment : 64 28470b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj address sizes : 36 bits physical, 48 bits virtual 28480b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj power management: 28490b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj*/ 28500b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardjvoid amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st ) 28510b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj{ 28520b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj# define SET_ABCD(_a,_b,_c,_d) \ 28530b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj do { st->guest_RAX = (ULong)(_a); \ 28540b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj st->guest_RBX = (ULong)(_b); \ 28550b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj st->guest_RCX = (ULong)(_c); \ 28560b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj st->guest_RDX = (ULong)(_d); \ 28570b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj } while (0) 28580b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 28590b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj UInt old_eax = (UInt)st->guest_RAX; 28600b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj UInt old_ecx = (UInt)st->guest_RCX; 28610b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 28620b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj switch (old_eax) { 28630b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000000: 28640b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x0000000b, 0x756e6547, 0x6c65746e, 0x49656e69); 28650b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28660b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000001: 2867ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe SET_ABCD(0x00020652, 0x00100800, 0x0298e3ff, 0xbfebfbff); 28680b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28690b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000002: 28700b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x55035a01, 0x00f0b2e3, 0x00000000, 0x09ca212c); 28710b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28720b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000003: 28730b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 28740b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28750b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000004: 28760b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj switch (old_ecx) { 28770b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000000: SET_ABCD(0x1c004121, 0x01c0003f, 28780b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x0000003f, 0x00000000); break; 28790b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000001: SET_ABCD(0x1c004122, 0x00c0003f, 28800b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x0000007f, 0x00000000); break; 28810b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000002: SET_ABCD(0x1c004143, 0x01c0003f, 28820b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x000001ff, 0x00000000); break; 28830b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000003: SET_ABCD(0x1c03c163, 0x03c0003f, 28840b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000fff, 0x00000002); break; 28850b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj default: SET_ABCD(0x00000000, 0x00000000, 28860b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000000, 0x00000000); break; 28870b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj } 28880b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28890b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000005: 28900b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00001120); 28910b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28920b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000006: 28930b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000007, 0x00000002, 0x00000001, 0x00000000); 28940b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28950b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000007: 28960b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 28970b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 28980b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000008: 28990b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 29000b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29010b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000009: 29020b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 29030b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29040b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x0000000a: 29050b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x07300403, 0x00000004, 0x00000000, 0x00000603); 29060b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29070b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x0000000b: 29080b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj switch (old_ecx) { 29090b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000000: 29100b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000001, 0x00000002, 29110b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000100, 0x00000000); break; 29120b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000001: 29130b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000004, 0x00000004, 29140b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000201, 0x00000000); break; 29150b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj default: 29160b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 29170b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj old_ecx, 0x00000000); break; 29180b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj } 29190b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29200b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x0000000c: 29210b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000001, 0x00000002, 0x00000100, 0x00000000); 29220b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29230b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x0000000d: 29240b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj switch (old_ecx) { 29250b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000000: SET_ABCD(0x00000001, 0x00000002, 29260b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000100, 0x00000000); break; 29270b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x00000001: SET_ABCD(0x00000004, 0x00000004, 29280b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 0x00000201, 0x00000000); break; 29290b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj default: SET_ABCD(0x00000000, 0x00000000, 29300b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj old_ecx, 0x00000000); break; 29310b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj } 29320b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29330b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000000: 29340b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 29350b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29360b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000001: 29370b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x28100800); 29380b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29390b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000002: 29400b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 29410b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29420b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000003: 29430b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x35692029, 0x55504320, 0x20202020, 0x20202020); 29440b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29450b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000004: 29460b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x30373620, 0x20402020, 0x37342e33, 0x007a4847); 29470b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29480b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000005: 29490b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 29500b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29510b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000006: 29520b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x01006040, 0x00000000); 29530b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29540b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000007: 29550b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000100); 29560b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29570b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj case 0x80000008: 29580b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 29590b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29600b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj default: 29610b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj SET_ABCD(0x00000001, 0x00000002, 0x00000100, 0x00000000); 29620b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj break; 29630b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj } 29640b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj# undef SET_ABCD 29650b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj} 29660b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 29670b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 2968fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj/* Claim to be the following CPU (4 x ...), which is AVX and cx16 29699e4c3763314031a712e06d96746716aa2dd96a31sewardj capable. Plus (kludge!) it "supports" HTM. 2970fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 297170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj Also with the following change: claim that XSaveOpt is not 297270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj available, by cpuid(eax=0xD,ecx=1).eax[0] returns 0, compared to 1 297370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj on the real CPU. Consequently, programs that correctly observe 297470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj these CPUID values should only try to use 3 of the 8 XSave-family 297570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj instructions: XGETBV, XSAVE and XRSTOR. In particular this avoids 297670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj having to implement the compacted or optimised save/restore 297770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj variants. 297870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 2979fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj vendor_id : GenuineIntel 2980fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cpu family : 6 2981fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj model : 42 2982fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj model name : Intel(R) Core(TM) i5-2300 CPU @ 2.80GHz 2983fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj stepping : 7 2984fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cpu MHz : 1600.000 2985fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cache size : 6144 KB 2986fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj physical id : 0 2987fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj siblings : 4 2988fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj core id : 3 2989fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cpu cores : 4 2990fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj apicid : 6 2991fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj initial apicid : 6 2992fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj fpu : yes 2993fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj fpu_exception : yes 2994fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cpuid level : 13 2995fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj wp : yes 2996fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2997fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj mtrr pge mca cmov pat pse36 clflush dts acpi 2998fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp 2999fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj lm constant_tsc arch_perfmon pebs bts rep_good 3000fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq 3001fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 3002fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj xtpr pdcm sse4_1 sse4_2 popcnt aes xsave avx 3003fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj lahf_lm ida arat epb xsaveopt pln pts dts 3004fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj tpr_shadow vnmi flexpriority ept vpid 3005fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 3006fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj bogomips : 5768.94 3007fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj clflush size : 64 3008fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj cache_alignment : 64 3009fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj address sizes : 36 bits physical, 48 bits virtual 3010fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj power management: 3011fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj*/ 3012fe0c5e78ee12edb0a857e73dd21181b03299e560sewardjvoid amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st ) 3013fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj{ 3014fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj# define SET_ABCD(_a,_b,_c,_d) \ 3015fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj do { st->guest_RAX = (ULong)(_a); \ 3016fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj st->guest_RBX = (ULong)(_b); \ 3017fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj st->guest_RCX = (ULong)(_c); \ 3018fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj st->guest_RDX = (ULong)(_d); \ 3019fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj } while (0) 3020fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 3021fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj UInt old_eax = (UInt)st->guest_RAX; 3022fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj UInt old_ecx = (UInt)st->guest_RCX; 3023fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 3024fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj switch (old_eax) { 3025fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000000: 3026fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69); 3027fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3028fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000001: 3029fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x000206a7, 0x00100800, 0x1f9ae3bf, 0xbfebfbff); 3030fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3031fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000002: 3032fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000); 3033fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3034fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000003: 3035fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 3036fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3037fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000004: 3038fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj switch (old_ecx) { 3039fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000000: SET_ABCD(0x1c004121, 0x01c0003f, 3040fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x0000003f, 0x00000000); break; 3041fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000001: SET_ABCD(0x1c004122, 0x01c0003f, 3042fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x0000003f, 0x00000000); break; 3043fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000002: SET_ABCD(0x1c004143, 0x01c0003f, 3044fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x000001ff, 0x00000000); break; 3045fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000003: SET_ABCD(0x1c03c163, 0x02c0003f, 3046fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00001fff, 0x00000006); break; 3047fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj default: SET_ABCD(0x00000000, 0x00000000, 3048fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000000, 0x00000000); break; 3049fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj } 3050fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3051fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000005: 3052fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00001120); 3053fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3054fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000006: 3055fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000077, 0x00000002, 0x00000009, 0x00000000); 3056fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3057fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000007: 30589e4c3763314031a712e06d96746716aa2dd96a31sewardj SET_ABCD(0x00000000, 0x00000800, 0x00000000, 0x00000000); 3059fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3060fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000008: 3061fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 3062fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3063fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000009: 3064fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 3065fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3066fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000a: 3067fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x07300803, 0x00000000, 0x00000000, 0x00000603); 3068fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3069fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000b: 3070fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj switch (old_ecx) { 3071fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000000: 3072fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000001, 0x00000001, 3073fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000100, 0x00000000); break; 3074fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000001: 3075fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000004, 0x00000004, 3076fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000201, 0x00000000); break; 3077fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj default: 3078fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 3079fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj old_ecx, 0x00000000); break; 3080fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj } 3081fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3082fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000c: 3083fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 3084fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3085fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000d: 3086fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj switch (old_ecx) { 3087fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000000: SET_ABCD(0x00000007, 0x00000340, 3088fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000340, 0x00000000); break; 308970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000001: SET_ABCD(0x00000000, 0x00000000, 3090fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000000, 0x00000000); break; 3091fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x00000002: SET_ABCD(0x00000100, 0x00000240, 3092fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000000, 0x00000000); break; 3093fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj default: SET_ABCD(0x00000000, 0x00000000, 3094fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 0x00000000, 0x00000000); break; 3095fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj } 3096fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3097fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000e: 3098fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 3099fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3100fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x0000000f: 3101fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 3102fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3103fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000000: 3104fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 3105fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3106fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000001: 3107fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x28100800); 3108fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3109fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000002: 3110fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x20202020, 0x20202020, 0x65746e49, 0x2952286c); 3111fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3112fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000003: 3113fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x726f4320, 0x4d542865, 0x35692029, 0x3033322d); 3114fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3115fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000004: 3116fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x50432030, 0x20402055, 0x30382e32, 0x007a4847); 3117fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3118fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000005: 3119fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 3120fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3121fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000006: 3122fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x01006040, 0x00000000); 3123fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3124fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000007: 3125fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000100); 3126fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3127fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj case 0x80000008: 3128fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 3129fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3130fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj default: 3131fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 3132fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj break; 3133fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj } 3134fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj# undef SET_ABCD 3135fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj} 3136fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 3137fe0c5e78ee12edb0a857e73dd21181b03299e560sewardj 313870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/* Claim to be the following CPU (4 x ...), which is AVX2 capable. 313970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 314070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj With the following change: claim that XSaveOpt is not available, by 314170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cpuid(eax=0xD,ecx=1).eax[0] returns 0, compared to 1 on the real 314270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj CPU. Consequently, programs that correctly observe these CPUID 314370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj values should only try to use 3 of the 8 XSave-family instructions: 314470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj XGETBV, XSAVE and XRSTOR. In particular this avoids having to 314570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj implement the compacted or optimised save/restore variants. 314670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 314770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vendor_id : GenuineIntel 314870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cpu family : 6 314970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj model : 60 315070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj model name : Intel(R) Core(TM) i7-4910MQ CPU @ 2.90GHz 315170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj stepping : 3 315270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj microcode : 0x1c 315370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cpu MHz : 919.957 315470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cache size : 8192 KB 315570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj physical id : 0 315670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj siblings : 4 315770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj core id : 3 315870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cpu cores : 4 315970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj apicid : 6 316070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj initial apicid : 6 316170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj fpu : yes 316270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj fpu_exception : yes 316370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cpuid level : 13 316470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj wp : yes 316570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 316670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht 316770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc 316870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc 316970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl 317070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vmx smx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 317170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave 317270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj avx f16c rdrand lahf_lm abm ida arat epb pln pts dtherm 317370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust 317470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj bmi1 avx2 smep bmi2 erms invpcid xsaveopt 317570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj bugs : 317670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj bogomips : 5786.68 317770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj clflush size : 64 317870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj cache_alignment : 64 317970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj address sizes : 39 bits physical, 48 bits virtual 318070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj power management: 318170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj*/ 318270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjvoid amd64g_dirtyhelper_CPUID_avx2 ( VexGuestAMD64State* st ) 318370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 318470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj# define SET_ABCD(_a,_b,_c,_d) \ 318570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj do { st->guest_RAX = (ULong)(_a); \ 318670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj st->guest_RBX = (ULong)(_b); \ 318770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj st->guest_RCX = (ULong)(_c); \ 318870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj st->guest_RDX = (ULong)(_d); \ 318970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } while (0) 319070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 319170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UInt old_eax = (UInt)st->guest_RAX; 319270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj UInt old_ecx = (UInt)st->guest_RCX; 319370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 319470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj switch (old_eax) { 319570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000000: 319670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69); 319770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 319870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000001: 3199e602fa310dfa91e38a164d4d88603eaa7bdf6b2fmjw /* Don't advertise RDRAND support, bit 30 in ECX. */ 3200e602fa310dfa91e38a164d4d88603eaa7bdf6b2fmjw SET_ABCD(0x000306c3, 0x02100800, 0x3ffafbff, 0xbfebfbff); 320170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 320270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000002: 320370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x76036301, 0x00f0b6ff, 0x00000000, 0x00c10000); 320470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 320570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000003: 320670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 320770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 320870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000004: 320970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj switch (old_ecx) { 321070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000000: SET_ABCD(0x1c004121, 0x01c0003f, 321170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x0000003f, 0x00000000); break; 321270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000001: SET_ABCD(0x1c004122, 0x01c0003f, 321370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x0000003f, 0x00000000); break; 321470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000002: SET_ABCD(0x1c004143, 0x01c0003f, 321570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x000001ff, 0x00000000); break; 321670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000003: SET_ABCD(0x1c03c163, 0x03c0003f, 321770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00001fff, 0x00000006); break; 321870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj default: SET_ABCD(0x00000000, 0x00000000, 321970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 322070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 322170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 322270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000005: 322370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00042120); 322470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 322570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000006: 322670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000077, 0x00000002, 0x00000009, 0x00000000); 322770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 322870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000007: 322970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj switch (old_ecx) { 323070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000000: SET_ABCD(0x00000000, 0x000027ab, 323170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 323270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj default: SET_ABCD(0x00000000, 0x00000000, 323370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 323470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 323570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 323670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000008: 323770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 323870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 323970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000009: 324070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 324170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 324270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x0000000a: 324370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x07300803, 0x00000000, 0x00000000, 0x00000603); 324470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 324570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x0000000b: 324670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj switch (old_ecx) { 324770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000000: SET_ABCD(0x00000001, 0x00000002, 324870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000100, 0x00000002); break; 324970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000001: SET_ABCD(0x00000004, 0x00000008, 325070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000201, 0x00000002); break; 325170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj default: SET_ABCD(0x00000000, 0x00000000, 325270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj old_ecx, 0x00000002); break; 325370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 325470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 325570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x0000000c: 325670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 325770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 325870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x0000000d: 325970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj switch (old_ecx) { 326070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000000: SET_ABCD(0x00000007, 0x00000340, 326170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000340, 0x00000000); break; 326270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000001: SET_ABCD(0x00000000, 0x00000000, 326370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 326470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x00000002: SET_ABCD(0x00000100, 0x00000240, 326570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 326670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj default: SET_ABCD(0x00000000, 0x00000000, 326770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 0x00000000, 0x00000000); break; 326870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 326970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 327070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000000: 327170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 327270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 327370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000001: 327470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000021, 0x2c100800); 327570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 327670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000002: 327770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 327870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 327970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000003: 328070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x37692029, 0x3139342d, 0x20514d30, 0x20555043); 328170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 328270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000004: 328370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x2e322040, 0x48473039, 0x0000007a, 0x00000000); 328470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 328570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000005: 328670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 328770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 328870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000006: 328970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x01006040, 0x00000000); 329070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 329170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000007: 329270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000100); 329370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 329470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case 0x80000008: 329570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00003027, 0x00000000, 0x00000000, 0x00000000); 329670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 329770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj default: 329870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 329970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 330070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 330170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj# undef SET_ABCD 330270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 330370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 330470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 330570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 330670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*--- Misc integer helpers, including rotates and crypto. ---*/ 330770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj/*---------------------------------------------------------------*/ 330870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 3309112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardjULong amd64g_calculate_RCR ( ULong arg, 3310112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj ULong rot_amt, 3311112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj ULong rflags_in, 3312112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj Long szIN ) 3313112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj{ 3314112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj Bool wantRflags = toBool(szIN < 0); 3315112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj ULong sz = wantRflags ? (-szIN) : szIN; 3316112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj ULong tempCOUNT = rot_amt & (sz == 8 ? 0x3F : 0x1F); 3317112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj ULong cf=0, of=0, tempcf; 3318112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj 3319112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj switch (sz) { 3320112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj case 8: 3321112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3322112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj of = ((arg >> 63) ^ cf) & 1; 3323112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT > 0) { 3324112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempcf = arg & 1; 3325112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj arg = (arg >> 1) | (cf << 63); 3326112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = tempcf; 3327112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempCOUNT--; 3328112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj } 3329112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj break; 3330112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj case 4: 3331112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT >= 33) tempCOUNT -= 33; 3332112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3333112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj of = ((arg >> 31) ^ cf) & 1; 3334112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT > 0) { 3335112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempcf = arg & 1; 3336112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj arg = ((arg >> 1) & 0x7FFFFFFFULL) | (cf << 31); 3337112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = tempcf; 3338112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempCOUNT--; 3339112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj } 3340112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj break; 3341112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj case 2: 3342112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 3343112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3344112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj of = ((arg >> 15) ^ cf) & 1; 3345112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT > 0) { 3346112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempcf = arg & 1; 3347112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj arg = ((arg >> 1) & 0x7FFFULL) | (cf << 15); 3348112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = tempcf; 3349112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempCOUNT--; 3350112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj } 3351112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj break; 3352112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj case 1: 3353112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 3354112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3355112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj of = ((arg >> 7) ^ cf) & 1; 3356112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj while (tempCOUNT > 0) { 3357112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempcf = arg & 1; 3358112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj arg = ((arg >> 1) & 0x7FULL) | (cf << 7); 3359112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf = tempcf; 3360112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj tempCOUNT--; 3361112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj } 3362112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj break; 3363112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj default: 3364112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj vpanic("calculate_RCR(amd64g): invalid size"); 3365112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj } 3366112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj 3367112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj cf &= 1; 3368112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj of &= 1; 3369112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj rflags_in &= ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O); 3370112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj rflags_in |= (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O); 3371112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj 3372112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj /* caller can ask to have back either the resulting flags or 3373112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj resulting value, but not both */ 3374112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj return wantRflags ? rflags_in : arg; 3375112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj} 3376112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj 3377b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardjULong amd64g_calculate_RCL ( ULong arg, 3378b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj ULong rot_amt, 3379b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj ULong rflags_in, 3380b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj Long szIN ) 3381b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj{ 3382b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj Bool wantRflags = toBool(szIN < 0); 3383b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj ULong sz = wantRflags ? (-szIN) : szIN; 3384b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj ULong tempCOUNT = rot_amt & (sz == 8 ? 0x3F : 0x1F); 3385b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj ULong cf=0, of=0, tempcf; 3386b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj 3387b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj switch (sz) { 3388b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj case 8: 3389b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3390b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT > 0) { 3391b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempcf = (arg >> 63) & 1; 3392b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj arg = (arg << 1) | (cf & 1); 3393b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = tempcf; 3394b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempCOUNT--; 3395b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj } 3396b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj of = ((arg >> 63) ^ cf) & 1; 3397b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj break; 3398b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj case 4: 3399b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT >= 33) tempCOUNT -= 33; 3400b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3401b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT > 0) { 3402b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempcf = (arg >> 31) & 1; 3403b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj arg = 0xFFFFFFFFULL & ((arg << 1) | (cf & 1)); 3404b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = tempcf; 3405b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempCOUNT--; 3406b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj } 3407b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj of = ((arg >> 31) ^ cf) & 1; 3408b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj break; 3409b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj case 2: 3410b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT >= 17) tempCOUNT -= 17; 3411b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3412b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT > 0) { 3413b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempcf = (arg >> 15) & 1; 3414b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj arg = 0xFFFFULL & ((arg << 1) | (cf & 1)); 3415b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = tempcf; 3416b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempCOUNT--; 3417b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj } 3418b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj of = ((arg >> 15) ^ cf) & 1; 3419b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj break; 3420b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj case 1: 3421b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT >= 9) tempCOUNT -= 9; 3422b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 3423b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj while (tempCOUNT > 0) { 3424b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempcf = (arg >> 7) & 1; 3425b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj arg = 0xFFULL & ((arg << 1) | (cf & 1)); 3426b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf = tempcf; 3427b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj tempCOUNT--; 3428b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj } 3429b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj of = ((arg >> 7) ^ cf) & 1; 3430b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj break; 3431b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj default: 3432b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj vpanic("calculate_RCL(amd64g): invalid size"); 3433b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj } 3434b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj 3435b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj cf &= 1; 3436b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj of &= 1; 3437b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj rflags_in &= ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O); 3438b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj rflags_in |= (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O); 3439b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj 3440b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj return wantRflags ? rflags_in : arg; 3441b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj} 3442b5e5c6ddb5ebc23c19494c2e3a8e8b9a6b36a04asewardj 34431a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj/* Taken from gf2x-0.9.5, released under GPLv2+ (later versions LGPLv2+) 34441a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj * svn://scm.gforge.inria.fr/svn/gf2x/trunk/hardware/opteron/gf2x_mul1.h@25 34451a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj */ 34461a179b5d699c167427e6a1f37ec01ba66674b2e1sewardjULong amd64g_calculate_pclmul(ULong a, ULong b, ULong which) 34471a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj{ 34481a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj ULong hi, lo, tmp, A[16]; 34491a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj 34501a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[0] = 0; A[1] = a; 34511a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[2] = A[1] << 1; A[3] = A[2] ^ a; 34521a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[4] = A[2] << 1; A[5] = A[4] ^ a; 34531a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[6] = A[3] << 1; A[7] = A[6] ^ a; 34541a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[8] = A[4] << 1; A[9] = A[8] ^ a; 34551a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[10] = A[5] << 1; A[11] = A[10] ^ a; 34561a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[12] = A[6] << 1; A[13] = A[12] ^ a; 34571a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj A[14] = A[7] << 1; A[15] = A[14] ^ a; 34581a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj 34591a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (A[b >> 60] << 4) ^ A[(b >> 56) & 15]; 34601a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = lo >> 56; 34611a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 52) & 15] << 4) ^ A[(b >> 48) & 15]; 34621a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34631a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 44) & 15] << 4) ^ A[(b >> 40) & 15]; 34641a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34651a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 36) & 15] << 4) ^ A[(b >> 32) & 15]; 34661a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34671a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 28) & 15] << 4) ^ A[(b >> 24) & 15]; 34681a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34691a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 20) & 15] << 4) ^ A[(b >> 16) & 15]; 34701a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34711a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 12) & 15] << 4) ^ A[(b >> 8) & 15]; 34721a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj hi = (hi << 8) | (lo >> 56); 34731a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj lo = (lo << 8) ^ (A[(b >> 4) & 15] << 4) ^ A[b & 15]; 34741a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj 34751a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj ULong m0 = -1; 34761a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj m0 /= 255; 34771a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 63) & 1); tmp &= ((b & (m0 * 0xfe)) >> 1); hi = hi ^ tmp; 34781a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 62) & 1); tmp &= ((b & (m0 * 0xfc)) >> 2); hi = hi ^ tmp; 34791a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 61) & 1); tmp &= ((b & (m0 * 0xf8)) >> 3); hi = hi ^ tmp; 34801a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 60) & 1); tmp &= ((b & (m0 * 0xf0)) >> 4); hi = hi ^ tmp; 34811a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 59) & 1); tmp &= ((b & (m0 * 0xe0)) >> 5); hi = hi ^ tmp; 34821a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 58) & 1); tmp &= ((b & (m0 * 0xc0)) >> 6); hi = hi ^ tmp; 34831a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj tmp = -((a >> 57) & 1); tmp &= ((b & (m0 * 0x80)) >> 7); hi = hi ^ tmp; 34841a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj 34851a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj return which ? hi : lo; 34861a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj} 34871a179b5d699c167427e6a1f37ec01ba66674b2e1sewardj 3488112b09931d68ea3bf991ad5582f5fe0c7e481ae2sewardj 3489bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj/* CALLED FROM GENERATED CODE */ 3490bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj/* DIRTY HELPER (non-referentially-transparent) */ 3491bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj/* Horrible hack. On non-amd64 platforms, return 1. */ 3492bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardjULong amd64g_dirtyhelper_RDTSC ( void ) 3493bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj{ 3494bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj# if defined(__x86_64__) 3495bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj UInt eax, edx; 3496bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj __asm__ __volatile__("rdtsc" : "=a" (eax), "=d" (edx)); 3497bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj return (((ULong)edx) << 32) | ((ULong)eax); 3498bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj# else 3499bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj return 1ULL; 3500bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj# endif 3501bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj} 3502bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj 3503818c730f624828ef2d5532e32e952924094b699esewardj/* CALLED FROM GENERATED CODE */ 3504818c730f624828ef2d5532e32e952924094b699esewardj/* DIRTY HELPER (non-referentially-transparent) */ 3505818c730f624828ef2d5532e32e952924094b699esewardj/* Horrible hack. On non-amd64 platforms, return 1. */ 3506818c730f624828ef2d5532e32e952924094b699esewardj/* This uses a different calling convention from _RDTSC just above 3507818c730f624828ef2d5532e32e952924094b699esewardj only because of the difficulty of returning 96 bits from a C 3508818c730f624828ef2d5532e32e952924094b699esewardj function -- RDTSC returns 64 bits and so is simple by comparison, 3509818c730f624828ef2d5532e32e952924094b699esewardj on amd64. */ 3510818c730f624828ef2d5532e32e952924094b699esewardjvoid amd64g_dirtyhelper_RDTSCP ( VexGuestAMD64State* st ) 3511818c730f624828ef2d5532e32e952924094b699esewardj{ 3512818c730f624828ef2d5532e32e952924094b699esewardj# if defined(__x86_64__) 3513818c730f624828ef2d5532e32e952924094b699esewardj UInt eax, ecx, edx; 3514818c730f624828ef2d5532e32e952924094b699esewardj __asm__ __volatile__("rdtscp" : "=a" (eax), "=d" (edx), "=c" (ecx)); 3515818c730f624828ef2d5532e32e952924094b699esewardj st->guest_RAX = (ULong)eax; 3516818c730f624828ef2d5532e32e952924094b699esewardj st->guest_RCX = (ULong)ecx; 3517818c730f624828ef2d5532e32e952924094b699esewardj st->guest_RDX = (ULong)edx; 3518818c730f624828ef2d5532e32e952924094b699esewardj# else 3519818c730f624828ef2d5532e32e952924094b699esewardj /* Do nothing. */ 3520818c730f624828ef2d5532e32e952924094b699esewardj# endif 3521818c730f624828ef2d5532e32e952924094b699esewardj} 3522bc6af53b0ac9e4199fbbfde77c275fa04f2841bfsewardj 3523bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* CALLED FROM GENERATED CODE */ 3524bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* DIRTY HELPER (non-referentially-transparent) */ 3525bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* Horrible hack. On non-amd64 platforms, return 0. */ 3526bb4396c768958b79f0ec1f737fe457aad984a0absewardjULong amd64g_dirtyhelper_IN ( ULong portno, ULong sz/*1,2 or 4*/ ) 3527bb4396c768958b79f0ec1f737fe457aad984a0absewardj{ 3528bb4396c768958b79f0ec1f737fe457aad984a0absewardj# if defined(__x86_64__) 3529bb4396c768958b79f0ec1f737fe457aad984a0absewardj ULong r = 0; 3530bb4396c768958b79f0ec1f737fe457aad984a0absewardj portno &= 0xFFFF; 3531bb4396c768958b79f0ec1f737fe457aad984a0absewardj switch (sz) { 3532bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 4: 3533bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("movq $0,%%rax; inl %w1,%%eax; movq %%rax,%0" 3534bb4396c768958b79f0ec1f737fe457aad984a0absewardj : "=a" (r) : "Nd" (portno)); 3535bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3536bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 2: 3537bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("movq $0,%%rax; inw %w1,%w0" 3538bb4396c768958b79f0ec1f737fe457aad984a0absewardj : "=a" (r) : "Nd" (portno)); 3539bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3540bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 1: 3541bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("movq $0,%%rax; inb %w1,%b0" 3542bb4396c768958b79f0ec1f737fe457aad984a0absewardj : "=a" (r) : "Nd" (portno)); 3543bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3544bb4396c768958b79f0ec1f737fe457aad984a0absewardj default: 3545bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; /* note: no 64-bit version of insn exists */ 3546bb4396c768958b79f0ec1f737fe457aad984a0absewardj } 3547bb4396c768958b79f0ec1f737fe457aad984a0absewardj return r; 3548bb4396c768958b79f0ec1f737fe457aad984a0absewardj# else 3549bb4396c768958b79f0ec1f737fe457aad984a0absewardj return 0; 3550bb4396c768958b79f0ec1f737fe457aad984a0absewardj# endif 3551bb4396c768958b79f0ec1f737fe457aad984a0absewardj} 3552bb4396c768958b79f0ec1f737fe457aad984a0absewardj 3553bb4396c768958b79f0ec1f737fe457aad984a0absewardj 3554bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* CALLED FROM GENERATED CODE */ 3555bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* DIRTY HELPER (non-referentially-transparent) */ 3556bb4396c768958b79f0ec1f737fe457aad984a0absewardj/* Horrible hack. On non-amd64 platforms, do nothing. */ 3557bb4396c768958b79f0ec1f737fe457aad984a0absewardjvoid amd64g_dirtyhelper_OUT ( ULong portno, ULong data, ULong sz/*1,2 or 4*/ ) 3558bb4396c768958b79f0ec1f737fe457aad984a0absewardj{ 3559bb4396c768958b79f0ec1f737fe457aad984a0absewardj# if defined(__x86_64__) 3560bb4396c768958b79f0ec1f737fe457aad984a0absewardj portno &= 0xFFFF; 3561bb4396c768958b79f0ec1f737fe457aad984a0absewardj switch (sz) { 3562bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 4: 3563bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("movq %0,%%rax; outl %%eax, %w1" 3564bb4396c768958b79f0ec1f737fe457aad984a0absewardj : : "a" (data), "Nd" (portno)); 3565bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3566bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 2: 3567bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("outw %w0, %w1" 3568bb4396c768958b79f0ec1f737fe457aad984a0absewardj : : "a" (data), "Nd" (portno)); 3569bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3570bb4396c768958b79f0ec1f737fe457aad984a0absewardj case 1: 3571bb4396c768958b79f0ec1f737fe457aad984a0absewardj __asm__ __volatile__("outb %b0, %w1" 3572bb4396c768958b79f0ec1f737fe457aad984a0absewardj : : "a" (data), "Nd" (portno)); 3573bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; 3574bb4396c768958b79f0ec1f737fe457aad984a0absewardj default: 3575bb4396c768958b79f0ec1f737fe457aad984a0absewardj break; /* note: no 64-bit version of insn exists */ 3576bb4396c768958b79f0ec1f737fe457aad984a0absewardj } 3577bb4396c768958b79f0ec1f737fe457aad984a0absewardj# else 3578bb4396c768958b79f0ec1f737fe457aad984a0absewardj /* do nothing */ 3579bb4396c768958b79f0ec1f737fe457aad984a0absewardj# endif 3580bb4396c768958b79f0ec1f737fe457aad984a0absewardj} 3581bb4396c768958b79f0ec1f737fe457aad984a0absewardj 3582b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* CALLED FROM GENERATED CODE */ 3583b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* DIRTY HELPER (non-referentially-transparent) */ 3584b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* Horrible hack. On non-amd64 platforms, do nothing. */ 3585b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj/* op = 0: call the native SGDT instruction. 3586b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj op = 1: call the native SIDT instruction. 3587b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj*/ 3588b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardjvoid amd64g_dirtyhelper_SxDT ( void *address, ULong op ) { 3589b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# if defined(__x86_64__) 3590b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj switch (op) { 3591b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 0: 3592b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory"); 3593b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 3594b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj case 1: 3595b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory"); 3596b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj break; 3597b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj default: 3598b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj vpanic("amd64g_dirtyhelper_SxDT"); 3599b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj } 3600b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# else 3601b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj /* do nothing */ 3602b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj UChar* p = (UChar*)address; 3603b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0; 3604b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj p[6] = p[7] = p[8] = p[9] = 0; 3605b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj# endif 3606b9dc2430577bddf8c42e3d3fbe887c32cada9130sewardj} 3607bb4396c768958b79f0ec1f737fe457aad984a0absewardj 36088711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj/*---------------------------------------------------------------*/ 36098711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj/*--- Helpers for MMX/SSE/SSE2. ---*/ 36108711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj/*---------------------------------------------------------------*/ 36118711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj 3612a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar abdU8 ( UChar xx, UChar yy ) { 3613a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(xx>yy ? xx-yy : yy-xx); 3614a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3615a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj 36168711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) { 36178711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return (((ULong)w1) << 32) | ((ULong)w0); 36188711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36198711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj 36208711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjstatic inline UShort sel16x4_3 ( ULong w64 ) { 36218711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj UInt hi32 = toUInt(w64 >> 32); 36228711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return toUShort(hi32 >> 16); 36238711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36248711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjstatic inline UShort sel16x4_2 ( ULong w64 ) { 36258711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj UInt hi32 = toUInt(w64 >> 32); 36268711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return toUShort(hi32); 36278711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36288711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjstatic inline UShort sel16x4_1 ( ULong w64 ) { 36298711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj UInt lo32 = toUInt(w64); 36308711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return toUShort(lo32 >> 16); 36318711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36328711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjstatic inline UShort sel16x4_0 ( ULong w64 ) { 36338711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj UInt lo32 = toUInt(w64); 36348711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return toUShort(lo32); 36358711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36368711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj 3637a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_7 ( ULong w64 ) { 3638a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt hi32 = toUInt(w64 >> 32); 3639a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(hi32 >> 24); 3640a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3641a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_6 ( ULong w64 ) { 3642a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt hi32 = toUInt(w64 >> 32); 3643a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(hi32 >> 16); 3644a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3645a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_5 ( ULong w64 ) { 3646a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt hi32 = toUInt(w64 >> 32); 3647a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(hi32 >> 8); 3648a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3649a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_4 ( ULong w64 ) { 3650a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt hi32 = toUInt(w64 >> 32); 3651a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(hi32 >> 0); 3652a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3653a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_3 ( ULong w64 ) { 3654a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt lo32 = toUInt(w64); 3655a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(lo32 >> 24); 3656a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3657a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_2 ( ULong w64 ) { 3658a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt lo32 = toUInt(w64); 3659a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(lo32 >> 16); 3660a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3661a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_1 ( ULong w64 ) { 3662a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt lo32 = toUInt(w64); 3663a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(lo32 >> 8); 3664a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3665a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjstatic inline UChar sel8x8_0 ( ULong w64 ) { 3666a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt lo32 = toUInt(w64); 3667a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return toUChar(lo32 >> 0); 3668a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3669a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj 36708711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 36718711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardjULong amd64g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) 36728711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj{ 36738711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj return 36748711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj mk32x2( 36758711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) 36768711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), 36778711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) 36788711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) 36798711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj ); 36808711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj} 36818711f665fcdcfa7cc49e06eb6ec4f27de1e4efafsewardj 3682a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3683a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardjULong amd64g_calculate_mmx_psadbw ( ULong xx, ULong yy ) 3684a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj{ 3685a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj UInt t = 0; 3686a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); 3687a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); 3688a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); 3689a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); 3690a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 3691a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 3692a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 3693a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 3694a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj t &= 0xFFFF; 3695a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj return (ULong)t; 3696a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj} 3697a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj 3698adffcef004712e8afc6a7d87b30ef90e4685df40sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 36998cb931eee8a5567a7d2b7eee011ebc4757474910sewardjULong amd64g_calculate_sse_phminposuw ( ULong sLo, ULong sHi ) 37008cb931eee8a5567a7d2b7eee011ebc4757474910sewardj{ 37018cb931eee8a5567a7d2b7eee011ebc4757474910sewardj UShort t, min; 37028cb931eee8a5567a7d2b7eee011ebc4757474910sewardj UInt idx; 37038cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_0(sLo); if (True) { min = t; idx = 0; } 37048cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_1(sLo); if (t < min) { min = t; idx = 1; } 37058cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_2(sLo); if (t < min) { min = t; idx = 2; } 37068cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_3(sLo); if (t < min) { min = t; idx = 3; } 37078cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_0(sHi); if (t < min) { min = t; idx = 4; } 37088cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_1(sHi); if (t < min) { min = t; idx = 5; } 37098cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_2(sHi); if (t < min) { min = t; idx = 6; } 37108cb931eee8a5567a7d2b7eee011ebc4757474910sewardj t = sel16x4_3(sHi); if (t < min) { min = t; idx = 7; } 37118cb931eee8a5567a7d2b7eee011ebc4757474910sewardj return ((ULong)(idx << 16)) | ((ULong)min); 37128cb931eee8a5567a7d2b7eee011ebc4757474910sewardj} 37138cb931eee8a5567a7d2b7eee011ebc4757474910sewardj 37148cb931eee8a5567a7d2b7eee011ebc4757474910sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3715186f8692b53961e36a7eb4b2d845c26ad2114039sewardjULong amd64g_calc_crc32b ( ULong crcIn, ULong b ) 3716186f8692b53961e36a7eb4b2d845c26ad2114039sewardj{ 3717186f8692b53961e36a7eb4b2d845c26ad2114039sewardj UInt i; 3718186f8692b53961e36a7eb4b2d845c26ad2114039sewardj ULong crc = (b & 0xFFULL) ^ crcIn; 3719186f8692b53961e36a7eb4b2d845c26ad2114039sewardj for (i = 0; i < 8; i++) 3720186f8692b53961e36a7eb4b2d845c26ad2114039sewardj crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3721186f8692b53961e36a7eb4b2d845c26ad2114039sewardj return crc; 3722186f8692b53961e36a7eb4b2d845c26ad2114039sewardj} 3723186f8692b53961e36a7eb4b2d845c26ad2114039sewardj 3724186f8692b53961e36a7eb4b2d845c26ad2114039sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3725186f8692b53961e36a7eb4b2d845c26ad2114039sewardjULong amd64g_calc_crc32w ( ULong crcIn, ULong w ) 3726186f8692b53961e36a7eb4b2d845c26ad2114039sewardj{ 3727186f8692b53961e36a7eb4b2d845c26ad2114039sewardj UInt i; 3728186f8692b53961e36a7eb4b2d845c26ad2114039sewardj ULong crc = (w & 0xFFFFULL) ^ crcIn; 3729186f8692b53961e36a7eb4b2d845c26ad2114039sewardj for (i = 0; i < 16; i++) 3730186f8692b53961e36a7eb4b2d845c26ad2114039sewardj crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3731186f8692b53961e36a7eb4b2d845c26ad2114039sewardj return crc; 3732186f8692b53961e36a7eb4b2d845c26ad2114039sewardj} 3733186f8692b53961e36a7eb4b2d845c26ad2114039sewardj 3734186f8692b53961e36a7eb4b2d845c26ad2114039sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3735186f8692b53961e36a7eb4b2d845c26ad2114039sewardjULong amd64g_calc_crc32l ( ULong crcIn, ULong l ) 3736186f8692b53961e36a7eb4b2d845c26ad2114039sewardj{ 3737186f8692b53961e36a7eb4b2d845c26ad2114039sewardj UInt i; 3738186f8692b53961e36a7eb4b2d845c26ad2114039sewardj ULong crc = (l & 0xFFFFFFFFULL) ^ crcIn; 3739186f8692b53961e36a7eb4b2d845c26ad2114039sewardj for (i = 0; i < 32; i++) 3740186f8692b53961e36a7eb4b2d845c26ad2114039sewardj crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3741186f8692b53961e36a7eb4b2d845c26ad2114039sewardj return crc; 3742186f8692b53961e36a7eb4b2d845c26ad2114039sewardj} 3743186f8692b53961e36a7eb4b2d845c26ad2114039sewardj 3744186f8692b53961e36a7eb4b2d845c26ad2114039sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3745186f8692b53961e36a7eb4b2d845c26ad2114039sewardjULong amd64g_calc_crc32q ( ULong crcIn, ULong q ) 3746186f8692b53961e36a7eb4b2d845c26ad2114039sewardj{ 3747186f8692b53961e36a7eb4b2d845c26ad2114039sewardj ULong crc = amd64g_calc_crc32l(crcIn, q); 3748186f8692b53961e36a7eb4b2d845c26ad2114039sewardj return amd64g_calc_crc32l(crc, q >> 32); 3749186f8692b53961e36a7eb4b2d845c26ad2114039sewardj} 3750186f8692b53961e36a7eb4b2d845c26ad2114039sewardj 3751d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 37524d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj/* .. helper for next fn .. */ 37534d5bce29aabaa27792db8e4ac17da5d174df88e2sewardjstatic inline ULong sad_8x4 ( ULong xx, ULong yy ) 37544d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj{ 37554d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj UInt t = 0; 37564d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 37574d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 37584d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 37594d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 37604d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj return (ULong)t; 37614d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj} 37624d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj 37634d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 37644d5bce29aabaa27792db8e4ac17da5d174df88e2sewardjULong amd64g_calc_mpsadbw ( ULong sHi, ULong sLo, 37654d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong dHi, ULong dLo, 37664d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong imm_and_return_control_bit ) 37674d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj{ 37684d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj UInt imm8 = imm_and_return_control_bit & 7; 37694d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj Bool calcHi = (imm_and_return_control_bit >> 7) & 1; 37704d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj UInt srcOffsL = imm8 & 3; /* src offs in 32-bit (L) chunks */ 37714d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj UInt dstOffsL = (imm8 >> 2) & 1; /* dst offs in ditto chunks */ 37724d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* For src we only need 32 bits, so get them into the 37734d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj lower half of a 64 bit word. */ 37744d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong src = ((srcOffsL & 2) ? sHi : sLo) >> (32 * (srcOffsL & 1)); 37754d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* For dst we need to get hold of 56 bits (7 bytes) from a total of 37764d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj 11 bytes. If calculating the low part of the result, need bytes 37774d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dstOffsL * 4 + (0 .. 6); if calculating the high part, 37784d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dstOffsL * 4 + (4 .. 10). */ 37794d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong dst; 37804d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* dstOffL = 0, Lo -> 0 .. 6 37814d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dstOffL = 1, Lo -> 4 .. 10 37824d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dstOffL = 0, Hi -> 4 .. 10 37834d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dstOffL = 1, Hi -> 8 .. 14 37844d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj */ 37854d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj if (calcHi && dstOffsL) { 37864d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* 8 .. 14 */ 37874d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dst = dHi & 0x00FFFFFFFFFFFFFFULL; 37884d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj } 37894d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj else if (!calcHi && !dstOffsL) { 37904d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* 0 .. 6 */ 37914d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dst = dLo & 0x00FFFFFFFFFFFFFFULL; 37924d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj } 37934d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj else { 37944d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj /* 4 .. 10 */ 37954d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj dst = (dLo >> 32) | ((dHi & 0x00FFFFFFULL) << 32); 37964d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj } 37974d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong r0 = sad_8x4( dst >> 0, src ); 37984d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong r1 = sad_8x4( dst >> 8, src ); 37994d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong r2 = sad_8x4( dst >> 16, src ); 38004d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong r3 = sad_8x4( dst >> 24, src ); 38014d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj ULong res = (r3 << 48) | (r2 << 32) | (r1 << 16) | r0; 38024d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj return res; 38034d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj} 38044d5bce29aabaa27792db8e4ac17da5d174df88e2sewardj 3805cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3806cc3d219c3120150c9ab67f1f4850be0f39a9499csewardjULong amd64g_calculate_pext ( ULong src_masked, ULong mask ) 3807cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ 3808cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong dst = 0; 3809cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong src_bit; 3810cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong dst_bit = 1; 3811cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj for (src_bit = 1; src_bit; src_bit <<= 1) { 3812cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj if (mask & src_bit) { 3813cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj if (src_masked & src_bit) dst |= dst_bit; 3814cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj dst_bit <<= 1; 3815cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } 3816cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } 3817cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return dst; 3818cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 3819cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 3820cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3821cc3d219c3120150c9ab67f1f4850be0f39a9499csewardjULong amd64g_calculate_pdep ( ULong src, ULong mask ) 3822cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj{ 3823cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong dst = 0; 3824cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong dst_bit; 3825cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj ULong src_bit = 1; 3826cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj for (dst_bit = 1; dst_bit; dst_bit <<= 1) { 3827cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj if (mask & dst_bit) { 3828cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj if (src & src_bit) dst |= dst_bit; 3829cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj src_bit <<= 1; 3830cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } 3831cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj } 3832cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj return dst; 3833cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj} 3834cc3d219c3120150c9ab67f1f4850be0f39a9499csewardj 3835f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 38360b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj/*--- Helpers for SSE4.2 PCMP{E,I}STR{I,M} ---*/ 38370b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj/*---------------------------------------------------------------*/ 38380b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 3839acfbd7d59ee5c85911c687c6666940a38019f48fsewardjstatic UInt zmask_from_V128 ( V128* arg ) 38400b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj{ 3841acfbd7d59ee5c85911c687c6666940a38019f48fsewardj UInt i, res = 0; 3842acfbd7d59ee5c85911c687c6666940a38019f48fsewardj for (i = 0; i < 16; i++) { 3843acfbd7d59ee5c85911c687c6666940a38019f48fsewardj res |= ((arg->w8[i] == 0) ? 1 : 0) << i; 3844acfbd7d59ee5c85911c687c6666940a38019f48fsewardj } 3845acfbd7d59ee5c85911c687c6666940a38019f48fsewardj return res; 38460b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj} 38470b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 38483c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardjstatic UInt zmask_from_V128_wide ( V128* arg ) 38493c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj{ 38503c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj UInt i, res = 0; 38513c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj for (i = 0; i < 8; i++) { 38523c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj res |= ((arg->w16[i] == 0) ? 1 : 0) << i; 38533c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } 38543c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj return res; 38553c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj} 38563c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj 3857acfbd7d59ee5c85911c687c6666940a38019f48fsewardj/* Helps with PCMP{I,E}STR{I,M}. 38580b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 3859acfbd7d59ee5c85911c687c6666940a38019f48fsewardj CALLED FROM GENERATED CODE: DIRTY HELPER(s). (But not really, 3860acfbd7d59ee5c85911c687c6666940a38019f48fsewardj actually it could be a clean helper, but for the fact that we can't 3861acfbd7d59ee5c85911c687c6666940a38019f48fsewardj pass by value 2 x V128 to a clean helper, nor have one returned.) 3862acfbd7d59ee5c85911c687c6666940a38019f48fsewardj Reads guest state, writes to guest state for the xSTRM cases, no 3863acfbd7d59ee5c85911c687c6666940a38019f48fsewardj accesses of memory, is a pure function. 3864acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3865acfbd7d59ee5c85911c687c6666940a38019f48fsewardj opc_and_imm contains (4th byte of opcode << 8) | the-imm8-byte so 3866acfbd7d59ee5c85911c687c6666940a38019f48fsewardj the callee knows which I/E and I/M variant it is dealing with and 3867acfbd7d59ee5c85911c687c6666940a38019f48fsewardj what the specific operation is. 4th byte of opcode is in the range 3868acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 0x60 to 0x63: 3869acfbd7d59ee5c85911c687c6666940a38019f48fsewardj istri 66 0F 3A 63 3870acfbd7d59ee5c85911c687c6666940a38019f48fsewardj istrm 66 0F 3A 62 3871acfbd7d59ee5c85911c687c6666940a38019f48fsewardj estri 66 0F 3A 61 3872acfbd7d59ee5c85911c687c6666940a38019f48fsewardj estrm 66 0F 3A 60 3873acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3874acfbd7d59ee5c85911c687c6666940a38019f48fsewardj gstOffL and gstOffR are the guest state offsets for the two XMM 3875acfbd7d59ee5c85911c687c6666940a38019f48fsewardj register inputs. We never have to deal with the memory case since 3876acfbd7d59ee5c85911c687c6666940a38019f48fsewardj that is handled by pre-loading the relevant value into the fake 3877acfbd7d59ee5c85911c687c6666940a38019f48fsewardj XMM16 register. 3878acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3879acfbd7d59ee5c85911c687c6666940a38019f48fsewardj For ESTRx variants, edxIN and eaxIN hold the values of those two 3880acfbd7d59ee5c85911c687c6666940a38019f48fsewardj registers. 3881acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3882acfbd7d59ee5c85911c687c6666940a38019f48fsewardj In all cases, the bottom 16 bits of the result contain the new 3883acfbd7d59ee5c85911c687c6666940a38019f48fsewardj OSZACP %rflags values. For xSTRI variants, bits[31:16] of the 3884acfbd7d59ee5c85911c687c6666940a38019f48fsewardj result hold the new %ecx value. For xSTRM variants, the helper 3885acfbd7d59ee5c85911c687c6666940a38019f48fsewardj writes the result directly to the guest XMM0. 3886acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3887acfbd7d59ee5c85911c687c6666940a38019f48fsewardj Declarable side effects: in all cases, reads guest state at 3888acfbd7d59ee5c85911c687c6666940a38019f48fsewardj [gstOffL, +16) and [gstOffR, +16). For xSTRM variants, also writes 3889acfbd7d59ee5c85911c687c6666940a38019f48fsewardj guest_XMM0. 3890acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3891acfbd7d59ee5c85911c687c6666940a38019f48fsewardj Is expected to be called with opc_and_imm combinations which have 3892acfbd7d59ee5c85911c687c6666940a38019f48fsewardj actually been validated, and will assert if otherwise. The front 3893acfbd7d59ee5c85911c687c6666940a38019f48fsewardj end should ensure we're only called with verified values. 3894acfbd7d59ee5c85911c687c6666940a38019f48fsewardj*/ 3895acfbd7d59ee5c85911c687c6666940a38019f48fsewardjULong amd64g_dirtyhelper_PCMPxSTRx ( 3896acfbd7d59ee5c85911c687c6666940a38019f48fsewardj VexGuestAMD64State* gst, 3897acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord opc4_and_imm, 3898acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord gstOffL, HWord gstOffR, 3899acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord edxIN, HWord eaxIN 3900acfbd7d59ee5c85911c687c6666940a38019f48fsewardj ) 39010b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj{ 3902acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord opc4 = (opc4_and_imm >> 8) & 0xFF; 3903acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord imm8 = opc4_and_imm & 0xFF; 3904acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord isISTRx = opc4 & 2; 3905acfbd7d59ee5c85911c687c6666940a38019f48fsewardj HWord isxSTRM = (opc4 & 1) ^ 1; 3906acfbd7d59ee5c85911c687c6666940a38019f48fsewardj vassert((opc4 & 0xFC) == 0x60); /* 0x60 .. 0x63 */ 39073c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj HWord wide = (imm8 & 1); 3908acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3909acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // where the args are 3910acfbd7d59ee5c85911c687c6666940a38019f48fsewardj V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 3911acfbd7d59ee5c85911c687c6666940a38019f48fsewardj V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 3912acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3913acfbd7d59ee5c85911c687c6666940a38019f48fsewardj /* Create the arg validity masks, either from the vectors 3914acfbd7d59ee5c85911c687c6666940a38019f48fsewardj themselves or from the supplied edx/eax values. */ 3915acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // FIXME: this is only right for the 8-bit data cases. 3916acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // At least that is asserted above. 3917acfbd7d59ee5c85911c687c6666940a38019f48fsewardj UInt zmaskL, zmaskR; 39180b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 3919acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // temp spot for the resulting flags and vector. 3920acfbd7d59ee5c85911c687c6666940a38019f48fsewardj V128 resV; 3921acfbd7d59ee5c85911c687c6666940a38019f48fsewardj UInt resOSZACP; 3922acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 39233c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj // for checking whether case was handled 39243c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj Bool ok = False; 39253c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj 39263c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (wide) { 39273c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (isISTRx) { 39283c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL = zmask_from_V128_wide(argL); 39293c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskR = zmask_from_V128_wide(argR); 39303c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } else { 39313c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj Int tmp; 39323c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj tmp = edxIN & 0xFFFFFFFF; 39333c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < -8) tmp = -8; 39343c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp > 8) tmp = 8; 39353c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < 0) tmp = -tmp; 39363c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj vassert(tmp >= 0 && tmp <= 8); 39373c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL = (1 << tmp) & 0xFF; 39383c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj tmp = eaxIN & 0xFFFFFFFF; 39393c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < -8) tmp = -8; 39403c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp > 8) tmp = 8; 39413c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < 0) tmp = -tmp; 39423c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj vassert(tmp >= 0 && tmp <= 8); 39433c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskR = (1 << tmp) & 0xFF; 39443c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } 39453c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj // do the meyaath 39463c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj ok = compute_PCMPxSTRx_wide ( 39473c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj &resV, &resOSZACP, argL, argR, 39483c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL, zmaskR, imm8, (Bool)isxSTRM 39493c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj ); 39503c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } else { 39513c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (isISTRx) { 39523c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL = zmask_from_V128(argL); 39533c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskR = zmask_from_V128(argR); 39543c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } else { 39553c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj Int tmp; 39563c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj tmp = edxIN & 0xFFFFFFFF; 39573c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < -16) tmp = -16; 39583c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp > 16) tmp = 16; 39593c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < 0) tmp = -tmp; 39603c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj vassert(tmp >= 0 && tmp <= 16); 39613c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL = (1 << tmp) & 0xFFFF; 39623c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj tmp = eaxIN & 0xFFFFFFFF; 39633c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < -16) tmp = -16; 39643c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp > 16) tmp = 16; 39653c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj if (tmp < 0) tmp = -tmp; 39663c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj vassert(tmp >= 0 && tmp <= 16); 39673c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskR = (1 << tmp) & 0xFFFF; 39683c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } 39693c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj // do the meyaath 39703c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj ok = compute_PCMPxSTRx ( 39713c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj &resV, &resOSZACP, argL, argR, 39723c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj zmaskL, zmaskR, imm8, (Bool)isxSTRM 39733c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj ); 39743c3d6d62cb9fcf2cb8f96b21f28788a51960c5c3sewardj } 3975acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3976acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // front end shouldn't pass us any imm8 variants we can't 3977acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // handle. Hence: 3978acfbd7d59ee5c85911c687c6666940a38019f48fsewardj vassert(ok); 3979acfbd7d59ee5c85911c687c6666940a38019f48fsewardj 3980acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // So, finally we need to get the results back to the caller. 3981acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // In all cases, the new OSZACP value is the lowest 16 of 3982acfbd7d59ee5c85911c687c6666940a38019f48fsewardj // the return value. 3983acfbd7d59ee5c85911c687c6666940a38019f48fsewardj if (isxSTRM) { 3984c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj gst->guest_YMM0[0] = resV.w32[0]; 3985c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj gst->guest_YMM0[1] = resV.w32[1]; 3986c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj gst->guest_YMM0[2] = resV.w32[2]; 3987c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj gst->guest_YMM0[3] = resV.w32[3]; 3988acfbd7d59ee5c85911c687c6666940a38019f48fsewardj return resOSZACP & 0x8D5; 3989acfbd7d59ee5c85911c687c6666940a38019f48fsewardj } else { 3990acfbd7d59ee5c85911c687c6666940a38019f48fsewardj UInt newECX = resV.w32[0] & 0xFFFF; 3991acfbd7d59ee5c85911c687c6666940a38019f48fsewardj return (newECX << 16) | (resOSZACP & 0x8D5); 3992acfbd7d59ee5c85911c687c6666940a38019f48fsewardj } 39930b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj} 39940b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 3995ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/*---------------------------------------------------------------*/ 3996ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/*--- AES primitives and helpers ---*/ 3997ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/*---------------------------------------------------------------*/ 3998ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* a 16 x 16 matrix */ 3999ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar sbox[256] = { // row nr 4000ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, // 1 4001ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 4002ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, // 2 4003ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 4004ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, // 3 4005ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 4006ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, // 4 4007ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 4008ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, // 5 4009ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 4010ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, // 6 4011ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 4012ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, // 7 4013ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 4014ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, // 8 4015ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 4016ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, // 9 4017ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 4018ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, //10 4019ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 4020ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, //11 4021ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 4022ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, //12 4023ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 4024ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, //13 4025ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 4026ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, //14 4027ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 4028ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, //15 4029ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 4030ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, //16 4031ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 4032ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe}; 4033ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void SubBytes (V128* v) 4034ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4035ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4036ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt i; 4037ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (i = 0; i < 16; i++) 4038ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r.w8[i] = sbox[v->w8[i]]; 4039ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4040ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4041ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4042ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* a 16 x 16 matrix */ 4043ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar invsbox[256] = { // row nr 4044ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, // 1 4045ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 4046ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, // 2 4047ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 4048ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, // 3 4049ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 4050ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, // 4 4051ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 4052ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, // 5 4053ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 4054ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, // 6 4055ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 4056ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, // 7 4057ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 4058ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, // 8 4059ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 4060ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, // 9 4061ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 4062ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, //10 4063ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 4064ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, //11 4065ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 4066ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, //12 4067ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 4068ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, //13 4069ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 4070ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, //14 4071ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 4072ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, //15 4073ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 4074ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, //16 4075ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 4076ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe}; 4077ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void InvSubBytes (V128* v) 4078ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4079ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4080ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt i; 4081ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (i = 0; i < 16; i++) 4082ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r.w8[i] = invsbox[v->w8[i]]; 4083ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4084ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4085ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4086ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar ShiftRows_op[16] = 4087ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe {11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5, 0}; 4088ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void ShiftRows (V128* v) 4089ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4090ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4091ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt i; 4092ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (i = 0; i < 16; i++) 4093ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r.w8[i] = v->w8[ShiftRows_op[15-i]]; 4094ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4095ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4096ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4097ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar InvShiftRows_op[16] = 4098ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe {3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0}; 4099ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void InvShiftRows (V128* v) 4100ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4101ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4102ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt i; 4103ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (i = 0; i < 16; i++) 4104ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r.w8[i] = v->w8[InvShiftRows_op[15-i]]; 4105ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4106ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4107ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4108ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* Multiplication of the finite fields elements of AES. 4109ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe See "A Specification for The AES Algorithm Rijndael 4110ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe (by Joan Daemen & Vincent Rijmen)" 4111ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe Dr. Brian Gladman, v3.1, 3rd March 2001. */ 4112ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* N values so that (hex) xy = 0x03^N. 4113ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x00 cannot be used. We put 0xff for this value.*/ 4114ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* a 16 x 16 matrix */ 4115ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar Nxy[256] = { // row nr 4116ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xff, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, // 1 4117ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03, 4118ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, // 2 4119ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 4120ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, // 3 4121ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78, 4122ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, // 4 4123ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e, 4124ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, // 5 4125ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 4126ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, // 6 4127ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10, 4128ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, // 7 4129ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba, 4130ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, // 8 4131ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 4132ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, // 9 4133ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8, 4134ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, //10 4135ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0, 4136ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, //11 4137ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 4138ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, //12 4139ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d, 4140ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, //13 4141ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1, 4142ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, //14 4143ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 4144ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, //15 4145ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5, 4146ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, //16 4147ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07 4148ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe}; 4149ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4150ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* E values so that E = 0x03^xy. */ 4151ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic const UChar Exy[256] = { // row nr 4152ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x01, 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, // 1 4153ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x1a, 0x2e, 0x72, 0x96, 0xa1, 0xf8, 0x13, 0x35, 4154ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4, // 2 4155ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 4156ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xe5, 0x34, 0x5c, 0xe4, 0x37, 0x59, 0xeb, 0x26, // 3 4157ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31, 4158ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, // 4 4159ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4f, 0xd1, 0x68, 0xb8, 0xd3, 0x6e, 0xb2, 0xcd, 4160ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7, // 5 4161ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 4162ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x83, 0x9e, 0xb9, 0xd0, 0x6b, 0xbd, 0xdc, 0x7f, // 6 4163ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a, 4164ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, // 7 4165ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x0b, 0x1d, 0x27, 0x69, 0xbb, 0xd6, 0x61, 0xa3, 4166ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec, // 8 4167ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 4168ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xfb, 0x16, 0x3a, 0x4e, 0xd2, 0x6d, 0xb7, 0xc2, // 9 4169ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41, 4170ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, //10 4171ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x5b, 0xed, 0x2c, 0x74, 0x9c, 0xbf, 0xda, 0x75, 4172ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e, //11 4173ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 4174ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x9b, 0xb6, 0xc1, 0x58, 0xe8, 0x23, 0x65, 0xaf, //12 4175ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54, 4176ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, //13 4177ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x1b, 0x2d, 0x77, 0x99, 0xb0, 0xcb, 0x46, 0xca, 4178ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91, //14 4179ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 4180ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x12, 0x36, 0x5a, 0xee, 0x29, 0x7b, 0x8d, 0x8c, //15 4181ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17, 4182ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, //16 4183ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 0x1c, 0x24, 0x6c, 0xb4, 0xc7, 0x52, 0xf6, 0x01}; 4184ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4185ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic inline UChar ff_mul(UChar u1, UChar u2) 4186ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4187ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe if ((u1 > 0) && (u2 > 0)) { 4188ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt ui = Nxy[u1] + Nxy[u2]; 4189ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe if (ui >= 255) 4190ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ui = ui - 255; 4191ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe return Exy[ui]; 4192ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe } else { 4193ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe return 0; 4194ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe }; 4195ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4196ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4197ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void MixColumns (V128* v) 4198ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4199ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4200ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe Int j; 4201ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe#define P(x,row,col) (x)->w8[((row)*4+(col))] 4202ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (j = 0; j < 4; j++) { 4203ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,0) = ff_mul(0x02, P(v,j,0)) ^ ff_mul(0x03, P(v,j,1)) 4204ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ P(v,j,2) ^ P(v,j,3); 4205ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,1) = P(v,j,0) ^ ff_mul( 0x02, P(v,j,1) ) 4206ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x03, P(v,j,2) ) ^ P(v,j,3); 4207ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,2) = P(v,j,0) ^ P(v,j,1) ^ ff_mul( 0x02, P(v,j,2) ) 4208ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x03, P(v,j,3) ); 4209ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,3) = ff_mul(0x03, P(v,j,0) ) ^ P(v,j,1) ^ P(v,j,2) 4210ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul( 0x02, P(v,j,3) ); 4211ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe } 4212ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4213ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe#undef P 4214ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4215ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4216ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic void InvMixColumns (V128* v) 4217ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4218ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128 r; 4219ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe Int j; 4220ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe#define P(x,row,col) (x)->w8[((row)*4+(col))] 4221ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe for (j = 0; j < 4; j++) { 4222ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,0) = ff_mul(0x0e, P(v,j,0) ) ^ ff_mul(0x0b, P(v,j,1) ) 4223ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x0d,P(v,j,2) ) ^ ff_mul(0x09, P(v,j,3) ); 4224ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,1) = ff_mul(0x09, P(v,j,0) ) ^ ff_mul(0x0e, P(v,j,1) ) 4225ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x0b,P(v,j,2) ) ^ ff_mul(0x0d, P(v,j,3) ); 4226ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,2) = ff_mul(0x0d, P(v,j,0) ) ^ ff_mul(0x09, P(v,j,1) ) 4227ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x0e,P(v,j,2) ) ^ ff_mul(0x0b, P(v,j,3) ); 4228ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe P(&r,j,3) = ff_mul(0x0b, P(v,j,0) ) ^ ff_mul(0x0d, P(v,j,1) ) 4229ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ^ ff_mul(0x09,P(v,j,2) ) ^ ff_mul(0x0e, P(v,j,3) ); 4230ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe } 4231ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe *v = r; 4232ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe#undef P 4233ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4234ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4235ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4236ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* For description, see definition in guest_amd64_defs.h */ 4237ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippevoid amd64g_dirtyhelper_AES ( 4238ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe VexGuestAMD64State* gst, 42391407a363d94885ef7f748299ad54669dd97361efsewardj HWord opc4, HWord gstOffD, 4240ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe HWord gstOffL, HWord gstOffR 4241ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ) 4242ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4243ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe // where the args are 42441407a363d94885ef7f748299ad54669dd97361efsewardj V128* argD = (V128*)( ((UChar*)gst) + gstOffD ); 4245ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 4246ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 42471407a363d94885ef7f748299ad54669dd97361efsewardj V128 r; 4248ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4249ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe switch (opc4) { 4250ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe case 0xDC: /* AESENC */ 4251ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe case 0xDD: /* AESENCLAST */ 42521407a363d94885ef7f748299ad54669dd97361efsewardj r = *argR; 42531407a363d94885ef7f748299ad54669dd97361efsewardj ShiftRows (&r); 42541407a363d94885ef7f748299ad54669dd97361efsewardj SubBytes (&r); 4255ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe if (opc4 == 0xDC) 42561407a363d94885ef7f748299ad54669dd97361efsewardj MixColumns (&r); 42571407a363d94885ef7f748299ad54669dd97361efsewardj argD->w64[0] = r.w64[0] ^ argL->w64[0]; 42581407a363d94885ef7f748299ad54669dd97361efsewardj argD->w64[1] = r.w64[1] ^ argL->w64[1]; 4259ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe break; 4260ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4261ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe case 0xDE: /* AESDEC */ 4262ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe case 0xDF: /* AESDECLAST */ 42631407a363d94885ef7f748299ad54669dd97361efsewardj r = *argR; 42641407a363d94885ef7f748299ad54669dd97361efsewardj InvShiftRows (&r); 42651407a363d94885ef7f748299ad54669dd97361efsewardj InvSubBytes (&r); 4266ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe if (opc4 == 0xDE) 42671407a363d94885ef7f748299ad54669dd97361efsewardj InvMixColumns (&r); 42681407a363d94885ef7f748299ad54669dd97361efsewardj argD->w64[0] = r.w64[0] ^ argL->w64[0]; 42691407a363d94885ef7f748299ad54669dd97361efsewardj argD->w64[1] = r.w64[1] ^ argL->w64[1]; 4270ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe break; 4271ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4272ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe case 0xDB: /* AESIMC */ 42731407a363d94885ef7f748299ad54669dd97361efsewardj *argD = *argL; 42741407a363d94885ef7f748299ad54669dd97361efsewardj InvMixColumns (argD); 4275ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe break; 4276ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe default: vassert(0); 4277ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe } 4278ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4279ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4280ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic inline UInt RotWord (UInt w32) 4281ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4282ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe return ((w32 >> 8) | (w32 << 24)); 4283ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4284ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4285ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippestatic inline UInt SubWord (UInt w32) 4286ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4287ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UChar *w8; 4288ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UChar *r8; 4289ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe UInt res; 4290ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe w8 = (UChar*) &w32; 4291ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r8 = (UChar*) &res; 4292ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r8[0] = sbox[w8[0]]; 4293ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r8[1] = sbox[w8[1]]; 4294ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r8[2] = sbox[w8[2]]; 4295ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe r8[3] = sbox[w8[3]]; 4296ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe return res; 4297ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4298ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4299ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe/* For description, see definition in guest_amd64_defs.h */ 4300ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippeextern void amd64g_dirtyhelper_AESKEYGENASSIST ( 4301ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe VexGuestAMD64State* gst, 4302ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe HWord imm8, 4303ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe HWord gstOffL, HWord gstOffR 4304ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe ) 4305ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe{ 4306ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe // where the args are 4307ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 4308ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 4309ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4310a35a6db21ee5267b80a07fa40158df5306feaf42sewardj // We have to create the result in a temporary in the 4311a35a6db21ee5267b80a07fa40158df5306feaf42sewardj // case where the src and dst regs are the same. See #341698. 4312a35a6db21ee5267b80a07fa40158df5306feaf42sewardj V128 tmp; 4313a35a6db21ee5267b80a07fa40158df5306feaf42sewardj 4314a35a6db21ee5267b80a07fa40158df5306feaf42sewardj tmp.w32[3] = RotWord (SubWord (argL->w32[3])) ^ imm8; 4315a35a6db21ee5267b80a07fa40158df5306feaf42sewardj tmp.w32[2] = SubWord (argL->w32[3]); 4316a35a6db21ee5267b80a07fa40158df5306feaf42sewardj tmp.w32[1] = RotWord (SubWord (argL->w32[1])) ^ imm8; 4317a35a6db21ee5267b80a07fa40158df5306feaf42sewardj tmp.w32[0] = SubWord (argL->w32[1]); 4318a35a6db21ee5267b80a07fa40158df5306feaf42sewardj 4319a35a6db21ee5267b80a07fa40158df5306feaf42sewardj argR->w32[3] = tmp.w32[3]; 4320a35a6db21ee5267b80a07fa40158df5306feaf42sewardj argR->w32[2] = tmp.w32[2]; 4321a35a6db21ee5267b80a07fa40158df5306feaf42sewardj argR->w32[1] = tmp.w32[1]; 4322a35a6db21ee5267b80a07fa40158df5306feaf42sewardj argR->w32[0] = tmp.w32[0]; 4323ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe} 4324ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 4325ff4d6beb6a5b17380bc9e08b5d239f5bffa90262philippe 43260b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj 43270b2d3fe2b6eba2410dfcd3874af5bb78078f09c8sewardj/*---------------------------------------------------------------*/ 4328f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- Helpers for dealing with, and describing, ---*/ 4329f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*--- guest state as a whole. ---*/ 4330f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/*---------------------------------------------------------------*/ 4331f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4332f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* Initialise the entire amd64 guest state. */ 4333f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj/* VISIBLE TO LIBVEX CLIENT */ 4334f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardjvoid LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state ) 4335f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj{ 4336c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->host_EvC_FAILADDR = 0; 4337c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->host_EvC_COUNTER = 0; 4338c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->pad0 = 0; 4339c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4340f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RAX = 0; 4341f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RCX = 0; 4342f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RDX = 0; 4343f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RBX = 0; 4344f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RSP = 0; 4345f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RBP = 0; 4346f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RSI = 0; 4347f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RDI = 0; 4348f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R8 = 0; 4349f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R9 = 0; 4350f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R10 = 0; 4351f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R11 = 0; 4352f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R12 = 0; 4353f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R13 = 0; 4354f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R14 = 0; 4355f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_R15 = 0; 4356f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4357f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_OP = AMD64G_CC_OP_COPY; 4358f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_DEP1 = 0; 4359f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_DEP2 = 0; 4360f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_CC_NDEP = 0; 4361f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4362d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vex_state->guest_DFLAG = 1; /* forwards */ 436385520e44c14bebadea604ba9ba32113b55988227sewardj vex_state->guest_IDFLAG = 0; 43640e457fcf846af2963d8eea8ad728309d8a66a263sewardj vex_state->guest_ACFLAG = 0; 4365f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 4366e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe /* HACK: represent the offset associated with a constant %fs. 4367e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe Typically, on linux, this assumes that %fs is only ever zero (main 4368e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe thread) or 0x63. */ 4369e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe vex_state->guest_FS_CONST = 0; 4370a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj 4371f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj vex_state->guest_RIP = 0; 4372f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 43738d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* Initialise the simulated FPU */ 43748d965316c72c2392f670dcdfa127547ec77c7e56sewardj amd64g_dirtyhelper_FINIT( vex_state ); 43758d965316c72c2392f670dcdfa127547ec77c7e56sewardj 4376c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj /* Initialise the AVX state. */ 4377c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj# define AVXZERO(_ymm) \ 4378c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj do { _ymm[0]=_ymm[1]=_ymm[2]=_ymm[3] = 0; \ 4379c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj _ymm[4]=_ymm[5]=_ymm[6]=_ymm[7] = 0; \ 4380c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj } while (0) 4381cb6091d51134327150448a26a897dc8acb4dde0fsewardj vex_state->guest_SSEROUND = (ULong)Irrm_NEAREST; 4382c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM0); 4383c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM1); 4384c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM2); 4385c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM3); 4386c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM4); 4387c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM5); 4388c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM6); 4389c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM7); 4390c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM8); 4391c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM9); 4392c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM10); 4393c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM11); 4394c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM12); 4395c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM13); 4396c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM14); 4397c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM15); 4398c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj AVXZERO(vex_state->guest_YMM16); 4399c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj 4400c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj# undef AVXZERO 4401f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 44026ef84bed9bb3af22060eb1759788034602bbcc88florian vex_state->guest_EMNOTE = EmNote_NONE; 44031f126c5c092801acfc1ac968d2f1a37dde334bccsewardj 44041f126c5c092801acfc1ac968d2f1a37dde334bccsewardj /* These should not ever be either read or written, but we 44051f126c5c092801acfc1ac968d2f1a37dde334bccsewardj initialise them anyway. */ 440605f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj vex_state->guest_CMSTART = 0; 440705f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj vex_state->guest_CMLEN = 0; 4408ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj 4409d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_NRADDR = 0; 4410d660d41d4174e44f284bad3264601662ed68d4a1sewardj vex_state->guest_SC_CLASS = 0; 4411e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe vex_state->guest_GS_CONST = 0; 4412d660d41d4174e44f284bad3264601662ed68d4a1sewardj 4413e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj vex_state->guest_IP_AT_SYSCALL = 0; 4414c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_state->pad1 = 0; 441544d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj} 441644d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 4417f8c37f78bcd038e9e8513a415bf7b6e675fc6804sewardj 44182f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj/* Figure out if any part of the guest state contained in minoff 44192f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj .. maxoff requires precise memory exceptions. If in doubt return 44206c46befd9eb90c1b6e739926c1fa335cba75bf46philippe True (but this generates significantly slower code). 44212f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 44224cca75cb48776ceda40e8e305232d85f62021804sewardj By default we enforce precise exns for guest %RSP, %RBP and %RIP 44234cca75cb48776ceda40e8e305232d85f62021804sewardj only. These are the minimum needed to extract correct stack 44244cca75cb48776ceda40e8e305232d85f62021804sewardj backtraces from amd64 code. 44256c46befd9eb90c1b6e739926c1fa335cba75bf46philippe 44266c46befd9eb90c1b6e739926c1fa335cba75bf46philippe Only %RSP is needed in mode VexRegUpdSpAtMemAccess. 44272f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj*/ 4428ca2c3c75784d35d136fc7c952717cdee5063c193sewardjBool guest_amd64_state_requires_precise_mem_exns ( 4429ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Int minoff, Int maxoff, VexRegisterUpdates pxControl 4430ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ) 443144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj{ 44324cca75cb48776ceda40e8e305232d85f62021804sewardj Int rbp_min = offsetof(VexGuestAMD64State, guest_RBP); 44334cca75cb48776ceda40e8e305232d85f62021804sewardj Int rbp_max = rbp_min + 8 - 1; 44342f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj Int rsp_min = offsetof(VexGuestAMD64State, guest_RSP); 44352f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj Int rsp_max = rsp_min + 8 - 1; 44362f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj Int rip_min = offsetof(VexGuestAMD64State, guest_RIP); 44372f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj Int rip_max = rip_min + 8 - 1; 44382f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 44396c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < rsp_min || minoff > rsp_max) { 44406c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* no overlap with rsp */ 4441ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl == VexRegUpdSpAtMemAccess) 44426c46befd9eb90c1b6e739926c1fa335cba75bf46philippe return False; // We only need to check stack pointer. 44434cca75cb48776ceda40e8e305232d85f62021804sewardj } else { 44444cca75cb48776ceda40e8e305232d85f62021804sewardj return True; 44454cca75cb48776ceda40e8e305232d85f62021804sewardj } 44464cca75cb48776ceda40e8e305232d85f62021804sewardj 44476c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < rbp_min || minoff > rbp_max) { 44486c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* no overlap with rbp */ 44492f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj } else { 44502f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj return True; 44512f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj } 44522f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 44532f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj if (maxoff < rip_min || minoff > rip_max) { 44542f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj /* no overlap with eip */ 44552f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj } else { 44562f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj return True; 44572f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj } 44582f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 44592f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj return False; 446044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj} 44612f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 44622f959cc53dea4ec13926d7a829dd6fb79225c5c3sewardj 4463c85e91c7db5b5957cc2682275e98b224bcd33270sewardj#define ALWAYSDEFD(field) \ 4464c85e91c7db5b5957cc2682275e98b224bcd33270sewardj { offsetof(VexGuestAMD64State, field), \ 4465c85e91c7db5b5957cc2682275e98b224bcd33270sewardj (sizeof ((VexGuestAMD64State*)0)->field) } 446644d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 446744d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardjVexGuestLayout 4468c85e91c7db5b5957cc2682275e98b224bcd33270sewardj amd64guest_layout 446944d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj = { 447044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* Total size of the guest state, in bytes. */ 4471c85e91c7db5b5957cc2682275e98b224bcd33270sewardj .total_sizeB = sizeof(VexGuestAMD64State), 447244d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 447344d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* Describe the stack pointer. */ 4474c85e91c7db5b5957cc2682275e98b224bcd33270sewardj .offset_SP = offsetof(VexGuestAMD64State,guest_RSP), 4475c85e91c7db5b5957cc2682275e98b224bcd33270sewardj .sizeof_SP = 8, 447644d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 4477a203330aad67bc3e52ca1395a55e94ef9a091223sewardj /* Describe the frame pointer. */ 4478a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .offset_FP = offsetof(VexGuestAMD64State,guest_RBP), 4479a203330aad67bc3e52ca1395a55e94ef9a091223sewardj .sizeof_FP = 8, 4480a203330aad67bc3e52ca1395a55e94ef9a091223sewardj 448144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* Describe the instruction pointer. */ 4482c85e91c7db5b5957cc2682275e98b224bcd33270sewardj .offset_IP = offsetof(VexGuestAMD64State,guest_RIP), 4483c85e91c7db5b5957cc2682275e98b224bcd33270sewardj .sizeof_IP = 8, 448444d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 448544d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* Describe any sections to be regarded by Memcheck as 448644d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 'always-defined'. */ 4487e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj .n_alwaysDefd = 16, 448844d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj 448944d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* flags thunk: OP and NDEP are always defd, whereas DEP1 449044d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj and DEP2 have to be tracked. See detailed comment in 449144d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj gdefs.h on meaning of thunk fields. */ 449244d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj .alwaysDefd 449344d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj = { /* 0 */ ALWAYSDEFD(guest_CC_OP), 449444d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), 449585520e44c14bebadea604ba9ba32113b55988227sewardj /* 2 */ ALWAYSDEFD(guest_DFLAG), 449685520e44c14bebadea604ba9ba32113b55988227sewardj /* 3 */ ALWAYSDEFD(guest_IDFLAG), 449785520e44c14bebadea604ba9ba32113b55988227sewardj /* 4 */ ALWAYSDEFD(guest_RIP), 4498e2cc4defff3eec3be8e38ccc21df5ee460f930e9philippe /* 5 */ ALWAYSDEFD(guest_FS_CONST), 44998d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* 6 */ ALWAYSDEFD(guest_FTOP), 45008d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* 7 */ ALWAYSDEFD(guest_FPTAG), 45018d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* 8 */ ALWAYSDEFD(guest_FPROUND), 45028d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* 9 */ ALWAYSDEFD(guest_FC3210), 450385520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_CS), 450485520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_DS), 450585520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_ES), 450685520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_FS), 450785520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_GS), 450885520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_SS), 450985520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_LDT), 451085520e44c14bebadea604ba9ba32113b55988227sewardj // /* */ ALWAYSDEFD(guest_GDT), 45116ef84bed9bb3af22060eb1759788034602bbcc88florian /* 10 */ ALWAYSDEFD(guest_EMNOTE), 451216a403bac07df30df6e6587c8c911cf6df3f780dsewardj /* 11 */ ALWAYSDEFD(guest_SSEROUND), 451305f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 12 */ ALWAYSDEFD(guest_CMSTART), 451405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 13 */ ALWAYSDEFD(guest_CMLEN), 4515e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 14 */ ALWAYSDEFD(guest_SC_CLASS), 4516e86310f555a233cc2ca02e1a5d0adb555f12bdcdsewardj /* 15 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) 451744d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj } 451844d494dfad0c12f96f61cf9edfc889dfa69e3b30sewardj }; 45199c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 45209c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn 45219c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn/*---------------------------------------------------------------*/ 4522cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end guest_amd64_helpers.c ---*/ 45239c6acb0c7f7b5ff5c4a8d5a22259d8151edff499njn/*---------------------------------------------------------------*/ 4524