blob: 49e644ccc32f265c9f918c2180862ad2002a7eff [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
carll1f5fe1f2014-08-07 23:25:23 +00003/*--- Begin main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 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.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 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
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
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.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex.h"
florian33b02432012-08-25 21:48:04 +000037#include "libvex_emnote.h"
sewardj81ec4182004-10-25 23:15:52 +000038#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000039#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000040#include "libvex_guest_arm.h"
sewardjbbcf1882014-01-12 12:49:10 +000041#include "libvex_guest_arm64.h"
cerionaabdfbf2005-01-29 12:56:15 +000042#include "libvex_guest_ppc32.h"
cerionf0de28c2005-12-13 20:21:11 +000043#include "libvex_guest_ppc64.h"
sewardj2019a972011-03-07 16:04:07 +000044#include "libvex_guest_s390x.h"
sewardjd0e5fe72012-06-07 08:51:02 +000045#include "libvex_guest_mips32.h"
petarjb92a9542013-02-27 22:57:17 +000046#include "libvex_guest_mips64.h"
sewardjf13a16a2004-07-05 17:10:14 +000047
sewardjcef7d3e2009-07-02 12:21:59 +000048#include "main_globals.h"
49#include "main_util.h"
50#include "host_generic_regs.h"
51#include "ir_opt.h"
sewardj35421a32004-07-05 13:12:34 +000052
sewardjcef7d3e2009-07-02 12:21:59 +000053#include "host_x86_defs.h"
54#include "host_amd64_defs.h"
55#include "host_ppc_defs.h"
sewardj6c299f32009-12-31 18:00:12 +000056#include "host_arm_defs.h"
sewardjbbcf1882014-01-12 12:49:10 +000057#include "host_arm64_defs.h"
sewardj2019a972011-03-07 16:04:07 +000058#include "host_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000059#include "host_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000060
sewardjcef7d3e2009-07-02 12:21:59 +000061#include "guest_generic_bb_to_IR.h"
62#include "guest_x86_defs.h"
63#include "guest_amd64_defs.h"
64#include "guest_arm_defs.h"
sewardjbbcf1882014-01-12 12:49:10 +000065#include "guest_arm64_defs.h"
sewardjcef7d3e2009-07-02 12:21:59 +000066#include "guest_ppc_defs.h"
sewardj2019a972011-03-07 16:04:07 +000067#include "guest_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000068#include "guest_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000069
sewardj69d98e32010-06-18 08:17:41 +000070#include "host_generic_simd128.h"
71
sewardj35421a32004-07-05 13:12:34 +000072
73/* This file contains the top level interface to the library. */
74
sewardj5117ce12006-01-27 21:20:15 +000075/* --------- fwds ... --------- */
76
77static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
florian55085f82012-11-21 00:36:55 +000078static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
sewardj5117ce12006-01-27 21:20:15 +000079
80
sewardj8bde7f12013-04-11 13:57:43 +000081/* --------- helpers --------- */
82
83__attribute__((noinline))
84static UInt udiv32 ( UInt x, UInt y ) { return x/y; }
85__attribute__((noinline))
86static Int sdiv32 ( Int x, Int y ) { return x/y; }
87
88
sewardj35421a32004-07-05 13:12:34 +000089/* --------- Initialise the library. --------- */
90
91/* Exported to library client. */
92
sewardj08613742004-10-25 13:01:45 +000093void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
94{
sewardj65902992014-05-03 21:20:56 +000095 vex_bzero(vcon, sizeof(*vcon));
sewardj08613742004-10-25 13:01:45 +000096 vcon->iropt_verbosity = 0;
97 vcon->iropt_level = 2;
philippec8e2f982012-08-01 22:04:13 +000098 vcon->iropt_register_updates = VexRegUpdUnwindregsAtMemAccess;
sewardj08613742004-10-25 13:01:45 +000099 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +0000100 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +0000101 vcon->guest_chase_thresh = 10;
sewardj984d9b12010-01-15 10:53:21 +0000102 vcon->guest_chase_cond = False;
sewardj08613742004-10-25 13:01:45 +0000103}
104
105
106/* Exported to library client. */
107
sewardj887a11a2004-07-05 17:26:47 +0000108void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000109 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000110 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000111 void (*failure_exit) ( void ),
112 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000113 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000114 /* debug paranoia level */
115 Int debuglevel,
sewardj08613742004-10-25 13:01:45 +0000116 /* Control ... */
florianf72c2c12014-09-05 21:52:29 +0000117 const VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000118)
119{
sewardj08613742004-10-25 13:01:45 +0000120 /* First off, do enough minimal setup so that the following
121 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000122 vex_failure_exit = failure_exit;
123 vex_log_bytes = log_bytes;
124
125 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000126 vassert(!vex_initdone);
127 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000128 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000129 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000130
131 vassert(vcon->iropt_verbosity >= 0);
132 vassert(vcon->iropt_level >= 0);
133 vassert(vcon->iropt_level <= 2);
134 vassert(vcon->iropt_unroll_thresh >= 0);
135 vassert(vcon->iropt_unroll_thresh <= 400);
136 vassert(vcon->guest_max_insns >= 1);
137 vassert(vcon->guest_max_insns <= 100);
138 vassert(vcon->guest_chase_thresh >= 0);
139 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj984d9b12010-01-15 10:53:21 +0000140 vassert(vcon->guest_chase_cond == True
141 || vcon->guest_chase_cond == False);
sewardj443cd9d2004-07-18 23:06:45 +0000142
sewardjea602bc2004-10-14 21:40:12 +0000143 /* Check that Vex has been built with sizes of basic types as
144 stated in priv/libvex_basictypes.h. Failure of any of these is
145 a serious configuration error and should be corrected
146 immediately. If any of these assertions fail you can fully
147 expect Vex not to work properly, if at all. */
148
149 vassert(1 == sizeof(UChar));
150 vassert(1 == sizeof(Char));
151 vassert(2 == sizeof(UShort));
152 vassert(2 == sizeof(Short));
153 vassert(4 == sizeof(UInt));
154 vassert(4 == sizeof(Int));
155 vassert(8 == sizeof(ULong));
156 vassert(8 == sizeof(Long));
157 vassert(4 == sizeof(Float));
158 vassert(8 == sizeof(Double));
159 vassert(1 == sizeof(Bool));
160 vassert(4 == sizeof(Addr32));
161 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000162 vassert(16 == sizeof(U128));
sewardj69d98e32010-06-18 08:17:41 +0000163 vassert(16 == sizeof(V128));
sewardjc9069f22012-06-01 16:09:50 +0000164 vassert(32 == sizeof(U256));
sewardjea602bc2004-10-14 21:40:12 +0000165
166 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
167 vassert(sizeof(void*) == sizeof(int*));
168 vassert(sizeof(void*) == sizeof(HWord));
169
sewardj97e87932005-02-07 00:00:50 +0000170 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
171 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
172
sewardjc6f970f2012-04-02 21:54:49 +0000173 /* These take a lot of space, so make sure we don't have
174 any unnoticed size regressions. */
175 if (VEX_HOST_WORDSIZE == 4) {
florian420bfa92012-06-02 20:29:22 +0000176 vassert(sizeof(IRExpr) == 16);
sewardjc6f970f2012-04-02 21:54:49 +0000177 vassert(sizeof(IRStmt) == 20 /* x86 */
178 || sizeof(IRStmt) == 24 /* arm */);
179 } else {
florian420bfa92012-06-02 20:29:22 +0000180 vassert(sizeof(IRExpr) == 32);
floriand6f38b32012-05-31 15:46:18 +0000181 vassert(sizeof(IRStmt) == 32);
sewardjc6f970f2012-04-02 21:54:49 +0000182 }
183
sewardj8bde7f12013-04-11 13:57:43 +0000184 /* Check that signed integer division on the host rounds towards
185 zero. If not, h_calc_sdiv32_w_arm_semantics() won't work
186 correctly. */
187 /* 100.0 / 7.0 == 14.2857 */
188 vassert(udiv32(100, 7) == 14);
189 vassert(sdiv32(100, 7) == 14);
190 vassert(sdiv32(-100, 7) == -14); /* and not -15 */
191 vassert(sdiv32(100, -7) == -14); /* ditto */
192 vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
193
sewardjea602bc2004-10-14 21:40:12 +0000194 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000195 vex_debuglevel = debuglevel;
sewardj08613742004-10-25 13:01:45 +0000196 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000197 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000198 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000199}
200
201
202/* --------- Make a translation. --------- */
203
204/* Exported to library client. */
205
sewardj17c7f952005-12-15 14:02:34 +0000206VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000207{
sewardj81bd5502004-07-21 18:49:27 +0000208 /* This the bundle of functions we need to do the back-end stuff
209 (insn selection, reg-alloc, assembly) whilst being insulated
210 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000211 HReg* available_real_regs;
212 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000213 Bool (*isMove) ( HInstr*, HReg*, HReg* );
214 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
215 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000216 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
217 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000218 HInstr* (*directReload) ( HInstr*, HReg, Short );
219 void (*ppInstr) ( HInstr*, Bool );
220 void (*ppReg) ( HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000221 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
222 Int, Int, Bool, Bool, Addr64 );
223 Int (*emit) ( /*MB_MOD*/Bool*,
sewardj9b769162014-07-24 12:42:03 +0000224 UChar*, Int, HInstr*, Bool, VexEndness,
florian8462d112014-09-24 15:18:09 +0000225 const void*, const void*, const void*,
226 const void* );
florian1ff47562012-10-21 02:09:51 +0000227 IRExpr* (*specHelper) ( const HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000228 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000229
sewardj9e6491a2005-07-02 19:24:10 +0000230 DisOneInstrFn disInstrFn;
231
sewardjeeac8412004-11-02 00:26:55 +0000232 VexGuestLayout* guest_layout;
sewardjdd40fdf2006-12-24 02:20:24 +0000233 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000234 HInstrArray* vcode;
235 HInstrArray* rcode;
236 Int i, j, k, out_used, guest_sizeB;
sewardj05f5e012014-05-04 10:52:11 +0000237 Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
sewardjc6f970f2012-04-02 21:54:49 +0000238 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000239 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000240 IRType guest_word_type;
241 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000242 Bool mode64, chainingAllowed;
243 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000244
sewardj49651f42004-10-28 22:11:04 +0000245 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000246 available_real_regs = NULL;
247 n_available_real_regs = 0;
248 isMove = NULL;
249 getRegUsage = NULL;
250 mapRegs = NULL;
251 genSpill = NULL;
252 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000253 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000254 ppInstr = NULL;
255 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000256 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000257 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000258 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000259 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000260 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000261 guest_word_type = Ity_INVALID;
262 host_word_type = Ity_INVALID;
sewardj05f5e012014-05-04 10:52:11 +0000263 offB_CMSTART = 0;
264 offB_CMLEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000265 offB_GUEST_IP = 0;
266 szB_GUEST_IP = 0;
267 offB_HOST_EvC_COUNTER = 0;
268 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000269 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000270 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000271
sewardj17c7f952005-12-15 14:02:34 +0000272 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000273
sewardj35421a32004-07-05 13:12:34 +0000274 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000275 vassert(vta->needs_self_check != NULL);
276 vassert(vta->disp_cp_xassisted != NULL);
277 /* Both the chainers and the indir are either NULL or non-NULL. */
278 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
279 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
280 vassert(vta->disp_cp_xindir != NULL);
281 chainingAllowed = True;
282 } else {
283 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
284 vassert(vta->disp_cp_xindir == NULL);
285 }
florian2eeeb9b2011-09-23 18:03:21 +0000286
sewardj2d6b14a2005-11-23 04:25:07 +0000287 vexSetAllocModeTEMP_and_clear();
288 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000289
sewardjf13a16a2004-07-05 17:10:14 +0000290 /* First off, check that the guest and host insn sets
291 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000292
sewardj17c7f952005-12-15 14:02:34 +0000293 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000294
sewardjbef170b2004-12-21 01:23:00 +0000295 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000296 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000297 getAllocableRegs_X86 ( &n_available_real_regs,
298 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000299 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000300 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
301 getRegUsage_X86Instr;
sewardjfb7373a2007-08-25 21:29:03 +0000302 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000303 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
304 genSpill_X86;
305 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
306 genReload_X86;
sewardjfb7373a2007-08-25 21:29:03 +0000307 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
308 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
309 ppReg = (void(*)(HReg)) ppHRegX86;
310 iselSB = iselSB_X86;
sewardj9b769162014-07-24 12:42:03 +0000311 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000312 const void*,const void*,const void*,
313 const void*))
sewardj010ac542011-05-29 09:29:18 +0000314 emit_X86Instr;
sewardjcf787902004-11-03 09:08:33 +0000315 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000316 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000317 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjf13a16a2004-07-05 17:10:14 +0000318 break;
sewardj2a9ad022004-11-25 02:46:58 +0000319
sewardjc33671d2005-02-01 20:30:00 +0000320 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000321 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000322 getAllocableRegs_AMD64 ( &n_available_real_regs,
323 &available_real_regs );
324 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000325 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
326 getRegUsage_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000327 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000328 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
329 genSpill_AMD64;
330 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
331 genReload_AMD64;
cerion92b64362005-12-13 12:02:26 +0000332 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000333 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000334 iselSB = iselSB_AMD64;
sewardj9b769162014-07-24 12:42:03 +0000335 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000336 const void*,const void*,const void*,
337 const void*))
sewardj010ac542011-05-29 09:29:18 +0000338 emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000339 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000340 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000341 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjc33671d2005-02-01 20:30:00 +0000342 break;
343
cerion487e4c92005-02-04 16:28:19 +0000344 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000345 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000346 getAllocableRegs_PPC ( &n_available_real_regs,
347 &available_real_regs, mode64 );
348 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
349 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
350 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000351 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
352 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000353 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
354 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000355 iselSB = iselSB_PPC;
sewardj9b769162014-07-24 12:42:03 +0000356 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000357 const void*,const void*,const void*,
358 const void*))
sewardj010ac542011-05-29 09:29:18 +0000359 emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000360 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000361 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000362 vassert(vta->archinfo_host.endness == VexEndnessBE);
cerion487e4c92005-02-04 16:28:19 +0000363 break;
364
cerionf0de28c2005-12-13 20:21:11 +0000365 case VexArchPPC64:
366 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000367 getAllocableRegs_PPC ( &n_available_real_regs,
368 &available_real_regs, mode64 );
369 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
370 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
371 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000372 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
373 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000374 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
375 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000376 iselSB = iselSB_PPC;
sewardj9b769162014-07-24 12:42:03 +0000377 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000378 const void*,const void*,const void*,
379 const void*))
sewardj010ac542011-05-29 09:29:18 +0000380 emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000381 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000382 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000383 vassert(vta->archinfo_host.endness == VexEndnessBE ||
384 vta->archinfo_host.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000385 break;
386
sewardj2019a972011-03-07 16:04:07 +0000387 case VexArchS390X:
388 mode64 = True;
389 getAllocableRegs_S390 ( &n_available_real_regs,
390 &available_real_regs, mode64 );
391 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
392 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
393 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
394 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
395 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
florian017c0d52014-10-07 21:57:05 +0000396 // fixs390: consider implementing directReload_S390
sewardj2019a972011-03-07 16:04:07 +0000397 ppInstr = (void(*)(HInstr*, Bool)) ppS390Instr;
398 ppReg = (void(*)(HReg)) ppHRegS390;
399 iselSB = iselSB_S390;
sewardj9b769162014-07-24 12:42:03 +0000400 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000401 const void*,const void*,const void*,
402 const void*))
403 emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000404 host_word_type = Ity_I64;
405 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000406 vassert(vta->archinfo_host.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000407 break;
408
sewardj6c299f32009-12-31 18:00:12 +0000409 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000410 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000411 getAllocableRegs_ARM ( &n_available_real_regs,
412 &available_real_regs );
sewardj2a1ed8e2009-12-31 19:26:03 +0000413 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
414 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
415 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
416 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
417 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
418 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
419 ppReg = (void(*)(HReg)) ppHRegARM;
420 iselSB = iselSB_ARM;
sewardj9b769162014-07-24 12:42:03 +0000421 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000422 const void*,const void*,const void*,
423 const void*))
sewardj010ac542011-05-29 09:29:18 +0000424 emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000425 host_word_type = Ity_I32;
426 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000427 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000428 break;
429
sewardjbbcf1882014-01-12 12:49:10 +0000430 case VexArchARM64:
431 mode64 = True;
432 getAllocableRegs_ARM64 ( &n_available_real_regs,
433 &available_real_regs );
434 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARM64Instr;
435 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
436 getRegUsage_ARM64Instr;
437 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool))
438 mapRegs_ARM64Instr;
439 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
440 genSpill_ARM64;
441 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
442 genReload_ARM64;
443 ppInstr = (void(*)(HInstr*, Bool)) ppARM64Instr;
444 ppReg = (void(*)(HReg)) ppHRegARM64;
445 iselSB = iselSB_ARM64;
sewardj9b769162014-07-24 12:42:03 +0000446 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000447 const void*,const void*,const void*,
448 const void*))
sewardjbbcf1882014-01-12 12:49:10 +0000449 emit_ARM64Instr;
sewardjbbcf1882014-01-12 12:49:10 +0000450 host_word_type = Ity_I64;
451 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000452 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000453 break;
454
sewardjd0e5fe72012-06-07 08:51:02 +0000455 case VexArchMIPS32:
456 mode64 = False;
457 getAllocableRegs_MIPS ( &n_available_real_regs,
458 &available_real_regs, mode64 );
459 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
460 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
461 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
462 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
463 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
464 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
465 ppReg = (void(*)(HReg)) ppHRegMIPS;
466 iselSB = iselSB_MIPS;
sewardj9b769162014-07-24 12:42:03 +0000467 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000468 const void*,const void*,const void*,
469 const void*))
sewardjd0e5fe72012-06-07 08:51:02 +0000470 emit_MIPSInstr;
sewardjd0e5fe72012-06-07 08:51:02 +0000471 host_word_type = Ity_I32;
472 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000473 vassert(vta->archinfo_host.endness == VexEndnessLE
474 || vta->archinfo_host.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000475 break;
476
petarjb92a9542013-02-27 22:57:17 +0000477 case VexArchMIPS64:
478 mode64 = True;
479 getAllocableRegs_MIPS ( &n_available_real_regs,
480 &available_real_regs, mode64 );
481 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
482 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
483 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
484 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
485 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
486 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
487 ppReg = (void(*)(HReg)) ppHRegMIPS;
488 iselSB = iselSB_MIPS;
sewardj9b769162014-07-24 12:42:03 +0000489 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8462d112014-09-24 15:18:09 +0000490 const void*,const void*,const void*,
491 const void*))
petarjb92a9542013-02-27 22:57:17 +0000492 emit_MIPSInstr;
petarjb92a9542013-02-27 22:57:17 +0000493 host_word_type = Ity_I64;
494 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000495 vassert(vta->archinfo_host.endness == VexEndnessLE
496 || vta->archinfo_host.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000497 break;
498
sewardjf13a16a2004-07-05 17:10:14 +0000499 default:
sewardj6c299f32009-12-31 18:00:12 +0000500 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000501 }
502
sewardj2a9ad022004-11-25 02:46:58 +0000503
sewardj17c7f952005-12-15 14:02:34 +0000504 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000505
sewardjbef170b2004-12-21 01:23:00 +0000506 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000507 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
508 disInstrFn = disInstr_X86;
509 specHelper = guest_x86_spechelper;
510 guest_sizeB = sizeof(VexGuestX86State);
511 guest_word_type = Ity_I32;
512 guest_layout = &x86guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000513 offB_CMSTART = offsetof(VexGuestX86State,guest_CMSTART);
514 offB_CMLEN = offsetof(VexGuestX86State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000515 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
516 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
517 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
518 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000519 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000520 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000521 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000522 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
523 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000524 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000525 break;
sewardj2a9ad022004-11-25 02:46:58 +0000526
sewardj44d494d2005-01-20 20:26:33 +0000527 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000528 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
529 disInstrFn = disInstr_AMD64;
530 specHelper = guest_amd64_spechelper;
531 guest_sizeB = sizeof(VexGuestAMD64State);
532 guest_word_type = Ity_I64;
533 guest_layout = &amd64guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000534 offB_CMSTART = offsetof(VexGuestAMD64State,guest_CMSTART);
535 offB_CMLEN = offsetof(VexGuestAMD64State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000536 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
537 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
538 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
539 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000540 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000541 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000542 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000543 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
544 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000545 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000546 break;
547
cerionaabdfbf2005-01-29 12:56:15 +0000548 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000549 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
550 disInstrFn = disInstr_PPC;
551 specHelper = guest_ppc32_spechelper;
552 guest_sizeB = sizeof(VexGuestPPC32State);
553 guest_word_type = Ity_I32;
554 guest_layout = &ppc32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000555 offB_CMSTART = offsetof(VexGuestPPC32State,guest_CMSTART);
556 offB_CMLEN = offsetof(VexGuestPPC32State,guest_CMLEN);
sewardj3dee8492012-04-20 00:13:28 +0000557 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
558 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
559 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
560 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000561 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000562 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj6c299f32009-12-31 18:00:12 +0000563 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000564 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
565 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000566 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000567 break;
568
cerionf0de28c2005-12-13 20:21:11 +0000569 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000570 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
571 disInstrFn = disInstr_PPC;
572 specHelper = guest_ppc64_spechelper;
573 guest_sizeB = sizeof(VexGuestPPC64State);
574 guest_word_type = Ity_I64;
575 guest_layout = &ppc64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000576 offB_CMSTART = offsetof(VexGuestPPC64State,guest_CMSTART);
577 offB_CMLEN = offsetof(VexGuestPPC64State,guest_CMLEN);
sewardj9e1cf152012-04-20 02:18:31 +0000578 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
579 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
580 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
581 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000582 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000583 vassert(vta->archinfo_guest.endness == VexEndnessBE ||
584 vta->archinfo_guest.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000585 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000586 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART ) == 8);
587 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN ) == 8);
sewardj3fd39672006-01-27 22:05:55 +0000588 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
589 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000590 break;
591
sewardj2019a972011-03-07 16:04:07 +0000592 case VexArchS390X:
593 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
594 disInstrFn = disInstr_S390;
595 specHelper = guest_s390x_spechelper;
596 guest_sizeB = sizeof(VexGuestS390XState);
597 guest_word_type = Ity_I64;
598 guest_layout = &s390xGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000599 offB_CMSTART = offsetof(VexGuestS390XState,guest_CMSTART);
600 offB_CMLEN = offsetof(VexGuestS390XState,guest_CMLEN);
florian8844a632012-04-13 04:04:06 +0000601 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
602 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
603 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
604 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000605 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000606 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000607 vassert(0 == sizeof(VexGuestS390XState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000608 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART ) == 8);
609 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN ) == 8);
sewardj2019a972011-03-07 16:04:07 +0000610 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
611 break;
612
sewardj6c299f32009-12-31 18:00:12 +0000613 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000614 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
615 disInstrFn = disInstr_ARM;
616 specHelper = guest_arm_spechelper;
617 guest_sizeB = sizeof(VexGuestARMState);
618 guest_word_type = Ity_I32;
619 guest_layout = &armGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000620 offB_CMSTART = offsetof(VexGuestARMState,guest_CMSTART);
621 offB_CMLEN = offsetof(VexGuestARMState,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000622 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
623 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
624 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
625 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000626 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000627 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000628 vassert(0 == sizeof(VexGuestARMState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000629 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
630 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN ) == 4);
sewardj6c299f32009-12-31 18:00:12 +0000631 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
632 break;
633
sewardjbbcf1882014-01-12 12:49:10 +0000634 case VexArchARM64:
635 preciseMemExnsFn = guest_arm64_state_requires_precise_mem_exns;
636 disInstrFn = disInstr_ARM64;
637 specHelper = guest_arm64_spechelper;
638 guest_sizeB = sizeof(VexGuestARM64State);
639 guest_word_type = Ity_I64;
640 guest_layout = &arm64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000641 offB_CMSTART = offsetof(VexGuestARM64State,guest_CMSTART);
642 offB_CMLEN = offsetof(VexGuestARM64State,guest_CMLEN);
sewardjbbcf1882014-01-12 12:49:10 +0000643 offB_GUEST_IP = offsetof(VexGuestARM64State,guest_PC);
644 szB_GUEST_IP = sizeof( ((VexGuestARM64State*)0)->guest_PC );
645 offB_HOST_EvC_COUNTER = offsetof(VexGuestARM64State,host_EvC_COUNTER);
646 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
647 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000648 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000649 vassert(0 == sizeof(VexGuestARM64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000650 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
651 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN ) == 8);
sewardjbbcf1882014-01-12 12:49:10 +0000652 vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
653 break;
654
sewardjd0e5fe72012-06-07 08:51:02 +0000655 case VexArchMIPS32:
656 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
657 disInstrFn = disInstr_MIPS;
658 specHelper = guest_mips32_spechelper;
659 guest_sizeB = sizeof(VexGuestMIPS32State);
660 guest_word_type = Ity_I32;
661 guest_layout = &mips32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000662 offB_CMSTART = offsetof(VexGuestMIPS32State,guest_CMSTART);
663 offB_CMLEN = offsetof(VexGuestMIPS32State,guest_CMLEN);
sewardjd0e5fe72012-06-07 08:51:02 +0000664 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
665 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
666 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
667 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
668 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000669 vassert(vta->archinfo_guest.endness == VexEndnessLE
670 || vta->archinfo_guest.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000671 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000672 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
673 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN ) == 4);
sewardjd0e5fe72012-06-07 08:51:02 +0000674 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
675 break;
676
petarjb92a9542013-02-27 22:57:17 +0000677 case VexArchMIPS64:
678 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
679 disInstrFn = disInstr_MIPS;
680 specHelper = guest_mips64_spechelper;
681 guest_sizeB = sizeof(VexGuestMIPS64State);
682 guest_word_type = Ity_I64;
683 guest_layout = &mips64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000684 offB_CMSTART = offsetof(VexGuestMIPS64State,guest_CMSTART);
685 offB_CMLEN = offsetof(VexGuestMIPS64State,guest_CMLEN);
petarjb92a9542013-02-27 22:57:17 +0000686 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
687 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
688 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
689 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
690 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000691 vassert(vta->archinfo_guest.endness == VexEndnessLE
692 || vta->archinfo_guest.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000693 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000694 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
695 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN ) == 8);
petarjb92a9542013-02-27 22:57:17 +0000696 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
697 break;
698
sewardjf13a16a2004-07-05 17:10:14 +0000699 default:
sewardj887a11a2004-07-05 17:26:47 +0000700 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000701 }
702
sewardjbc161a42011-06-07 21:28:38 +0000703 /* Set up result struct. */
704 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000705 res.status = VexTransOK;
706 res.n_sc_extents = 0;
707 res.offs_profInc = -1;
708 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000709
sewardj9df271d2004-12-31 22:37:42 +0000710 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000711 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000712 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000713 we are simulating one flavour of an architecture a different
714 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000715 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9b769162014-07-24 12:42:03 +0000716 /* ditto */
717 vassert(vta->archinfo_guest.endness == vta->archinfo_host.endness);
sewardj9df271d2004-12-31 22:37:42 +0000718 }
sewardj2a9ad022004-11-25 02:46:58 +0000719
sewardj2d6b14a2005-11-23 04:25:07 +0000720 vexAllocSanityCheck();
721
sewardjf48ac192004-10-29 00:41:29 +0000722 if (vex_traceflags & VEX_TRACE_FE)
723 vex_printf("\n------------------------"
724 " Front end "
725 "------------------------\n\n");
726
sewardjdd40fdf2006-12-24 02:20:24 +0000727 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000728 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000729 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000730 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000731 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000732 vta->guest_bytes,
733 vta->guest_bytes_addr,
734 vta->chase_into_ok,
sewardj9b769162014-07-24 12:42:03 +0000735 vta->archinfo_host.endness,
sewardj442e51a2012-12-06 18:08:04 +0000736 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000737 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000738 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000739 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000740 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000741 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000742 vta->preamble_function,
sewardj05f5e012014-05-04 10:52:11 +0000743 offB_CMSTART,
744 offB_CMLEN,
sewardjc6f970f2012-04-02 21:54:49 +0000745 offB_GUEST_IP,
746 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000747
sewardj2d6b14a2005-11-23 04:25:07 +0000748 vexAllocSanityCheck();
749
sewardjdd40fdf2006-12-24 02:20:24 +0000750 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000751 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000752 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000753 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000754 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000755 }
sewardjaa59f942004-10-09 09:34:36 +0000756
sewardj17c7f952005-12-15 14:02:34 +0000757 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
758 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
759 for (i = 0; i < vta->guest_extents->n_used; i++) {
760 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000761 }
762
sewardjaa59f942004-10-09 09:34:36 +0000763 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000764 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000765 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000766 vex_printf("can't show code due to extents > 1\n");
767 } else {
768 /* HACK */
florian8462d112014-09-24 15:18:09 +0000769 const UChar* p = vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000770 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000771 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000772 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
773 guest_bytes_read );
774 for (i = 0; i < guest_bytes_read; i++) {
775 UInt b = (UInt)p[i];
776 vex_printf(" %02x", b );
777 sum = (sum << 1) ^ b;
778 }
779 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000780 }
sewardjaa59f942004-10-09 09:34:36 +0000781 }
782
783 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000784 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000785 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000786
sewardj2d6b14a2005-11-23 04:25:07 +0000787 vexAllocSanityCheck();
788
sewardjedf4d692004-08-17 13:52:58 +0000789 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000790 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000791 vta->guest_bytes_addr,
792 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000793 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000794 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000795
sewardjf48ac192004-10-29 00:41:29 +0000796 if (vex_traceflags & VEX_TRACE_OPT1) {
797 vex_printf("\n------------------------"
798 " After pre-instr IR optimisation "
799 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000800 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000801 vex_printf("\n");
802 }
803
sewardj2d6b14a2005-11-23 04:25:07 +0000804 vexAllocSanityCheck();
805
sewardjf13a16a2004-07-05 17:10:14 +0000806 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000807 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000808 irsb = vta->instrument1(vta->callback_opaque,
809 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000810 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000811 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000812 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000813 vexAllocSanityCheck();
814
sewardj17c7f952005-12-15 14:02:34 +0000815 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000816 irsb = vta->instrument2(vta->callback_opaque,
817 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000818 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000819 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000820 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000821
sewardjf48ac192004-10-29 00:41:29 +0000822 if (vex_traceflags & VEX_TRACE_INST) {
823 vex_printf("\n------------------------"
824 " After instrumentation "
825 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000826 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000827 vex_printf("\n");
828 }
829
sewardj17c7f952005-12-15 14:02:34 +0000830 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000831 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000832 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000833
sewardj9578a8b2004-11-04 19:44:48 +0000834 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000835 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000836 do_deadcode_BB( irsb );
837 irsb = cprop_BB( irsb );
838 do_deadcode_BB( irsb );
839 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000840 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000841 }
842
sewardj2d6b14a2005-11-23 04:25:07 +0000843 vexAllocSanityCheck();
844
sewardj9578a8b2004-11-04 19:44:48 +0000845 if (vex_traceflags & VEX_TRACE_OPT2) {
846 vex_printf("\n------------------------"
847 " After post-instr IR optimisation "
848 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000849 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000850 vex_printf("\n");
851 }
852
sewardjf9517d02005-11-28 13:39:37 +0000853 /* Turn it into virtual-registerised code. Build trees -- this
854 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000855 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000856
sewardjbe1b6ff2007-08-28 06:06:27 +0000857 if (vta->finaltidy) {
858 irsb = vta->finaltidy(irsb);
859 }
860
sewardj2d6b14a2005-11-23 04:25:07 +0000861 vexAllocSanityCheck();
862
sewardjf48ac192004-10-29 00:41:29 +0000863 if (vex_traceflags & VEX_TRACE_TREES) {
864 vex_printf("\n------------------------"
865 " After tree-building "
866 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000867 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000868 vex_printf("\n");
869 }
870
sewardje908c422005-02-04 21:18:16 +0000871 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000872 if (0) {
873 *(vta->host_bytes_used) = 0;
874 res.status = VexTransOK; return res;
875 }
sewardje908c422005-02-04 21:18:16 +0000876 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000877
sewardjf48ac192004-10-29 00:41:29 +0000878 if (vex_traceflags & VEX_TRACE_VCODE)
879 vex_printf("\n------------------------"
880 " Instruction selection "
881 "------------------------\n");
882
sewardjc6f970f2012-04-02 21:54:49 +0000883 /* No guest has its IP field at offset zero. If this fails it
884 means some transformation pass somewhere failed to update/copy
885 irsb->offsIP properly. */
886 vassert(irsb->offsIP >= 16);
887
888 vcode = iselSB ( irsb, vta->arch_host,
889 &vta->archinfo_host,
890 &vta->abiinfo_both,
891 offB_HOST_EvC_COUNTER,
892 offB_HOST_EvC_FAILADDR,
893 chainingAllowed,
894 vta->addProfInc,
895 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000896
sewardj2d6b14a2005-11-23 04:25:07 +0000897 vexAllocSanityCheck();
898
sewardjf48ac192004-10-29 00:41:29 +0000899 if (vex_traceflags & VEX_TRACE_VCODE)
900 vex_printf("\n");
901
sewardjf48ac192004-10-29 00:41:29 +0000902 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000903 for (i = 0; i < vcode->arr_used; i++) {
904 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000905 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000906 vex_printf("\n");
907 }
sewardjfbcaf332004-07-08 01:46:01 +0000908 vex_printf("\n");
909 }
sewardjfbcaf332004-07-08 01:46:01 +0000910
sewardjf13a16a2004-07-05 17:10:14 +0000911 /* Register allocate. */
912 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000913 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000914 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000915 genSpill, genReload, directReload,
916 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000917 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000918
sewardj2d6b14a2005-11-23 04:25:07 +0000919 vexAllocSanityCheck();
920
sewardjf48ac192004-10-29 00:41:29 +0000921 if (vex_traceflags & VEX_TRACE_RCODE) {
922 vex_printf("\n------------------------"
923 " Register-allocated code "
924 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000925 for (i = 0; i < rcode->arr_used; i++) {
926 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000927 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000928 vex_printf("\n");
929 }
sewardjfbcaf332004-07-08 01:46:01 +0000930 vex_printf("\n");
931 }
sewardjfbcaf332004-07-08 01:46:01 +0000932
sewardje908c422005-02-04 21:18:16 +0000933 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000934 if (0) {
935 *(vta->host_bytes_used) = 0;
936 res.status = VexTransOK; return res;
937 }
sewardje908c422005-02-04 21:18:16 +0000938 /* end HACK */
939
sewardj81bd5502004-07-21 18:49:27 +0000940 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000941 if (vex_traceflags & VEX_TRACE_ASM) {
942 vex_printf("\n------------------------"
943 " Assembly "
944 "------------------------\n\n");
945 }
946
sewardj81bd5502004-07-21 18:49:27 +0000947 out_used = 0; /* tracks along the host_bytes array */
948 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000949 HInstr* hi = rcode->arr[i];
950 Bool hi_isProfInc = False;
951 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
952 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000953 vex_printf("\n");
954 }
sewardjc6f970f2012-04-02 21:54:49 +0000955 j = emit( &hi_isProfInc,
sewardj9b769162014-07-24 12:42:03 +0000956 insn_bytes, sizeof insn_bytes, hi,
957 mode64, vta->archinfo_host.endness,
sewardjc6f970f2012-04-02 21:54:49 +0000958 vta->disp_cp_chain_me_to_slowEP,
959 vta->disp_cp_chain_me_to_fastEP,
960 vta->disp_cp_xindir,
961 vta->disp_cp_xassisted );
962 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000963 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000964 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000965 vex_printf("0%x ", (UInt)insn_bytes[k]);
966 else
967 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000968 vex_printf("\n\n");
969 }
sewardjc6f970f2012-04-02 21:54:49 +0000970 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000971 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000972 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000973 res.status = VexTransOutputFull;
974 return res;
sewardj81bd5502004-07-21 18:49:27 +0000975 }
sewardjc6f970f2012-04-02 21:54:49 +0000976 if (UNLIKELY(hi_isProfInc)) {
977 vassert(vta->addProfInc); /* else where did it come from? */
978 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
979 vassert(out_used >= 0);
980 res.offs_profInc = out_used;
981 }
982 { UChar* dst = &vta->host_bytes[out_used];
983 for (k = 0; k < j; k++) {
984 dst[k] = insn_bytes[k];
985 }
986 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000987 }
sewardj17c7f952005-12-15 14:02:34 +0000988 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000989 }
sewardj17c7f952005-12-15 14:02:34 +0000990 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000991
sewardj2d6b14a2005-11-23 04:25:07 +0000992 vexAllocSanityCheck();
993
994 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000995
sewardj65ea17e2012-12-28 09:01:59 +0000996 if (vex_traceflags) {
997 /* Print the expansion ratio for this SB. */
998 j = 0; /* total guest bytes */
999 for (i = 0; i < vta->guest_extents->n_used; i++) {
1000 j += vta->guest_extents->len[i];
1001 }
1002 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
1003 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
1004 }
1005
sewardjf48ac192004-10-29 00:41:29 +00001006 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +00001007 res.status = VexTransOK;
1008 return res;
sewardj35421a32004-07-05 13:12:34 +00001009}
1010
1011
sewardjc6f970f2012-04-02 21:54:49 +00001012/* --------- Chain/Unchain XDirects. --------- */
1013
florian7d6f81d2014-09-22 21:43:37 +00001014VexInvalRange LibVEX_Chain ( VexArch arch_host,
1015 VexEndness endness_host,
1016 void* place_to_chain,
1017 const void* disp_cp_chain_me_EXPECTED,
1018 const void* place_to_jump_to )
sewardjc6f970f2012-04-02 21:54:49 +00001019{
sewardjc6f970f2012-04-02 21:54:49 +00001020 switch (arch_host) {
1021 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001022 return chainXDirect_X86(endness_host,
1023 place_to_chain,
1024 disp_cp_chain_me_EXPECTED,
1025 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +00001026 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001027 return chainXDirect_AMD64(endness_host,
1028 place_to_chain,
1029 disp_cp_chain_me_EXPECTED,
1030 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +00001031 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001032 return chainXDirect_ARM(endness_host,
1033 place_to_chain,
1034 disp_cp_chain_me_EXPECTED,
1035 place_to_jump_to);
sewardjbbcf1882014-01-12 12:49:10 +00001036 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001037 return chainXDirect_ARM64(endness_host,
1038 place_to_chain,
1039 disp_cp_chain_me_EXPECTED,
1040 place_to_jump_to);
florian8844a632012-04-13 04:04:06 +00001041 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001042 return chainXDirect_S390(endness_host,
1043 place_to_chain,
1044 disp_cp_chain_me_EXPECTED,
1045 place_to_jump_to);
sewardj3dee8492012-04-20 00:13:28 +00001046 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001047 return chainXDirect_PPC(endness_host,
1048 place_to_chain,
sewardj3dee8492012-04-20 00:13:28 +00001049 disp_cp_chain_me_EXPECTED,
1050 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001051 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001052 return chainXDirect_PPC(endness_host,
1053 place_to_chain,
sewardjf252de52012-04-20 10:42:24 +00001054 disp_cp_chain_me_EXPECTED,
1055 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001056 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001057 return chainXDirect_MIPS(endness_host,
1058 place_to_chain,
sewardjd0e5fe72012-06-07 08:51:02 +00001059 disp_cp_chain_me_EXPECTED,
1060 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001061 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001062 return chainXDirect_MIPS(endness_host,
1063 place_to_chain,
petarjb92a9542013-02-27 22:57:17 +00001064 disp_cp_chain_me_EXPECTED,
1065 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001066 default:
1067 vassert(0);
1068 }
sewardjc6f970f2012-04-02 21:54:49 +00001069}
1070
florian7d6f81d2014-09-22 21:43:37 +00001071VexInvalRange LibVEX_UnChain ( VexArch arch_host,
1072 VexEndness endness_host,
1073 void* place_to_unchain,
1074 const void* place_to_jump_to_EXPECTED,
1075 const void* disp_cp_chain_me )
sewardjc6f970f2012-04-02 21:54:49 +00001076{
sewardjc6f970f2012-04-02 21:54:49 +00001077 switch (arch_host) {
1078 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001079 return unchainXDirect_X86(endness_host,
1080 place_to_unchain,
1081 place_to_jump_to_EXPECTED,
1082 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001083 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001084 return unchainXDirect_AMD64(endness_host,
1085 place_to_unchain,
1086 place_to_jump_to_EXPECTED,
1087 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001088 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001089 return unchainXDirect_ARM(endness_host,
1090 place_to_unchain,
1091 place_to_jump_to_EXPECTED,
1092 disp_cp_chain_me);
sewardjc6acaa42014-02-19 17:42:59 +00001093 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001094 return unchainXDirect_ARM64(endness_host,
1095 place_to_unchain,
1096 place_to_jump_to_EXPECTED,
1097 disp_cp_chain_me);
florian8844a632012-04-13 04:04:06 +00001098 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001099 return unchainXDirect_S390(endness_host,
1100 place_to_unchain,
1101 place_to_jump_to_EXPECTED,
1102 disp_cp_chain_me);
sewardj3dee8492012-04-20 00:13:28 +00001103 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001104 return unchainXDirect_PPC(endness_host,
1105 place_to_unchain,
sewardj3dee8492012-04-20 00:13:28 +00001106 place_to_jump_to_EXPECTED,
1107 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001108 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001109 return unchainXDirect_PPC(endness_host,
1110 place_to_unchain,
sewardjf252de52012-04-20 10:42:24 +00001111 place_to_jump_to_EXPECTED,
1112 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001113 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001114 return unchainXDirect_MIPS(endness_host,
1115 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001116 place_to_jump_to_EXPECTED,
1117 disp_cp_chain_me, False/*!mode64*/);
1118 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001119 return unchainXDirect_MIPS(endness_host,
1120 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001121 place_to_jump_to_EXPECTED,
1122 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001123 default:
1124 vassert(0);
1125 }
sewardjc6f970f2012-04-02 21:54:49 +00001126}
1127
sewardj9b769162014-07-24 12:42:03 +00001128Int LibVEX_evCheckSzB ( VexArch arch_host,
1129 VexEndness endness_host )
sewardjc6f970f2012-04-02 21:54:49 +00001130{
1131 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1132 if (UNLIKELY(cached == 0)) {
1133 switch (arch_host) {
1134 case VexArchX86:
sewardj9b769162014-07-24 12:42:03 +00001135 cached = evCheckSzB_X86(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001136 case VexArchAMD64:
sewardj9b769162014-07-24 12:42:03 +00001137 cached = evCheckSzB_AMD64(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001138 case VexArchARM:
sewardj9b769162014-07-24 12:42:03 +00001139 cached = evCheckSzB_ARM(endness_host); break;
sewardjbbcf1882014-01-12 12:49:10 +00001140 case VexArchARM64:
sewardj9b769162014-07-24 12:42:03 +00001141 cached = evCheckSzB_ARM64(endness_host); break;
florian8844a632012-04-13 04:04:06 +00001142 case VexArchS390X:
sewardj9b769162014-07-24 12:42:03 +00001143 cached = evCheckSzB_S390(endness_host); break;
sewardj3dee8492012-04-20 00:13:28 +00001144 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001145 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001146 cached = evCheckSzB_PPC(endness_host); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001147 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001148 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001149 cached = evCheckSzB_MIPS(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001150 default:
1151 vassert(0);
1152 }
1153 }
1154 return cached;
1155}
1156
sewardj9b769162014-07-24 12:42:03 +00001157VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1158 VexEndness endness_host,
1159 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001160 const ULong* location_of_counter )
sewardjc6f970f2012-04-02 21:54:49 +00001161{
sewardjc6f970f2012-04-02 21:54:49 +00001162 switch (arch_host) {
1163 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001164 return patchProfInc_X86(endness_host, place_to_patch,
1165 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001166 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001167 return patchProfInc_AMD64(endness_host, place_to_patch,
1168 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001169 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001170 return patchProfInc_ARM(endness_host, place_to_patch,
1171 location_of_counter);
sewardj0ad37a92014-08-29 21:58:03 +00001172 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001173 return patchProfInc_ARM64(endness_host, place_to_patch,
1174 location_of_counter);
florian8844a632012-04-13 04:04:06 +00001175 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001176 return patchProfInc_S390(endness_host, place_to_patch,
1177 location_of_counter);
sewardj3dee8492012-04-20 00:13:28 +00001178 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001179 return patchProfInc_PPC(endness_host, place_to_patch,
sewardj3dee8492012-04-20 00:13:28 +00001180 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001181 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001182 return patchProfInc_PPC(endness_host, place_to_patch,
sewardjf252de52012-04-20 10:42:24 +00001183 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001184 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001185 return patchProfInc_MIPS(endness_host, place_to_patch,
sewardjd0e5fe72012-06-07 08:51:02 +00001186 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001187 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001188 return patchProfInc_MIPS(endness_host, place_to_patch,
petarjb92a9542013-02-27 22:57:17 +00001189 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001190 default:
1191 vassert(0);
1192 }
sewardjc6f970f2012-04-02 21:54:49 +00001193}
1194
1195
sewardj893aada2004-11-29 19:57:54 +00001196/* --------- Emulation warnings. --------- */
1197
florian1ff47562012-10-21 02:09:51 +00001198const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001199{
1200 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001201 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001202 return "none";
1203 case EmWarn_X86_x87exns:
1204 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001205 case EmWarn_X86_x87precision:
1206 return "Selection of non-80-bit x87 FP precision";
1207 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001208 return "Unmasking SSE FP exceptions";
1209 case EmWarn_X86_fz:
1210 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1211 case EmWarn_X86_daz:
1212 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001213 case EmWarn_X86_acFlag:
1214 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001215 case EmWarn_PPCexns:
1216 return "Unmasking PPC32/64 FP exceptions";
1217 case EmWarn_PPC64_redir_overflow:
1218 return "PPC64 function redirection stack overflow";
1219 case EmWarn_PPC64_redir_underflow:
1220 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001221 case EmWarn_S390X_fpext_rounding:
1222 return "The specified rounding mode cannot be supported. That\n"
1223 " feature requires the floating point extension facility.\n"
1224 " which is not available on this host. Continuing using\n"
1225 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001226 case EmWarn_S390X_invalid_rounding:
1227 return "The specified rounding mode is invalid.\n"
1228 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001229 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001230 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001231 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001232 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001233 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001234 return "Instruction ecag is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001235 case EmFail_S390X_fpext:
1236 return "Encountered an instruction that requires the floating "
1237 "point extension facility.\n"
1238 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001239 case EmFail_S390X_invalid_PFPO_rounding_mode:
1240 return "The rounding mode specified in GPR 0 for PFPO instruction"
1241 " is invalid";
1242 case EmFail_S390X_invalid_PFPO_function:
1243 return "The function code specified in GPR 0 for PFPO instruction"
1244 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001245 default:
florian6ef84be2012-08-26 03:20:07 +00001246 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001247 }
1248}
sewardj35421a32004-07-05 13:12:34 +00001249
sewardj5117ce12006-01-27 21:20:15 +00001250/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001251
1252const HChar* LibVEX_ppVexArch ( VexArch arch )
1253{
1254 switch (arch) {
1255 case VexArch_INVALID: return "INVALID";
1256 case VexArchX86: return "X86";
1257 case VexArchAMD64: return "AMD64";
1258 case VexArchARM: return "ARM";
sewardjbbcf1882014-01-12 12:49:10 +00001259 case VexArchARM64: return "ARM64";
sewardj0ec57c52005-02-01 15:24:10 +00001260 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001261 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001262 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001263 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001264 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001265 default: return "VexArch???";
1266 }
1267}
1268
sewardj9b769162014-07-24 12:42:03 +00001269const HChar* LibVEX_ppVexEndness ( VexEndness endness )
1270{
1271 switch (endness) {
1272 case VexEndness_INVALID: return "INVALID";
1273 case VexEndnessLE: return "LittleEndian";
1274 case VexEndnessBE: return "BigEndian";
1275 default: return "VexEndness???";
1276 }
1277}
1278
sewardj5117ce12006-01-27 21:20:15 +00001279const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001280{
florian55085f82012-11-21 00:36:55 +00001281 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001282 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001283}
1284
sewardj5117ce12006-01-27 21:20:15 +00001285
sewardj27e1dd62005-06-30 11:49:14 +00001286/* Write default settings info *vai. */
1287void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1288{
sewardj65902992014-05-03 21:20:56 +00001289 vex_bzero(vai, sizeof(*vai));
sewardj9b769162014-07-24 12:42:03 +00001290 vai->hwcaps = 0;
1291 vai->endness = VexEndness_INVALID;
1292 vai->ppc_icache_line_szB = 0;
1293 vai->ppc_dcbz_szB = 0;
1294 vai->ppc_dcbzl_szB = 0;
sewardj65902992014-05-03 21:20:56 +00001295 vai->arm64_dMinLine_lg2_szB = 0;
1296 vai->arm64_iMinLine_lg2_szB = 0;
florianf192a392012-10-07 19:44:40 +00001297 vai->hwcache_info.num_levels = 0;
1298 vai->hwcache_info.num_caches = 0;
sewardj65902992014-05-03 21:20:56 +00001299 vai->hwcache_info.caches = NULL;
florianf192a392012-10-07 19:44:40 +00001300 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001301}
1302
sewardjdd40fdf2006-12-24 02:20:24 +00001303/* Write default settings info *vbi. */
1304void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001305{
sewardj65902992014-05-03 21:20:56 +00001306 vex_bzero(vbi, sizeof(*vbi));
sewardjdd40fdf2006-12-24 02:20:24 +00001307 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001308 vbi->guest_amd64_assume_fs_is_zero = False;
1309 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001310 vbi->guest_ppc_zap_RZ_at_blr = False;
1311 vbi->guest_ppc_zap_RZ_at_bl = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +00001312 vbi->host_ppc_calls_use_fndescrs = False;
sewardjaca070a2006-10-17 00:28:22 +00001313}
1314
sewardj27e1dd62005-06-30 11:49:14 +00001315
sewardj5117ce12006-01-27 21:20:15 +00001316/* Return a string showing the hwcaps in a nice way. The string will
1317 be NULL for invalid combinations of flags, so these functions also
1318 serve as a way to validate hwcaps values. */
1319
florian55085f82012-11-21 00:36:55 +00001320static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001321{
mjw6c65c122013-08-27 10:19:03 +00001322 /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001323 switch (hwcaps) {
1324 case 0:
1325 return "x86-sse0";
mjw6c65c122013-08-27 10:19:03 +00001326 case VEX_HWCAPS_X86_MMXEXT:
1327 return "x86-mmxext";
1328 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1329 return "x86-mmxext-sse1";
1330 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1331 return "x86-mmxext-sse1-sse2";
1332 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001333 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001334 return "x86-mmxext-sse1-sse2-lzcnt";
1335 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001336 | VEX_HWCAPS_X86_SSE3:
mjw6c65c122013-08-27 10:19:03 +00001337 return "x86-mmxext-sse1-sse2-sse3";
1338 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001339 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001340 return "x86-mmxext-sse1-sse2-sse3-lzcnt";
sewardj536fbab2010-07-29 15:39:05 +00001341 default:
1342 return NULL;
1343 }
sewardj5117ce12006-01-27 21:20:15 +00001344}
1345
florian55085f82012-11-21 00:36:55 +00001346static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001347{
sewardje9d8a262009-07-01 08:06:34 +00001348 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1349 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001350 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001351 orthogonal. */
1352
1353 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001354 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1355 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001356 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1357 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1358 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001359 if (have_avx && !have_sse3)
1360 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001361 /* AVX2 or BMI without AVX */
1362 if ((have_avx2 || have_bmi) && !have_avx)
1363 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001364
1365 /* This isn't threadsafe. We might need to fix it at some point. */
1366 static HChar buf[100] = { 0 };
1367 if (buf[0] != 0) return buf; /* already constructed */
1368
1369 vex_bzero(buf, sizeof(buf));
1370
1371 HChar* p = &buf[0];
1372
1373 p = p + vex_sprintf(p, "%s", "amd64");
1374 if (hwcaps == 0) {
1375 /* special-case the baseline case */
1376 p = p + vex_sprintf(p, "%s", "-sse2");
1377 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001378 }
sewardj818c7302013-03-26 13:53:18 +00001379 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1380 p = p + vex_sprintf(p, "%s", "-cx16");
1381 }
1382 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1383 p = p + vex_sprintf(p, "%s", "-lzcnt");
1384 }
1385 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1386 p = p + vex_sprintf(p, "%s", "-rdtscp");
1387 }
1388 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1389 p = p + vex_sprintf(p, "%s", "-sse3");
1390 }
1391 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1392 p = p + vex_sprintf(p, "%s", "-avx");
1393 }
sewardjcc3d2192013-03-27 11:37:33 +00001394 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1395 p = p + vex_sprintf(p, "%s", "-avx2");
1396 }
1397 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1398 p = p + vex_sprintf(p, "%s", "-bmi");
1399 }
sewardj818c7302013-03-26 13:53:18 +00001400
1401 out:
1402 vassert(buf[sizeof(buf)-1] == 0);
1403 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001404}
1405
florian55085f82012-11-21 00:36:55 +00001406static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001407{
1408 /* Monotonic with complications. Basically V > F > baseline,
1409 but once you have F then you can have FX or GX too. */
1410 const UInt F = VEX_HWCAPS_PPC32_F;
1411 const UInt V = VEX_HWCAPS_PPC32_V;
1412 const UInt FX = VEX_HWCAPS_PPC32_FX;
1413 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001414 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001415 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
carll0c74bb52013-08-12 18:01:40 +00001416 const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001417 UInt c = hwcaps;
1418 if (c == 0) return "ppc32-int";
1419 if (c == F) return "ppc32-int-flt";
1420 if (c == (F|FX)) return "ppc32-int-flt-FX";
1421 if (c == (F|GX)) return "ppc32-int-flt-GX";
1422 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1423 if (c == (F|V)) return "ppc32-int-flt-vmx";
1424 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1425 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1426 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001427 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1428 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001429 if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1430 return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1431
sewardj5117ce12006-01-27 21:20:15 +00001432 return NULL;
1433}
1434
florian55085f82012-11-21 00:36:55 +00001435static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001436{
1437 /* Monotonic with complications. Basically V > baseline(==F),
1438 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001439 const UInt V = VEX_HWCAPS_PPC64_V;
1440 const UInt FX = VEX_HWCAPS_PPC64_FX;
1441 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001442 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001443 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
carll0c74bb52013-08-12 18:01:40 +00001444 const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001445 UInt c = hwcaps;
1446 if (c == 0) return "ppc64-int-flt";
1447 if (c == FX) return "ppc64-int-flt-FX";
1448 if (c == GX) return "ppc64-int-flt-GX";
1449 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1450 if (c == V) return "ppc64-int-flt-vmx";
1451 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1452 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1453 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001454 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1455 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001456 if (c == (V|FX|GX|VX|DFP|ISA2_07))
1457 return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
sewardj5117ce12006-01-27 21:20:15 +00001458 return NULL;
1459}
1460
florian55085f82012-11-21 00:36:55 +00001461static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001462{
sewardjec0d9a02010-08-22 12:54:56 +00001463 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1464 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1465 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1466 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1467 case 5:
1468 if (N)
1469 return NULL;
1470 if (vfp)
1471 return "ARMv5-vfp";
1472 else
1473 return "ARMv5";
1474 return NULL;
1475 case 6:
1476 if (N)
1477 return NULL;
1478 if (vfp)
1479 return "ARMv6-vfp";
1480 else
1481 return "ARMv6";
1482 return NULL;
1483 case 7:
1484 if (vfp) {
1485 if (N)
1486 return "ARMv7-vfp-neon";
1487 else
1488 return "ARMv7-vfp";
1489 } else {
1490 if (N)
1491 return "ARMv7-neon";
1492 else
1493 return "ARMv7";
1494 }
1495 default:
1496 return NULL;
1497 }
sewardj5117ce12006-01-27 21:20:15 +00001498 return NULL;
1499}
1500
sewardjbbcf1882014-01-12 12:49:10 +00001501static const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1502{
1503 /* Since there are no variants, just insist that hwcaps is zero,
1504 and declare it invalid otherwise. */
1505 if (hwcaps == 0)
1506 return "baseline";
1507 return NULL;
1508}
1509
florian55085f82012-11-21 00:36:55 +00001510static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001511{
sewardjd07b8562011-04-27 11:58:22 +00001512 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001513 static const struct {
1514 UInt hwcaps_bit;
1515 HChar name[6];
1516 } hwcaps_list[] = {
1517 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1518 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1519 { VEX_HWCAPS_S390X_GIE, "gie" },
1520 { VEX_HWCAPS_S390X_DFP, "dfp" },
1521 { VEX_HWCAPS_S390X_FGX, "fgx" },
1522 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1523 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1524 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1525 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1526 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1527 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001528 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001529 };
florian9061eb32012-12-09 17:53:45 +00001530#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1531 static HChar buf[sizeof prefix +
1532 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1533 1]; // '\0'
1534 HChar *p;
1535 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001536
1537 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001538
sewardj652b56a2011-04-13 15:38:17 +00001539 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1540
sewardjd07b8562011-04-27 11:58:22 +00001541 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001542 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1543 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1544 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1545 }
sewardj2019a972011-03-07 16:04:07 +00001546
sewardjd07b8562011-04-27 11:58:22 +00001547 /* If there are no facilities, add "zarch" */
1548 if (hwcaps == 0)
1549 vex_sprintf(p, "-%s", "zarch");
1550
1551 return buf;
sewardj2019a972011-03-07 16:04:07 +00001552}
1553
florian55085f82012-11-21 00:36:55 +00001554static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001555{
dejanjc3fee0d2013-07-25 09:08:03 +00001556 /* MIPS baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001557 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
dejanjc3fee0d2013-07-25 09:08:03 +00001558 /* MIPS baseline with dspr2. */
petarjbc7d6f42013-09-16 18:11:59 +00001559 if (VEX_MIPS_PROC_DSP2(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001560 return "MIPS-baseline-dspr2";
1561 }
1562 /* MIPS baseline with dsp. */
petarjbc7d6f42013-09-16 18:11:59 +00001563 if (VEX_MIPS_PROC_DSP(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001564 return "MIPS-baseline-dsp";
1565 }
1566 return "MIPS-baseline";
1567 }
1568
1569 /* Broadcom baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001570 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
dejanjc3fee0d2013-07-25 09:08:03 +00001571 return "Broadcom-baseline";
1572 }
1573
1574 /* Netlogic baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001575 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
dejanjc3fee0d2013-07-25 09:08:03 +00001576 return "Netlogic-baseline";
1577 }
1578
petarjbc7d6f42013-09-16 18:11:59 +00001579 /* Cavium baseline. */
1580 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1581 return "Cavium-baseline";
1582 }
1583
sewardjd0e5fe72012-06-07 08:51:02 +00001584 return NULL;
1585}
1586
petarjb92a9542013-02-27 22:57:17 +00001587static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1588{
1589 return "mips64-baseline";
1590}
1591
sewardj5117ce12006-01-27 21:20:15 +00001592/* ---- */
florian55085f82012-11-21 00:36:55 +00001593static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001594{
1595 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001596 case VexArchX86: return show_hwcaps_x86(hwcaps);
1597 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1598 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1599 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1600 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardjbbcf1882014-01-12 12:49:10 +00001601 case VexArchARM64: return show_hwcaps_arm64(hwcaps);
sewardjd0e5fe72012-06-07 08:51:02 +00001602 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1603 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001604 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001605 default: return NULL;
1606 }
1607}
1608
1609static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1610{
1611 return show_hwcaps(arch,hwcaps) != NULL;
1612}
1613
1614
sewardj35421a32004-07-05 13:12:34 +00001615/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001616/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001617/*---------------------------------------------------------------*/