sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 1 | |
| 2 | /*---------------------------------------------------------------*/ |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 3 | /*--- begin libvex.h ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 4 | /*---------------------------------------------------------------*/ |
| 5 | |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 6 | /* |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 7 | This file is part of Valgrind, a dynamic binary instrumentation |
| 8 | framework. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 9 | |
sewardj | 785952d | 2015-08-21 11:29:16 +0000 | [diff] [blame] | 10 | Copyright (C) 2004-2015 OpenWorks LLP |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 11 | info@open-works.net |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 12 | |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 13 | This program is free software; you can redistribute it and/or |
| 14 | modify it under the terms of the GNU General Public License as |
| 15 | published by the Free Software Foundation; either version 2 of the |
| 16 | License, or (at your option) any later version. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 17 | |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 18 | This program is distributed in the hope that it will be useful, but |
| 19 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | General Public License for more details. |
| 22 | |
| 23 | You should have received a copy of the GNU General Public License |
| 24 | along with this program; if not, write to the Free Software |
| 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
sewardj | 7bd6ffe | 2005-08-03 16:07:36 +0000 | [diff] [blame] | 26 | 02110-1301, USA. |
| 27 | |
sewardj | 752f906 | 2010-05-03 21:38:49 +0000 | [diff] [blame] | 28 | The GNU General Public License is contained in the file COPYING. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 29 | |
| 30 | Neither the names of the U.S. Department of Energy nor the |
| 31 | University of California nor the names of its contributors may be |
| 32 | used to endorse or promote products derived from this software |
| 33 | without prior written permission. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 34 | */ |
| 35 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 36 | #ifndef __LIBVEX_H |
| 37 | #define __LIBVEX_H |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 38 | |
| 39 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 40 | #include "libvex_basictypes.h" |
| 41 | #include "libvex_ir.h" |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 42 | |
| 43 | |
| 44 | /*---------------------------------------------------------------*/ |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 45 | /*--- This file defines the top-level interface to LibVEX. ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 46 | /*---------------------------------------------------------------*/ |
| 47 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 48 | /*-------------------------------------------------------*/ |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 49 | /*--- Architectures, variants, and other arch info ---*/ |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 50 | /*-------------------------------------------------------*/ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 51 | |
| 52 | typedef |
| 53 | enum { |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 54 | VexArch_INVALID=0x400, |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 55 | VexArchX86, |
| 56 | VexArchAMD64, |
cerion | 896a137 | 2005-01-25 12:24:25 +0000 | [diff] [blame] | 57 | VexArchARM, |
sewardj | bbcf188 | 2014-01-12 12:49:10 +0000 | [diff] [blame] | 58 | VexArchARM64, |
cerion | d953ebb | 2005-11-29 13:27:20 +0000 | [diff] [blame] | 59 | VexArchPPC32, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 60 | VexArchPPC64, |
sewardj | d0e5fe7 | 2012-06-07 08:51:02 +0000 | [diff] [blame] | 61 | VexArchS390X, |
petarj | b92a954 | 2013-02-27 22:57:17 +0000 | [diff] [blame] | 62 | VexArchMIPS32, |
sewardj | 0de8019 | 2015-04-10 12:27:40 +0000 | [diff] [blame] | 63 | VexArchMIPS64, |
| 64 | VexArchTILEGX |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 65 | } |
| 66 | VexArch; |
| 67 | |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 68 | |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 69 | /* Information about endianness. */ |
| 70 | typedef |
| 71 | enum { |
| 72 | VexEndness_INVALID=0x600, /* unknown endianness */ |
| 73 | VexEndnessLE, /* little endian */ |
| 74 | VexEndnessBE /* big endian */ |
| 75 | } |
| 76 | VexEndness; |
| 77 | |
| 78 | |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 79 | /* For a given architecture, these specify extra capabilities beyond |
| 80 | the minimum supported (baseline) capabilities. They may be OR'd |
| 81 | together, although some combinations don't make sense. (eg, SSE2 |
| 82 | but not SSE1). LibVEX_Translate will check for nonsensical |
| 83 | combinations. */ |
| 84 | |
sewardj | e9d8a26 | 2009-07-01 08:06:34 +0000 | [diff] [blame] | 85 | /* x86: baseline capability is Pentium-1 (FPU, MMX, but no SSE), with |
mjw | 6c65c12 | 2013-08-27 10:19:03 +0000 | [diff] [blame] | 86 | cmpxchg8b. MMXEXT is a special AMD only subset of SSE1 (Integer SSE). */ |
| 87 | #define VEX_HWCAPS_X86_MMXEXT (1<<1) /* A subset of SSE1 on early AMD */ |
| 88 | #define VEX_HWCAPS_X86_SSE1 (1<<2) /* SSE1 support (Pentium III) */ |
| 89 | #define VEX_HWCAPS_X86_SSE2 (1<<3) /* SSE2 support (Pentium 4) */ |
| 90 | #define VEX_HWCAPS_X86_SSE3 (1<<4) /* SSE3 support (>= Prescott) */ |
| 91 | #define VEX_HWCAPS_X86_LZCNT (1<<5) /* SSE4a LZCNT insn */ |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 92 | |
sewardj | e9d8a26 | 2009-07-01 08:06:34 +0000 | [diff] [blame] | 93 | /* amd64: baseline capability is SSE2, with cmpxchg8b but not |
| 94 | cmpxchg16b. */ |
sewardj | cc3d219 | 2013-03-27 11:37:33 +0000 | [diff] [blame] | 95 | #define VEX_HWCAPS_AMD64_SSE3 (1<<5) /* SSE3 support */ |
| 96 | #define VEX_HWCAPS_AMD64_CX16 (1<<6) /* cmpxchg16b support */ |
| 97 | #define VEX_HWCAPS_AMD64_LZCNT (1<<7) /* SSE4a LZCNT insn */ |
| 98 | #define VEX_HWCAPS_AMD64_AVX (1<<8) /* AVX instructions */ |
| 99 | #define VEX_HWCAPS_AMD64_RDTSCP (1<<9) /* RDTSCP instruction */ |
| 100 | #define VEX_HWCAPS_AMD64_BMI (1<<10) /* BMI1 instructions */ |
| 101 | #define VEX_HWCAPS_AMD64_AVX2 (1<<11) /* AVX2 instructions */ |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 102 | |
| 103 | /* ppc32: baseline capability is integer only */ |
sewardj | 536fbab | 2010-07-29 15:39:05 +0000 | [diff] [blame] | 104 | #define VEX_HWCAPS_PPC32_F (1<<8) /* basic (non-optional) FP */ |
| 105 | #define VEX_HWCAPS_PPC32_V (1<<9) /* Altivec (VMX) */ |
| 106 | #define VEX_HWCAPS_PPC32_FX (1<<10) /* FP extns (fsqrt, fsqrts) */ |
| 107 | #define VEX_HWCAPS_PPC32_GX (1<<11) /* Graphics extns |
| 108 | (fres,frsqrte,fsel,stfiwx) */ |
sewardj | 66d5ef2 | 2011-04-15 11:55:00 +0000 | [diff] [blame] | 109 | #define VEX_HWCAPS_PPC32_VX (1<<12) /* Vector-scalar floating-point (VSX); implies ISA 2.06 or higher */ |
sewardj | a0fb119 | 2012-06-03 23:11:49 +0000 | [diff] [blame] | 110 | #define VEX_HWCAPS_PPC32_DFP (1<<17) /* Decimal Floating Point (DFP) -- e.g., dadd */ |
carll | 0c74bb5 | 2013-08-12 18:01:40 +0000 | [diff] [blame] | 111 | #define VEX_HWCAPS_PPC32_ISA2_07 (1<<19) /* ISA 2.07 -- e.g., mtvsrd */ |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 112 | #define VEX_HWCAPS_PPC32_ISA3_0 (1<<21) /* ISA 3.0 -- e.g., cnttzw */ |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 113 | |
| 114 | /* ppc64: baseline capability is integer and basic FP insns */ |
sewardj | 66d5ef2 | 2011-04-15 11:55:00 +0000 | [diff] [blame] | 115 | #define VEX_HWCAPS_PPC64_V (1<<13) /* Altivec (VMX) */ |
| 116 | #define VEX_HWCAPS_PPC64_FX (1<<14) /* FP extns (fsqrt, fsqrts) */ |
| 117 | #define VEX_HWCAPS_PPC64_GX (1<<15) /* Graphics extns |
sewardj | 536fbab | 2010-07-29 15:39:05 +0000 | [diff] [blame] | 118 | (fres,frsqrte,fsel,stfiwx) */ |
sewardj | 66d5ef2 | 2011-04-15 11:55:00 +0000 | [diff] [blame] | 119 | #define VEX_HWCAPS_PPC64_VX (1<<16) /* Vector-scalar floating-point (VSX); implies ISA 2.06 or higher */ |
sewardj | c66d6fa | 2012-04-02 21:24:12 +0000 | [diff] [blame] | 120 | #define VEX_HWCAPS_PPC64_DFP (1<<18) /* Decimal Floating Point (DFP) -- e.g., dadd */ |
carll | 0c74bb5 | 2013-08-12 18:01:40 +0000 | [diff] [blame] | 121 | #define VEX_HWCAPS_PPC64_ISA2_07 (1<<20) /* ISA 2.07 -- e.g., mtvsrd */ |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 122 | #define VEX_HWCAPS_PPC64_ISA3_0 (1<<22) /* ISA 3.0 -- e.g., cnttzw */ |
sewardj | c66d6fa | 2012-04-02 21:24:12 +0000 | [diff] [blame] | 123 | |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 124 | /* s390x: Hardware capability encoding |
| 125 | |
florian | beef61a | 2012-05-27 16:59:56 +0000 | [diff] [blame] | 126 | Bits [26:31] encode the machine model (see VEX_S390X_MODEL... below) |
| 127 | Bits [0:20] encode specific hardware capabilities |
| 128 | (see VEX_HWAPS_S390X_... below) |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 129 | */ |
| 130 | |
| 131 | /* Model numbers must be assigned in chronological order. |
| 132 | They are used as array index. */ |
| 133 | #define VEX_S390X_MODEL_Z900 0 |
| 134 | #define VEX_S390X_MODEL_Z800 1 |
| 135 | #define VEX_S390X_MODEL_Z990 2 |
| 136 | #define VEX_S390X_MODEL_Z890 3 |
| 137 | #define VEX_S390X_MODEL_Z9_EC 4 |
| 138 | #define VEX_S390X_MODEL_Z9_BC 5 |
| 139 | #define VEX_S390X_MODEL_Z10_EC 6 |
| 140 | #define VEX_S390X_MODEL_Z10_BC 7 |
| 141 | #define VEX_S390X_MODEL_Z196 8 |
florian | 87b48b6 | 2011-09-02 22:19:47 +0000 | [diff] [blame] | 142 | #define VEX_S390X_MODEL_Z114 9 |
florian | c9e43b1 | 2012-08-28 13:31:31 +0000 | [diff] [blame] | 143 | #define VEX_S390X_MODEL_ZEC12 10 |
florian | 1bdaac5 | 2013-07-28 15:28:57 +0000 | [diff] [blame] | 144 | #define VEX_S390X_MODEL_ZBC12 11 |
florian | dee60ed | 2015-03-17 13:44:14 +0000 | [diff] [blame] | 145 | #define VEX_S390X_MODEL_Z13 12 |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 146 | #define VEX_S390X_MODEL_Z13S 13 |
| 147 | #define VEX_S390X_MODEL_UNKNOWN 14 /* always last in list */ |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 148 | #define VEX_S390X_MODEL_MASK 0x3F |
| 149 | |
sewardj | d07b856 | 2011-04-27 11:58:22 +0000 | [diff] [blame] | 150 | #define VEX_HWCAPS_S390X_LDISP (1<<6) /* Long-displacement facility */ |
| 151 | #define VEX_HWCAPS_S390X_EIMM (1<<7) /* Extended-immediate facility */ |
| 152 | #define VEX_HWCAPS_S390X_GIE (1<<8) /* General-instruction-extension facility */ |
| 153 | #define VEX_HWCAPS_S390X_DFP (1<<9) /* Decimal floating point facility */ |
| 154 | #define VEX_HWCAPS_S390X_FGX (1<<10) /* FPR-GR transfer facility */ |
florian | 9af3769 | 2012-01-15 21:01:16 +0000 | [diff] [blame] | 155 | #define VEX_HWCAPS_S390X_ETF2 (1<<11) /* ETF2-enhancement facility */ |
florian | 90ece04 | 2012-04-21 15:41:51 +0000 | [diff] [blame] | 156 | #define VEX_HWCAPS_S390X_STFLE (1<<12) /* STFLE facility */ |
florian | 79bee4b | 2012-05-03 01:30:48 +0000 | [diff] [blame] | 157 | #define VEX_HWCAPS_S390X_ETF3 (1<<13) /* ETF3-enhancement facility */ |
florian | a4c3669 | 2012-08-26 04:22:33 +0000 | [diff] [blame] | 158 | #define VEX_HWCAPS_S390X_STCKF (1<<14) /* STCKF facility */ |
florian | 60b665b | 2012-08-30 20:28:00 +0000 | [diff] [blame] | 159 | #define VEX_HWCAPS_S390X_FPEXT (1<<15) /* Floating point extension facility */ |
florian | aec8e05 | 2012-12-09 17:26:32 +0000 | [diff] [blame] | 160 | #define VEX_HWCAPS_S390X_LSC (1<<16) /* Conditional load/store facility */ |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 161 | #define VEX_HWCAPS_S390X_PFPO (1<<17) /* Perform floating point ops facility */ |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 162 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 163 | /* Special value representing all available s390x hwcaps */ |
| 164 | #define VEX_HWCAPS_S390X_ALL (VEX_HWCAPS_S390X_LDISP | \ |
| 165 | VEX_HWCAPS_S390X_EIMM | \ |
| 166 | VEX_HWCAPS_S390X_GIE | \ |
sewardj | d07b856 | 2011-04-27 11:58:22 +0000 | [diff] [blame] | 167 | VEX_HWCAPS_S390X_DFP | \ |
florian | 9af3769 | 2012-01-15 21:01:16 +0000 | [diff] [blame] | 168 | VEX_HWCAPS_S390X_FGX | \ |
florian | 90ece04 | 2012-04-21 15:41:51 +0000 | [diff] [blame] | 169 | VEX_HWCAPS_S390X_STFLE | \ |
florian | a4c3669 | 2012-08-26 04:22:33 +0000 | [diff] [blame] | 170 | VEX_HWCAPS_S390X_STCKF | \ |
florian | 60b665b | 2012-08-30 20:28:00 +0000 | [diff] [blame] | 171 | VEX_HWCAPS_S390X_FPEXT | \ |
florian | aec8e05 | 2012-12-09 17:26:32 +0000 | [diff] [blame] | 172 | VEX_HWCAPS_S390X_LSC | \ |
florian | 79bee4b | 2012-05-03 01:30:48 +0000 | [diff] [blame] | 173 | VEX_HWCAPS_S390X_ETF3 | \ |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 174 | VEX_HWCAPS_S390X_ETF2 | \ |
| 175 | VEX_HWCAPS_S390X_PFPO) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 176 | |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 177 | #define VEX_HWCAPS_S390X(x) ((x) & ~VEX_S390X_MODEL_MASK) |
| 178 | #define VEX_S390X_MODEL(x) ((x) & VEX_S390X_MODEL_MASK) |
| 179 | |
sewardj | 0de8019 | 2015-04-10 12:27:40 +0000 | [diff] [blame] | 180 | /* Tilegx: baseline capability is TILEGX36 */ |
| 181 | #define VEX_HWCAPS_TILEGX_BASE (1<<16) /* TILEGX Baseline */ |
| 182 | |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 183 | /* arm: baseline capability is ARMv4 */ |
sewardj | ec0d9a0 | 2010-08-22 12:54:56 +0000 | [diff] [blame] | 184 | /* Bits 5:0 - architecture level (e.g. 5 for v5, 6 for v6 etc) */ |
| 185 | #define VEX_HWCAPS_ARM_VFP (1<<6) /* VFP extension */ |
| 186 | #define VEX_HWCAPS_ARM_VFP2 (1<<7) /* VFPv2 */ |
| 187 | #define VEX_HWCAPS_ARM_VFP3 (1<<8) /* VFPv3 */ |
| 188 | /* Bits 15:10 reserved for (possible) future VFP revisions */ |
| 189 | #define VEX_HWCAPS_ARM_NEON (1<<16) /* Advanced SIMD also known as NEON */ |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 190 | |
sewardj | ec0d9a0 | 2010-08-22 12:54:56 +0000 | [diff] [blame] | 191 | /* Get an ARM architecure level from HWCAPS */ |
| 192 | #define VEX_ARM_ARCHLEVEL(x) ((x) & 0x3f) |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 193 | |
sewardj | bbcf188 | 2014-01-12 12:49:10 +0000 | [diff] [blame] | 194 | /* ARM64: baseline capability is AArch64 v8. */ |
| 195 | /* (no definitions since no variants so far) */ |
| 196 | |
sewardj | d0e5fe7 | 2012-06-07 08:51:02 +0000 | [diff] [blame] | 197 | /* MIPS baseline capability */ |
| 198 | /* Assigned Company values for bits 23:16 of the PRId Register |
| 199 | (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from |
| 200 | MTI, the PRId register is defined in this (backwards compatible) |
| 201 | way: |
| 202 | |
| 203 | +----------------+----------------+----------------+----------------+ |
| 204 | | Company Options| Company ID | Processor ID | Revision | |
| 205 | +----------------+----------------+----------------+----------------+ |
| 206 | 31 24 23 16 15 8 7 |
| 207 | |
| 208 | */ |
| 209 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 210 | #define VEX_PRID_COMP_LEGACY 0x00000000 |
| 211 | #define VEX_PRID_COMP_MIPS 0x00010000 |
| 212 | #define VEX_PRID_COMP_BROADCOM 0x00020000 |
| 213 | #define VEX_PRID_COMP_NETLOGIC 0x000C0000 |
| 214 | #define VEX_PRID_COMP_CAVIUM 0x000D0000 |
| 215 | #define VEX_PRID_COMP_INGENIC_E1 0x00E10000 /* JZ4780 */ |
| 216 | |
| 217 | /* |
| 218 | * These are valid when 23:16 == PRID_COMP_LEGACY |
| 219 | */ |
| 220 | #define VEX_PRID_IMP_LOONGSON_64 0x6300 /* Loongson-2/3 */ |
sewardj | d0e5fe7 | 2012-06-07 08:51:02 +0000 | [diff] [blame] | 221 | |
petarj | bc7d6f4 | 2013-09-16 18:11:59 +0000 | [diff] [blame] | 222 | /* |
| 223 | * These are the PRID's for when 23:16 == PRID_COMP_MIPS |
| 224 | */ |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 225 | #define VEX_PRID_IMP_34K 0x9500 |
| 226 | #define VEX_PRID_IMP_74K 0x9700 |
petarj | bc7d6f4 | 2013-09-16 18:11:59 +0000 | [diff] [blame] | 227 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 228 | /* |
| 229 | * Instead of Company Options values, bits 31:24 will be packed with |
| 230 | * additional information, such as isa level and FP mode. |
| 231 | */ |
| 232 | #define VEX_MIPS_CPU_ISA_M32R1 0x01000000 |
| 233 | #define VEX_MIPS_CPU_ISA_M32R2 0x02000000 |
| 234 | #define VEX_MIPS_CPU_ISA_M64R1 0x04000000 |
| 235 | #define VEX_MIPS_CPU_ISA_M64R2 0x08000000 |
| 236 | #define VEX_MIPS_CPU_ISA_M32R6 0x10000000 |
| 237 | #define VEX_MIPS_CPU_ISA_M64R6 0x20000000 |
| 238 | /* FP mode is FR = 1 (32 dbl. prec. FP registers) */ |
| 239 | #define VEX_MIPS_HOST_FR 0x40000000 |
| 240 | /* Get MIPS Extended Information */ |
| 241 | #define VEX_MIPS_EX_INFO(x) ((x) & 0xFF000000) |
petarj | bc7d6f4 | 2013-09-16 18:11:59 +0000 | [diff] [blame] | 242 | /* Get MIPS Company ID from HWCAPS */ |
| 243 | #define VEX_MIPS_COMP_ID(x) ((x) & 0x00FF0000) |
| 244 | /* Get MIPS Processor ID from HWCAPS */ |
dejanj | 0e006f2 | 2014-02-19 11:56:29 +0000 | [diff] [blame] | 245 | #define VEX_MIPS_PROC_ID(x) ((x) & 0x0000FF00) |
| 246 | /* Get MIPS Revision from HWCAPS */ |
| 247 | #define VEX_MIPS_REV(x) ((x) & 0x000000FF) |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 248 | /* Get host FP mode */ |
| 249 | #define VEX_MIPS_HOST_FP_MODE(x) (!!(VEX_MIPS_EX_INFO(x) & VEX_MIPS_HOST_FR)) |
| 250 | /* Check if the processor supports MIPS32R2. */ |
| 251 | #define VEX_MIPS_CPU_HAS_MIPS32R2(x) (VEX_MIPS_EX_INFO(x) & \ |
| 252 | VEX_MIPS_CPU_ISA_M32R2) |
petarj | bc7d6f4 | 2013-09-16 18:11:59 +0000 | [diff] [blame] | 253 | /* Check if the processor supports DSP ASE Rev 2. */ |
| 254 | #define VEX_MIPS_PROC_DSP2(x) ((VEX_MIPS_COMP_ID(x) == VEX_PRID_COMP_MIPS) && \ |
| 255 | (VEX_MIPS_PROC_ID(x) == VEX_PRID_IMP_74K)) |
| 256 | /* Check if the processor supports DSP ASE Rev 1. */ |
| 257 | #define VEX_MIPS_PROC_DSP(x) (VEX_MIPS_PROC_DSP2(x) || \ |
| 258 | ((VEX_MIPS_COMP_ID(x) == VEX_PRID_COMP_MIPS) && \ |
| 259 | (VEX_MIPS_PROC_ID(x) == VEX_PRID_IMP_34K))) |
dejanj | c3fee0d | 2013-07-25 09:08:03 +0000 | [diff] [blame] | 260 | |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 261 | /* These return statically allocated strings. */ |
| 262 | |
| 263 | extern const HChar* LibVEX_ppVexArch ( VexArch ); |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 264 | extern const HChar* LibVEX_ppVexEndness ( VexEndness endness ); |
sewardj | 5117ce1 | 2006-01-27 21:20:15 +0000 | [diff] [blame] | 265 | extern const HChar* LibVEX_ppVexHwCaps ( VexArch, UInt ); |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 266 | |
sewardj | bbcf188 | 2014-01-12 12:49:10 +0000 | [diff] [blame] | 267 | |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 268 | /* The various kinds of caches */ |
| 269 | typedef enum { |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 270 | DATA_CACHE=0x500, |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 271 | INSN_CACHE, |
| 272 | UNIFIED_CACHE |
| 273 | } VexCacheKind; |
| 274 | |
| 275 | /* Information about a particular cache */ |
| 276 | typedef struct { |
| 277 | VexCacheKind kind; |
| 278 | UInt level; /* level this cache is at, e.g. 1 for L1 cache */ |
| 279 | UInt sizeB; /* size of this cache in bytes */ |
| 280 | UInt line_sizeB; /* cache line size in bytes */ |
| 281 | UInt assoc; /* set associativity */ |
florian | 80ab265 | 2012-10-18 03:11:39 +0000 | [diff] [blame] | 282 | Bool is_trace_cache; /* False, except for certain Pentium 4 models */ |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 283 | } VexCache; |
| 284 | |
| 285 | /* Convenience macro to initialise a VexCache */ |
| 286 | #define VEX_CACHE_INIT(_kind, _level, _size, _line_size, _assoc) \ |
| 287 | ({ (VexCache) { .kind = _kind, .level = _level, .sizeB = _size, \ |
florian | 80ab265 | 2012-10-18 03:11:39 +0000 | [diff] [blame] | 288 | .line_sizeB = _line_size, .assoc = _assoc, \ |
| 289 | .is_trace_cache = False }; }) |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 290 | |
| 291 | /* Information about the cache system as a whole */ |
| 292 | typedef struct { |
| 293 | UInt num_levels; |
| 294 | UInt num_caches; |
| 295 | /* Unordered array of caches for this host. NULL if there are |
florian | 80ab265 | 2012-10-18 03:11:39 +0000 | [diff] [blame] | 296 | no caches. The following can always be assumed: |
| 297 | (1) There is at most one cache of a given kind per cache level. |
| 298 | (2) If there exists a unified cache at a particular level then |
| 299 | no other cache exists at that level. |
| 300 | (3) The existence of a cache at level N > 1 implies the existence of |
| 301 | at least one cache at level N-1. */ |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 302 | VexCache *caches; |
| 303 | Bool icaches_maintain_coherence; |
| 304 | } VexCacheInfo; |
| 305 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 306 | |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 307 | /* This struct is a bit of a hack, but is needed to carry misc |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 308 | important bits of info about an arch. Fields which are meaningless |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 309 | or ignored for the platform in question should be set to zero. |
| 310 | Nb: if you add fields to the struct make sure to update function |
| 311 | LibVEX_default_VexArchInfo. */ |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 312 | |
| 313 | typedef |
| 314 | struct { |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 315 | /* The following three fields are mandatory. */ |
| 316 | UInt hwcaps; |
| 317 | VexEndness endness; |
florian | f192a39 | 2012-10-07 19:44:40 +0000 | [diff] [blame] | 318 | VexCacheInfo hwcache_info; |
florian | 9138b17 | 2013-08-03 19:36:55 +0000 | [diff] [blame] | 319 | /* PPC32/PPC64 only: size of instruction cache line */ |
| 320 | Int ppc_icache_line_szB; |
sewardj | e971c6a | 2010-09-03 15:49:57 +0000 | [diff] [blame] | 321 | /* PPC32/PPC64 only: sizes zeroed by the dcbz/dcbzl instructions |
sewardj | 6590299 | 2014-05-03 21:20:56 +0000 | [diff] [blame] | 322 | (bug#135264) */ |
sewardj | e971c6a | 2010-09-03 15:49:57 +0000 | [diff] [blame] | 323 | UInt ppc_dcbz_szB; |
| 324 | UInt ppc_dcbzl_szB; /* 0 means unsupported (SIGILL) */ |
sewardj | 6590299 | 2014-05-03 21:20:56 +0000 | [diff] [blame] | 325 | /* ARM64: I- and D- minimum line sizes in log2(bytes), as |
| 326 | obtained from ctr_el0.DminLine and .IminLine. For example, a |
| 327 | line size of 64 bytes would be encoded here as 6. */ |
| 328 | UInt arm64_dMinLine_lg2_szB; |
| 329 | UInt arm64_iMinLine_lg2_szB; |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 330 | } |
| 331 | VexArchInfo; |
| 332 | |
| 333 | /* Write default settings info *vai. */ |
| 334 | extern |
| 335 | void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai ); |
| 336 | |
| 337 | |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 338 | /* This struct carries guest and host ABI variant information that may |
| 339 | be needed. Fields which are meaningless or ignored for the |
| 340 | platform in question should be set to zero. |
| 341 | |
| 342 | Settings which are believed to be correct are: |
| 343 | |
| 344 | guest_stack_redzone_size |
| 345 | guest is ppc32-linux ==> 0 |
| 346 | guest is ppc64-linux ==> 288 |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 347 | guest is amd64-linux ==> 128 |
| 348 | guest is other ==> inapplicable |
| 349 | |
philippe | e2cc4de | 2014-12-16 23:57:51 +0000 | [diff] [blame] | 350 | guest_amd64_assume_fs_is_const |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 351 | guest is amd64-linux ==> True |
| 352 | guest is amd64-darwin ==> False |
sewardj | 3e5d82d | 2015-07-21 14:43:23 +0000 | [diff] [blame] | 353 | guest is amd64-solaris ==> True |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 354 | guest is other ==> inapplicable |
| 355 | |
philippe | e2cc4de | 2014-12-16 23:57:51 +0000 | [diff] [blame] | 356 | guest_amd64_assume_gs_is_const |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 357 | guest is amd64-darwin ==> True |
philippe | e2cc4de | 2014-12-16 23:57:51 +0000 | [diff] [blame] | 358 | guest is amd64-linux ==> True |
sewardj | 3e5d82d | 2015-07-21 14:43:23 +0000 | [diff] [blame] | 359 | guest is amd64-solaris ==> False |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 360 | guest is other ==> inapplicable |
| 361 | |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 362 | guest_ppc_zap_RZ_at_blr |
| 363 | guest is ppc64-linux ==> True |
| 364 | guest is ppc32-linux ==> False |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 365 | guest is other ==> inapplicable |
| 366 | |
| 367 | guest_ppc_zap_RZ_at_bl |
| 368 | guest is ppc64-linux ==> const True |
| 369 | guest is ppc32-linux ==> const False |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 370 | guest is other ==> inapplicable |
| 371 | |
| 372 | host_ppc_calls_use_fndescrs: |
| 373 | host is ppc32-linux ==> False |
| 374 | host is ppc64-linux ==> True |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 375 | host is other ==> inapplicable |
| 376 | */ |
| 377 | |
| 378 | typedef |
| 379 | struct { |
| 380 | /* PPC and AMD64 GUESTS only: how many bytes below the |
| 381 | stack pointer are validly addressible? */ |
| 382 | Int guest_stack_redzone_size; |
| 383 | |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 384 | /* AMD64 GUESTS only: should we translate %fs-prefixed |
| 385 | instructions using the assumption that %fs always contains |
sewardj | 3e5d82d | 2015-07-21 14:43:23 +0000 | [diff] [blame] | 386 | the same value? (typically zero on linux and solaris) */ |
philippe | e2cc4de | 2014-12-16 23:57:51 +0000 | [diff] [blame] | 387 | Bool guest_amd64_assume_fs_is_const; |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 388 | |
| 389 | /* AMD64 GUESTS only: should we translate %gs-prefixed |
| 390 | instructions using the assumption that %gs always contains |
philippe | e2cc4de | 2014-12-16 23:57:51 +0000 | [diff] [blame] | 391 | the same value? (typically 0x60 on darwin)? */ |
| 392 | Bool guest_amd64_assume_gs_is_const; |
sewardj | 2e28ac4 | 2008-12-04 00:05:12 +0000 | [diff] [blame] | 393 | |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 394 | /* PPC GUESTS only: should we zap the stack red zone at a 'blr' |
| 395 | (function return) ? */ |
| 396 | Bool guest_ppc_zap_RZ_at_blr; |
| 397 | |
| 398 | /* PPC GUESTS only: should we zap the stack red zone at a 'bl' |
| 399 | (function call) ? Is supplied with the guest address of the |
| 400 | target of the call since that may be significant. If NULL, |
| 401 | is assumed equivalent to a fn which always returns False. */ |
florian | bdf99f0 | 2015-01-04 17:20:19 +0000 | [diff] [blame] | 402 | Bool (*guest_ppc_zap_RZ_at_bl)(Addr); |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 403 | |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 404 | /* PPC32/PPC64 HOSTS only: does '&f' give us a pointer to a |
| 405 | function descriptor on the host, or to the function code |
| 406 | itself? True => descriptor, False => code. */ |
| 407 | Bool host_ppc_calls_use_fndescrs; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 408 | |
| 409 | Bool guest_mips_fp_mode64; |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 410 | } |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 411 | VexAbiInfo; |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 412 | |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 413 | /* Write default settings info *vbi. */ |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 414 | extern |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 415 | void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi ); |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 416 | |
| 417 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 418 | /*-------------------------------------------------------*/ |
| 419 | /*--- Control of Vex's optimiser (iropt). ---*/ |
| 420 | /*-------------------------------------------------------*/ |
| 421 | |
philippe | c8e2f98 | 2012-08-01 22:04:13 +0000 | [diff] [blame] | 422 | |
| 423 | /* VexRegisterUpdates specifies when to ensure that the guest state is |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 424 | up to date, in order of increasing accuracy but increasing expense. |
philippe | c8e2f98 | 2012-08-01 22:04:13 +0000 | [diff] [blame] | 425 | |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 426 | VexRegUpdSpAtMemAccess: all registers are updated at superblock |
| 427 | exits, and SP is also up to date at memory exception points. The |
| 428 | SP is described by the arch specific functions |
| 429 | guest_<arch>_state_requires_precise_mem_exns. |
philippe | 6c46bef | 2012-08-14 22:29:01 +0000 | [diff] [blame] | 430 | |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 431 | VexRegUpdUnwindregsAtMemAccess: registers needed to make a stack |
| 432 | trace are up to date at memory exception points. Typically, |
| 433 | these are PC/SP/FP. The minimal registers are described by the |
| 434 | arch specific functions guest_<arch>_state_requires_precise_mem_exns. |
| 435 | This is what Valgrind sets as the default. |
philippe | c8e2f98 | 2012-08-01 22:04:13 +0000 | [diff] [blame] | 436 | |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 437 | VexRegUpdAllregsAtMemAccess: all registers up to date at memory |
| 438 | exception points. This is what normally might be considered as |
| 439 | providing "precise exceptions for memory", but does not |
| 440 | necessarily provide precise register values at any other kind of |
| 441 | exception. |
philippe | c8e2f98 | 2012-08-01 22:04:13 +0000 | [diff] [blame] | 442 | |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 443 | VexRegUpdAllregsAtEachInsn: all registers up to date at each |
| 444 | instruction. |
| 445 | */ |
| 446 | typedef |
| 447 | enum { |
| 448 | VexRegUpd_INVALID=0x700, |
| 449 | VexRegUpdSpAtMemAccess, |
| 450 | VexRegUpdUnwindregsAtMemAccess, |
| 451 | VexRegUpdAllregsAtMemAccess, |
| 452 | VexRegUpdAllregsAtEachInsn |
| 453 | } |
| 454 | VexRegisterUpdates; |
philippe | c8e2f98 | 2012-08-01 22:04:13 +0000 | [diff] [blame] | 455 | |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 456 | /* Control of Vex's optimiser. */ |
| 457 | |
| 458 | typedef |
| 459 | struct { |
| 460 | /* Controls verbosity of iropt. 0 = no output. */ |
| 461 | Int iropt_verbosity; |
| 462 | /* Control aggressiveness of iropt. 0 = no opt, 1 = simple |
| 463 | opts, 2 (default) = max optimisation. */ |
| 464 | Int iropt_level; |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 465 | /* Controls when registers are updated in guest state. Note |
| 466 | that this is the default value. The VEX client can override |
| 467 | this on a per-IRSB basis if it wants. bb_to_IR() will query |
| 468 | the client to ask if it wants a different setting for the |
| 469 | block under construction, and that new setting is transported |
| 470 | back to LibVEX_Translate, which feeds it to iropt via the |
| 471 | various do_iropt_BB calls. */ |
| 472 | VexRegisterUpdates iropt_register_updates_default; |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 473 | /* How aggressive should iropt be in unrolling loops? Higher |
| 474 | numbers make it more enthusiastic about loop unrolling. |
| 475 | Default=120. A setting of zero disables unrolling. */ |
| 476 | Int iropt_unroll_thresh; |
| 477 | /* What's the maximum basic block length the front end(s) allow? |
| 478 | BBs longer than this are split up. Default=50 (guest |
| 479 | insns). */ |
| 480 | Int guest_max_insns; |
| 481 | /* How aggressive should front ends be in following |
| 482 | unconditional branches to known destinations? Default=10, |
| 483 | meaning that if a block contains less than 10 guest insns so |
| 484 | far, the front end(s) will attempt to chase into its |
| 485 | successor. A setting of zero disables chasing. */ |
| 486 | Int guest_chase_thresh; |
sewardj | 984d9b1 | 2010-01-15 10:53:21 +0000 | [diff] [blame] | 487 | /* EXPERIMENTAL: chase across conditional branches? Not all |
| 488 | front ends honour this. Default: NO. */ |
| 489 | Bool guest_chase_cond; |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 490 | } |
| 491 | VexControl; |
| 492 | |
| 493 | |
| 494 | /* Write the default settings into *vcon. */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 495 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 496 | extern |
| 497 | void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon ); |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 498 | |
| 499 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 500 | /*-------------------------------------------------------*/ |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 501 | /*--- Storage management control ---*/ |
| 502 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 503 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 504 | /* Allocate in Vex's temporary allocation area. Be careful with this. |
| 505 | You can only call it inside an instrumentation or optimisation |
| 506 | callback that you have previously specified in a call to |
| 507 | LibVEX_Translate. The storage allocated will only stay alive until |
florian | bde3406 | 2014-10-11 14:48:38 +0000 | [diff] [blame] | 508 | translation of the current basic block is complete. */ |
florian | 04fc6b1 | 2014-12-29 20:22:26 +0000 | [diff] [blame] | 509 | extern void* LibVEX_Alloc ( SizeT nbytes ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 510 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 511 | /* Show Vex allocation statistics. */ |
| 512 | extern void LibVEX_ShowAllocStats ( void ); |
| 513 | |
| 514 | |
| 515 | /*-------------------------------------------------------*/ |
| 516 | /*--- Describing guest state layout ---*/ |
| 517 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 518 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 519 | /* Describe the guest state enough that the instrumentation |
| 520 | functions can work. */ |
| 521 | |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 522 | /* The max number of guest state chunks which we can describe as |
| 523 | always defined (for the benefit of Memcheck). */ |
sewardj | e86310f | 2009-03-19 22:21:40 +0000 | [diff] [blame] | 524 | #define VEXGLO_N_ALWAYSDEFD 24 |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 525 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 526 | typedef |
| 527 | struct { |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 528 | /* Total size of the guest state, in bytes. Must be |
florian | 95a487b | 2014-02-14 08:55:32 +0000 | [diff] [blame] | 529 | 16-aligned. */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 530 | Int total_sizeB; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 531 | /* Whereabouts is the stack pointer? */ |
| 532 | Int offset_SP; |
| 533 | Int sizeof_SP; /* 4 or 8 */ |
sewardj | a203330 | 2008-08-19 11:15:10 +0000 | [diff] [blame] | 534 | /* Whereabouts is the frame pointer? */ |
| 535 | Int offset_FP; |
| 536 | Int sizeof_FP; /* 4 or 8 */ |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 537 | /* Whereabouts is the instruction pointer? */ |
| 538 | Int offset_IP; |
| 539 | Int sizeof_IP; /* 4 or 8 */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 540 | /* Describe parts of the guest state regarded as 'always |
| 541 | defined'. */ |
| 542 | Int n_alwaysDefd; |
| 543 | struct { |
| 544 | Int offset; |
| 545 | Int size; |
| 546 | } alwaysDefd[VEXGLO_N_ALWAYSDEFD]; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 547 | } |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 548 | VexGuestLayout; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 549 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 550 | /* A note about guest state layout. |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 551 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 552 | LibVEX defines the layout for the guest state, in the file |
sewardj | 478646f | 2008-05-01 20:13:04 +0000 | [diff] [blame] | 553 | pub/libvex_guest_<arch>.h. The struct will have an 16-aligned |
| 554 | size. Each translated bb is assumed to be entered with a specified |
| 555 | register pointing at such a struct. Beyond that is two copies of |
| 556 | the shadow state area with the same size as the struct. Beyond |
| 557 | that is a spill area that LibVEX may spill into. It must have size |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 558 | LibVEX_N_SPILL_BYTES, and this must be a 16-aligned number. |
| 559 | |
sewardj | 478646f | 2008-05-01 20:13:04 +0000 | [diff] [blame] | 560 | On entry, the baseblock pointer register must be 16-aligned. |
| 561 | |
| 562 | There must be no holes in between the primary guest state, its two |
| 563 | copies, and the spill area. In short, all 4 areas must have a |
| 564 | 16-aligned size and be 16-aligned, and placed back-to-back. |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 565 | */ |
| 566 | |
sewardj | d652012 | 2009-07-01 08:45:02 +0000 | [diff] [blame] | 567 | #define LibVEX_N_SPILL_BYTES 4096 |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 568 | |
florian | 5074b49 | 2015-02-13 16:25:41 +0000 | [diff] [blame] | 569 | /* The size of the guest state must be a multiple of this number. */ |
| 570 | #define LibVEX_GUEST_STATE_ALIGN 16 |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 571 | |
| 572 | /*-------------------------------------------------------*/ |
| 573 | /*--- Initialisation of the library ---*/ |
| 574 | /*-------------------------------------------------------*/ |
| 575 | |
| 576 | /* Initialise the library. You must call this first. */ |
| 577 | |
| 578 | extern void LibVEX_Init ( |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 579 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 580 | /* failure exit function */ |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 581 | # if __cplusplus == 1 && __GNUC__ && __GNUC__ <= 3 |
| 582 | /* g++ 3.x doesn't understand attributes on function parameters. |
| 583 | See #265762. */ |
| 584 | # else |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 585 | __attribute__ ((noreturn)) |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 586 | # endif |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 587 | void (*failure_exit) ( void ), |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 588 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 589 | /* logging output function */ |
florian | 04fc6b1 | 2014-12-29 20:22:26 +0000 | [diff] [blame] | 590 | void (*log_bytes) ( const HChar*, SizeT nbytes ), |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 591 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 592 | /* debug paranoia level */ |
| 593 | Int debuglevel, |
sewardj | 6312e80 | 2011-03-15 08:05:12 +0000 | [diff] [blame] | 594 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 595 | /* Control ... */ |
florian | f72c2c1 | 2014-09-05 21:52:29 +0000 | [diff] [blame] | 596 | const VexControl* vcon |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 597 | ); |
| 598 | |
| 599 | |
| 600 | /*-------------------------------------------------------*/ |
| 601 | /*--- Make a translation ---*/ |
| 602 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 603 | |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 604 | /* Describes the outcome of a translation attempt. */ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 605 | typedef |
sewardj | bc161a4 | 2011-06-07 21:28:38 +0000 | [diff] [blame] | 606 | struct { |
| 607 | /* overall status */ |
sewardj | 9b76916 | 2014-07-24 12:42:03 +0000 | [diff] [blame] | 608 | enum { VexTransOK=0x800, |
sewardj | bc161a4 | 2011-06-07 21:28:38 +0000 | [diff] [blame] | 609 | VexTransAccessFail, VexTransOutputFull } status; |
| 610 | /* The number of extents that have a self-check (0 to 3) */ |
| 611 | UInt n_sc_extents; |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 612 | /* Offset in generated code of the profile inc, or -1 if |
| 613 | none. Needed for later patching. */ |
| 614 | Int offs_profInc; |
sewardj | fadbbe2 | 2012-04-24 11:49:03 +0000 | [diff] [blame] | 615 | /* Stats only: the number of guest insns included in the |
| 616 | translation. It may be zero (!). */ |
| 617 | UInt n_guest_instrs; |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 618 | } |
| 619 | VexTranslateResult; |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 620 | |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 621 | |
| 622 | /* Describes precisely the pieces of guest code that a translation |
| 623 | covers. Now that Vex can chase across BB boundaries, the old |
| 624 | scheme of describing a chunk of guest code merely by its start |
| 625 | address and length is inadequate. |
| 626 | |
florian | bdf99f0 | 2015-01-04 17:20:19 +0000 | [diff] [blame] | 627 | This struct uses 20 bytes on a 32-bit archtecture and 32 bytes on a |
| 628 | 64-bit architecture. Space is important as clients will have to store |
| 629 | one of these for each translation made. |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 630 | */ |
| 631 | typedef |
| 632 | struct { |
florian | bdf99f0 | 2015-01-04 17:20:19 +0000 | [diff] [blame] | 633 | Addr base[3]; |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 634 | UShort len[3]; |
| 635 | UShort n_used; |
| 636 | } |
| 637 | VexGuestExtents; |
| 638 | |
| 639 | |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 640 | /* A structure to carry arguments for LibVEX_Translate. There are so |
| 641 | many of them, it seems better to have a structure. */ |
| 642 | typedef |
| 643 | struct { |
sewardj | aca070a | 2006-10-17 00:28:22 +0000 | [diff] [blame] | 644 | /* IN: The instruction sets we are translating from and to. And |
| 645 | guest/host misc info. */ |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 646 | VexArch arch_guest; |
| 647 | VexArchInfo archinfo_guest; |
| 648 | VexArch arch_host; |
| 649 | VexArchInfo archinfo_host; |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 650 | VexAbiInfo abiinfo_both; |
sewardj | f461149 | 2005-10-18 12:01:48 +0000 | [diff] [blame] | 651 | |
sewardj | c716aea | 2006-01-17 01:48:46 +0000 | [diff] [blame] | 652 | /* IN: an opaque value which is passed as the first arg to all |
| 653 | callback functions supplied in this struct. Vex has no idea |
| 654 | what's at the other end of this pointer. */ |
| 655 | void* callback_opaque; |
| 656 | |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 657 | /* IN: the block to translate, and its guest address. */ |
| 658 | /* where are the actual bytes in the host's address space? */ |
florian | 8462d11 | 2014-09-24 15:18:09 +0000 | [diff] [blame] | 659 | const UChar* guest_bytes; |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 660 | /* where do the bytes really come from in the guest's aspace? |
sewardj | c716aea | 2006-01-17 01:48:46 +0000 | [diff] [blame] | 661 | This is the post-redirection guest address. Not that Vex |
| 662 | understands anything about redirection; that is all done on |
| 663 | the Valgrind side. */ |
florian | d4cc0de | 2015-01-02 11:44:12 +0000 | [diff] [blame] | 664 | Addr guest_bytes_addr; |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 665 | |
| 666 | /* Is it OK to chase into this guest address? May not be |
| 667 | NULL. */ |
florian | beac530 | 2014-12-31 12:09:38 +0000 | [diff] [blame] | 668 | Bool (*chase_into_ok) ( /*callback_opaque*/void*, Addr ); |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 669 | |
| 670 | /* OUT: which bits of guest code actually got translated */ |
| 671 | VexGuestExtents* guest_extents; |
| 672 | |
| 673 | /* IN: a place to put the resulting code, and its size */ |
| 674 | UChar* host_bytes; |
| 675 | Int host_bytes_size; |
| 676 | /* OUT: how much of the output area is used. */ |
| 677 | Int* host_bytes_used; |
| 678 | |
| 679 | /* IN: optionally, two instrumentation functions. May be |
| 680 | NULL. */ |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 681 | IRSB* (*instrument1) ( /*callback_opaque*/void*, |
| 682 | IRSB*, |
florian | 0a5494e | 2014-09-24 12:00:49 +0000 | [diff] [blame] | 683 | const VexGuestLayout*, |
| 684 | const VexGuestExtents*, |
| 685 | const VexArchInfo*, |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 686 | IRType gWordTy, IRType hWordTy ); |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 687 | IRSB* (*instrument2) ( /*callback_opaque*/void*, |
| 688 | IRSB*, |
florian | 0a5494e | 2014-09-24 12:00:49 +0000 | [diff] [blame] | 689 | const VexGuestLayout*, |
| 690 | const VexGuestExtents*, |
| 691 | const VexArchInfo*, |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 692 | IRType gWordTy, IRType hWordTy ); |
| 693 | |
sewardj | be1b6ff | 2007-08-28 06:06:27 +0000 | [diff] [blame] | 694 | IRSB* (*finaltidy) ( IRSB* ); |
| 695 | |
sewardj | bc161a4 | 2011-06-07 21:28:38 +0000 | [diff] [blame] | 696 | /* IN: a callback used to ask the caller which of the extents, |
florian | 2eeeb9b | 2011-09-23 18:03:21 +0000 | [diff] [blame] | 697 | if any, a self check is required for. Must not be NULL. |
| 698 | The returned value is a bitmask with a 1 in position i indicating |
| 699 | that the i'th extent needs a check. Since there can be at most |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 700 | 3 extents, the returned values must be between 0 and 7. |
| 701 | |
| 702 | This call also gives the VEX client the opportunity to change |
| 703 | the precision of register update preservation as performed by |
| 704 | the IR optimiser. Before the call, VEX will set *pxControl |
| 705 | to hold the default register-update status value as specified |
| 706 | by VexControl::iropt_register_updates_default as passed to |
| 707 | LibVEX_Init at library initialisation time. The client (in |
| 708 | this callback) can if it wants, inspect the value and change |
| 709 | it to something different, and that value will be used for |
| 710 | subsequent IR optimisation of the block. */ |
sewardj | bc161a4 | 2011-06-07 21:28:38 +0000 | [diff] [blame] | 711 | UInt (*needs_self_check)( /*callback_opaque*/void*, |
sewardj | ca2c3c7 | 2015-02-05 12:53:20 +0000 | [diff] [blame] | 712 | /*MAYBE_MOD*/VexRegisterUpdates* pxControl, |
florian | 0a5494e | 2014-09-24 12:00:49 +0000 | [diff] [blame] | 713 | const VexGuestExtents* ); |
sewardj | c716aea | 2006-01-17 01:48:46 +0000 | [diff] [blame] | 714 | |
| 715 | /* IN: optionally, a callback which allows the caller to add its |
| 716 | own IR preamble following the self-check and any other |
| 717 | VEX-generated preamble, if any. May be NULL. If non-NULL, |
sewardj | f6c8ebf | 2007-02-06 01:52:52 +0000 | [diff] [blame] | 718 | the IRSB under construction is handed to this function, which |
sewardj | c716aea | 2006-01-17 01:48:46 +0000 | [diff] [blame] | 719 | presumably adds IR statements to it. The callback may |
| 720 | optionally complete the block and direct bb_to_IR not to |
| 721 | disassemble any instructions into it; this is indicated by |
| 722 | the callback returning True. |
| 723 | */ |
sewardj | dd40fdf | 2006-12-24 02:20:24 +0000 | [diff] [blame] | 724 | Bool (*preamble_function)(/*callback_opaque*/void*, IRSB*); |
sewardj | ce02aa7 | 2006-01-12 12:27:58 +0000 | [diff] [blame] | 725 | |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 726 | /* IN: debug: trace vex activity at various points */ |
| 727 | Int traceflags; |
| 728 | |
sewardj | 442e51a | 2012-12-06 18:08:04 +0000 | [diff] [blame] | 729 | /* IN: debug: print diagnostics when an illegal instr is detected */ |
| 730 | Bool sigill_diag; |
| 731 | |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 732 | /* IN: profiling: add a 64 bit profiler counter increment to the |
| 733 | translation? */ |
| 734 | Bool addProfInc; |
| 735 | |
sewardj | 010ac54 | 2011-05-29 09:29:18 +0000 | [diff] [blame] | 736 | /* IN: address of the dispatcher entry points. Describes the |
| 737 | places where generated code should jump to at the end of each |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 738 | bb. |
| 739 | |
| 740 | At the end of each translation, the next guest address is |
| 741 | placed in the host's standard return register (x86: %eax, |
| 742 | amd64: %rax, ppc32: %r3, ppc64: %r3). Optionally, the guest |
| 743 | state pointer register (on host x86: %ebp; amd64: %rbp; |
| 744 | ppc32/64: r31) may be set to a VEX_TRC_ value to indicate any |
| 745 | special action required before the next block is run. |
| 746 | |
| 747 | Control is then passed back to the dispatcher (beyond Vex's |
| 748 | control; caller supplies this) in the following way: |
| 749 | |
| 750 | - On host archs which lack a link register (x86, amd64), by a |
sewardj | 010ac54 | 2011-05-29 09:29:18 +0000 | [diff] [blame] | 751 | jump to the host address specified in |
| 752 | 'dispatcher_assisted', if the guest state pointer has been |
| 753 | changed so as to request some action before the next block |
| 754 | is run, or 'dispatcher_unassisted' (the fast path), in |
| 755 | which it is assumed that the guest state pointer is |
| 756 | unchanged and we wish to continue directly with the next |
| 757 | translation. Both of these must be non-NULL. |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 758 | |
| 759 | - On host archs which have a link register (ppc32, ppc64), by |
| 760 | a branch to the link register (which is guaranteed to be |
| 761 | unchanged from whatever it was at entry to the |
sewardj | 010ac54 | 2011-05-29 09:29:18 +0000 | [diff] [blame] | 762 | translation). 'dispatch_assisted' and |
| 763 | 'dispatch_unassisted' must be NULL. |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 764 | |
| 765 | The aim is to get back and forth between translations and the |
| 766 | dispatcher without creating memory traffic to store return |
| 767 | addresses. |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 768 | |
| 769 | FIXME: update this comment |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 770 | */ |
florian | 8462d11 | 2014-09-24 15:18:09 +0000 | [diff] [blame] | 771 | const void* disp_cp_chain_me_to_slowEP; |
| 772 | const void* disp_cp_chain_me_to_fastEP; |
| 773 | const void* disp_cp_xindir; |
| 774 | const void* disp_cp_xassisted; |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 775 | } |
| 776 | VexTranslateArgs; |
| 777 | |
| 778 | |
| 779 | extern |
| 780 | VexTranslateResult LibVEX_Translate ( VexTranslateArgs* ); |
| 781 | |
sewardj | c24824a | 2005-07-07 13:52:03 +0000 | [diff] [blame] | 782 | /* A subtlety re interaction between self-checking translations and |
| 783 | bb-chasing. The supplied chase_into_ok function should say NO |
| 784 | (False) when presented with any address for which you might want to |
| 785 | make a self-checking translation. |
| 786 | |
| 787 | If it doesn't do that, you may end up with Vex chasing from BB #1 |
| 788 | to BB #2 (fine); but if you wanted checking for #2 and not #1, that |
| 789 | would not be the result. Therefore chase_into_ok should disallow |
| 790 | following into #2. That will force the caller to eventually |
| 791 | request a new translation starting at #2, at which point Vex will |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 792 | correctly observe the make-a-self-check flag. |
| 793 | |
| 794 | FIXME: is this still up to date? */ |
| 795 | |
| 796 | |
| 797 | /*-------------------------------------------------------*/ |
| 798 | /*--- Patch existing translations ---*/ |
| 799 | /*-------------------------------------------------------*/ |
| 800 | |
florian | 5ea257b | 2012-09-29 17:05:46 +0000 | [diff] [blame] | 801 | /* A host address range that was modified by the functions below. |
| 802 | Callers must request I-cache syncing after the call as appropriate. */ |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 803 | typedef |
| 804 | struct { |
| 805 | HWord start; |
florian | 5ea257b | 2012-09-29 17:05:46 +0000 | [diff] [blame] | 806 | HWord len; /* always > 0 */ |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 807 | } |
| 808 | VexInvalRange; |
| 809 | |
| 810 | /* Chain an XDirect jump located at place_to_chain so it jumps to |
| 811 | place_to_jump_to. It is expected (and checked) that this site |
| 812 | currently contains a call to the dispatcher specified by |
| 813 | disp_cp_chain_me_EXPECTED. */ |
| 814 | extern |
florian | 7d6f81d | 2014-09-22 21:43:37 +0000 | [diff] [blame] | 815 | VexInvalRange LibVEX_Chain ( VexArch arch_host, |
| 816 | VexEndness endhess_host, |
| 817 | void* place_to_chain, |
| 818 | const void* disp_cp_chain_me_EXPECTED, |
| 819 | const void* place_to_jump_to ); |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 820 | |
| 821 | /* Undo an XDirect jump located at place_to_unchain, so it is |
| 822 | converted back into a call to disp_cp_chain_me. It is expected |
| 823 | (and checked) that this site currently contains a jump directly to |
| 824 | the address specified by place_to_jump_to_EXPECTED. */ |
| 825 | extern |
florian | 7d6f81d | 2014-09-22 21:43:37 +0000 | [diff] [blame] | 826 | VexInvalRange LibVEX_UnChain ( VexArch arch_host, |
| 827 | VexEndness endness_host, |
| 828 | void* place_to_unchain, |
| 829 | const void* place_to_jump_to_EXPECTED, |
| 830 | const void* disp_cp_chain_me ); |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 831 | |
| 832 | /* Returns a constant -- the size of the event check that is put at |
| 833 | the start of every translation. This makes it possible to |
| 834 | calculate the fast entry point address if the slow entry point |
| 835 | address is known (the usual case), or vice versa. */ |
| 836 | extern |
florian | 7ce2cc8 | 2015-01-10 16:10:58 +0000 | [diff] [blame] | 837 | Int LibVEX_evCheckSzB ( VexArch arch_host ); |
sewardj | c6f970f | 2012-04-02 21:54:49 +0000 | [diff] [blame] | 838 | |
| 839 | |
| 840 | /* Patch the counter location into an existing ProfInc point. The |
| 841 | specified point is checked to make sure it is plausible. */ |
| 842 | extern |
florian | 7d6f81d | 2014-09-22 21:43:37 +0000 | [diff] [blame] | 843 | VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host, |
| 844 | VexEndness endness_host, |
| 845 | void* place_to_patch, |
| 846 | const ULong* location_of_counter ); |
sewardj | c24824a | 2005-07-07 13:52:03 +0000 | [diff] [blame] | 847 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 848 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 849 | /*-------------------------------------------------------*/ |
| 850 | /*--- Show accumulated statistics ---*/ |
| 851 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 852 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 853 | extern void LibVEX_ShowStats ( void ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 854 | |
florian | 2245ce9 | 2012-08-28 16:49:30 +0000 | [diff] [blame] | 855 | /*-------------------------------------------------------*/ |
| 856 | /*-- IR injection --*/ |
| 857 | /*-------------------------------------------------------*/ |
| 858 | |
| 859 | /* IR Injection Control Block */ |
| 860 | |
| 861 | #define NO_ROUNDING_MODE (~0u) |
| 862 | |
| 863 | typedef |
| 864 | struct { |
| 865 | IROp op; // the operation to perform |
| 866 | HWord result; // address of the result |
| 867 | HWord opnd1; // address of 1st operand |
| 868 | HWord opnd2; // address of 2nd operand |
| 869 | HWord opnd3; // address of 3rd operand |
| 870 | HWord opnd4; // address of 4th operand |
| 871 | IRType t_result; // type of result |
| 872 | IRType t_opnd1; // type of 1st operand |
| 873 | IRType t_opnd2; // type of 2nd operand |
| 874 | IRType t_opnd3; // type of 3rd operand |
| 875 | IRType t_opnd4; // type of 4th operand |
| 876 | UInt rounding_mode; |
| 877 | UInt num_operands; // excluding rounding mode, if any |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 878 | /* The following two members describe if this operand has immediate |
| 879 | * operands. There are a few restrictions: |
| 880 | * (1) An operator can have at most one immediate operand. |
| 881 | * (2) If there is an immediate operand, it is the right-most operand |
| 882 | * An immediate_index of 0 means there is no immediate operand. |
| 883 | */ |
| 884 | UInt immediate_type; // size of immediate Ity_I8, Ity_16 |
| 885 | UInt immediate_index; // operand number: 1, 2 |
florian | 2245ce9 | 2012-08-28 16:49:30 +0000 | [diff] [blame] | 886 | } |
| 887 | IRICB; |
| 888 | |
| 889 | extern void LibVEX_InitIRI ( const IRICB * ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 890 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 891 | /*-------------------------------------------------------*/ |
| 892 | /*--- Notes ---*/ |
| 893 | /*-------------------------------------------------------*/ |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 894 | |
| 895 | /* Code generation conventions that need to be recorded somewhere. |
| 896 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 897 | |
| 898 | x86 |
| 899 | ~~~ |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 900 | Generated code should be entered using a JMP instruction. On |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 901 | entry, %ebp should point to the guest state, and %esp should be a |
| 902 | valid stack pointer. The generated code may change %eax, %ebx, |
| 903 | %ecx, %edx, %esi, %edi, all the FP registers and control state, and |
| 904 | all the XMM registers. |
| 905 | |
sewardj | 6915b97 | 2005-01-13 16:36:42 +0000 | [diff] [blame] | 906 | On entry, the FPU control word should be set to 0x027F, and the SSE |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 907 | control word (%mxcsr) should be set to 0x1F80. On exit, they |
| 908 | should still have those values (after masking off the lowest 6 bits |
| 909 | of %mxcsr). If they don't, there is a bug in VEX-generated code. |
| 910 | |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 911 | Generated code returns to the scheduler using a JMP instruction, to |
| 912 | the address specified in the .dispatch field of VexTranslateArgs. |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 913 | %eax (or %eax:%edx, if simulating a 64-bit target) will contain the |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 914 | guest address of the next block to execute. %ebp may be changed |
| 915 | to a VEX_TRC_ value, otherwise it should be as it was at entry. |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 916 | |
| 917 | CRITICAL ISSUES in x86 code generation. The only known critical |
| 918 | issue is that the host FPU and SSE state is not properly saved |
| 919 | across calls to helper functions. If any helper references any |
| 920 | such state, it is likely (1) to misbehave itself, since the FP |
| 921 | stack tags will not be as expected, and (2) after returning to |
| 922 | generated code, the generated code is likely to go wrong. This |
| 923 | really should be fixed. |
sewardj | db4738a | 2005-07-07 01:32:16 +0000 | [diff] [blame] | 924 | |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 925 | amd64 |
| 926 | ~~~~~ |
| 927 | Analogous to x86. |
| 928 | |
| 929 | ppc32 |
| 930 | ~~~~~ |
| 931 | On entry, guest state pointer is r31. .dispatch must be NULL. |
| 932 | Control is returned with a branch to the link register. Generated |
| 933 | code will not change lr. At return, r3 holds the next guest addr |
| 934 | (or r3:r4 ?). r31 may be may be changed to a VEX_TRC_ value, |
| 935 | otherwise it should be as it was at entry. |
| 936 | |
| 937 | ppc64 |
| 938 | ~~~~~ |
cerion | 5b2325f | 2005-12-23 00:55:09 +0000 | [diff] [blame] | 939 | Same as ppc32. |
sewardj | 17c7f95 | 2005-12-15 14:02:34 +0000 | [diff] [blame] | 940 | |
sewardj | bbcf188 | 2014-01-12 12:49:10 +0000 | [diff] [blame] | 941 | arm32 |
| 942 | ~~~~~ |
| 943 | r8 is GSP. |
| 944 | |
| 945 | arm64 |
| 946 | ~~~~~ |
| 947 | r21 is GSP. |
| 948 | |
sewardj | db4738a | 2005-07-07 01:32:16 +0000 | [diff] [blame] | 949 | ALL GUEST ARCHITECTURES |
| 950 | ~~~~~~~~~~~~~~~~~~~~~~~ |
sewardj | 05f5e01 | 2014-05-04 10:52:11 +0000 | [diff] [blame] | 951 | The guest state must contain two pseudo-registers, guest_CMSTART |
| 952 | and guest_CMLEN. These are used to specify guest address ranges, |
| 953 | either of code to be invalidated, when used in conjunction with |
| 954 | Ijk_InvalICache, or of d-cache ranges to be flushed, when used in |
| 955 | conjunction with Ijk_FlushDCache. In such cases, the two _CM |
| 956 | pseudo-regs should be filled in by the IR, and then an exit with |
| 957 | one of the two abovementioned Ijk_ kinds should happen, so that the |
| 958 | dispatcher can action them. Both pseudo-regs must have size equal |
| 959 | to the guest word size. |
sewardj | ce02aa7 | 2006-01-12 12:27:58 +0000 | [diff] [blame] | 960 | |
| 961 | The architecture must a third pseudo-register, guest_NRADDR, also |
| 962 | guest-word-sized. This is used to record the unredirected guest |
| 963 | address at the start of a translation whose start has been |
| 964 | redirected. By reading this pseudo-register shortly afterwards, |
| 965 | the translation can find out what the corresponding no-redirection |
| 966 | address was. Note, this is only set for wrap-style redirects, not |
| 967 | for replace-style ones. |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 968 | */ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 969 | #endif /* ndef __LIBVEX_H */ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 970 | |
| 971 | /*---------------------------------------------------------------*/ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 972 | /*--- libvex.h ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 973 | /*---------------------------------------------------------------*/ |