1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- begin guest_arm64_helpers.c ---*/ 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This file is part of Valgrind, a dynamic binary instrumentation 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov framework. 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2013-2013 OpenWorks 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov info@open-works.net 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This program is free software; you can redistribute it and/or 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov modify it under the terms of the GNU General Public License as 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov published by the Free Software Foundation; either version 2 of the 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov License, or (at your option) any later version. 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This program is distributed in the hope that it will be useful, but 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov WITHOUT ANY WARRANTY; without even the implied warranty of 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov General Public License for more details. 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov You should have received a copy of the GNU General Public License 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov along with this program; if not, write to the Free Software 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 02110-1301, USA. 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov The GNU General Public License is contained in the file COPYING. 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_basictypes.h" 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_emnote.h" 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_guest_arm64.h" 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex_ir.h" 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex.h" 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "main_util.h" 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "main_globals.h" 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "guest_generic_bb_to_IR.h" 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "guest_arm64_defs.h" 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* This file contains helper functions for arm guest code. Calls to 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov these functions are generated by the back end. These calls are of 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov course in the host machine code and this file will be compiled to 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov host machine code, so that all makes sense. 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Only change the signatures of these helper functions very 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov carefully. If you change the signature here, you'll have to change 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov the parameters passed to it in the IR calls constructed by 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov guest_arm64_toIR.c. 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Set to 1 to get detailed profiling info about individual N, Z, C 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov and V flag evaluation. */ 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define PROFILE_NZCV_FLAGS 0 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if PROFILE_NZCV_FLAGS 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt tab_eval[ARM64G_CC_OP_NUMBER][16]; 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt initted = 0; 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt tot_evals = 0; 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void initCounts ( void ) 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt i, j; 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; i < ARM64G_CC_OP_NUMBER; i++) { 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (j = 0; j < 16; j++) { 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tab_eval[i][j] = 0; 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov initted = 1; 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void showCounts ( void ) 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* nameCC[16] 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = { "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV" }; 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt i, j; 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong sum = 0; 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("\nCC_OP 0 1 2 3 " 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov " 4 5 6\n"); 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf( "--------------------------------------------------" 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "--------------------------\n"); 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (j = 0; j < 16; j++) { 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("%2d %s ", j, nameCC[j]); 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; i < ARM64G_CC_OP_NUMBER; i++) { 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("%9d ", tab_eval[i][j]); 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sum += tab_eval[i][j]; 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("\n"); 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("(In total %llu calls)\n", sum); 96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define NOTE_EVAL(_cc_op, _cond) \ 99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do { \ 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!initted) initCounts(); \ 101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert( ((UInt)(_cc_op)) < ARM64G_CC_OP_NUMBER); \ 102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert( ((UInt)(_cond)) < 16); \ 103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tab_eval[(UInt)(_cc_op)][(UInt)(cond)]++; \ 104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tot_evals++; \ 105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0 == (tot_evals & 0x7FFF)) \ 106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov showCounts(); \ 107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } while (0) 108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif /* PROFILE_NZCV_FLAGS */ 110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate the N flag from the supplied thunk components, in the 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov least significant bit of the word. Returned bits 63:1 are zero. */ 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_flag_n ( ULong cc_op, ULong cc_dep1, 116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cc_op) { 119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_COPY: { 120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (nzcv:28x0, unused, unused) */ 121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = (cc_dep1 >> ARM64G_CC_SHIFT_N) & 1; 122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD32: { 125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL + argR; 129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = (ULong)(res >> 31); 130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD64: { 133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL + argR; 137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = (ULong)(res >> 63); 138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB32: { 141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL - argR; 145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = (ULong)(res >> 31); 146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB64: { 149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL - argR; 153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = res >> 63; 154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 156b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC32: { 157b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 158b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 159b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 160b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 161b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 162b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL + argR + oldC; 163b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong nf = res >> 31; 164b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return nf; 165b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 166b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC64: { 167b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 168b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 169b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 170b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 171b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 172b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL + argR + oldC; 173b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong nf = res >> 63; 174b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return nf; 175b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 176b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC32: { 177b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 178b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 179b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 180b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 181b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 182b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL - argR - (oldC ^ 1); 183b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong nf = res >> 31; 184b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return nf; 185b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 186b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC64: { 187b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 188b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 189b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 190b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 191b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 192b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL - argR - (oldC ^ 1); 193b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong nf = res >> 63; 194b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return nf; 195b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC32: { 197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = (UInt)cc_dep1; 199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = res >> 31; 200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC64: { 203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = cc_dep1; 205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf = res >> 63; 206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nf; 207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MUL: { 209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (res, unused, oldC:oldV) */ 210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt res = cc_dep1; 211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt nf = res >> 31; 212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return nf; 213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MULL: { 215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (resLo32, resHi32, oldC:oldV) */ 216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt resHi32 = cc_dep2; 217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt nf = resHi32 >> 31; 218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return nf; 219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* shouldn't really make these calls from generated code */ 222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("arm64g_calculate_flag_n" 223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "( op=%llu, dep1=0x%llx, dep2=0x%llx, dep3=0x%llx )\n", 224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_op, cc_dep1, cc_dep2, cc_dep3 ); 225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("arm64g_calculate_flag_n"); 226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate the Z flag from the supplied thunk components, in the 231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov least significant bit of the word. Returned bits 63:1 are zero. */ 232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic 233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_flag_z ( ULong cc_op, ULong cc_dep1, 234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cc_op) { 237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_COPY: { 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (nzcv:28x0, unused, unused) */ 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = (cc_dep1 >> ARM64G_CC_SHIFT_Z) & 1; 240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD32: { 243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL + argR; 247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD64: { 251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL + argR; 255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB32: { 259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL - argR; 263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB64: { 267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL - argR; 271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 274b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC32: { 275b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 276b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 277b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 278b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 279b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 280b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL + argR + oldC; 281b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong zf = res == 0; 282b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return zf; 283b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 284b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC64: { 285b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 286b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 287b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 288b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 289b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 290b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL + argR + oldC; 291b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong zf = res == 0; 292b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return zf; 293b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 294b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC32: { 295b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 296b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 297b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 298b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 299b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 300b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL - argR - (oldC ^ 1); 301b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong zf = res == 0; 302b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return zf; 303b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 304b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC64: { 305b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 306b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 307b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 308b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 309b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 310b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL - argR - (oldC ^ 1); 311b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong zf = res == 0; 312b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return zf; 313b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC32: { 315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = (UInt)cc_dep1; 317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC64: { 321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = cc_dep1; 323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong zf = res == 0; 324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return zf; 325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MUL: { 327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (res, unused, oldC:oldV) */ 328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt res = cc_dep1; 329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt zf = res == 0; 330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return zf; 331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MULL: { 333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (resLo32, resHi32, oldC:oldV) */ 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt resLo32 = cc_dep1; 335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt resHi32 = cc_dep2; 336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt zf = (resHi32|resLo32) == 0; 337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return zf; 338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* shouldn't really make these calls from generated code */ 341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("arm64g_calculate_flag_z" 342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "( op=%llu, dep1=0x%llx, dep2=0x%llx, dep3=0x%llx )\n", 343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_op, cc_dep1, cc_dep2, cc_dep3 ); 344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("arm64g_calculate_flag_z"); 345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate the C flag from the supplied thunk components, in the 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov least significant bit of the word. Returned bits 63:1 are zero. */ 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_flag_c ( ULong cc_op, ULong cc_dep1, 353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cc_op) { 356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_COPY: { 357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (nzcv:28x0, unused, unused) */ 358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cf = (cc_dep1 >> ARM64G_CC_SHIFT_C) & 1; 359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf; 360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD32: { 362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL + argR; 366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cf = res < argL; 367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf; 368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD64: { 370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL + argR; 374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cf = res < argL; 375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf; 376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB32: { 378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cf = argL >= argR; 382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf; 383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB64: { 385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cf = argL >= argR; 389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cf; 390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 391b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC32: { 392b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 393b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 394b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 395b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 396b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 397b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL + argR + oldC; 398b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong cf = oldC ? (res <= argL) : (res < argL); 399b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return cf; 400b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 401b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC64: { 402b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 403b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 404b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 405b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 406b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 407b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL + argR + oldC; 408b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong cf = oldC ? (res <= argL) : (res < argL); 409b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return cf; 410b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 411b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC32: { 412b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 413b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 414b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 415b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 416b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 417b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong cf = oldC ? (argL >= argR) : (argL > argR); 418b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return cf; 419b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 420b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC64: { 421b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 422b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 423b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 424b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 425b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 426b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong cf = oldC ? (argL >= argR) : (argL > argR); 427b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return cf; 428b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC32: 430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC64: { 431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; // C after logic is zero on arm64 433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MUL: { 435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (res, unused, oldC:oldV) */ 436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt oldC = (cc_dep3 >> 1) & 1; 437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert((cc_dep3 & ~3) == 0); 438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt cf = oldC; 439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return cf; 440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MULL: { 442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (resLo32, resHi32, oldC:oldV) */ 443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt oldC = (cc_dep3 >> 1) & 1; 444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert((cc_dep3 & ~3) == 0); 445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt cf = oldC; 446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return cf; 447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* shouldn't really make these calls from generated code */ 450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("arm64g_calculate_flag_c" 451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "( op=%llu, dep1=0x%llx, dep2=0x%llx, dep3=0x%llx )\n", 452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_op, cc_dep1, cc_dep2, cc_dep3 ); 453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("arm64g_calculate_flag_c"); 454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate the V flag from the supplied thunk components, in the 460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov least significant bit of the word. Returned bits 63:1 are zero. */ 461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic 462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_flag_v ( ULong cc_op, ULong cc_dep1, 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cc_op) { 466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_COPY: { 467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (nzcv:28x0, unused, unused) */ 468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong vf = (cc_dep1 >> ARM64G_CC_SHIFT_V) & 1; 469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return vf; 470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD32: { 472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL + argR; 476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong vf = (ULong)(((res ^ argL) & (res ^ argR)) >> 31); 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return vf; 478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_ADD64: { 480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL + argR; 484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong vf = ((res ^ argL) & (res ^ argR)) >> 63; 485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return vf; 486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB32: { 488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argL = (UInt)cc_dep1; 490436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argR = (UInt)cc_dep2; 491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt res = argL - argR; 492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong vf = (ULong)(((argL ^ argR) & (argL ^ res)) >> 31); 493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return vf; 494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_SUB64: { 496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (argL, argR, unused) */ 497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argL = cc_dep1; 498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong argR = cc_dep2; 499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = argL - argR; 500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong vf = (((argL ^ argR) & (argL ^ res))) >> 63; 501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return vf; 502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 503b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC32: { 504b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 505b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 506b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 507b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 508b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 509b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL + argR + oldC; 510b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong vf = ((res ^ argL) & (res ^ argR)) >> 31; 511b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return vf; 512b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 513b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_ADC64: { 514b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 515b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 516b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 517b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 518b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 519b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL + argR + oldC; 520b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong vf = ((res ^ argL) & (res ^ argR)) >> 63; 521b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return vf; 522b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 523b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC32: { 524b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 525b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argL = cc_dep1; 526b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt argR = cc_dep2; 527b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt oldC = cc_dep3; 528b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 529b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov UInt res = argL - argR - (oldC ^ 1); 530b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong vf = ((argL ^ argR) & (argL ^ res)) >> 31; 531b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return vf; 532b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 533b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov case ARM64G_CC_OP_SBC64: { 534b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* (argL, argR, oldC) */ 535b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argL = cc_dep1; 536b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong argR = cc_dep2; 537b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong oldC = cc_dep3; 538b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov vassert((oldC & ~1) == 0); 539b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong res = argL - argR - (oldC ^ 1); 540b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ULong vf = ((argL ^ argR) & (argL ^ res)) >> 63; 541b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return vf; 542b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC32: 544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64G_CC_OP_LOGIC64: { 545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* (res, unused, unused) */ 546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; // V after logic is zero on arm64 547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MUL: { 549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (res, unused, oldC:oldV) */ 550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt oldV = (cc_dep3 >> 0) & 1; 551436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert((cc_dep3 & ~3) == 0); 552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt vf = oldV; 553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return vf; 554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ case ARMG_CC_OP_MULL: { 556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* (resLo32, resHi32, oldC:oldV) */ 557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt oldV = (cc_dep3 >> 0) & 1; 558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert((cc_dep3 & ~3) == 0); 559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt vf = oldV; 560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return vf; 561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* shouldn't really make these calls from generated code */ 564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("arm64g_calculate_flag_v" 565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "( op=%llu, dep1=0x%llx, dep2=0x%llx, dep3=0x%llx )\n", 566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_op, cc_dep1, cc_dep2, cc_dep3 ); 567436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("arm64g_calculate_flag_v"); 568436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 569436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 571436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate NZCV from the supplied thunk components, in the positions 574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov they appear in the CPSR, viz bits 31:28 for N Z C V respectively. 575436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Returned bits 27:0 are zero. */ 576436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_flags_nzcv ( ULong cc_op, ULong cc_dep1, 577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong f; 580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong res = 0; 581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov f = 1 & arm64g_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3); 582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res |= (f << ARM64G_CC_SHIFT_N); 583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov f = 1 & arm64g_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3); 584436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res |= (f << ARM64G_CC_SHIFT_Z); 585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov f = 1 & arm64g_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3); 586436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res |= (f << ARM64G_CC_SHIFT_C); 587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov f = 1 & arm64g_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3); 588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res |= (f << ARM64G_CC_SHIFT_V); 589436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return res; 590436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 591436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 592436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* CALLED FROM GENERATED CODE: CLEAN HELPER */ 594436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Calculate the QC flag from the arguments, in the lowest bit 595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ of the word (bit 0). Urr, having this out of line is bizarre. 596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Push back inline. */ 597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2, 598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ UInt resR1, UInt resR2 ) 599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ { 600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (resL1 != resR1 || resL2 != resR2) 601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return 1; 602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ else 603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return 0; 604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 606436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* CALLED FROM GENERATED CODE: CLEAN HELPER */ 607436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Calculate the specified condition from the thunk components, in the 608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lowest bit of the word (bit 0). Returned bits 63:1 are zero. */ 609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong arm64g_calculate_condition ( /* ARM64Condcode << 4 | cc_op */ 610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cond_n_op , 611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep1, 612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_dep2, ULong cc_dep3 ) 613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cond = cond_n_op >> 4; 615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cc_op = cond_n_op & 0xF; 616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong inv = cond & 1; 617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nf, zf, vf, cf; 618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if PROFILE_NZCV_FLAGS 620436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NOTE_EVAL(cc_op, cond); 621436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# endif 622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // vex_printf("XXXXXXXX %llx %llx %llx %llx\n", 624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // cond_n_op, cc_dep1, cc_dep2, cc_dep3); 625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cond) { 627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondEQ: // Z=1 => z 628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondNE: // Z=0 629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = arm64g_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3); 630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ zf; 631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondCS: // C=1 => c 633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondCC: // C=0 634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = arm64g_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3); 635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ cf; 636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondMI: // N=1 => n 638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondPL: // N=0 639436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nf = arm64g_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3); 640436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ nf; 641436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondVS: // V=1 => v 643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondVC: // V=0 644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vf = arm64g_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3); 645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ vf; 646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondHI: // C=1 && Z=0 => c & ~z 648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondLS: // C=0 || Z=1 649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cf = arm64g_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3); 650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = arm64g_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3); 651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ (1 & (cf & ~zf)); 652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondGE: // N=V => ~(n^v) 654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondLT: // N!=V 655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nf = arm64g_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3); 656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vf = arm64g_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3); 657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ (1 & ~(nf ^ vf)); 658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondGT: // Z=0 && N=V => ~z & ~(n^v) => ~(z | (n^v)) 660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondLE: // Z=1 || N!=V 661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nf = arm64g_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3); 662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vf = arm64g_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3); 663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zf = arm64g_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3); 664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return inv ^ (1 & ~(zf | (nf ^ vf))); 665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondAL: // 1 667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case ARM64CondNV: // 1 668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 1; 669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* shouldn't really make these calls from generated code */ 672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("arm64g_calculate_condition(ARM64)" 673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "( %llu, %llu, 0x%llx, 0x%llx, 0x%llx )\n", 674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cond, cc_op, cc_dep1, cc_dep2, cc_dep3 ); 675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("armg_calculate_condition(ARM64)"); 676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- Flag-helpers translation-time function specialisers. ---*/ 682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- These help iropt specialise calls the above run-time ---*/ 683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- flags functions. ---*/ 684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Used by the optimiser to try specialisations. Returns an 687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov equivalent expression, or NULL if none. */ 688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool isU64 ( IRExpr* e, ULong n ) 690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov toBool( e->tag == Iex_Const 693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Const.con->tag == Ico_U64 694436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Const.con->Ico.U64 == n ); 695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovIRExpr* guest_arm64_spechelper ( const HChar* function_name, 698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr** args, 699436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRStmt** precedingStmts, 700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int n_precedingStmts ) 701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define unop(_op,_a1) IRExpr_Unop((_op),(_a1)) 703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2)) 704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) 705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) 706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 707436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int i, arity = 0; 708436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; args[i]; i++) 709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov arity++; 710436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ # if 0 711436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_printf("spec request:\n"); 712436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_printf(" %s ", function_name); 713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ for (i = 0; i < arity; i++) { 714436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_printf(" "); 715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ppIRExpr(args[i]); 716436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_printf("\n"); 718436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ # endif 719436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 720436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- specialising "arm64g_calculate_condition" --------- */ 721436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 722436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (vex_streq(function_name, "arm64g_calculate_condition")) { 723436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* specialise calls to the "arm64g_calculate_condition" function. 725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Not sure whether this is strictly necessary, but: the 726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov replacement IR must produce only the values 0 or 1. Bits 727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 63:1 are required to be zero. */ 728b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov IRExpr *cond_n_op, *cc_dep1, *cc_dep2, *cc_ndep; 729436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(arity == 4); 730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cond_n_op = args[0]; /* (ARM64Condcode << 4) | ARM64G_CC_OP_* */ 731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_dep1 = args[1]; 732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc_dep2 = args[2]; 733b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov cc_ndep = args[3]; 734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*---------------- SUB64 ----------------*/ 736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 0, 1 */ 738436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondEQ << 4) | ARM64G_CC_OP_SUB64)) { 739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* EQ after SUB --> test argL == argR */ 740436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 741436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 743436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondNE << 4) | ARM64G_CC_OP_SUB64)) { 744436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* NE after SUB --> test argL != argR */ 745436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 746436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 747436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 748436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 2, 3 */ 750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCS << 4) | ARM64G_CC_OP_SUB64)) { 751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CS after SUB --> test argL >=u argR 752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <=u argL */ 753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCC << 4) | ARM64G_CC_OP_SUB64)) { 757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CC after SUB --> test argL <u argR */ 758436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 8, 9 */ 763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLS << 4) | ARM64G_CC_OP_SUB64)) { 764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LS after SUB --> test argL <=u argR */ 765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 768436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondHI << 4) | ARM64G_CC_OP_SUB64)) { 769436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* HI after SUB --> test argL >u argR 770436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <u argL */ 771436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 772436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT64U, cc_dep2, cc_dep1)); 773436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 774436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 775436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 10, 11 */ 776436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLT << 4) | ARM64G_CC_OP_SUB64)) { 777436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LT after SUB --> test argL <s argR */ 778436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 779436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT64S, cc_dep1, cc_dep2)); 780436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 781436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondGE << 4) | ARM64G_CC_OP_SUB64)) { 782436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* GE after SUB --> test argL >=s argR 783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <=s argL */ 784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE64S, cc_dep2, cc_dep1)); 786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 788436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 12, 13 */ 789436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondGT << 4) | ARM64G_CC_OP_SUB64)) { 790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* GT after SUB --> test argL >s argR 791436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <s argL */ 792436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 793436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT64S, cc_dep2, cc_dep1)); 794436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 795436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLE << 4) | ARM64G_CC_OP_SUB64)) { 796436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LE after SUB --> test argL <=s argR */ 797436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 798436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE64S, cc_dep1, cc_dep2)); 799436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 800436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 801436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*---------------- SUB32 ----------------*/ 802436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 803436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 0, 1 */ 804436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondEQ << 4) | ARM64G_CC_OP_SUB32)) { 805436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* EQ after SUB --> test argL == argR */ 806436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 807436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1), 808436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 809436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 810436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondNE << 4) | ARM64G_CC_OP_SUB32)) { 811436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* NE after SUB --> test argL != argR */ 812436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 813436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpNE32, unop(Iop_64to32, cc_dep1), 814436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 815436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 816436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 2, 3 */ 818436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCS << 4) | ARM64G_CC_OP_SUB32)) { 819436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CS after SUB --> test argL >=u argR 820436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <=u argL */ 821436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 822436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE32U, unop(Iop_64to32, cc_dep2), 823436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep1))); 824436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 825436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCC << 4) | ARM64G_CC_OP_SUB32)) { 826436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CC after SUB --> test argL <u argR */ 827436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 828436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT32U, unop(Iop_64to32, cc_dep1), 829436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 830436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 831436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 832436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 8, 9 */ 833436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLS << 4) | ARM64G_CC_OP_SUB32)) { 834436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LS after SUB --> test argL <=u argR */ 835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 836436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE32U, unop(Iop_64to32, cc_dep1), 837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 839436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondHI << 4) | ARM64G_CC_OP_SUB32)) { 840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* HI after SUB --> test argL >u argR 841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <u argL */ 842436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 843436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT32U, unop(Iop_64to32, cc_dep2), 844436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep1))); 845436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 10, 11 */ 848436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLT << 4) | ARM64G_CC_OP_SUB32)) { 849436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LT after SUB --> test argL <s argR */ 850436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 851436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT32S, unop(Iop_64to32, cc_dep1), 852436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 853436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 854436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondGE << 4) | ARM64G_CC_OP_SUB32)) { 855436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* GE after SUB --> test argL >=s argR 856436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <=s argL */ 857436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 858436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE32S, unop(Iop_64to32, cc_dep2), 859436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep1))); 860436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 12, 13 */ 863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondGT << 4) | ARM64G_CC_OP_SUB32)) { 864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* GT after SUB --> test argL >s argR 865436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov --> test argR <s argL */ 866436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLT32S, unop(Iop_64to32, cc_dep2), 868436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep1))); 869436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 870436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondLE << 4) | ARM64G_CC_OP_SUB32)) { 871436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* LE after SUB --> test argL <=s argR */ 872436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return unop(Iop_1Uto64, 873436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_CmpLE32S, unop(Iop_64to32, cc_dep1), 874436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unop(Iop_64to32, cc_dep2))); 875436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 876436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 877b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /*---------------- SBC64 ----------------*/ 878b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov 879b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCS << 4) | ARM64G_CC_OP_SBC64)) { 880b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* This seems to happen a lot in softfloat code, eg __divdf3+140 */ 881b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */ 882b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* HS after SBC (same as C after SBC below) 883b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov --> oldC ? (argL >=u argR) : (argL >u argR) 884b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov --> oldC ? (argR <=u argL) : (argR <u argL) 885b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov */ 886b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return 887b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov IRExpr_ITE( 888b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov binop(Iop_CmpNE64, cc_ndep, mkU64(0)), 889b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* case oldC != 0 */ 890b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_1Uto64, binop(Iop_CmpLE32U, cc_dep2, cc_dep1)), 891b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* case oldC == 0 */ 892b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_1Uto64, binop(Iop_CmpLT32U, cc_dep2, cc_dep1)) 893b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ); 894b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 895b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov 896b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /*---------------- SBC32 ----------------*/ 897b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov 898b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov if (isU64(cond_n_op, (ARM64CondCS << 4) | ARM64G_CC_OP_SBC32)) { 899b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* This seems to happen a lot in softfloat code, eg __divdf3+140 */ 900b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */ 901b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* HS after SBC (same as C after SBC below) 902b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov --> oldC ? (argL >=u argR) : (argL >u argR) 903b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov --> oldC ? (argR <=u argL) : (argR <u argL) 904b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov */ 905b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov return 906b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov IRExpr_ITE( 907b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov binop(Iop_CmpNE64, cc_ndep, mkU64(0)), 908b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* case oldC != 0 */ 909b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_1Uto64, binop(Iop_CmpLE32U, unop(Iop_64to32, cc_dep2), 910b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_64to32, cc_dep1))), 911b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov /* case oldC == 0 */ 912b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_1Uto64, binop(Iop_CmpLT32U, unop(Iop_64to32, cc_dep2), 913b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov unop(Iop_64to32, cc_dep1))) 914b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov ); 915b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov } 916b3f721d071c0089debafb21f2297cebc40ea6014Dmitriy Ivanov 917436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /*---------------- LOGIC ----------------*/ 918436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 919436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cond_n_op, (ARMCondEQ << 4) | ARMG_CC_OP_LOGIC)) { 920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* EQ after LOGIC --> test res == 0 */ 921436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return unop(Iop_1Uto32, 922436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); 923436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 924436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cond_n_op, (ARMCondNE << 4) | ARMG_CC_OP_LOGIC)) { 925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* NE after LOGIC --> test res != 0 */ 926436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return unop(Iop_1Uto32, 927436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpNE32, cc_dep1, mkU32(0))); 928436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 929436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 930436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cond_n_op, (ARMCondPL << 4) | ARMG_CC_OP_LOGIC)) { 931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* PL after LOGIC --> test (res >> 31) == 0 */ 932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return unop(Iop_1Uto32, 933436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpEQ32, 934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Shr32, cc_dep1, mkU8(31)), 935436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ mkU32(0))); 936436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cond_n_op, (ARMCondMI << 4) | ARMG_CC_OP_LOGIC)) { 938436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* MI after LOGIC --> test (res >> 31) == 1 */ 939436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return unop(Iop_1Uto32, 940436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpEQ32, 941436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Shr32, cc_dep1, mkU8(31)), 942436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ mkU32(1))); 943436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 944436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 945436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*---------------- COPY ----------------*/ 946436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 947436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondEQ << 4) | ARM64G_CC_OP_COPY)) { 948436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* EQ after COPY --> (cc_dep1 >> ARM64G_CC_SHIFT_Z) & 1 */ 949436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return binop(Iop_And64, 950436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_Shr64, cc_dep1, 951436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkU8(ARM64G_CC_SHIFT_Z)), 952436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkU64(1)); 953436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 954436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (isU64(cond_n_op, (ARM64CondNE << 4) | ARM64G_CC_OP_COPY)) { 955436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* NE after COPY --> ((cc_dep1 >> ARM64G_CC_SHIFT_Z) ^ 1) & 1 */ 956436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return binop(Iop_And64, 957436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_Xor64, 958436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov binop(Iop_Shr64, cc_dep1, 959436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkU8(ARM64G_CC_SHIFT_Z)), 960436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkU64(1)), 961436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mkU64(1)); 962436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 963436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 964436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /*----------------- AL -----------------*/ 965436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 966436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* A critically important case for Thumb code. 967436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 968436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ What we're trying to spot is the case where cond_n_op is an 969436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ expression of the form Or32(..., 0xE0) since that means the 970436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ caller is asking for CondAL and we can simply return 1 971436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ without caring what the ... part is. This is a potentially 972436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ dodgy kludge in that it assumes that the ... part has zeroes 973436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ in bits 7:4, so that the result of the Or32 is guaranteed to 974436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ be 0xE in bits 7:4. Given that the places where this first 975436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ arg are constructed (in guest_arm_toIR.c) are very 976436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ constrained, we can get away with this. To make this 977436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ guaranteed safe would require to have a new primop, Slice44 978436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ or some such, thusly 979436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 980436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Slice44(arg1, arg2) = 0--(24)--0 arg1[7:4] arg2[3:0] 981436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 982436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ and we would then look for Slice44(0xE0, ...) 983436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ which would give the required safety property. 984436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 985436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ It would be infeasibly expensive to scan backwards through 986436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ the entire block looking for an assignment to the temp, so 987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ just look at the previous 16 statements. That should find it 988436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if it is an interesting case, as a result of how the 989436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ boilerplate guff at the start of each Thumb insn translation 990436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ is made. 991436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ */ 992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (cond_n_op->tag == Iex_RdTmp) { 993436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Int j; 994436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRTemp look_for = cond_n_op->Iex.RdTmp.tmp; 995436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Int limit = n_precedingStmts - 16; 996436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (limit < 0) limit = 0; 997436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (0) vex_printf("scanning %d .. %d\n", n_precedingStmts-1, limit); 998436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ for (j = n_precedingStmts - 1; j >= limit; j--) { 999436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRStmt* st = precedingStmts[j]; 1000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (st->tag == Ist_WrTmp 1001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ && st->Ist.WrTmp.tmp == look_for 1002436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ && st->Ist.WrTmp.data->tag == Iex_Binop 1003436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ && st->Ist.WrTmp.data->Iex.Binop.op == Iop_Or32 1004436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ && isU32(st->Ist.WrTmp.data->Iex.Binop.arg2, (ARMCondAL << 4))) 1005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return mkU32(1); 1006436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1007436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Didn't find any useful binding to the first arg 1008436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ in the previous 16 stmts. */ 1009436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1010436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1011436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1012436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* --------- specialising "armg_calculate_flag_c" --------- */ 1013436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1014436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ else 1015436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_streq(function_name, "armg_calculate_flag_c")) { 1016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1017436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* specialise calls to the "armg_calculate_flag_c" function. 1018436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Note that the returned value must be either 0 or 1; nonzero 1019436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ bits 31:1 are not allowed. In turn, incoming oldV and oldC 1020436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ values (from the thunk) are assumed to have bits 31:1 1021436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ clear. */ 1022436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1023436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert(arity == 4); 1024436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_op = args[0]; /* ARMG_CC_OP_* */ 1025436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_dep1 = args[1]; 1026436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_dep2 = args[2]; 1027436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_ndep = args[3]; 1028436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1029436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_LOGIC)) { 1030436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Thunk args are (result, shco, oldV) */ 1031436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* C after LOGIC --> shco */ 1032436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return cc_dep2; 1033436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1034436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1035436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_SUB)) { 1036436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Thunk args are (argL, argR, unused) */ 1037436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* C after SUB --> argL >=u argR 1038436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> argR <=u argL */ 1039436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return unop(Iop_1Uto32, 1040436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpLE32U, cc_dep2, cc_dep1)); 1041436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1042436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1043436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_SBB)) { 1044436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* This happens occasionally in softfloat code, eg __divdf3+140 */ 1045436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */ 1046436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* C after SBB (same as HS after SBB above) 1047436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> oldC ? (argL >=u argR) : (argL >u argR) 1048436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> oldC ? (argR <=u argL) : (argR <u argL) 1049436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ */ 1050436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return 1051436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRExpr_ITE( 1052436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_CmpNE32, cc_ndep, mkU32(0)), 1053436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* case oldC != 0 */ 1054436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ unop(Iop_1Uto32, binop(Iop_CmpLE32U, cc_dep2, cc_dep1)), 1055436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* case oldC == 0 */ 1056436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ unop(Iop_1Uto32, binop(Iop_CmpLT32U, cc_dep2, cc_dep1)) 1057436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ); 1058436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1059436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1060436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1061436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1062436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* --------- specialising "armg_calculate_flag_v" --------- */ 1063436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1064436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ else 1065436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_streq(function_name, "armg_calculate_flag_v")) { 1066436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1067436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* specialise calls to the "armg_calculate_flag_v" function. 1068436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Note that the returned value must be either 0 or 1; nonzero 1069436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ bits 31:1 are not allowed. In turn, incoming oldV and oldC 1070436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ values (from the thunk) are assumed to have bits 31:1 1071436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ clear. */ 1072436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep; 1073436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert(arity == 4); 1074436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_op = args[0]; /* ARMG_CC_OP_* */ 1075436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_dep1 = args[1]; 1076436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_dep2 = args[2]; 1077436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_ndep = args[3]; 1078436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1079436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_LOGIC)) { 1080436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Thunk args are (result, shco, oldV) */ 1081436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* V after LOGIC --> oldV */ 1082436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return cc_ndep; 1083436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1084436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1085436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_SUB)) { 1086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Thunk args are (argL, argR, unused) */ 1087436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* V after SUB 1088436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> let res = argL - argR 1089436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ in ((argL ^ argR) & (argL ^ res)) >> 31 1090436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> ((argL ^ argR) & (argL ^ (argL - argR))) >> 31 1091436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ */ 1092436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRExpr* argL = cc_dep1; 1093436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ IRExpr* argR = cc_dep2; 1094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return 1095436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Shr32, 1096436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_And32, 1097436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Xor32, argL, argR), 1098436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Xor32, argL, binop(Iop_Sub32, argL, argR)) 1099436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ), 1100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ mkU8(31) 1101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ); 1102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (isU32(cc_op, ARMG_CC_OP_SBB)) { 1105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* This happens occasionally in softfloat code, eg __divdf3+140 */ 1106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */ 1107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* V after SBB 1108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ --> let res = argL - argR - (oldC ^ 1) 1109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ in (argL ^ argR) & (argL ^ res) & 1 1110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ */ 1111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ return 1112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop( 1113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Iop_And32, 1114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop( 1115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ Iop_And32, 1116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // argL ^ argR 1117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Xor32, cc_dep1, cc_dep2), 1118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // argL ^ (argL - argR - (oldC ^ 1)) 1119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Xor32, 1120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cc_dep1, 1121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Sub32, 1122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Sub32, cc_dep1, cc_dep2), 1123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ binop(Iop_Xor32, cc_ndep, mkU32(1))) 1124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ) 1125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ), 1126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ mkU32(1) 1127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ ); 1128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef unop 1133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef binop 1134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef mkU64 1135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef mkU8 1136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return NULL; 1138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 1139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*----------------------------------------------*/ 1142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- The exported fns .. ---*/ 1143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*----------------------------------------------*/ 1144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* VISIBLE TO LIBVEX CLIENT */ 1146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ #if 0 1147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ void LibVEX_GuestARM_put_flags ( UInt flags_native, 1148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /*OUT*/VexGuestARMState* vex_state ) 1149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ { 1150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vassert(0); // FIXME 1151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Mask out everything except N Z V C. */ 1153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ flags_native 1154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ &= (ARMG_CC_MASK_N | ARMG_CC_MASK_Z | ARMG_CC_MASK_V | ARMG_CC_MASK_C); 1155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_OP = ARMG_CC_OP_COPY; 1157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_DEP1 = flags_native; 1158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_DEP2 = 0; 1159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_NDEP = 0; 1160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 1161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ #endif 1162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* VISIBLE TO LIBVEX CLIENT */ 1164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong LibVEX_GuestARM64_get_nzcv ( /*IN*/const VexGuestARM64State* vex_state ) 1165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 1166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong nzcv = 0; 1167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // NZCV 1168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nzcv |= arm64g_calculate_flags_nzcv( 1169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_CC_OP, 1170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_CC_DEP1, 1171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_CC_DEP2, 1172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_CC_NDEP 1173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ); 1174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0 == (nzcv & 0xFFFFFFFF0FFFFFFFULL)); 1175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // Q 1176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_QFLAG32 > 0) 1177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 27); 1178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // GE 1179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_GEFLAG0 > 0) 1180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 16); 1181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_GEFLAG1 > 0) 1182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 17); 1183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_GEFLAG2 > 0) 1184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 18); 1185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_GEFLAG3 > 0) 1186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 19); 1187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // M 1188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 4); // 0b10000 means user-mode 1189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // J,T J (bit 24) is zero by initialisation above 1190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // T we copy from R15T[0] 1191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (vex_state->guest_R15T & 1) 1192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ cpsr |= (1 << 5); 1193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // ITSTATE we punt on for the time being. Could compute it 1194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // if needed though. 1195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // E, endianness, 0 (littleendian) from initialisation above 1196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // A,I,F disable some async exceptions. Not sure about these. 1197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // Leave as zero for the time being. 1198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return nzcv; 1199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 1200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* VISIBLE TO LIBVEX CLIENT */ 1202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid LibVEX_GuestARM64_initialise ( /*OUT*/VexGuestARM64State* vex_state ) 1203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 1204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_bzero(vex_state, sizeof(*vex_state)); 1205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->host_EvC_FAILADDR = 0; 1206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->host_EvC_COUNTER = 0; 1207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R0 = 0; 1209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R1 = 0; 1210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R2 = 0; 1211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R3 = 0; 1212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R4 = 0; 1213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R5 = 0; 1214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R6 = 0; 1215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R7 = 0; 1216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R8 = 0; 1217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R9 = 0; 1218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R10 = 0; 1219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R11 = 0; 1220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R12 = 0; 1221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R13 = 0; 1222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R14 = 0; 1223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_R15T = 0; /* NB: implies ARM mode */ 1224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_state->guest_CC_OP = ARM64G_CC_OP_COPY; 1226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_DEP1 = 0; 1227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_DEP2 = 0; 1228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_CC_NDEP = 0; 1229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_QFLAG32 = 0; 1230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_GEFLAG0 = 0; 1231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_GEFLAG1 = 0; 1232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_GEFLAG2 = 0; 1233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_GEFLAG3 = 0; 1234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_EMNOTE = EmNote_NONE; 1236eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov//ZZ vex_state->guest_CMSTART = 0; 1237eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov//ZZ vex_state->guest_CMLEN = 0; 1238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_NRADDR = 0; 1239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_IP_AT_SYSCALL = 0; 1240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D0 = 0; 1242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D1 = 0; 1243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D2 = 0; 1244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D3 = 0; 1245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D4 = 0; 1246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D5 = 0; 1247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D6 = 0; 1248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D7 = 0; 1249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D8 = 0; 1250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D9 = 0; 1251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D10 = 0; 1252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D11 = 0; 1253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D12 = 0; 1254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D13 = 0; 1255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D14 = 0; 1256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D15 = 0; 1257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D16 = 0; 1258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D17 = 0; 1259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D18 = 0; 1260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D19 = 0; 1261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D20 = 0; 1262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D21 = 0; 1263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D22 = 0; 1264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D23 = 0; 1265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D24 = 0; 1266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D25 = 0; 1267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D26 = 0; 1268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D27 = 0; 1269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D28 = 0; 1270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D29 = 0; 1271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D30 = 0; 1272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_D31 = 0; 1273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* ARM encoded; zero is the default as it happens (result flags 1275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ (NZCV) cleared, FZ disabled, round to nearest, non-vector mode, 1276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ all exns masked, all exn sticky bits cleared). */ 1277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_FPSCR = 0; 1278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_TPIDRURO = 0; 1280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ /* Not in a Thumb IT block. */ 1282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->guest_ITSTATE = 0; 1283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ 1284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->padding1 = 0; 1285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->padding2 = 0; 1286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->padding3 = 0; 1287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->padding4 = 0; 1288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vex_state->padding5 = 0; 1289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 1290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-----------------------------------------------------------*/ 1293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- Describing the arm guest state, for the benefit ---*/ 1294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- of iropt and instrumenters. ---*/ 1295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*-----------------------------------------------------------*/ 1296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Figure out if any part of the guest state contained in minoff 1298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .. maxoff requires precise memory exceptions. If in doubt return 1299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov True (but this generates significantly slower code). 1300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov We enforce precise exns for guest SP, PC, 29(FP), 30(LR). 1302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov That might be overkill (for 29 and 30); I don't know. 1303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 1304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovBool guest_arm64_state_requires_precise_mem_exns ( Int minoff, 1305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int maxoff) 1306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 1307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int xsp_min = offsetof(VexGuestARM64State, guest_XSP); 1308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int xsp_max = xsp_min + 8 - 1; 1309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int pc_min = offsetof(VexGuestARM64State, guest_PC); 1310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int pc_max = pc_min + 8 - 1; 1311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < xsp_min || minoff > xsp_max) { 1313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with xsp */ 1314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess) 1315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return False; // We only need to check stack pointer. 1316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return True; 1318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < pc_min || minoff > pc_max) { 1321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with pc */ 1322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return True; 1324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Guessing that we need PX for FP, but I don't really know. */ 1327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int x29_min = offsetof(VexGuestARM64State, guest_X29); 1328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int x29_max = x29_min + 8 - 1; 1329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < x29_min || minoff > x29_max) { 1331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with x29 */ 1332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return True; 1334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Guessing that we need PX for LR, but I don't really know. */ 1337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int x30_min = offsetof(VexGuestARM64State, guest_X30); 1338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int x30_max = x30_min + 8 - 1; 1339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (maxoff < x30_min || minoff > x30_max) { 1341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* no overlap with r30 */ 1342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return True; 1344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return False; 1347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 1348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define ALWAYSDEFD(field) \ 1351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { offsetof(VexGuestARM64State, field), \ 1352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (sizeof ((VexGuestARM64State*)0)->field) } 1353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovVexGuestLayout 1354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov arm64Guest_layout 1355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = { 1356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Total size of the guest state, in bytes. */ 1357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .total_sizeB = sizeof(VexGuestARM64State), 1358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Describe the stack pointer. */ 1360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .offset_SP = offsetof(VexGuestARM64State,guest_XSP), 1361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .sizeof_SP = 8, 1362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Describe the instruction pointer. */ 1364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .offset_IP = offsetof(VexGuestARM64State,guest_PC), 1365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .sizeof_IP = 8, 1366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Describe any sections to be regarded by Memcheck as 1368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 'always-defined'. */ 1369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .n_alwaysDefd = 10, 1370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* flags thunk: OP is always defd, whereas DEP1 and DEP2 1372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov have to be tracked. See detailed comment in gdefs.h on 1373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov meaning of thunk fields. */ 1374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .alwaysDefd 1375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = { /* 0 */ ALWAYSDEFD(guest_PC), 1376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 1 */ ALWAYSDEFD(guest_CC_OP), 1377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 2 */ ALWAYSDEFD(guest_CC_NDEP), 1378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 3 */ ALWAYSDEFD(guest_EMNOTE), 1379eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* 4 */ ALWAYSDEFD(guest_CMSTART), 1380eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* 5 */ ALWAYSDEFD(guest_CMLEN), 1381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 6 */ ALWAYSDEFD(guest_NRADDR), 1382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), 1383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 8 */ ALWAYSDEFD(guest_FPCR), 1384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 9 */ ALWAYSDEFD(guest_FPSR) 1385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov }; 1387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 1390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- end guest_arm64_helpers.c ---*/ 1391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*---------------------------------------------------------------*/ 1392