guest_amd64_helpers.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin guest_amd64_helpers.c ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2004-2013 OpenWorks LLP 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.net 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02110-1301, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h" 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_emnote.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_amd64.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_ir.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_util.h" 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "main_globals.h" 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_generic_bb_to_IR.h" 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_amd64_defs.h" 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "guest_generic_x87.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This file contains helper functions for amd64 guest code. 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Calls to these functions are generated by the back end. 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown These calls are of course in the host machine code and 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this file will be compiled to host machine code, so that 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown all makes sense. 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Only change the signatures of these helper functions very 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown carefully. If you change the signature here, you'll have to change 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the parameters passed to it in the IR calls constructed by 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest-amd64/toIR.c. 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The convention used is that all functions called from generated 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown code are named amd64g_<something>, and any function whose name lacks 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that prefix is not called from generated code. Note that some 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LibVEX_* functions can however be called by VEX's client, but that 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is not the same as calling them from VEX-generated code. 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set to 1 to get detailed profiling info about use of the flag 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown machinery. */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PROFILE_RFLAGS 0 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- %rflags run-time helpers. ---*/ 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do 64x64 -> 128 signed/unsigned multiplies, for computing flags 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown after imulq/mulq. */ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mullS64 ( Long u, Long v, Long* rHi, Long* rLo ) 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u0, v0, w0; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long u1, v1, w1, w2, t; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 = u & 0xFFFFFFFFULL; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u1 = u >> 32; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown v0 = v & 0xFFFFFFFFULL; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown v1 = v >> 32; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w0 = u0 * v0; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t = u1 * v0 + (w0 >> 32); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w1 = t & 0xFFFFFFFFULL; 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w2 = t >> 32; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w1 = u0 * v1 + w1; 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rHi = u1 * v1 + w2 + (w1 >> 32); 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rLo = u * v; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mullU64 ( ULong u, ULong v, ULong* rHi, ULong* rLo ) 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u0, v0, w0; 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u1, v1, w1,w2,t; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 = u & 0xFFFFFFFFULL; 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u1 = u >> 32; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown v0 = v & 0xFFFFFFFFULL; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown v1 = v >> 32; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w0 = u0 * v0; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t = u1 * v0 + (w0 >> 32); 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w1 = t & 0xFFFFFFFFULL; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w2 = t >> 32; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w1 = u0 * v1 + w1; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rHi = u1 * v1 + w2 + (w1 >> 32); 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rLo = u * v; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const UChar parity_table[256] = { 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, AMD64G_CC_MASK_P, AMD64G_CC_MASK_P, 0, AMD64G_CC_MASK_P, 0, 0, AMD64G_CC_MASK_P, 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* generalised left-shifter */ 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Long lshift ( Long x, Int n ) 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n >= 0) 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return x << n; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return x >> (-n); 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* identity on ULong */ 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline ULong idULong ( ULong x ) 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return x; 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PREAMBLE(__data_bits) \ 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* const */ ULong DATA_MASK \ 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = __data_bits==8 \ 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFULL \ 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : (__data_bits==16 \ 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFFFULL \ 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : (__data_bits==32 \ 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFFFFFFFULL \ 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : 0xFFFFFFFFFFFFFFFFULL)); \ 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* const */ ULong SIGN_MASK = 1ULL << (__data_bits - 1); \ 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* const */ ULong CC_DEP1 = cc_dep1_formal; \ 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* const */ ULong CC_DEP2 = cc_dep2_formal; \ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* const */ ULong CC_NDEP = cc_ndep_formal; \ 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Four bogus assignments, which hopefully gcc can */ \ 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* optimise away, and which stop it complaining about */ \ 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unused variables. */ \ 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SIGN_MASK = SIGN_MASK; \ 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_MASK = DATA_MASK; \ 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CC_DEP2 = CC_DEP2; \ 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CC_NDEP = CC_NDEP; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_ADD(DATA_BITS,DATA_UTYPE) \ 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, res; \ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = CC_DEP1; \ 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = CC_DEP2; \ 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = argL + argR; \ 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE) \ 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, res; \ 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = CC_DEP1; \ 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = CC_DEP2; \ 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = argL - argR; \ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift((argL ^ argR) & (argL ^ res), \ 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE) \ 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, oldC, res; \ 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oldC = CC_NDEP & AMD64G_CC_MASK_C; \ 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = CC_DEP1; \ 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = CC_DEP2 ^ oldC; \ 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = (argL + argR) + oldC; \ 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (oldC) \ 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL; \ 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else \ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)res < (DATA_UTYPE)argL; \ 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift((argL ^ argR ^ -1) & (argL ^ res), \ 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SBB(DATA_BITS,DATA_UTYPE) \ 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, oldC, res; \ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oldC = CC_NDEP & AMD64G_CC_MASK_C; \ 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = CC_DEP1; \ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = CC_DEP2 ^ oldC; \ 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = (argL - argR) - oldC; \ 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (oldC) \ 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR; \ 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else \ 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR; \ 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift((argL ^ argR) & (argL ^ res), \ 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12 - DATA_BITS) & AMD64G_CC_MASK_O; \ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE) \ 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = 0; \ 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)CC_DEP1]; \ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; \ 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = 0; \ 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_INC(DATA_BITS,DATA_UTYPE) \ 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, res; \ 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = CC_DEP1; \ 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = res - 1; \ 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = 1; \ 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = CC_NDEP & AMD64G_CC_MASK_C; \ 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((res & DATA_MASK) == SIGN_MASK) << 11; \ 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_DEC(DATA_BITS,DATA_UTYPE) \ 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long argL, argR, res; \ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = CC_DEP1; \ 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argL = res + 1; \ 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argR = 1; \ 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = CC_NDEP & AMD64G_CC_MASK_C; \ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)res]; \ 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = (res ^ argL ^ argR) & 0x10; \ 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)res == 0) << 6; \ 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(res, 8 - DATA_BITS) & 0x80; \ 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((res & DATA_MASK) \ 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == ((ULong)SIGN_MASK - 1)) << 11; \ 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SHL(DATA_BITS,DATA_UTYPE) \ 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (CC_DEP2 >> (DATA_BITS - 1)) & AMD64G_CC_MASK_C; \ 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)CC_DEP1]; \ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* of is defined if shift count == 1 */ \ 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & AMD64G_CC_MASK_O; \ 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE) \ 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = CC_DEP2 & 1; \ 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)CC_DEP1]; \ 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* of is defined if shift count == 1 */ \ 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) \ 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & AMD64G_CC_MASK_O; \ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ROL: cf' = lsb(result). of' = msb(result) ^ lsb(result). */ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DEP1 = result, NDEP = old flags */ 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_ROL(DATA_BITS,DATA_UTYPE) \ 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long fl \ 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = (CC_NDEP & ~(AMD64G_CC_MASK_O | AMD64G_CC_MASK_C)) \ 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (AMD64G_CC_MASK_C & CC_DEP1) \ 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (AMD64G_CC_MASK_O & (lshift(CC_DEP1, \ 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11-(DATA_BITS-1)) \ 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ lshift(CC_DEP1, 11))); \ 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fl; \ 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ROR: cf' = msb(result). of' = msb(result) ^ msb-1(result). */ 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DEP1 = result, NDEP = old flags */ 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_ROR(DATA_BITS,DATA_UTYPE) \ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long fl \ 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = (CC_NDEP & ~(AMD64G_CC_MASK_O | AMD64G_CC_MASK_C)) \ 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (AMD64G_CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1))) \ 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (AMD64G_CC_MASK_O & (lshift(CC_DEP1, \ 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11-(DATA_BITS-1)) \ 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1))); \ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fl; \ 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_UMUL(DATA_BITS, DATA_UTYPE, NARROWtoU, \ 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_U2TYPE, NARROWto2U) \ 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_UTYPE hi; \ 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_UTYPE lo \ 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * ((DATA_UTYPE)CC_DEP2) ); \ 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_U2TYPE rr \ 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = NARROWto2U( \ 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (hi != 0); \ 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)lo]; \ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = (lo == 0) << 6; \ 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = cf << 11; \ 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_S2TYPE, NARROWto2S) \ 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(DATA_BITS); \ 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_STYPE hi; \ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_STYPE lo \ 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = NARROWtoS( ((DATA_STYPE)CC_DEP1) \ 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * ((DATA_STYPE)CC_DEP2) ); \ 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DATA_S2TYPE rr \ 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = NARROWto2S( \ 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)lo]; \ 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = (lo == 0) << 6; \ 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = cf << 11; \ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_UMULQ \ 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(64); \ 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong lo, hi; \ 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mullU64( (ULong)CC_DEP1, (ULong)CC_DEP2, &hi, &lo ); \ 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (hi != 0); \ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)lo]; \ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = (lo == 0) << 6; \ 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(lo, 8 - 64) & 0x80; \ 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = cf << 11; \ 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------*/ 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ACTIONS_SMULQ \ 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PREAMBLE(64); \ 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { Long cf, pf, af, zf, sf, of; \ 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long lo, hi; \ 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mullS64( (Long)CC_DEP1, (Long)CC_DEP2, &hi, &lo ); \ 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (hi != (lo >>/*s*/ (64-1))); \ 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = parity_table[(UChar)lo]; \ 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown af = 0; /* undefined */ \ 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = (lo == 0) << 6; \ 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = lshift(lo, 8 - 64) & 0x80; \ 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = cf << 11; \ 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cf | pf | af | zf | sf | of; \ 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-------------------------------------------------------------*/ 496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define ACTIONS_ANDN(DATA_BITS,DATA_UTYPE) \ 498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ \ 499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov PREAMBLE(DATA_BITS); \ 500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { Long cf, pf, af, zf, sf, of; \ 501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = 0; \ 502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pf = 0; \ 503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov af = 0; \ 504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov of = 0; \ 507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf | pf | af | zf | sf | of; \ 508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } \ 509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 510436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 511436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-------------------------------------------------------------*/ 512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 513436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define ACTIONS_BLSI(DATA_BITS,DATA_UTYPE) \ 514436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ \ 515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov PREAMBLE(DATA_BITS); \ 516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { Long cf, pf, af, zf, sf, of; \ 517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = ((DATA_UTYPE)CC_DEP2 != 0); \ 518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pf = 0; \ 519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov af = 0; \ 520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov of = 0; \ 523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf | pf | af | zf | sf | of; \ 524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } \ 525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-------------------------------------------------------------*/ 528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define ACTIONS_BLSMSK(DATA_BITS,DATA_UTYPE) \ 530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ \ 531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov PREAMBLE(DATA_BITS); \ 532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { Long cf, pf, af, zf, sf, of; \ 533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = ((DATA_UTYPE)CC_DEP2 == 0); \ 534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pf = 0; \ 535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov af = 0; \ 536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = 0; \ 537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov of = 0; \ 539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf | pf | af | zf | sf | of; \ 540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } \ 541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-------------------------------------------------------------*/ 544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define ACTIONS_BLSR(DATA_BITS,DATA_UTYPE) \ 546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ \ 547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov PREAMBLE(DATA_BITS); \ 548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { Long cf, pf, af, zf, sf, of; \ 549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = ((DATA_UTYPE)CC_DEP2 == 0); \ 550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pf = 0; \ 551436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov af = 0; \ 552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6; \ 553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80; \ 554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov of = 0; \ 555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf | pf | af | zf | sf | of; \ 556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } \ 557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-------------------------------------------------------------*/ 560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if PROFILE_RFLAGS 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool initted = False; 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* C flag, fast route */ 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt tabc_fast[AMD64G_CC_OP_NUMBER]; 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* C flag, slow route */ 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt tabc_slow[AMD64G_CC_OP_NUMBER]; 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* table for calculate_cond */ 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt tab_cond[AMD64G_CC_OP_NUMBER][16]; 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* total entry counts for calc_all, calc_c, calc_cond. */ 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt n_calc_all = 0; 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt n_calc_c = 0; 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt n_calc_cond = 0; 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond))) 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void showCounts ( void ) 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int op, co; 583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar ch; 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_calc_all, n_calc_cond, n_calc_c); 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " S NS P NP L NL LE NLE\n"); 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" -----------------------------------------------------" 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "----------------------------------------\n"); 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (op = 0; op < AMD64G_CC_OP_NUMBER; op++) { 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ch = ' '; 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (op > 0 && (op-1) % 4 == 0) 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ch = 'B'; 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (op > 0 && (op-1) % 4 == 1) 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ch = 'W'; 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (op > 0 && (op-1) % 4 == 2) 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ch = 'L'; 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (op > 0 && (op-1) % 4 == 3) 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ch = 'Q'; 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("%2d%c: ", op, ch); 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("%6u ", tabc_slow[op]); 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("%6u ", tabc_fast[op]); 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (co = 0; co < 16; co++) { 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n = tab_cond[op][co]; 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n >= 1000) { 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" %3dK", n / 1000); 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n >= 0) { 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" %3d ", n ); 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" "); 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void initCounts ( void ) 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int op, co; 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown initted = True; 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (op = 0; op < AMD64G_CC_OP_NUMBER; op++) { 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tabc_fast[op] = tabc_slow[op] = 0; 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (co = 0; co < 16; co++) 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tab_cond[op][co] = 0; 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PROFILE_RFLAGS */ 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Calculate all the 6 flags from the supplied thunk parameters. 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Worker function, not directly called from generated code. */ 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_rflags_all_WRK ( ULong cc_op, 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep1_formal, 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep2_formal, 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_ndep_formal ) 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (cc_op) { 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_COPY: 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cc_dep1_formal 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & (AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P); 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADDQ: ACTIONS_ADD( 64, ULong ); 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ADCQ: ACTIONS_ADC( 64, ULong ); 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SUBQ: ACTIONS_SUB( 64, ULong ); 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SBBQ: ACTIONS_SBB( 64, ULong ); 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICQ: ACTIONS_LOGIC( 64, ULong ); 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_INCQ: ACTIONS_INC( 64, ULong ); 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_DECQ: ACTIONS_DEC( 64, ULong ); 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHLQ: ACTIONS_SHL( 64, ULong ); 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SHRQ: ACTIONS_SHR( 64, ULong ); 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_ROLQ: ACTIONS_ROL( 64, ULong ); 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_RORQ: ACTIONS_ROR( 64, ULong ); 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort, toUShort ); 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt, toUInt ); 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong, idULong ); 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_UMULQ: ACTIONS_UMULQ; 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Short, toUShort ); 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int, toUInt ); 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long, idULong ); 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_SMULQ: ACTIONS_SMULQ; 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_ANDN32: ACTIONS_ANDN( 32, UInt ); 725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_ANDN64: ACTIONS_ANDN( 64, ULong ); 726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSI32: ACTIONS_BLSI( 32, UInt ); 728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSI64: ACTIONS_BLSI( 64, ULong ); 729436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSMSK32: ACTIONS_BLSMSK( 32, UInt ); 731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSMSK64: ACTIONS_BLSMSK( 64, ULong ); 732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSR32: ACTIONS_BLSR( 32, UInt ); 734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case AMD64G_CC_OP_BLSR64: ACTIONS_BLSR( 64, ULong ); 735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* shouldn't really make these calls from generated code */ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("amd64g_calculate_rflags_all_WRK(AMD64)" 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "( %llu, 0x%llx, 0x%llx, 0x%llx )\n", 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("amd64g_calculate_rflags_all_WRK(AMD64)"); 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Calculate all the 6 flags from the supplied thunk parameters. */ 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_rflags_all ( ULong cc_op, 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep1, 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep2, 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_ndep ) 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if PROFILE_RFLAGS 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!initted) initCounts(); 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_calc_all++; 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (SHOW_COUNTS_NOW) showCounts(); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown amd64g_calculate_rflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep ); 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Calculate just the carry flag from the supplied thunk parameters. */ 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_rflags_c ( ULong cc_op, 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep1, 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep2, 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_ndep ) 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if PROFILE_RFLAGS 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!initted) initCounts(); 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_calc_c++; 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tabc_fast[cc_op]++; 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (SHOW_COUNTS_NOW) showCounts(); 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Fast-case some common ones. */ 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (cc_op) { 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_COPY: 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (cc_dep1 >> AMD64G_CC_SHIFT_C) & 1; 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICQ: 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICL: 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICW: 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64G_CC_OP_LOGICB: 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // case AMD64G_CC_OP_SUBL: 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // return ((UInt)cc_dep1) < ((UInt)cc_dep2) 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // ? AMD64G_CC_MASK_C : 0; 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // case AMD64G_CC_OP_SUBW: 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // ? AMD64G_CC_MASK_C : 0; 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // case AMD64G_CC_OP_SUBB: 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // ? AMD64G_CC_MASK_C : 0; 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // case AMD64G_CC_OP_INCL: 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // case AMD64G_CC_OP_DECL: 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // return cc_ndep & AMD64G_CC_MASK_C; 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if PROFILE_RFLAGS 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tabc_fast[cc_op]--; 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tabc_slow[cc_op]++; 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return amd64g_calculate_rflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & AMD64G_CC_MASK_C; 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* returns 1 or 0 */ 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_condition ( ULong/*AMD64Condcode*/ cond, 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_op, 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep1, 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_dep2, 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cc_ndep ) 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rflags = amd64g_calculate_rflags_all_WRK(cc_op, cc_dep1, 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep2, cc_ndep); 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong of,sf,zf,cf,pf; 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong inv = cond & 1; 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if PROFILE_RFLAGS 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!initted) initCounts(); 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tab_cond[cc_op][cond]++; 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_calc_cond++; 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (SHOW_COUNTS_NOW) showCounts(); 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (cond) { 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNO: 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondO: /* OF == 1 */ 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = rflags >> AMD64G_CC_SHIFT_O; 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ of); 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNZ: 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondZ: /* ZF == 1 */ 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = rflags >> AMD64G_CC_SHIFT_Z; 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ zf); 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNB: 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondB: /* CF == 1 */ 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = rflags >> AMD64G_CC_SHIFT_C; 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ cf); 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNBE: 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondBE: /* (CF or ZF) == 1 */ 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = rflags >> AMD64G_CC_SHIFT_C; 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = rflags >> AMD64G_CC_SHIFT_Z; 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ (cf | zf)); 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNS: 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondS: /* SF == 1 */ 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = rflags >> AMD64G_CC_SHIFT_S; 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ sf); 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNP: 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondP: /* PF == 1 */ 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf = rflags >> AMD64G_CC_SHIFT_P; 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ pf); 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNL: 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondL: /* (SF xor OF) == 1 */ 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = rflags >> AMD64G_CC_SHIFT_S; 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = rflags >> AMD64G_CC_SHIFT_O; 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ (sf ^ of)); 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondNLE: 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case AMD64CondLE: /* ((SF xor OF) or ZF) == 1 */ 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sf = rflags >> AMD64G_CC_SHIFT_S; 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = rflags >> AMD64G_CC_SHIFT_O; 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zf = rflags >> AMD64G_CC_SHIFT_Z; 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1 & (inv ^ ((sf ^ of) | zf)); 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* shouldn't really make these calls from generated code */ 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("amd64g_calculate_condition" 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "( %llu, %llu, 0x%llx, 0x%llx, 0x%llx )\n", 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("amd64g_calculate_condition"); 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* VISIBLE TO LIBVEX CLIENT */ 892436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state ) 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rflags = amd64g_calculate_rflags_all_WRK( 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_OP, 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP1, 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP2, 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_NDEP 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long dflag = vex_state->guest_DFLAG; 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(dflag == 1 || dflag == -1); 902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dflag == -1) 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags |= (1<<10); 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_state->guest_IDFLAG == 1) 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags |= (1<<21); 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_state->guest_ACFLAG == 1) 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags |= (1<<18); 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return rflags; 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* VISIBLE TO LIBVEX CLIENT */ 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownLibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag, 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/VexGuestAMD64State* vex_state ) 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong oszacp = amd64g_calculate_rflags_all_WRK( 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_OP, 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP1, 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP2, 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_NDEP 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (new_carry_flag & 1) { 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oszacp |= AMD64G_CC_MASK_C; 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oszacp &= ~AMD64G_CC_MASK_C; 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_OP = AMD64G_CC_OP_COPY; 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP1 = oszacp; 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP2 = 0; 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_NDEP = 0; 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- %rflags translation-time function specialisers. ---*/ 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- These help iropt specialise calls the above run-time ---*/ 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- %rflags functions. ---*/ 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Used by the optimiser to try specialisations. Returns an 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown equivalent expression, or NULL if none. */ 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool isU64 ( IRExpr* e, ULong n ) 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( e->tag == Iex_Const 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->tag == Ico_U64 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->Ico.U64 == n ); 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 951436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovIRExpr* guest_amd64_spechelper ( const HChar* function_name, 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args, 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt** precedingStmts, 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_precedingStmts ) 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) 959b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, arity = 0; 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; args[i]; i++) 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arity++; 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if 0 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("spec request:\n"); 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" %s ", function_name); 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < arity; i++) { 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" "); 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(args[i]); 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --------- specialising "amd64g_calculate_condition" --------- */ 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_streq(function_name, "amd64g_calculate_condition")) { 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* specialise calls to above "calculate condition" function */ 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr *cond, *cc_op, *cc_dep1, *cc_dep2; 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(arity == 5); 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cond = args[0]; 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_op = args[1]; 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep1 = args[2]; 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep2 = args[3]; 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- ADDQ ----------------*/ 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_ADDQ) && isU64(cond, AMD64CondZ)) { 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long add, then Z --> test (dst+src == 0) */ 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ64, 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Add64, cc_dep1, cc_dep2), 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- SUBQ ----------------*/ 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondZ)) { 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then Z --> test dst==src */ 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ64,cc_dep1,cc_dep2)); 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNZ)) { 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then NZ --> test dst!=src */ 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpNE64,cc_dep1,cc_dep2)); 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondL)) { 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then L (signed less than) 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <s src */ 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLT64S, cc_dep1, cc_dep2)); 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondB)) { 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then B (unsigned less than) 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <u src */ 1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNB)) { 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then NB (unsigned greater than or equal) 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test src <=u dst */ 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note, args are opposite way round from the usual */ 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1030436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNLE)) { 1031436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* long sub/cmp, then NLE (signed greater than) 1032436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test !(dst <=s src) 1033436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test (dst >s src) 1034436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test (src <s dst) */ 1035436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 1036436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT64S, cc_dep2, cc_dep1)); 1037436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1038436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1039436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondBE)) { 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long sub/cmp, then BE (unsigned less than or equal) 1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <=u src */ 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNBE)) { 1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* long long sub/cmp, then NBE (unsigned greater than) 1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng --> test !(dst <=u src) */ 1049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return binop(Iop_Xor64, 1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unop(Iop_1Uto64, 1051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng binop(Iop_CmpLE64U, cc_dep1, cc_dep2)), 1052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mkU64(1)); 1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- SUBL ----------------*/ 1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondZ)) { 1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then Z --> test dst==src */ 1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpEQ32, 1061b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1062b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNZ)) { 1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then NZ --> test dst!=src */ 1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1067b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpNE32, 1068b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1069b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondL)) { 1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then L (signed less than) 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <s src */ 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1076b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32S, 1077b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1078b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondLE)) { 1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then LE (signed less than or equal) 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <=s src */ 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1085b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLE32S, 1086b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1087b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNLE)) { 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then NLE (signed greater than) 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test !(dst <=s src) 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test (dst >s src) 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test (src <s dst) */ 1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1096b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32S, 1097b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2), 1098b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1))); 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondBE)) { 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then BE (unsigned less than or equal) 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <=u src */ 1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLE32U, 1107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNBE)) { 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then NBE (unsigned greater than) 1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test src <u dst */ 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note, args are opposite way round from the usual */ 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32U, 1116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2), 1117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1))); 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondS)) { 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long sub/cmp, then S (negative) --> test (dst-src <s 0) */ 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32S, 1124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_Sub32, 1125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2)), 1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU32(0))); 1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondB)) { 1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* long sub/cmp, then B (unsigned less than) 1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov --> test dst <u src */ 1133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return unop(Iop_1Uto64, 1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32U, 1135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- SUBW ----------------*/ 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondZ)) { 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* word sub/cmp, then Z --> test dst==src */ 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ16, 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to16,cc_dep1), 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to16,cc_dep2))); 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondNZ)) { 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* word sub/cmp, then NZ --> test dst!=src */ 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpNE16, 1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to16,cc_dep1), 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to16,cc_dep2))); 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBW) && isU64(cond, AMD64CondLE)) { 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* word sub/cmp, then LE (signed less than or equal) 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <=s src */ 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLE64S, 1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shl64,cc_dep1,mkU8(48)), 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shl64,cc_dep2,mkU8(48)))); 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- SUBB ----------------*/ 1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondZ)) { 1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte sub/cmp, then Z --> test dst==src */ 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ8, 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to8,cc_dep1), 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to8,cc_dep2))); 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNZ)) { 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte sub/cmp, then NZ --> test dst!=src */ 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpNE8, 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to8,cc_dep1), 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop(Iop_64to8,cc_dep2))); 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondBE)) { 1184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* byte sub/cmp, then BE (unsigned less than or equal) 1185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov --> test dst <=u src */ 1186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return unop(Iop_1Uto64, 1187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLE64U, 1188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_And64, cc_dep1, mkU64(0xFF)), 1189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_And64, cc_dep2, mkU64(0xFF)))); 1190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondS) 1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isU64(cc_dep2, 0)) { 1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte sub/cmp of zero, then S --> test (dst-0 <s 0) 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test dst <s 0 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> (ULong)dst[7] 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This is yet another scheme by which gcc figures out if the 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown top bit of a byte is 1 or 0. See also LOGICB/CondS below. */ 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: isU64(cc_dep2, 0) is correct, even though this is 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for an 8-bit comparison, since the args to the helper 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function are always U64s. */ 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return binop(Iop_And64, 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64,cc_dep1,mkU8(7)), 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1)); 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNS) 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isU64(cc_dep2, 0)) { 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte sub/cmp of zero, then NS --> test !(dst-0 <s 0) 1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> test !(dst <s 0) 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --> (ULong) !dst[7] 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return binop(Iop_Xor64, 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_And64, 1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64,cc_dep1,mkU8(7)), 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1)), 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1)); 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- LOGICQ ----------------*/ 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondZ)) { 1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long and/or/xor, then Z --> test dst==0 */ 1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondNZ)) { 1227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* long long and/or/xor, then NZ --> test dst!=0 */ 1228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return unop(Iop_1Uto64, 1229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 1230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondL)) { 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long long and/or/xor, then L 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LOGIC sets SF and ZF according to the 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result and makes OF be zero. L computes SF ^ OF, but 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OF is zero, so this reduces to SF -- which will be 1 iff 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the result is < signed 0. Hence ... 1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLT64S, 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep1, 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- LOGICL ----------------*/ 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondZ)) { 1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long and/or/xor, then Z --> test dst==0 */ 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpEQ32, 1251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU32(0))); 1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondNZ)) { 1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long and/or/xor, then NZ --> test dst!=0 */ 1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpNE32, 1258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU32(0))); 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondLE)) { 1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* long and/or/xor, then LE 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This is pretty subtle. LOGIC sets SF and ZF according to the 1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result and makes OF be zero. LE computes (SF ^ OF) | ZF, but 1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OF is zero, so this reduces to SF | ZF -- which will be 1 iff 1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the result is <=signed 0. Hence ... 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLE32S, 1271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU32(0))); 1273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondS)) { 1276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* long and/or/xor, then S --> (ULong)result[31] */ 1277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return binop(Iop_And64, 1278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_Shr64, cc_dep1, mkU8(31)), 1279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU64(1)); 1280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondNS)) { 1282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* long and/or/xor, then S --> (ULong) ~ result[31] */ 1283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return binop(Iop_Xor64, 1284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_And64, 1285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_Shr64, cc_dep1, mkU8(31)), 1286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU64(1)), 1287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU64(1)); 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*---------------- LOGICW ----------------*/ 1291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isU64(cc_op, AMD64G_CC_OP_LOGICW) && isU64(cond, AMD64CondZ)) { 1293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* word and/or/xor, then Z --> test dst==0 */ 1294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return unop(Iop_1Uto64, 1295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng binop(Iop_CmpEQ64, 1296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng binop(Iop_And64, cc_dep1, mkU64(0xFFFF)), 1297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mkU64(0))); 1298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isU64(cc_op, AMD64G_CC_OP_LOGICW) && isU64(cond, AMD64CondNZ)) { 1300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* word and/or/xor, then NZ --> test dst!=0 */ 1301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return unop(Iop_1Uto64, 1302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng binop(Iop_CmpNE64, 1303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng binop(Iop_And64, cc_dep1, mkU64(0xFFFF)), 1304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mkU64(0))); 1305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- LOGICB ----------------*/ 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondZ)) { 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte and/or/xor, then Z --> test dst==0 */ 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ64, binop(Iop_And64,cc_dep1,mkU64(255)), 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondNZ)) { 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte and/or/xor, then NZ --> test dst!=0 */ 1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpNE64, binop(Iop_And64,cc_dep1,mkU64(255)), 1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondS)) { 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* this is an idiom gcc sometimes uses to find out if the top 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bit of a byte register is set: eg testb %al,%al; js .. 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Since it just depends on the top bit of the byte, extract 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that bit and explicitly get rid of all the rest. This 1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown helps memcheck avoid false positives in the case where any 1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of the other bits in the byte are undefined. */ 1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* byte and/or/xor, then S --> (UInt)result[7] */ 1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return binop(Iop_And64, 1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64,cc_dep1,mkU8(7)), 1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1)); 1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondNS)) { 1335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* byte and/or/xor, then NS --> (UInt)!result[7] */ 1336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return binop(Iop_Xor64, 1337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_And64, 1338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_Shr64,cc_dep1,mkU8(7)), 1339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU64(1)), 1340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU64(1)); 1341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- INCB ----------------*/ 1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_INCB) && isU64(cond, AMD64CondLE)) { 1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8-bit inc, then LE --> sign bit of the arg */ 1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return binop(Iop_And64, 1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, 1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Sub64, cc_dep1, mkU64(1)), 1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU8(7)), 1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1)); 1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- INCW ----------------*/ 1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_INCW) && isU64(cond, AMD64CondZ)) { 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 16-bit inc, then Z --> test dst == 0 */ 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpEQ64, 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shl64,cc_dep1,mkU8(48)), 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- DECL ----------------*/ 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_DECL) && isU64(cond, AMD64CondZ)) { 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* dec L, then Z --> test dst == 0 */ 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpEQ32, 1370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mkU32(0))); 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- DECW ----------------*/ 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_DECW) && isU64(cond, AMD64CondNZ)) { 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 16-bit dec, then NZ --> test dst != 0 */ 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpNE64, 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shl64,cc_dep1,mkU8(48)), 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0))); 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*---------------- COPY ----------------*/ 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This can happen, as a result of amd64 FP compares: "comisd ... ; 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jbe" for example. */ 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_COPY) && 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (isU64(cond, AMD64CondBE) || isU64(cond, AMD64CondNBE))) { 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then BE --> extract C and Z from dep1, and test (C 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or Z == 1). */ 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then NBE --> extract C and Z from dep1, and test (C 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or Z == 0). */ 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong nnn = isU64(cond, AMD64CondBE) ? 1 : 0; 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop( 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto64, 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ64, 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_And64, 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_Or64, 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_C)), 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_Z)) 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ), 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1) 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ), 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(nnn) 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_COPY) && isU64(cond, AMD64CondB)) { 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then B --> extract C dep1, and test (C == 1). */ 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop( 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto64, 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNE64, 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_And64, 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_C)), 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1) 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ), 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0) 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_COPY) 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (isU64(cond, AMD64CondZ) || isU64(cond, AMD64CondNZ))) { 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */ 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */ 1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt nnn = isU64(cond, AMD64CondZ) ? 1 : 0; 1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop( 1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto64, 1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpEQ64, 1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_And64, 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_Z)), 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1) 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ), 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(nnn) 1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_COPY) && isU64(cond, AMD64CondP)) { 1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* COPY, then P --> extract P from dep1, and test (P == 1). */ 1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unop( 1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_1Uto64, 1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNE64, 1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop( 1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_And64, 1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_P)), 1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(1) 1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ), 1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mkU64(0) 1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --------- specialising "amd64g_calculate_rflags_c" --------- */ 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_streq(function_name, "amd64g_calculate_rflags_c")) { 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* specialise calls to above "calculate_rflags_c" function */ 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(arity == 4); 1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_op = args[0]; 1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep1 = args[1]; 1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep2 = args[2]; 1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_ndep = args[3]; 1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBQ)) { 1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* C after sub denotes unsigned less than */ 1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLT64U, 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep1, 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc_dep2)); 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBL)) { 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* C after sub denotes unsigned less than */ 1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov binop(Iop_CmpLT32U, 1493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep1), 1494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unop(Iop_64to32, cc_dep2))); 1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_SUBB)) { 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* C after sub denotes unsigned less than */ 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return unop(Iop_1Uto64, 1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_CmpLT64U, 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_And64,cc_dep1,mkU64(0xFF)), 1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binop(Iop_And64,cc_dep2,mkU64(0xFF)))); 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || isU64(cc_op, AMD64G_CC_OP_LOGICL) 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || isU64(cc_op, AMD64G_CC_OP_LOGICW) 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || isU64(cc_op, AMD64G_CC_OP_LOGICB)) { 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* cflag after logic is zero */ 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return mkU64(0); 1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isU64(cc_op, AMD64G_CC_OP_DECL) || isU64(cc_op, AMD64G_CC_OP_INCL) 1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || isU64(cc_op, AMD64G_CC_OP_DECQ) || isU64(cc_op, AMD64G_CC_OP_INCQ)) { 1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */ 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cc_ndep; 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if 0 1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cc_op->tag == Iex_Const) { 1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n"); 1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef unop 1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef binop 1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef mkU64 1528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# undef mkU32 1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef mkU8 1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Supporting functions for x87 FPU activities. ---*/ 1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool host_is_little_endian ( void ) 1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt x = 0x76543210; 1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = (UChar*)(&x); 1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool(*p == 0x10); 1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inspect a value and its tag, as per the x87 'FXAM' instruction. */ 1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_FXAM ( ULong tag, ULong dbl ) 1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool mantissaIsZero; 1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int bexp; 1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar sign; 1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* f64; 1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(host_is_little_endian()); 1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("calculate_FXAM ( %d, %llx ) .. ", tag, dbl ); */ 1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown f64 = (UChar*)(&dbl); 1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sign = toUChar( (f64[7] >> 7) & 1 ); 1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First off, if the tag indicates the register was empty, 1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1,0,sign,1 */ 1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == 0) { 1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("Empty\n"); */ 1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return AMD64G_FC_MASK_C3 | 0 | (sign << AMD64G_FC_SHIFT_C1) 1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | AMD64G_FC_MASK_C0; 1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bexp = (f64[7] << 4) | ((f64[6] >> 4) & 0x0F); 1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bexp &= 0x7FF; 1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mantissaIsZero 1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toBool( 1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (f64[6] & 0x0F) == 0 1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (f64[5] | f64[4] | f64[3] | f64[2] | f64[1] | f64[0]) == 0 1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If both exponent and mantissa are zero, the value is zero. 1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return 1,0,sign,0. */ 1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bexp == 0 && mantissaIsZero) { 1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("Zero\n"); */ 1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return AMD64G_FC_MASK_C3 | 0 1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (sign << AMD64G_FC_SHIFT_C1) | 0; 1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If exponent is zero but mantissa isn't, it's a denormal. 1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return 1,1,sign,0. */ 1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bexp == 0 && !mantissaIsZero) { 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("Denormal\n"); */ 1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return AMD64G_FC_MASK_C3 | AMD64G_FC_MASK_C2 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | (sign << AMD64G_FC_SHIFT_C1) | 0; 1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the exponent is 7FF and the mantissa is zero, this is an infinity. 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return 0,1,sign,1. */ 1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bexp == 0x7FF && mantissaIsZero) { 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("Inf\n"); */ 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0 | AMD64G_FC_MASK_C2 | (sign << AMD64G_FC_SHIFT_C1) 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | AMD64G_FC_MASK_C0; 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the exponent is 7FF and the mantissa isn't zero, this is a NaN. 1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return 0,0,sign,1. */ 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bexp == 0x7FF && !mantissaIsZero) { 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("NaN\n"); */ 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0 | 0 | (sign << AMD64G_FC_SHIFT_C1) | AMD64G_FC_MASK_C0; 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Uh, ok, we give up. It must be a normal finite number. 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return 0,1,sign,0. 1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("normal\n"); */ 1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0 | AMD64G_FC_MASK_C2 | (sign << AMD64G_FC_SHIFT_C1) | 0; 1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1618f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* This is used to implement both 'frstor' and 'fldenv'. The latter 1619f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root appears to differ from the former only in that the 8 FP registers 1620f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root themselves are not transferred into the guest state. */ 1621f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic 1622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexEmNote do_put_x87 ( Bool moveRegs, 1623f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /*IN*/UChar* x87_state, 1624f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /*OUT*/VexGuestAMD64State* vex_state ) 1625f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 1626f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root Int stno, preg; 1627f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt tag; 1628f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1629f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 1630f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root Fpu_State* x87 = (Fpu_State*)x87_state; 1631f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt ftop = (x87->env[FP_ENV_STAT] >> 11) & 7; 1632f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt tagw = x87->env[FP_ENV_TAG]; 1633f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt fpucw = x87->env[FP_ENV_CTRL]; 1634f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt c3210 = x87->env[FP_ENV_STAT] & 0x4700; 1635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote ew; 1636f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt fpround; 1637f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong pair; 1638f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1639f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Copy registers and tags */ 1640f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (stno = 0; stno < 8; stno++) { 1641f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root preg = (stno + ftop) & 7; 1642f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root tag = (tagw >> (2*preg)) & 3; 1643f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (tag == 3) { 1644f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* register is empty */ 1645f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* hmm, if it's empty, does it still get written? Probably 1646f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root safer to say it does. If we don't, memcheck could get out 1647f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root of sync, in that it thinks all FP registers are defined by 1648f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root this helper, but in reality some have not been updated. */ 1649f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (moveRegs) 1650f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 1651f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vexTags[preg] = 0; 1652f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } else { 1653f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* register is non-empty */ 1654f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (moveRegs) 1655f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root convert_f80le_to_f64le( &x87->reg[10*stno], 1656f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root (UChar*)&vexRegs[preg] ); 1657f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vexTags[preg] = 1; 1658f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1659f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1660f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1661f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* stack pointer */ 1662f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vex_state->guest_FTOP = ftop; 1663f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1664f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* status word */ 1665f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vex_state->guest_FC3210 = c3210; 1666f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1667f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* handle the control word, setting FPROUND and detecting any 1668f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root emulation warnings. */ 1669f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root pair = amd64g_check_fldcw ( (ULong)fpucw ); 1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpround = (UInt)pair & 0xFFFFFFFFULL; 1671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ew = (VexEmNote)(pair >> 32); 1672f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1673f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vex_state->guest_FPROUND = fpround & 3; 1674f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1675f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* emulation warnings --> caller */ 1676f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return ew; 1677f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 1678f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1679f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create an x87 FPU state from the guest state, as close as 1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we can approximate it. */ 1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_get_x87 ( /*IN*/VexGuestAMD64State* vex_state, 1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/UChar* x87_state ) 1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, stno, preg; 1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt tagw; 1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Fpu_State* x87 = (Fpu_State*)x87_state; 1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ftop = vex_state->guest_FTOP; 1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt c3210 = vex_state->guest_FC3210; 1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < 14; i++) 1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[i] = 0; 1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_STAT] 1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_CTRL] 1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toUShort(amd64g_create_fpucw( vex_state->guest_FPROUND )); 1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Dump the register stack in ST order. */ 1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw = 0; 1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (stno = 0; stno < 8; stno++) { 1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown preg = (stno + ftop) & 7; 1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vexTags[preg] == 0) { 1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* register is empty */ 1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw |= (3 << (2*preg)); 1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &x87->reg[10*stno] ); 1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* register is full. */ 1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw |= (0 << (2*preg)); 1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &x87->reg[10*stno] ); 1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_TAG] = toUShort(tagw); 1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (reads guest state, writes guest mem) */ 1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* NOTE: only handles 32-bit format (no REX.W on the insn) */ 1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_FXSAVE ( VexGuestAMD64State* gst, HWord addr ) 1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Derived from values obtained from 1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vendor_id : AuthenticAMD 1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu family : 15 1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model : 12 1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model name : AMD Athlon(tm) 64 Processor 3200+ 1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stepping : 0 1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu MHz : 2200.000 1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache size : 512 KB 1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Somewhat roundabout, but at least it's simple. */ 1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Fpu_State tmp; 1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort* addrS = (UShort*)addr; 1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* addrC = (UChar*)addr; 1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown U128* xmm = (U128*)(addr + 160); 1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt mxcsr; 1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort fp_tags; 1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt summary_tags; 1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int r, stno; 1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort *srcS, *dstS; 1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_get_x87( gst, (UChar*)&tmp ); 1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mxcsr = amd64g_create_mxcsr( gst->guest_SSEROUND ); 1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now build the proper fxsave image from the x87 image we just 1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown made. */ 1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[0] = tmp.env[FP_ENV_CTRL]; /* FCW: fpu control word */ 1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[1] = tmp.env[FP_ENV_STAT]; /* FCW: fpu status word */ 1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* set addrS[2] in an endian-independent way */ 1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown summary_tags = 0; 1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fp_tags = tmp.env[FP_ENV_TAG]; 1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (r = 0; r < 8; r++) { 1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( ((fp_tags >> (2*r)) & 3) != 3 ) 1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown summary_tags |= (1 << r); 1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrC[4] = toUChar(summary_tags); /* FTW: tag summary byte */ 1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrC[5] = 0; /* pad */ 1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FOP: faulting fpu opcode. From experimentation, the real CPU 1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does not write this field. (?!) */ 1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[3] = 0; /* BOGUS */ 1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* RIP (Last x87 instruction pointer). From experimentation, the 1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown real CPU does not write this field. (?!) */ 1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[4] = 0; /* BOGUS */ 1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[5] = 0; /* BOGUS */ 1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[6] = 0; /* BOGUS */ 1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[7] = 0; /* BOGUS */ 1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* RDP (Last x87 data pointer). From experimentation, the real CPU 1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does not write this field. (?!) */ 1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[8] = 0; /* BOGUS */ 1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[9] = 0; /* BOGUS */ 1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[10] = 0; /* BOGUS */ 1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[11] = 0; /* BOGUS */ 1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[12] = toUShort(mxcsr); /* MXCSR */ 1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[13] = toUShort(mxcsr >> 16); 1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[14] = 0xFFFF; /* MXCSR mask (lo16) */ 1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addrS[15] = 0x0000; /* MXCSR mask (hi16) */ 1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy in the FP registers, in ST order. */ 1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (stno = 0; stno < 8; stno++) { 1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown srcS = (UShort*)(&tmp.reg[10*stno]); 1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS = (UShort*)(&addrS[16 + 8*stno]); 1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[0] = srcS[0]; 1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[1] = srcS[1]; 1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[2] = srcS[2]; 1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[3] = srcS[3]; 1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[4] = srcS[4]; 1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[5] = 0; 1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[6] = 0; 1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dstS[7] = 0; 1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* That's the first 160 bytes of the image done. Now only %xmm0 1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .. %xmm15 remain to be copied. If the host is big-endian, these 1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown need to be byte-swapped. */ 1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(host_is_little_endian()); 1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define COPY_U128(_dst,_src) \ 1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (0) 1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[0], gst->guest_YMM0 ); 1816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[1], gst->guest_YMM1 ); 1817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[2], gst->guest_YMM2 ); 1818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[3], gst->guest_YMM3 ); 1819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[4], gst->guest_YMM4 ); 1820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[5], gst->guest_YMM5 ); 1821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[6], gst->guest_YMM6 ); 1822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[7], gst->guest_YMM7 ); 1823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[8], gst->guest_YMM8 ); 1824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[9], gst->guest_YMM9 ); 1825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[10], gst->guest_YMM10 ); 1826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[11], gst->guest_YMM11 ); 1827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[12], gst->guest_YMM12 ); 1828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[13], gst->guest_YMM13 ); 1829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[14], gst->guest_YMM14 ); 1830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( xmm[15], gst->guest_YMM15 ); 1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef COPY_U128 1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1836f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* CALLED FROM GENERATED CODE */ 1837f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* DIRTY HELPER (writes guest state, reads guest mem) */ 1838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexEmNote amd64g_dirtyhelper_FXRSTOR ( VexGuestAMD64State* gst, HWord addr ) 1839f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 1840f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root Fpu_State tmp; 1841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote warnX87 = EmNote_NONE; 1842436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote warnXMM = EmNote_NONE; 1843f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UShort* addrS = (UShort*)addr; 1844f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UChar* addrC = (UChar*)addr; 1845f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root U128* xmm = (U128*)(addr + 160); 1846f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UShort fp_tags; 1847f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root Int r, stno, i; 1848f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1849f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Restore %xmm0 .. %xmm15. If the host is big-endian, these need 1850f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root to be byte-swapped. */ 1851f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vassert(host_is_little_endian()); 1852f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1853f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root# define COPY_U128(_dst,_src) \ 1854f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root do { _dst[0] = _src[0]; _dst[1] = _src[1]; \ 1855f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root _dst[2] = _src[2]; _dst[3] = _src[3]; } \ 1856f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while (0) 1857f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM0, xmm[0] ); 1859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM1, xmm[1] ); 1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM2, xmm[2] ); 1861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM3, xmm[3] ); 1862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM4, xmm[4] ); 1863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM5, xmm[5] ); 1864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM6, xmm[6] ); 1865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM7, xmm[7] ); 1866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM8, xmm[8] ); 1867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM9, xmm[9] ); 1868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM10, xmm[10] ); 1869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM11, xmm[11] ); 1870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM12, xmm[12] ); 1871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM13, xmm[13] ); 1872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM14, xmm[14] ); 1873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng COPY_U128( gst->guest_YMM15, xmm[15] ); 1874f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1875f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root# undef COPY_U128 1876f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1877f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Copy the x87 registers out of the image, into a temporary 1878f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root Fpu_State struct. */ 1879f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (i = 0; i < 14; i++) tmp.env[i] = 0; 1880f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (i = 0; i < 80; i++) tmp.reg[i] = 0; 1881f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* fill in tmp.reg[0..7] */ 1882f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (stno = 0; stno < 8; stno++) { 1883f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UShort* dstS = (UShort*)(&tmp.reg[10*stno]); 1884f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UShort* srcS = (UShort*)(&addrS[16 + 8*stno]); 1885f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root dstS[0] = srcS[0]; 1886f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root dstS[1] = srcS[1]; 1887f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root dstS[2] = srcS[2]; 1888f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root dstS[3] = srcS[3]; 1889f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root dstS[4] = srcS[4]; 1890f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1891f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* fill in tmp.env[0..13] */ 1892f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root tmp.env[FP_ENV_CTRL] = addrS[0]; /* FCW: fpu control word */ 1893f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root tmp.env[FP_ENV_STAT] = addrS[1]; /* FCW: fpu status word */ 1894f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1895f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root fp_tags = 0; 1896f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (r = 0; r < 8; r++) { 1897f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (addrC[4] & (1<<r)) 1898f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root fp_tags |= (0 << (2*r)); /* EMPTY */ 1899f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root else 1900f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root fp_tags |= (3 << (2*r)); /* VALID -- not really precise enough. */ 1901f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1902f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root tmp.env[FP_ENV_TAG] = fp_tags; 1903f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1904f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Now write 'tmp' into the guest state. */ 1905f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root warnX87 = do_put_x87( True/*moveRegs*/, (UChar*)&tmp, gst ); 1906f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1907f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root { UInt w32 = (((UInt)addrS[12]) & 0xFFFF) 1908f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root | ((((UInt)addrS[13]) & 0xFFFF) << 16); 1909f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong w64 = amd64g_check_ldmxcsr( (ULong)w32 ); 1910f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1911436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov warnXMM = (VexEmNote)(w64 >> 32); 1912f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1913f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root gst->guest_SSEROUND = w64 & 0xFFFFFFFFULL; 1914f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1915f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1916f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Prefer an X87 emwarn over an XMM one, if both exist. */ 1917436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (warnX87 != EmNote_NONE) 1918f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return warnX87; 1919f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root else 1920f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return warnXMM; 1921f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 1922f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1923f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (writes guest state) */ 1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialise the x87 FPU state as per 'finit'. */ 1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_FINIT ( VexGuestAMD64State* gst ) 1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gst->guest_FTOP = 0; 1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < 8; i++) { 1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gst->guest_FPTAG[i] = 0; /* empty */ 1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */ 1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gst->guest_FPROUND = (ULong)Irrm_NEAREST; 1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gst->guest_FC3210 = 0; 1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (reads guest memory) */ 1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_dirtyhelper_loadF80le ( ULong addrU ) 1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong f64; 1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_f80le_to_f64le ( (UChar*)ULong_to_Ptr(addrU), (UChar*)&f64 ); 1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return f64; 1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (writes guest memory) */ 1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_storeF80le ( ULong addrU, ULong f64 ) 1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_f64le_to_f80le( (UChar*)&f64, (UChar*)ULong_to_Ptr(addrU) ); 1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CLEAN HELPER */ 1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* mxcsr[15:0] contains a SSE native format MXCSR value. 1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Extract from it the required SSEROUND value and any resulting 1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emulation warning, and return (warn << 32) | sseround value. 1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_check_ldmxcsr ( ULong mxcsr ) 1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Decide on a rounding mode. mxcsr[14:13] holds it. */ 1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* NOTE, encoded exactly as per enum IRRoundingMode. */ 1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rmode = (mxcsr >> 13) & 3; 1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Detect any required emulation warnings. */ 1969436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote ew = EmNote_NONE; 1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((mxcsr & 0x1F80) != 0x1F80) { 1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unmasked exceptions! */ 1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ew = EmWarn_X86_sseExns; 1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mxcsr & (1<<15)) { 1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FZ is set */ 1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ew = EmWarn_X86_fz; 1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mxcsr & (1<<6)) { 1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* DAZ is set */ 1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ew = EmWarn_X86_daz; 1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (((ULong)ew) << 32) | ((ULong)rmode); 1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CLEAN HELPER */ 1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Given sseround as an IRRoundingMode value, create a suitable SSE 1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown native format MXCSR value. */ 1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_create_mxcsr ( ULong sseround ) 1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sseround &= 3; 1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0x1F80 | (sseround << 13); 1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CLEAN HELPER */ 2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* fpucw[15:0] contains a x87 native format FPU control word. 2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Extract from it the required FPROUND value and any resulting 2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emulation warning, and return (warn << 32) | fpround value. 2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_check_fldcw ( ULong fpucw ) 2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Decide on a rounding mode. fpucw[11:10] holds it. */ 2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* NOTE, encoded exactly as per enum IRRoundingMode. */ 2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rmode = (fpucw >> 10) & 3; 2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Detect any required emulation warnings. */ 2013436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote ew = EmNote_NONE; 2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((fpucw & 0x3F) != 0x3F) { 2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unmasked exceptions! */ 2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ew = EmWarn_X86_x87exns; 2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (((fpucw >> 8) & 3) != 3) { 2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unsupported precision */ 2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ew = EmWarn_X86_x87precision; 2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (((ULong)ew) << 32) | ((ULong)rmode); 2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CLEAN HELPER */ 2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Given fpround as an IRRoundingMode value, create a suitable x87 2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown native format FPU control word. */ 2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_create_fpucw ( ULong fpround ) 2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpround &= 3; 2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0x037F | (fpround << 10); 2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is used to implement 'fldenv'. 2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reads 28 bytes at x87_state[0 .. 27]. */ 2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER */ 2043436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexEmNote amd64g_dirtyhelper_FLDENV ( /*OUT*/VexGuestAMD64State* vex_state, 2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*IN*/HWord x87_state) 2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return do_put_x87( False, (UChar*)x87_state, vex_state ); 2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER */ 2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create an x87 FPU env from the guest state, as close as we can 2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown approximate it. Writes 28 bytes at x87_state[0..27]. */ 2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_FSTENV ( /*IN*/VexGuestAMD64State* vex_state, 2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/HWord x87_state ) 2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, stno, preg; 2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt tagw; 2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Fpu_State* x87 = (Fpu_State*)x87_state; 2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ftop = vex_state->guest_FTOP; 2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong c3210 = vex_state->guest_FC3210; 2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < 14; i++) 2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[i] = 0; 2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF; 2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_STAT] 2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toUShort(toUInt( ((ftop & 7) << 11) | (c3210 & 0x4700) )); 2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_CTRL] 2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toUShort(toUInt( amd64g_create_fpucw( vex_state->guest_FPROUND ) )); 2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compute the x87 tag word. */ 2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw = 0; 2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (stno = 0; stno < 8; stno++) { 2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown preg = (stno + ftop) & 7; 2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vexTags[preg] == 0) { 2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* register is empty */ 2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw |= (3 << (2*preg)); 2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* register is full. */ 2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tagw |= (0 << (2*preg)); 2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x87->env[FP_ENV_TAG] = toUShort(tagw); 2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We don't dump the x87 registers, tho. */ 2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is used to implement 'fnsave'. 2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Writes 108 bytes at x87_state[0 .. 107]. */ 2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE */ 2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DIRTY HELPER */ 2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid amd64g_dirtyhelper_FNSAVE ( /*IN*/VexGuestAMD64State* vex_state, 2096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*OUT*/HWord x87_state) 2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do_get_x87( vex_state, (UChar*)x87_state ); 2099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is used to implement 'fnsaves'. 2103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Writes 94 bytes at x87_state[0 .. 93]. */ 2104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE */ 2105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DIRTY HELPER */ 2106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid amd64g_dirtyhelper_FNSAVES ( /*IN*/VexGuestAMD64State* vex_state, 2107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*OUT*/HWord x87_state) 2108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, stno, preg; 2110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt tagw; 2111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 2112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 2113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Fpu_State_16* x87 = (Fpu_State_16*)x87_state; 2114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt ftop = vex_state->guest_FTOP; 2115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt c3210 = vex_state->guest_FC3210; 2116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 7; i++) 2118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x87->env[i] = 0; 2119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x87->env[FPS_ENV_STAT] 2121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = toUShort(((ftop & 7) << 11) | (c3210 & 0x4700)); 2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x87->env[FPS_ENV_CTRL] 2123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = toUShort(amd64g_create_fpucw( vex_state->guest_FPROUND )); 2124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Dump the register stack in ST order. */ 2126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tagw = 0; 2127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (stno = 0; stno < 8; stno++) { 2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng preg = (stno + ftop) & 7; 2129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vexTags[preg] == 0) { 2130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* register is empty */ 2131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tagw |= (3 << (2*preg)); 2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &x87->reg[10*stno] ); 2134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 2135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* register is full. */ 2136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tagw |= (0 << (2*preg)); 2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng convert_f64le_to_f80le( (UChar*)&vexRegs[preg], 2138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &x87->reg[10*stno] ); 2139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x87->env[FPS_ENV_TAG] = toUShort(tagw); 2142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is used to implement 'frstor'. 2146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Reads 108 bytes at x87_state[0 .. 107]. */ 2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE */ 2148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DIRTY HELPER */ 2149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexEmNote amd64g_dirtyhelper_FRSTOR ( /*OUT*/VexGuestAMD64State* vex_state, 2150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*IN*/HWord x87_state) 2151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return do_put_x87( True, (UChar*)x87_state, vex_state ); 2153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is used to implement 'frstors'. 2157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Reads 94 bytes at x87_state[0 .. 93]. */ 2158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE */ 2159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DIRTY HELPER */ 2160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexEmNote amd64g_dirtyhelper_FRSTORS ( /*OUT*/VexGuestAMD64State* vex_state, 2161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*IN*/HWord x87_state) 2162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int stno, preg; 2164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt tag; 2165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong* vexRegs = (ULong*)(&vex_state->guest_FPREG[0]); 2166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar* vexTags = (UChar*)(&vex_state->guest_FPTAG[0]); 2167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Fpu_State_16* x87 = (Fpu_State_16*)x87_state; 2168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt ftop = (x87->env[FPS_ENV_STAT] >> 11) & 7; 2169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt tagw = x87->env[FPS_ENV_TAG]; 2170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt fpucw = x87->env[FPS_ENV_CTRL]; 2171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt c3210 = x87->env[FPS_ENV_STAT] & 0x4700; 2172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexEmNote ew; 2173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt fpround; 2174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong pair; 2175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Copy registers and tags */ 2177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (stno = 0; stno < 8; stno++) { 2178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng preg = (stno + ftop) & 7; 2179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tag = (tagw >> (2*preg)) & 3; 2180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tag == 3) { 2181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* register is empty */ 2182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* hmm, if it's empty, does it still get written? Probably 2183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng safer to say it does. If we don't, memcheck could get out 2184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng of sync, in that it thinks all FP registers are defined by 2185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng this helper, but in reality some have not been updated. */ 2186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vexRegs[preg] = 0; /* IEEE754 64-bit zero */ 2187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vexTags[preg] = 0; 2188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 2189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* register is non-empty */ 2190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng convert_f80le_to_f64le( &x87->reg[10*stno], 2191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (UChar*)&vexRegs[preg] ); 2192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vexTags[preg] = 1; 2193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* stack pointer */ 2197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->guest_FTOP = ftop; 2198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* status word */ 2200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->guest_FC3210 = c3210; 2201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* handle the control word, setting FPROUND and detecting any 2203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng emulation warnings. */ 2204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pair = amd64g_check_fldcw ( (ULong)fpucw ); 2205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpround = (UInt)pair & 0xFFFFFFFFULL; 2206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ew = (VexEmNote)(pair >> 32); 2207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->guest_FPROUND = fpround & 3; 2209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* emulation warnings --> caller */ 2211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ew; 2212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Misc integer helpers, including rotates and CPUID. ---*/ 2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Claim to be the following CPU, which is probably representative of 2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the lowliest (earliest) amd64 offerings. It can do neither sse3 2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nor cx16. 2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vendor_id : AuthenticAMD 2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu family : 15 2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model : 5 2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model name : AMD Opteron (tm) Processor 848 2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stepping : 10 2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu MHz : 1797.682 2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache size : 1024 KB 2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu : yes 2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu_exception : yes 2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpuid level : 1 2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wp : yes 2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mtrr pge mca cmov pat pse36 clflush mmx fxsr 2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sse sse2 syscall nx mmxext lm 3dnowext 3dnow 2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bogomips : 3600.62 2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TLB size : 1088 4K pages 2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clflush size : 64 2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache_alignment : 64 2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address sizes : 40 bits physical, 48 bits virtual 2242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng power management: ts fid vid ttp 2243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2012-Feb-21: don't claim 3dnow or 3dnowext, since in fact 2245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng we don't support them. See #291568. 3dnow is 80000001.EDX.31 2246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and 3dnowext is 80000001.EDX.30. 2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_CPUID_baseline ( VexGuestAMD64State* st ) 2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define SET_ABCD(_a,_b,_c,_d) \ 2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { st->guest_RAX = (ULong)(_a); \ 2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RBX = (ULong)(_b); \ 2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RCX = (ULong)(_c); \ 2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RDX = (ULong)(_d); \ 2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (0xFFFFFFFF & st->guest_RAX) { 2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: 2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000001, 0x68747541, 0x444d4163, 0x69746e65); 2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: 2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000f5a, 0x01000800, 0x00000000, 0x078bfbff); 2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000000: 2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x80000018, 0x68747541, 0x444d4163, 0x69746e65); 2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000001: 2268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Don't claim to support 3dnow or 3dnowext. 0xe1d3fbff is 2269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the original it-is-supported value that the h/w provides. 2270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng See #291568. */ 2271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000f5a, 0x00000505, 0x00000000, /*0xe1d3fbff*/ 2272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x21d3fbff); 2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000002: 2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x20444d41, 0x6574704f, 0x206e6f72, 0x296d7428); 2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000003: 2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x6f725020, 0x73736563, 0x3820726f, 0x00003834); 2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000004: 2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000005: 2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0xff08ff08, 0xff20ff20, 0x40020140, 0x40020140); 2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000006: 2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x42004200, 0x04008140, 0x00000000); 2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000007: 2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x0000000f); 2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000008: 2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00003028, 0x00000000, 0x00000000, 0x00000000); 2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef SET_ABCD 2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Claim to be the following CPU (2 x ...), which is sse3 and cx16 2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown capable. 2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vendor_id : GenuineIntel 2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu family : 6 2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model : 15 2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz 2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stepping : 6 2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu MHz : 2394.000 2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache size : 4096 KB 2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown physical id : 0 2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown siblings : 2 2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown core id : 0 2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu cores : 2 2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu : yes 2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu_exception : yes 2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpuid level : 10 2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wp : yes 2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mtrr pge mca cmov pat pse36 clflush dts acpi 2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mmx fxsr sse sse2 ss ht tm syscall nx lm 2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown constant_tsc pni monitor ds_cpl vmx est tm2 2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cx16 xtpr lahf_lm 2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bogomips : 4798.78 2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clflush size : 64 2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache_alignment : 64 2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address sizes : 36 bits physical, 48 bits virtual 2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown power management: 2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_CPUID_sse3_and_cx16 ( VexGuestAMD64State* st ) 2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define SET_ABCD(_a,_b,_c,_d) \ 2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { st->guest_RAX = (ULong)(_a); \ 2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RBX = (ULong)(_b); \ 2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RCX = (ULong)(_c); \ 2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RDX = (ULong)(_d); \ 2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (0xFFFFFFFF & st->guest_RAX) { 2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: 2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69); 2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: 2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x000006f6, 0x00020800, 0x0000e3bd, 0xbfebfbff); 2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000002: 2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x05b0b101, 0x005657f0, 0x00000000, 0x2cb43049); 2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000003: 2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000004: { 2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (0xFFFFFFFF & st->guest_RCX) { 2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, 2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x0000003f, 0x00000001); break; 2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, 2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x0000003f, 0x00000001); break; 2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, 2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000fff, 0x00000001); break; 2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: SET_ABCD(0x00000000, 0x00000000, 2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000000, 0x00000000); break; 2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000005: 2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); 2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000006: 2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000001, 0x00000002, 0x00000001, 0x00000000); 2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000007: 2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000008: 2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000400, 0x00000000, 0x00000000, 0x00000000); 2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000009: 2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x0000000a: 2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unhandled_eax_value: 2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); 2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000000: 2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000001: 2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x20100800); 2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000002: 2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000003: 2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x43203229, 0x20205550, 0x20202020, 0x20202020); 2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000004: 2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x30303636, 0x20402020, 0x30342e32, 0x007a4847); 2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000005: 2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000006: 2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x10008040, 0x00000000); 2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000007: 2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000008: 2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto unhandled_eax_value; 2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef SET_ABCD 2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Claim to be the following CPU (4 x ...), which is sse4.2 and cx16 2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown capable. 2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vendor_id : GenuineIntel 2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu family : 6 2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model : 37 2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown model name : Intel(R) Core(TM) i5 CPU 670 @ 3.47GHz 2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stepping : 2 2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu MHz : 3334.000 2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache size : 4096 KB 2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown physical id : 0 2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown siblings : 4 2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown core id : 0 2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpu cores : 2 2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown apicid : 0 2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown initial apicid : 0 2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu : yes 2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fpu_exception : yes 2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cpuid level : 11 2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wp : yes 2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mtrr pge mca cmov pat pse36 clflush dts acpi 2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp 2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lm constant_tsc arch_perfmon pebs bts rep_good 2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xtopology nonstop_tsc aperfmperf pni pclmulqdq 2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xtpr pdcm sse4_1 sse4_2 popcnt aes lahf_lm ida 2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arat tpr_shadow vnmi flexpriority ept vpid 2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bogomips : 6957.57 2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clflush size : 64 2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache_alignment : 64 2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address sizes : 36 bits physical, 48 bits virtual 2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown power management: 2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st ) 2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define SET_ABCD(_a,_b,_c,_d) \ 2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { st->guest_RAX = (ULong)(_a); \ 2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RBX = (ULong)(_b); \ 2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RCX = (ULong)(_c); \ 2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->guest_RDX = (ULong)(_d); \ 2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt old_eax = (UInt)st->guest_RAX; 2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt old_ecx = (UInt)st->guest_RCX; 2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (old_eax) { 2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: 2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x0000000b, 0x756e6547, 0x6c65746e, 0x49656e69); 2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: 2471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00020652, 0x00100800, 0x0298e3ff, 0xbfebfbff); 2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000002: 2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x55035a01, 0x00f0b2e3, 0x00000000, 0x09ca212c); 2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000003: 2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000004: 2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (old_ecx) { 2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: SET_ABCD(0x1c004121, 0x01c0003f, 2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x0000003f, 0x00000000); break; 2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: SET_ABCD(0x1c004122, 0x00c0003f, 2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x0000007f, 0x00000000); break; 2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000002: SET_ABCD(0x1c004143, 0x01c0003f, 2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x000001ff, 0x00000000); break; 2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000003: SET_ABCD(0x1c03c163, 0x03c0003f, 2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000fff, 0x00000002); break; 2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: SET_ABCD(0x00000000, 0x00000000, 2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000000, 0x00000000); break; 2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000005: 2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00001120); 2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000006: 2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000007, 0x00000002, 0x00000001, 0x00000000); 2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000007: 2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000008: 2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000009: 2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x0000000a: 2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x07300403, 0x00000004, 0x00000000, 0x00000603); 2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x0000000b: 2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (old_ecx) { 2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: 2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000001, 0x00000002, 2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000100, 0x00000000); break; 2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: 2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000004, 0x00000004, 2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000201, 0x00000000); break; 2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown old_ecx, 0x00000000); break; 2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x0000000c: 2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000001, 0x00000002, 0x00000100, 0x00000000); 2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x0000000d: 2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (old_ecx) { 2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000000: SET_ABCD(0x00000001, 0x00000002, 2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000100, 0x00000000); break; 2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x00000001: SET_ABCD(0x00000004, 0x00000004, 2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x00000201, 0x00000000); break; 2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: SET_ABCD(0x00000000, 0x00000000, 2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown old_ecx, 0x00000000); break; 2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000000: 2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000001: 2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x28100800); 2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000002: 2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865); 2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000003: 2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x35692029, 0x55504320, 0x20202020, 0x20202020); 2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000004: 2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x30373620, 0x20402020, 0x37342e33, 0x007a4847); 2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000005: 2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000006: 2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x01006040, 0x00000000); 2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000007: 2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000100); 2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0x80000008: 2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SET_ABCD(0x00000001, 0x00000002, 0x00000100, 0x00000000); 2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef SET_ABCD 2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Claim to be the following CPU (4 x ...), which is AVX and cx16 2573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov capable. Plus (kludge!) it "supports" HTM. 2574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vendor_id : GenuineIntel 2576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cpu family : 6 2577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng model : 42 2578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng model name : Intel(R) Core(TM) i5-2300 CPU @ 2.80GHz 2579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stepping : 7 2580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cpu MHz : 1600.000 2581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cache size : 6144 KB 2582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng physical id : 0 2583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng siblings : 4 2584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng core id : 3 2585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cpu cores : 4 2586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng apicid : 6 2587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng initial apicid : 6 2588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpu : yes 2589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpu_exception : yes 2590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cpuid level : 13 2591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng wp : yes 2592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flags : fpu vme de pse tsc msr pae mce cx8 apic sep 2593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mtrr pge mca cmov pat pse36 clflush dts acpi 2594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp 2595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lm constant_tsc arch_perfmon pebs bts rep_good 2596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq 2597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 2598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng xtpr pdcm sse4_1 sse4_2 popcnt aes xsave avx 2599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lahf_lm ida arat epb xsaveopt pln pts dts 2600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tpr_shadow vnmi flexpriority ept vpid 2601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bogomips : 5768.94 2603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng clflush size : 64 2604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cache_alignment : 64 2605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng address sizes : 36 bits physical, 48 bits virtual 2606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng power management: 2607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 2608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st ) 2609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define SET_ABCD(_a,_b,_c,_d) \ 2611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { st->guest_RAX = (ULong)(_a); \ 2612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->guest_RBX = (ULong)(_b); \ 2613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->guest_RCX = (ULong)(_c); \ 2614663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->guest_RDX = (ULong)(_d); \ 2615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 2616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt old_eax = (UInt)st->guest_RAX; 2618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt old_ecx = (UInt)st->guest_RCX; 2619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (old_eax) { 2621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000000: 2622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69); 2623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000001: 2625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x000206a7, 0x00100800, 0x1f9ae3bf, 0xbfebfbff); 2626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000002: 2628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000); 2629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000003: 2631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000004: 2634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (old_ecx) { 2635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000000: SET_ABCD(0x1c004121, 0x01c0003f, 2636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x0000003f, 0x00000000); break; 2637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000001: SET_ABCD(0x1c004122, 0x01c0003f, 2638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x0000003f, 0x00000000); break; 2639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000002: SET_ABCD(0x1c004143, 0x01c0003f, 2640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x000001ff, 0x00000000); break; 2641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000003: SET_ABCD(0x1c03c163, 0x02c0003f, 2642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00001fff, 0x00000006); break; 2643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: SET_ABCD(0x00000000, 0x00000000, 2644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000000, 0x00000000); break; 2645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000005: 2648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00001120); 2649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000006: 2651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000077, 0x00000002, 0x00000009, 0x00000000); 2652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000007: 2654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SET_ABCD(0x00000000, 0x00000800, 0x00000000, 0x00000000); 2655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000008: 2657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000009: 2660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000a: 2663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x07300803, 0x00000000, 0x00000000, 0x00000603); 2664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000b: 2666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (old_ecx) { 2667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000000: 2668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000001, 0x00000001, 2669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000100, 0x00000000); break; 2670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000001: 2671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000004, 0x00000004, 2672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000201, 0x00000000); break; 2673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 2675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng old_ecx, 0x00000000); break; 2676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000c: 2679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000d: 2682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (old_ecx) { 2683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000000: SET_ABCD(0x00000007, 0x00000340, 2684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000340, 0x00000000); break; 2685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000001: SET_ABCD(0x00000001, 0x00000000, 2686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000000, 0x00000000); break; 2687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x00000002: SET_ABCD(0x00000100, 0x00000240, 2688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000000, 0x00000000); break; 2689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: SET_ABCD(0x00000000, 0x00000000, 2690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00000000, 0x00000000); break; 2691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000e: 2694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 2695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x0000000f: 2697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 2698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000000: 2700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x80000008, 0x00000000, 0x00000000, 0x00000000); 2701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000001: 2703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000001, 0x28100800); 2704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000002: 2706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x20202020, 0x20202020, 0x65746e49, 0x2952286c); 2707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000003: 2709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x726f4320, 0x4d542865, 0x35692029, 0x3033322d); 2710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000004: 2712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x50432030, 0x20402055, 0x30382e32, 0x007a4847); 2713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000005: 2715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); 2716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000006: 2718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x01006040, 0x00000000); 2719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000007: 2721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000100); 2722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0x80000008: 2724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); 2725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_ABCD(0x00000007, 0x00000340, 0x00000340, 0x00000000); 2728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# undef SET_ABCD 2731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_RCR ( ULong arg, 2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rot_amt, 2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rflags_in, 2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long szIN ) 2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool wantRflags = toBool(szIN < 0); 2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong sz = wantRflags ? (-szIN) : szIN; 2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong tempCOUNT = rot_amt & (sz == 8 ? 0x3F : 0x1F); 2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cf=0, of=0, tempcf; 2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (sz) { 2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: 2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 63) ^ cf) & 1; 2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = arg & 1; 2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = (arg >> 1) | (cf << 63); 2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 33) tempCOUNT -= 33; 2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 31) ^ cf) & 1; 2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = arg & 1; 2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = ((arg >> 1) & 0x7FFFFFFFULL) | (cf << 31); 2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 17) tempCOUNT -= 17; 2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 15) ^ cf) & 1; 2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = arg & 1; 2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = ((arg >> 1) & 0x7FFFULL) | (cf << 15); 2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 9) tempCOUNT -= 9; 2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 7) ^ cf) & 1; 2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = arg & 1; 2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = ((arg >> 1) & 0x7FULL) | (cf << 7); 2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("calculate_RCR(amd64g): invalid size"); 2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf &= 1; 2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of &= 1; 2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags_in &= ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O); 2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags_in |= (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O); 2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* caller can ask to have back either the resulting flags or 2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown resulting value, but not both */ 2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return wantRflags ? rflags_in : arg; 2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_RCL ( ULong arg, 2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rot_amt, 2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rflags_in, 2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long szIN ) 2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool wantRflags = toBool(szIN < 0); 2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong sz = wantRflags ? (-szIN) : szIN; 2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong tempCOUNT = rot_amt & (sz == 8 ? 0x3F : 0x1F); 2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong cf=0, of=0, tempcf; 2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (sz) { 2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: 2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = (arg >> 63) & 1; 2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = (arg << 1) | (cf & 1); 2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 63) ^ cf) & 1; 2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 33) tempCOUNT -= 33; 2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = (arg >> 31) & 1; 2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = 0xFFFFFFFFULL & ((arg << 1) | (cf & 1)); 2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 31) ^ cf) & 1; 2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 17) tempCOUNT -= 17; 2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = (arg >> 15) & 1; 2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = 0xFFFFULL & ((arg << 1) | (cf & 1)); 2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 15) ^ cf) & 1; 2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT >= 9) tempCOUNT -= 9; 2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1; 2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (tempCOUNT > 0) { 2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempcf = (arg >> 7) & 1; 2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown arg = 0xFFULL & ((arg << 1) | (cf & 1)); 2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf = tempcf; 2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempCOUNT--; 2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of = ((arg >> 7) ^ cf) & 1; 2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("calculate_RCL(amd64g): invalid size"); 2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cf &= 1; 2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of &= 1; 2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags_in &= ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O); 2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rflags_in |= (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O); 2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return wantRflags ? rflags_in : arg; 2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Taken from gf2x-0.9.5, released under GPLv2+ (later versions LGPLv2+) 2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * svn://scm.gforge.inria.fr/svn/gf2x/trunk/hardware/opteron/gf2x_mul1.h@25 2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_pclmul(ULong a, ULong b, ULong which) 2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong hi, lo, tmp, A[16]; 2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[0] = 0; A[1] = a; 2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[2] = A[1] << 1; A[3] = A[2] ^ a; 2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[4] = A[2] << 1; A[5] = A[4] ^ a; 2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[6] = A[3] << 1; A[7] = A[6] ^ a; 2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[8] = A[4] << 1; A[9] = A[8] ^ a; 2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[10] = A[5] << 1; A[11] = A[10] ^ a; 2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[12] = A[6] << 1; A[13] = A[12] ^ a; 2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A[14] = A[7] << 1; A[15] = A[14] ^ a; 2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (A[b >> 60] << 4) ^ A[(b >> 56) & 15]; 2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = lo >> 56; 2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 52) & 15] << 4) ^ A[(b >> 48) & 15]; 2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 44) & 15] << 4) ^ A[(b >> 40) & 15]; 2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 36) & 15] << 4) ^ A[(b >> 32) & 15]; 2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 28) & 15] << 4) ^ A[(b >> 24) & 15]; 2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 20) & 15] << 4) ^ A[(b >> 16) & 15]; 2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 12) & 15] << 4) ^ A[(b >> 8) & 15]; 2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi = (hi << 8) | (lo >> 56); 2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo = (lo << 8) ^ (A[(b >> 4) & 15] << 4) ^ A[b & 15]; 2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong m0 = -1; 2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown m0 /= 255; 2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 63) & 1); tmp &= ((b & (m0 * 0xfe)) >> 1); hi = hi ^ tmp; 2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 62) & 1); tmp &= ((b & (m0 * 0xfc)) >> 2); hi = hi ^ tmp; 2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 61) & 1); tmp &= ((b & (m0 * 0xf8)) >> 3); hi = hi ^ tmp; 2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 60) & 1); tmp &= ((b & (m0 * 0xf0)) >> 4); hi = hi ^ tmp; 2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 59) & 1); tmp &= ((b & (m0 * 0xe0)) >> 5); hi = hi ^ tmp; 2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 58) & 1); tmp &= ((b & (m0 * 0xc0)) >> 6); hi = hi ^ tmp; 2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp = -((a >> 57) & 1); tmp &= ((b & (m0 * 0x80)) >> 7); hi = hi ^ tmp; 2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return which ? hi : lo; 2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (non-referentially-transparent) */ 2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Horrible hack. On non-amd64 platforms, return 1. */ 2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_dirtyhelper_RDTSC ( void ) 2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(__x86_64__) 2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt eax, edx; 2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("rdtsc" : "=a" (eax), "=d" (edx)); 2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (((ULong)edx) << 32) | ((ULong)eax); 2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1ULL; 2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2928436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE */ 2929436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* DIRTY HELPER (non-referentially-transparent) */ 2930436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Horrible hack. On non-amd64 platforms, return 1. */ 2931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* This uses a different calling convention from _RDTSC just above 2932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov only because of the difficulty of returning 96 bits from a C 2933436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov function -- RDTSC returns 64 bits and so is simple by comparison, 2934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov on amd64. */ 2935436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid amd64g_dirtyhelper_RDTSCP ( VexGuestAMD64State* st ) 2936436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 2937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if defined(__x86_64__) 2938436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt eax, ecx, edx; 2939436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ __volatile__("rdtscp" : "=a" (eax), "=d" (edx), "=c" (ecx)); 2940436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov st->guest_RAX = (ULong)eax; 2941436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov st->guest_RCX = (ULong)ecx; 2942436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov st->guest_RDX = (ULong)edx; 2943436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# else 2944436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Do nothing. */ 2945436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# endif 2946436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (non-referentially-transparent) */ 2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Horrible hack. On non-amd64 platforms, return 0. */ 2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_dirtyhelper_IN ( ULong portno, ULong sz/*1,2 or 4*/ ) 2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(__x86_64__) 2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong r = 0; 2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown portno &= 0xFFFF; 2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (sz) { 2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("movq $0,%%rax; inl %w1,%%eax; movq %%rax,%0" 2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (r) : "Nd" (portno)); 2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("movq $0,%%rax; inw %w1,%w0" 2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (r) : "Nd" (portno)); 2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("movq $0,%%rax; inb %w1,%b0" 2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (r) : "Nd" (portno)); 2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /* note: no 64-bit version of insn exists */ 2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (non-referentially-transparent) */ 2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Horrible hack. On non-amd64 platforms, do nothing. */ 2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_OUT ( ULong portno, ULong data, ULong sz/*1,2 or 4*/ ) 2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(__x86_64__) 2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown portno &= 0xFFFF; 2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (sz) { 2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: 2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("movq %0,%%rax; outl %%eax, %w1" 2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : : "a" (data), "Nd" (portno)); 2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: 2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("outw %w0, %w1" 2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : : "a" (data), "Nd" (portno)); 2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("outb %b0, %w1" 2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : : "a" (data), "Nd" (portno)); 2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /* note: no 64-bit version of insn exists */ 3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* do nothing */ 3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */ 3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DIRTY HELPER (non-referentially-transparent) */ 3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Horrible hack. On non-amd64 platforms, do nothing. */ 3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* op = 0: call the native SGDT instruction. 3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown op = 1: call the native SIDT instruction. 3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid amd64g_dirtyhelper_SxDT ( void *address, ULong op ) { 3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(__x86_64__) 3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0: 3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory"); 3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: 3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory"); 3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("amd64g_dirtyhelper_SxDT"); 3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* do nothing */ 3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = (UChar*)address; 3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0; 3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p[6] = p[7] = p[8] = p[9] = 0; 3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helpers for MMX/SSE/SSE2. ---*/ 3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar abdU8 ( UChar xx, UChar yy ) { 3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(xx>yy ? xx-yy : yy-xx); 3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline ULong mk32x2 ( UInt w1, UInt w0 ) { 3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (((ULong)w1) << 32) | ((ULong)w0); 3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UShort sel16x4_3 ( ULong w64 ) { 3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUShort(hi32 >> 16); 3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UShort sel16x4_2 ( ULong w64 ) { 3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUShort(hi32); 3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UShort sel16x4_1 ( ULong w64 ) { 3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUShort(lo32 >> 16); 3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UShort sel16x4_0 ( ULong w64 ) { 3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUShort(lo32); 3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_7 ( ULong w64 ) { 3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(hi32 >> 24); 3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_6 ( ULong w64 ) { 3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(hi32 >> 16); 3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_5 ( ULong w64 ) { 3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(hi32 >> 8); 3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_4 ( ULong w64 ) { 3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt hi32 = toUInt(w64 >> 32); 3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(hi32 >> 0); 3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_3 ( ULong w64 ) { 3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(lo32 >> 24); 3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_2 ( ULong w64 ) { 3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(lo32 >> 16); 3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_1 ( ULong w64 ) { 3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(lo32 >> 8); 3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar sel8x8_0 ( ULong w64 ) { 3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt lo32 = toUInt(w64); 3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toUChar(lo32 >> 0); 3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_mmx_pmaddwd ( ULong xx, ULong yy ) 3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mk32x2( 3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) 3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), 3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) 3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) 3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_calculate_mmx_psadbw ( ULong xx, ULong yy ) 3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt t = 0; 3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_7(xx), sel8x8_7(yy) ); 3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_6(xx), sel8x8_6(yy) ); 3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_5(xx), sel8x8_5(yy) ); 3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_4(xx), sel8x8_4(yy) ); 3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t &= 0xFFFF; 3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ULong)t; 3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3124663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengULong amd64g_calculate_sse_phminposuw ( ULong sLo, ULong sHi ) 3125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort t, min; 3127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt idx; 3128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_0(sLo); if (True) { min = t; idx = 0; } 3129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_1(sLo); if (t < min) { min = t; idx = 1; } 3130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_2(sLo); if (t < min) { min = t; idx = 2; } 3131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_3(sLo); if (t < min) { min = t; idx = 3; } 3132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_0(sHi); if (t < min) { min = t; idx = 4; } 3133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_1(sHi); if (t < min) { min = t; idx = 5; } 3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_2(sHi); if (t < min) { min = t; idx = 6; } 3135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t = sel16x4_3(sHi); if (t < min) { min = t; idx = 7; } 3136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ((ULong)(idx << 16)) | ((ULong)min); 3137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3140f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootULong amd64g_calc_crc32b ( ULong crcIn, ULong b ) 3141f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 3142f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt i; 3143f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong crc = (b & 0xFFULL) ^ crcIn; 3144f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (i = 0; i < 8; i++) 3145f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3146f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return crc; 3147f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 3148f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 3149f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3150f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootULong amd64g_calc_crc32w ( ULong crcIn, ULong w ) 3151f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 3152f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt i; 3153f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong crc = (w & 0xFFFFULL) ^ crcIn; 3154f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (i = 0; i < 16; i++) 3155f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3156f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return crc; 3157f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 3158f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 3159f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3160f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootULong amd64g_calc_crc32l ( ULong crcIn, ULong l ) 3161f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 3162f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root UInt i; 3163f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong crc = (l & 0xFFFFFFFFULL) ^ crcIn; 3164f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root for (i = 0; i < 32; i++) 3165f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78ULL : 0); 3166f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return crc; 3167f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 3168f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 3169f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3170f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootULong amd64g_calc_crc32q ( ULong crcIn, ULong q ) 3171f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 3172f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ULong crc = amd64g_calc_crc32l(crcIn, q); 3173f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return amd64g_calc_crc32l(crc, q >> 32); 3174f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 3175f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* .. helper for next fn .. */ 3178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline ULong sad_8x4 ( ULong xx, ULong yy ) 3179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt t = 0; 3181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t += (UInt)abdU8( sel8x8_3(xx), sel8x8_3(yy) ); 3182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t += (UInt)abdU8( sel8x8_2(xx), sel8x8_2(yy) ); 3183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t += (UInt)abdU8( sel8x8_1(xx), sel8x8_1(yy) ); 3184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng t += (UInt)abdU8( sel8x8_0(xx), sel8x8_0(yy) ); 3185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return (ULong)t; 3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3189663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengULong amd64g_calc_mpsadbw ( ULong sHi, ULong sLo, 3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong dHi, ULong dLo, 3191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong imm_and_return_control_bit ) 3192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt imm8 = imm_and_return_control_bit & 7; 3194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool calcHi = (imm_and_return_control_bit >> 7) & 1; 3195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt srcOffsL = imm8 & 3; /* src offs in 32-bit (L) chunks */ 3196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt dstOffsL = (imm8 >> 2) & 1; /* dst offs in ditto chunks */ 3197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For src we only need 32 bits, so get them into the 3198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lower half of a 64 bit word. */ 3199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong src = ((srcOffsL & 2) ? sHi : sLo) >> (32 * (srcOffsL & 1)); 3200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For dst we need to get hold of 56 bits (7 bytes) from a total of 3201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 11 bytes. If calculating the low part of the result, need bytes 3202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstOffsL * 4 + (0 .. 6); if calculating the high part, 3203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstOffsL * 4 + (4 .. 10). */ 3204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong dst; 3205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* dstOffL = 0, Lo -> 0 .. 6 3206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstOffL = 1, Lo -> 4 .. 10 3207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstOffL = 0, Hi -> 4 .. 10 3208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstOffL = 1, Hi -> 8 .. 14 3209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 3210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (calcHi && dstOffsL) { 3211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 8 .. 14 */ 3212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst = dHi & 0x00FFFFFFFFFFFFFFULL; 3213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if (!calcHi && !dstOffsL) { 3215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 0 .. 6 */ 3216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst = dLo & 0x00FFFFFFFFFFFFFFULL; 3217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else { 3219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 4 .. 10 */ 3220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst = (dLo >> 32) | ((dHi & 0x00FFFFFFULL) << 32); 3221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong r0 = sad_8x4( dst >> 0, src ); 3223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong r1 = sad_8x4( dst >> 8, src ); 3224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong r2 = sad_8x4( dst >> 16, src ); 3225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong r3 = sad_8x4( dst >> 24, src ); 3226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong res = (r3 << 48) | (r2 << 32) | (r1 << 16) | r0; 3227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return res; 3228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong amd64g_calculate_pext ( ULong src_masked, ULong mask ) 3232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 3233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong dst = 0; 3234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong src_bit; 3235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong dst_bit = 1; 3236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (src_bit = 1; src_bit; src_bit <<= 1) { 3237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mask & src_bit) { 3238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (src_masked & src_bit) dst |= dst_bit; 3239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dst_bit <<= 1; 3240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 3244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 3246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong amd64g_calculate_pdep ( ULong src, ULong mask ) 3247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 3248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong dst = 0; 3249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong dst_bit; 3250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong src_bit = 1; 3251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (dst_bit = 1; dst_bit; dst_bit <<= 1) { 3252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mask & dst_bit) { 3253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (src & src_bit) dst |= dst_bit; 3254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov src_bit <<= 1; 3255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 3259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helpers for SSE4.2 PCMP{E,I}STR{I,M} ---*/ 3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt zmask_from_V128 ( V128* arg ) 3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt i, res = 0; 3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < 16; i++) { 3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res |= ((arg->w8[i] == 0) ? 1 : 0) << i; 3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt zmask_from_V128_wide ( V128* arg ) 3274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i, res = 0; 3276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 8; i++) { 3277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res |= ((arg->w16[i] == 0) ? 1 : 0) << i; 3278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return res; 3280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Helps with PCMP{I,E}STR{I,M}. 3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALLED FROM GENERATED CODE: DIRTY HELPER(s). (But not really, 3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown actually it could be a clean helper, but for the fact that we can't 3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pass by value 2 x V128 to a clean helper, nor have one returned.) 3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Reads guest state, writes to guest state for the xSTRM cases, no 3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown accesses of memory, is a pure function. 3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown opc_and_imm contains (4th byte of opcode << 8) | the-imm8-byte so 3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the callee knows which I/E and I/M variant it is dealing with and 3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what the specific operation is. 4th byte of opcode is in the range 3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x60 to 0x63: 3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown istri 66 0F 3A 63 3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown istrm 66 0F 3A 62 3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown estri 66 0F 3A 61 3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown estrm 66 0F 3A 60 3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gstOffL and gstOffR are the guest state offsets for the two XMM 3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register inputs. We never have to deal with the memory case since 3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that is handled by pre-loading the relevant value into the fake 3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XMM16 register. 3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For ESTRx variants, edxIN and eaxIN hold the values of those two 3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown registers. 3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In all cases, the bottom 16 bits of the result contain the new 3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OSZACP %rflags values. For xSTRI variants, bits[31:16] of the 3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result hold the new %ecx value. For xSTRM variants, the helper 3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown writes the result directly to the guest XMM0. 3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Declarable side effects: in all cases, reads guest state at 3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [gstOffL, +16) and [gstOffR, +16). For xSTRM variants, also writes 3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest_XMM0. 3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Is expected to be called with opc_and_imm combinations which have 3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown actually been validated, and will assert if otherwise. The front 3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end should ensure we're only called with verified values. 3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong amd64g_dirtyhelper_PCMPxSTRx ( 3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestAMD64State* gst, 3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord opc4_and_imm, 3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord gstOffL, HWord gstOffR, 3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord edxIN, HWord eaxIN 3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord opc4 = (opc4_and_imm >> 8) & 0xFF; 3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord imm8 = opc4_and_imm & 0xFF; 3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord isISTRx = opc4 & 2; 3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord isxSTRM = (opc4 & 1) ^ 1; 3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((opc4 & 0xFC) == 0x60); /* 0x60 .. 0x63 */ 3332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord wide = (imm8 & 1); 3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // where the args are 3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Create the arg validity masks, either from the vectors 3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown themselves or from the supplied edx/eax values. */ 3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // FIXME: this is only right for the 8-bit data cases. 3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // At least that is asserted above. 3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt zmaskL, zmaskR; 3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // temp spot for the resulting flags and vector. 3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown V128 resV; 3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt resOSZACP; 3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // for checking whether case was handled 3349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool ok = False; 3350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (wide) { 3352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isISTRx) { 3353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL = zmask_from_V128_wide(argL); 3354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskR = zmask_from_V128_wide(argR); 3355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int tmp; 3357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = edxIN & 0xFFFFFFFF; 3358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < -8) tmp = -8; 3359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp > 8) tmp = 8; 3360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < 0) tmp = -tmp; 3361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0 && tmp <= 8); 3362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL = (1 << tmp) & 0xFF; 3363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = eaxIN & 0xFFFFFFFF; 3364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < -8) tmp = -8; 3365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp > 8) tmp = 8; 3366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < 0) tmp = -tmp; 3367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0 && tmp <= 8); 3368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskR = (1 << tmp) & 0xFF; 3369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // do the meyaath 3371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ok = compute_PCMPxSTRx_wide ( 3372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &resV, &resOSZACP, argL, argR, 3373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL, zmaskR, imm8, (Bool)isxSTRM 3374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 3375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isISTRx) { 3377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL = zmask_from_V128(argL); 3378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskR = zmask_from_V128(argR); 3379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int tmp; 3381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = edxIN & 0xFFFFFFFF; 3382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < -16) tmp = -16; 3383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp > 16) tmp = 16; 3384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < 0) tmp = -tmp; 3385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0 && tmp <= 16); 3386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL = (1 << tmp) & 0xFFFF; 3387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp = eaxIN & 0xFFFFFFFF; 3388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < -16) tmp = -16; 3389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp > 16) tmp = 16; 3390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tmp < 0) tmp = -tmp; 3391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0 && tmp <= 16); 3392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskR = (1 << tmp) & 0xFFFF; 3393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // do the meyaath 3395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ok = compute_PCMPxSTRx ( 3396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &resV, &resOSZACP, argL, argR, 3397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng zmaskL, zmaskR, imm8, (Bool)isxSTRM 3398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 3399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // front end shouldn't pass us any imm8 variants we can't 3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // handle. Hence: 3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(ok); 3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // So, finally we need to get the results back to the caller. 3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // In all cases, the new OSZACP value is the lowest 16 of 3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the return value. 3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isxSTRM) { 3409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gst->guest_YMM0[0] = resV.w32[0]; 3410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gst->guest_YMM0[1] = resV.w32[1]; 3411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gst->guest_YMM0[2] = resV.w32[2]; 3412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gst->guest_YMM0[3] = resV.w32[3]; 3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return resOSZACP & 0x8D5; 3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt newECX = resV.w32[0] & 0xFFFF; 3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (newECX << 16) | (resOSZACP & 0x8D5); 3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 3421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- AES primitives and helpers ---*/ 3422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 3423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* a 16 x 16 matrix */ 3424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar sbox[256] = { // row nr 3425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, // 1 3426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 3427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, // 2 3428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 3429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, // 3 3430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 3431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, // 4 3432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 3433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, // 5 3434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 3435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, // 6 3436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 3437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, // 7 3438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 3439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, // 8 3440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 3441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, // 9 3442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 3443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, //10 3444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 3445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, //11 3446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 3447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, //12 3448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 3449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, //13 3450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 3451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, //14 3452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 3453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, //15 3454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 3455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, //16 3456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 3457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 3458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void SubBytes (V128* v) 3459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i; 3462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 16; i++) 3463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r.w8[i] = sbox[v->w8[i]]; 3464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* a 16 x 16 matrix */ 3468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar invsbox[256] = { // row nr 3469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, // 1 3470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 3471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, // 2 3472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 3473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, // 3 3474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 3475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, // 4 3476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 3477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, // 5 3478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 3479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, // 6 3480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 3481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, // 7 3482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 3483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, // 8 3484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 3485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, // 9 3486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 3487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, //10 3488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 3489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, //11 3490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 3491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, //12 3492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 3493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, //13 3494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 3495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, //14 3496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 3497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, //15 3498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 3499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, //16 3500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 3501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 3502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void InvSubBytes (V128* v) 3503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i; 3506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 16; i++) 3507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r.w8[i] = invsbox[v->w8[i]]; 3508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar ShiftRows_op[16] = 3512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5, 0}; 3513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void ShiftRows (V128* v) 3514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i; 3517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 16; i++) 3518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r.w8[i] = v->w8[ShiftRows_op[15-i]]; 3519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar InvShiftRows_op[16] = 3523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0}; 3524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void InvShiftRows (V128* v) 3525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i; 3528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 16; i++) 3529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r.w8[i] = v->w8[InvShiftRows_op[15-i]]; 3530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Multiplication of the finite fields elements of AES. 3534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng See "A Specification for The AES Algorithm Rijndael 3535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (by Joan Daemen & Vincent Rijmen)" 3536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Dr. Brian Gladman, v3.1, 3rd March 2001. */ 3537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* N values so that (hex) xy = 0x03^N. 3538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x00 cannot be used. We put 0xff for this value.*/ 3539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* a 16 x 16 matrix */ 3540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar Nxy[256] = { // row nr 3541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xff, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, // 1 3542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03, 3543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, // 2 3544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 3545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, // 3 3546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78, 3547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, // 4 3548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e, 3549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, // 5 3550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 3551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, // 6 3552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10, 3553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, // 7 3554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba, 3555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, // 8 3556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 3557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, // 9 3558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8, 3559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, //10 3560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0, 3561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, //11 3562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 3563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, //12 3564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d, 3565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, //13 3566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1, 3567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, //14 3568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 3569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, //15 3570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5, 3571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, //16 3572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07 3573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 3574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* E values so that E = 0x03^xy. */ 3576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic const UChar Exy[256] = { // row nr 3577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x01, 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, // 1 3578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x1a, 0x2e, 0x72, 0x96, 0xa1, 0xf8, 0x13, 0x35, 3579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4, // 2 3580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 3581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xe5, 0x34, 0x5c, 0xe4, 0x37, 0x59, 0xeb, 0x26, // 3 3582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31, 3583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, // 4 3584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4f, 0xd1, 0x68, 0xb8, 0xd3, 0x6e, 0xb2, 0xcd, 3585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7, // 5 3586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 3587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x83, 0x9e, 0xb9, 0xd0, 0x6b, 0xbd, 0xdc, 0x7f, // 6 3588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a, 3589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, // 7 3590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x0b, 0x1d, 0x27, 0x69, 0xbb, 0xd6, 0x61, 0xa3, 3591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec, // 8 3592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 3593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfb, 0x16, 0x3a, 0x4e, 0xd2, 0x6d, 0xb7, 0xc2, // 9 3594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41, 3595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, //10 3596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x5b, 0xed, 0x2c, 0x74, 0x9c, 0xbf, 0xda, 0x75, 3597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e, //11 3598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 3599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x9b, 0xb6, 0xc1, 0x58, 0xe8, 0x23, 0x65, 0xaf, //12 3600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54, 3601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, //13 3602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x1b, 0x2d, 0x77, 0x99, 0xb0, 0xcb, 0x46, 0xca, 3603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91, //14 3604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 3605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x12, 0x36, 0x5a, 0xee, 0x29, 0x7b, 0x8d, 0x8c, //15 3606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17, 3607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, //16 3608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x1c, 0x24, 0x6c, 0xb4, 0xc7, 0x52, 0xf6, 0x01}; 3609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline UChar ff_mul(UChar u1, UChar u2) 3611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((u1 > 0) && (u2 > 0)) { 3613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt ui = Nxy[u1] + Nxy[u2]; 3614663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ui >= 255) 3615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ui = ui - 255; 3616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return Exy[ui]; 3617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 3619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng }; 3620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void MixColumns (V128* v) 3623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int j; 3626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define P(x,row,col) (x)->w8[((row)*4+(col))] 3627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (j = 0; j < 4; j++) { 3628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,0) = ff_mul(0x02, P(v,j,0)) ^ ff_mul(0x03, P(v,j,1)) 3629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ P(v,j,2) ^ P(v,j,3); 3630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,1) = P(v,j,0) ^ ff_mul( 0x02, P(v,j,1) ) 3631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x03, P(v,j,2) ) ^ P(v,j,3); 3632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,2) = P(v,j,0) ^ P(v,j,1) ^ ff_mul( 0x02, P(v,j,2) ) 3633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x03, P(v,j,3) ); 3634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,3) = ff_mul(0x03, P(v,j,0) ) ^ P(v,j,1) ^ P(v,j,2) 3635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul( 0x02, P(v,j,3) ); 3636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef P 3639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void InvMixColumns (V128* v) 3642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int j; 3645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define P(x,row,col) (x)->w8[((row)*4+(col))] 3646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (j = 0; j < 4; j++) { 3647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,0) = ff_mul(0x0e, P(v,j,0) ) ^ ff_mul(0x0b, P(v,j,1) ) 3648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x0d,P(v,j,2) ) ^ ff_mul(0x09, P(v,j,3) ); 3649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,1) = ff_mul(0x09, P(v,j,0) ) ^ ff_mul(0x0e, P(v,j,1) ) 3650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x0b,P(v,j,2) ) ^ ff_mul(0x0d, P(v,j,3) ); 3651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,2) = ff_mul(0x0d, P(v,j,0) ) ^ ff_mul(0x09, P(v,j,1) ) 3652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x0e,P(v,j,2) ) ^ ff_mul(0x0b, P(v,j,3) ); 3653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng P(&r,j,3) = ff_mul(0x0b, P(v,j,0) ) ^ ff_mul(0x0d, P(v,j,1) ) 3654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ ff_mul(0x09,P(v,j,2) ) ^ ff_mul(0x0e, P(v,j,3) ); 3655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *v = r; 3657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef P 3658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* For description, see definition in guest_amd64_defs.h */ 3662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid amd64g_dirtyhelper_AES ( 3663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VexGuestAMD64State* gst, 3664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord opc4, HWord gstOffD, 3665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord gstOffL, HWord gstOffR 3666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ) 3667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // where the args are 3669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128* argD = (V128*)( ((UChar*)gst) + gstOffD ); 3670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 3671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 3672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128 r; 3673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (opc4) { 3675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0xDC: /* AESENC */ 3676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0xDD: /* AESENCLAST */ 3677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r = *argR; 3678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ShiftRows (&r); 3679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SubBytes (&r); 3680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (opc4 == 0xDC) 3681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MixColumns (&r); 3682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argD->w64[0] = r.w64[0] ^ argL->w64[0]; 3683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argD->w64[1] = r.w64[1] ^ argL->w64[1]; 3684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0xDE: /* AESDEC */ 3687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0xDF: /* AESDECLAST */ 3688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r = *argR; 3689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng InvShiftRows (&r); 3690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng InvSubBytes (&r); 3691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (opc4 == 0xDE) 3692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng InvMixColumns (&r); 3693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argD->w64[0] = r.w64[0] ^ argL->w64[0]; 3694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argD->w64[1] = r.w64[1] ^ argL->w64[1]; 3695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0xDB: /* AESIMC */ 3698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *argD = *argL; 3699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng InvMixColumns (argD); 3700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: vassert(0); 3702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline UInt RotWord (UInt w32) 3706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ((w32 >> 8) | (w32 << 24)); 3708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline UInt SubWord (UInt w32) 3711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar *w8; 3713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar *r8; 3714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt res; 3715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng w8 = (UChar*) &w32; 3716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r8 = (UChar*) &res; 3717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r8[0] = sbox[w8[0]]; 3718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r8[1] = sbox[w8[1]]; 3719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r8[2] = sbox[w8[2]]; 3720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r8[3] = sbox[w8[3]]; 3721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return res; 3722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* For description, see definition in guest_amd64_defs.h */ 3725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern void amd64g_dirtyhelper_AESKEYGENASSIST ( 3726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VexGuestAMD64State* gst, 3727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord imm8, 3728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord gstOffL, HWord gstOffR 3729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ) 3730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // where the args are 3732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128* argL = (V128*)( ((UChar*)gst) + gstOffL ); 3733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng V128* argR = (V128*)( ((UChar*)gst) + gstOffR ); 3734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3735663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argR->w32[3] = RotWord (SubWord (argL->w32[3])) ^ imm8; 3736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argR->w32[2] = SubWord (argL->w32[3]); 3737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argR->w32[1] = RotWord (SubWord (argL->w32[1])) ^ imm8; 3738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argR->w32[0] = SubWord (argL->w32[1]); 3739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helpers for dealing with, and describing, ---*/ 3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- guest state as a whole. ---*/ 3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialise the entire amd64 guest state. */ 3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* VISIBLE TO LIBVEX CLIENT */ 3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state ) 3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->host_EvC_FAILADDR = 0; 3753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->host_EvC_COUNTER = 0; 3754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->pad0 = 0; 3755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RAX = 0; 3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RCX = 0; 3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RDX = 0; 3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RBX = 0; 3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RSP = 0; 3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RBP = 0; 3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RSI = 0; 3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RDI = 0; 3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R8 = 0; 3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R9 = 0; 3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R10 = 0; 3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R11 = 0; 3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R12 = 0; 3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R13 = 0; 3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R14 = 0; 3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_R15 = 0; 3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_OP = AMD64G_CC_OP_COPY; 3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP1 = 0; 3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_DEP2 = 0; 3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_CC_NDEP = 0; 3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_DFLAG = 1; /* forwards */ 3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_IDFLAG = 0; 3780436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_ACFLAG = 0; 3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* HACK: represent the offset associated with %fs==0. This 3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumes that %fs is only ever zero. */ 3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_FS_ZERO = 0; 3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_RIP = 0; 3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Initialise the simulated FPU */ 3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown amd64g_dirtyhelper_FINIT( vex_state ); 3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Initialise the AVX state. */ 3792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define AVXZERO(_ymm) \ 3793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { _ymm[0]=_ymm[1]=_ymm[2]=_ymm[3] = 0; \ 3794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _ymm[4]=_ymm[5]=_ymm[6]=_ymm[7] = 0; \ 3795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 3796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_SSEROUND = (ULong)Irrm_NEAREST; 3797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM0); 3798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM1); 3799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM2); 3800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM3); 3801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM4); 3802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM5); 3803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM6); 3804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM7); 3805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM8); 3806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM9); 3807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM10); 3808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM11); 3809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM12); 3810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM13); 3811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM14); 3812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM15); 3813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng AVXZERO(vex_state->guest_YMM16); 3814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# undef AVXZERO 3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_EMNOTE = EmNote_NONE; 3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* These should not ever be either read or written, but we 3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown initialise them anyway. */ 3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_TISTART = 0; 3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_TILEN = 0; 3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_NRADDR = 0; 3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_SC_CLASS = 0; 3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_GS_0x60 = 0; 3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_state->guest_IP_AT_SYSCALL = 0; 3829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_state->pad1 = 0; 3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Figure out if any part of the guest state contained in minoff 3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .. maxoff requires precise memory exceptions. If in doubt return 3835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov True (but this generates significantly slower code). 3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown By default we enforce precise exns for guest %RSP, %RBP and %RIP 3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown only. These are the minimum needed to extract correct stack 3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown backtraces from amd64 code. 3840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Only %RSP is needed in mode VexRegUpdSpAtMemAccess. 3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool guest_amd64_state_requires_precise_mem_exns ( Int minoff, 3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int maxoff) 3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rbp_min = offsetof(VexGuestAMD64State, guest_RBP); 3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rbp_max = rbp_min + 8 - 1; 3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rsp_min = offsetof(VexGuestAMD64State, guest_RSP); 3849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rsp_max = rsp_min + 8 - 1; 3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rip_min = offsetof(VexGuestAMD64State, guest_RIP); 3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int rip_max = rip_min + 8 - 1; 3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3853436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < rsp_min || minoff > rsp_max) { 3854436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with rsp */ 3855436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess) 3856436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return False; // We only need to check stack pointer. 3857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < rbp_min || minoff > rbp_max) { 3862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with rbp */ 3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (maxoff < rip_min || minoff > rip_max) { 3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no overlap with eip */ 3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ALWAYSDEFD(field) \ 3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { offsetof(VexGuestAMD64State, field), \ 3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (sizeof ((VexGuestAMD64State*)0)->field) } 3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVexGuestLayout 3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown amd64guest_layout 3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = { 3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Total size of the guest state, in bytes. */ 3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .total_sizeB = sizeof(VexGuestAMD64State), 3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Describe the stack pointer. */ 3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .offset_SP = offsetof(VexGuestAMD64State,guest_RSP), 3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .sizeof_SP = 8, 3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Describe the frame pointer. */ 3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .offset_FP = offsetof(VexGuestAMD64State,guest_RBP), 3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .sizeof_FP = 8, 3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Describe the instruction pointer. */ 3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .offset_IP = offsetof(VexGuestAMD64State,guest_RIP), 3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .sizeof_IP = 8, 3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Describe any sections to be regarded by Memcheck as 3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'always-defined'. */ 3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .n_alwaysDefd = 16, 3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* flags thunk: OP and NDEP are always defd, whereas DEP1 3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and DEP2 have to be tracked. See detailed comment in 3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gdefs.h on meaning of thunk fields. */ 3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .alwaysDefd 3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = { /* 0 */ ALWAYSDEFD(guest_CC_OP), 3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 1 */ ALWAYSDEFD(guest_CC_NDEP), 3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 2 */ ALWAYSDEFD(guest_DFLAG), 3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 3 */ ALWAYSDEFD(guest_IDFLAG), 3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 4 */ ALWAYSDEFD(guest_RIP), 3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 5 */ ALWAYSDEFD(guest_FS_ZERO), 3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 6 */ ALWAYSDEFD(guest_FTOP), 3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 7 */ ALWAYSDEFD(guest_FPTAG), 3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 8 */ ALWAYSDEFD(guest_FPROUND), 3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 9 */ ALWAYSDEFD(guest_FC3210), 3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_CS), 3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_DS), 3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_ES), 3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_FS), 3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_GS), 3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_SS), 3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_LDT), 3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // /* */ ALWAYSDEFD(guest_GDT), 3925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 10 */ ALWAYSDEFD(guest_EMNOTE), 3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 11 */ ALWAYSDEFD(guest_SSEROUND), 3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 12 */ ALWAYSDEFD(guest_TISTART), 3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 13 */ ALWAYSDEFD(guest_TILEN), 3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 14 */ ALWAYSDEFD(guest_SC_CLASS), 3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 15 */ ALWAYSDEFD(guest_IP_AT_SYSCALL) 3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown }; 3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end guest_amd64_helpers.c ---*/ 3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3938