blob: bd29019a6b5c7151d715823338cd8f113353830a [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,
sewardjc6f970f2012-04-02 21:54:49 +0000225 void*, void*, void*, void* );
florian1ff47562012-10-21 02:09:51 +0000226 IRExpr* (*specHelper) ( const HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000227 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000228
sewardj9e6491a2005-07-02 19:24:10 +0000229 DisOneInstrFn disInstrFn;
230
sewardjeeac8412004-11-02 00:26:55 +0000231 VexGuestLayout* guest_layout;
sewardjdd40fdf2006-12-24 02:20:24 +0000232 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000233 HInstrArray* vcode;
234 HInstrArray* rcode;
235 Int i, j, k, out_used, guest_sizeB;
sewardj05f5e012014-05-04 10:52:11 +0000236 Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
sewardjc6f970f2012-04-02 21:54:49 +0000237 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000238 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000239 IRType guest_word_type;
240 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000241 Bool mode64, chainingAllowed;
242 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000243
sewardj49651f42004-10-28 22:11:04 +0000244 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000245 available_real_regs = NULL;
246 n_available_real_regs = 0;
247 isMove = NULL;
248 getRegUsage = NULL;
249 mapRegs = NULL;
250 genSpill = NULL;
251 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000252 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000253 ppInstr = NULL;
254 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000255 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000256 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000257 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000258 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000259 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000260 guest_word_type = Ity_INVALID;
261 host_word_type = Ity_INVALID;
sewardj05f5e012014-05-04 10:52:11 +0000262 offB_CMSTART = 0;
263 offB_CMLEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000264 offB_GUEST_IP = 0;
265 szB_GUEST_IP = 0;
266 offB_HOST_EvC_COUNTER = 0;
267 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000268 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000269 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000270
sewardj17c7f952005-12-15 14:02:34 +0000271 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000272
sewardj35421a32004-07-05 13:12:34 +0000273 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000274 vassert(vta->needs_self_check != NULL);
275 vassert(vta->disp_cp_xassisted != NULL);
276 /* Both the chainers and the indir are either NULL or non-NULL. */
277 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
278 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
279 vassert(vta->disp_cp_xindir != NULL);
280 chainingAllowed = True;
281 } else {
282 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
283 vassert(vta->disp_cp_xindir == NULL);
284 }
florian2eeeb9b2011-09-23 18:03:21 +0000285
sewardj2d6b14a2005-11-23 04:25:07 +0000286 vexSetAllocModeTEMP_and_clear();
287 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000288
sewardjf13a16a2004-07-05 17:10:14 +0000289 /* First off, check that the guest and host insn sets
290 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000291
sewardj17c7f952005-12-15 14:02:34 +0000292 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000293
sewardjbef170b2004-12-21 01:23:00 +0000294 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000295 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000296 getAllocableRegs_X86 ( &n_available_real_regs,
297 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000298 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000299 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
300 getRegUsage_X86Instr;
sewardjfb7373a2007-08-25 21:29:03 +0000301 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000302 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
303 genSpill_X86;
304 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
305 genReload_X86;
sewardjfb7373a2007-08-25 21:29:03 +0000306 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
307 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
308 ppReg = (void(*)(HReg)) ppHRegX86;
309 iselSB = iselSB_X86;
sewardj9b769162014-07-24 12:42:03 +0000310 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardjc6f970f2012-04-02 21:54:49 +0000311 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000312 emit_X86Instr;
sewardjcf787902004-11-03 09:08:33 +0000313 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000314 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000315 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjf13a16a2004-07-05 17:10:14 +0000316 break;
sewardj2a9ad022004-11-25 02:46:58 +0000317
sewardjc33671d2005-02-01 20:30:00 +0000318 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000319 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000320 getAllocableRegs_AMD64 ( &n_available_real_regs,
321 &available_real_regs );
322 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000323 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
324 getRegUsage_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000325 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000326 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
327 genSpill_AMD64;
328 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
329 genReload_AMD64;
cerion92b64362005-12-13 12:02:26 +0000330 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000331 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000332 iselSB = iselSB_AMD64;
sewardj9b769162014-07-24 12:42:03 +0000333 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardjc6f970f2012-04-02 21:54:49 +0000334 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000335 emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000336 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000337 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000338 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjc33671d2005-02-01 20:30:00 +0000339 break;
340
cerion487e4c92005-02-04 16:28:19 +0000341 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000342 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000343 getAllocableRegs_PPC ( &n_available_real_regs,
344 &available_real_regs, mode64 );
345 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
346 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
347 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000348 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
349 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000350 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
351 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000352 iselSB = iselSB_PPC;
sewardj9b769162014-07-24 12:42:03 +0000353 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardj3dee8492012-04-20 00:13:28 +0000354 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000355 emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000356 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000357 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000358 vassert(vta->archinfo_host.endness == VexEndnessBE);
cerion487e4c92005-02-04 16:28:19 +0000359 break;
360
cerionf0de28c2005-12-13 20:21:11 +0000361 case VexArchPPC64:
362 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000363 getAllocableRegs_PPC ( &n_available_real_regs,
364 &available_real_regs, mode64 );
365 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
366 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
367 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000368 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
369 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000370 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
371 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000372 iselSB = iselSB_PPC;
sewardj9b769162014-07-24 12:42:03 +0000373 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardj9e1cf152012-04-20 02:18:31 +0000374 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000375 emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000376 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000377 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000378 vassert(vta->archinfo_host.endness == VexEndnessBE ||
379 vta->archinfo_host.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000380 break;
381
sewardj2019a972011-03-07 16:04:07 +0000382 case VexArchS390X:
383 mode64 = True;
384 getAllocableRegs_S390 ( &n_available_real_regs,
385 &available_real_regs, mode64 );
386 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
387 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
388 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
389 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
390 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
391 ppInstr = (void(*)(HInstr*, Bool)) ppS390Instr;
392 ppReg = (void(*)(HReg)) ppHRegS390;
393 iselSB = iselSB_S390;
sewardj9b769162014-07-24 12:42:03 +0000394 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
florian8844a632012-04-13 04:04:06 +0000395 void*,void*,void*,void*)) emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000396 host_word_type = Ity_I64;
397 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000398 vassert(vta->archinfo_host.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000399 break;
400
sewardj6c299f32009-12-31 18:00:12 +0000401 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000402 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000403 getAllocableRegs_ARM ( &n_available_real_regs,
404 &available_real_regs );
sewardj2a1ed8e2009-12-31 19:26:03 +0000405 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
406 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
407 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
408 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
409 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
410 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
411 ppReg = (void(*)(HReg)) ppHRegARM;
412 iselSB = iselSB_ARM;
sewardj9b769162014-07-24 12:42:03 +0000413 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardjc6f970f2012-04-02 21:54:49 +0000414 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000415 emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000416 host_word_type = Ity_I32;
417 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000418 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000419 break;
420
sewardjbbcf1882014-01-12 12:49:10 +0000421 case VexArchARM64:
422 mode64 = True;
423 getAllocableRegs_ARM64 ( &n_available_real_regs,
424 &available_real_regs );
425 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARM64Instr;
426 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
427 getRegUsage_ARM64Instr;
428 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool))
429 mapRegs_ARM64Instr;
430 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
431 genSpill_ARM64;
432 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
433 genReload_ARM64;
434 ppInstr = (void(*)(HInstr*, Bool)) ppARM64Instr;
435 ppReg = (void(*)(HReg)) ppHRegARM64;
436 iselSB = iselSB_ARM64;
sewardj9b769162014-07-24 12:42:03 +0000437 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardjbbcf1882014-01-12 12:49:10 +0000438 void*,void*,void*,void*))
439 emit_ARM64Instr;
sewardjbbcf1882014-01-12 12:49:10 +0000440 host_word_type = Ity_I64;
441 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000442 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000443 break;
444
sewardjd0e5fe72012-06-07 08:51:02 +0000445 case VexArchMIPS32:
446 mode64 = False;
447 getAllocableRegs_MIPS ( &n_available_real_regs,
448 &available_real_regs, mode64 );
449 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
450 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
451 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
452 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
453 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
454 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
455 ppReg = (void(*)(HReg)) ppHRegMIPS;
456 iselSB = iselSB_MIPS;
sewardj9b769162014-07-24 12:42:03 +0000457 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
sewardjd0e5fe72012-06-07 08:51:02 +0000458 void*,void*,void*,void*))
459 emit_MIPSInstr;
sewardjd0e5fe72012-06-07 08:51:02 +0000460 host_word_type = Ity_I32;
461 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000462 vassert(vta->archinfo_host.endness == VexEndnessLE
463 || vta->archinfo_host.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000464 break;
465
petarjb92a9542013-02-27 22:57:17 +0000466 case VexArchMIPS64:
467 mode64 = True;
468 getAllocableRegs_MIPS ( &n_available_real_regs,
469 &available_real_regs, mode64 );
470 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
471 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
472 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
473 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
474 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
475 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
476 ppReg = (void(*)(HReg)) ppHRegMIPS;
477 iselSB = iselSB_MIPS;
sewardj9b769162014-07-24 12:42:03 +0000478 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,VexEndness,
petarjb92a9542013-02-27 22:57:17 +0000479 void*,void*,void*,void*))
480 emit_MIPSInstr;
petarjb92a9542013-02-27 22:57:17 +0000481 host_word_type = Ity_I64;
482 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000483 vassert(vta->archinfo_host.endness == VexEndnessLE
484 || vta->archinfo_host.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000485 break;
486
sewardjf13a16a2004-07-05 17:10:14 +0000487 default:
sewardj6c299f32009-12-31 18:00:12 +0000488 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000489 }
490
sewardj2a9ad022004-11-25 02:46:58 +0000491
sewardj17c7f952005-12-15 14:02:34 +0000492 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000493
sewardjbef170b2004-12-21 01:23:00 +0000494 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000495 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
496 disInstrFn = disInstr_X86;
497 specHelper = guest_x86_spechelper;
498 guest_sizeB = sizeof(VexGuestX86State);
499 guest_word_type = Ity_I32;
500 guest_layout = &x86guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000501 offB_CMSTART = offsetof(VexGuestX86State,guest_CMSTART);
502 offB_CMLEN = offsetof(VexGuestX86State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000503 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
504 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
505 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
506 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000507 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000508 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000509 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000510 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
511 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000512 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000513 break;
sewardj2a9ad022004-11-25 02:46:58 +0000514
sewardj44d494d2005-01-20 20:26:33 +0000515 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000516 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
517 disInstrFn = disInstr_AMD64;
518 specHelper = guest_amd64_spechelper;
519 guest_sizeB = sizeof(VexGuestAMD64State);
520 guest_word_type = Ity_I64;
521 guest_layout = &amd64guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000522 offB_CMSTART = offsetof(VexGuestAMD64State,guest_CMSTART);
523 offB_CMLEN = offsetof(VexGuestAMD64State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000524 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
525 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
526 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
527 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000528 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000529 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000530 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000531 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
532 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000533 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000534 break;
535
cerionaabdfbf2005-01-29 12:56:15 +0000536 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000537 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
538 disInstrFn = disInstr_PPC;
539 specHelper = guest_ppc32_spechelper;
540 guest_sizeB = sizeof(VexGuestPPC32State);
541 guest_word_type = Ity_I32;
542 guest_layout = &ppc32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000543 offB_CMSTART = offsetof(VexGuestPPC32State,guest_CMSTART);
544 offB_CMLEN = offsetof(VexGuestPPC32State,guest_CMLEN);
sewardj3dee8492012-04-20 00:13:28 +0000545 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
546 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
547 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
548 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000549 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000550 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj6c299f32009-12-31 18:00:12 +0000551 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000552 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
553 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000554 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000555 break;
556
cerionf0de28c2005-12-13 20:21:11 +0000557 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000558 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
559 disInstrFn = disInstr_PPC;
560 specHelper = guest_ppc64_spechelper;
561 guest_sizeB = sizeof(VexGuestPPC64State);
562 guest_word_type = Ity_I64;
563 guest_layout = &ppc64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000564 offB_CMSTART = offsetof(VexGuestPPC64State,guest_CMSTART);
565 offB_CMLEN = offsetof(VexGuestPPC64State,guest_CMLEN);
sewardj9e1cf152012-04-20 02:18:31 +0000566 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
567 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
568 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
569 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000570 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000571 vassert(vta->archinfo_guest.endness == VexEndnessBE ||
572 vta->archinfo_guest.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000573 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000574 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART ) == 8);
575 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN ) == 8);
sewardj3fd39672006-01-27 22:05:55 +0000576 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
577 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000578 break;
579
sewardj2019a972011-03-07 16:04:07 +0000580 case VexArchS390X:
581 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
582 disInstrFn = disInstr_S390;
583 specHelper = guest_s390x_spechelper;
584 guest_sizeB = sizeof(VexGuestS390XState);
585 guest_word_type = Ity_I64;
586 guest_layout = &s390xGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000587 offB_CMSTART = offsetof(VexGuestS390XState,guest_CMSTART);
588 offB_CMLEN = offsetof(VexGuestS390XState,guest_CMLEN);
florian8844a632012-04-13 04:04:06 +0000589 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
590 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
591 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
592 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000593 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000594 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000595 vassert(0 == sizeof(VexGuestS390XState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000596 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART ) == 8);
597 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN ) == 8);
sewardj2019a972011-03-07 16:04:07 +0000598 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
599 break;
600
sewardj6c299f32009-12-31 18:00:12 +0000601 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000602 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
603 disInstrFn = disInstr_ARM;
604 specHelper = guest_arm_spechelper;
605 guest_sizeB = sizeof(VexGuestARMState);
606 guest_word_type = Ity_I32;
607 guest_layout = &armGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000608 offB_CMSTART = offsetof(VexGuestARMState,guest_CMSTART);
609 offB_CMLEN = offsetof(VexGuestARMState,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000610 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
611 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
612 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
613 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000614 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000615 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000616 vassert(0 == sizeof(VexGuestARMState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000617 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
618 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN ) == 4);
sewardj6c299f32009-12-31 18:00:12 +0000619 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
620 break;
621
sewardjbbcf1882014-01-12 12:49:10 +0000622 case VexArchARM64:
623 preciseMemExnsFn = guest_arm64_state_requires_precise_mem_exns;
624 disInstrFn = disInstr_ARM64;
625 specHelper = guest_arm64_spechelper;
626 guest_sizeB = sizeof(VexGuestARM64State);
627 guest_word_type = Ity_I64;
628 guest_layout = &arm64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000629 offB_CMSTART = offsetof(VexGuestARM64State,guest_CMSTART);
630 offB_CMLEN = offsetof(VexGuestARM64State,guest_CMLEN);
sewardjbbcf1882014-01-12 12:49:10 +0000631 offB_GUEST_IP = offsetof(VexGuestARM64State,guest_PC);
632 szB_GUEST_IP = sizeof( ((VexGuestARM64State*)0)->guest_PC );
633 offB_HOST_EvC_COUNTER = offsetof(VexGuestARM64State,host_EvC_COUNTER);
634 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
635 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000636 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000637 vassert(0 == sizeof(VexGuestARM64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000638 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
639 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN ) == 8);
sewardjbbcf1882014-01-12 12:49:10 +0000640 vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
641 break;
642
sewardjd0e5fe72012-06-07 08:51:02 +0000643 case VexArchMIPS32:
644 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
645 disInstrFn = disInstr_MIPS;
646 specHelper = guest_mips32_spechelper;
647 guest_sizeB = sizeof(VexGuestMIPS32State);
648 guest_word_type = Ity_I32;
649 guest_layout = &mips32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000650 offB_CMSTART = offsetof(VexGuestMIPS32State,guest_CMSTART);
651 offB_CMLEN = offsetof(VexGuestMIPS32State,guest_CMLEN);
sewardjd0e5fe72012-06-07 08:51:02 +0000652 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
653 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
654 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
655 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
656 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000657 vassert(vta->archinfo_guest.endness == VexEndnessLE
658 || vta->archinfo_guest.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000659 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000660 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
661 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN ) == 4);
sewardjd0e5fe72012-06-07 08:51:02 +0000662 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
663 break;
664
petarjb92a9542013-02-27 22:57:17 +0000665 case VexArchMIPS64:
666 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
667 disInstrFn = disInstr_MIPS;
668 specHelper = guest_mips64_spechelper;
669 guest_sizeB = sizeof(VexGuestMIPS64State);
670 guest_word_type = Ity_I64;
671 guest_layout = &mips64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000672 offB_CMSTART = offsetof(VexGuestMIPS64State,guest_CMSTART);
673 offB_CMLEN = offsetof(VexGuestMIPS64State,guest_CMLEN);
petarjb92a9542013-02-27 22:57:17 +0000674 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
675 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
676 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
677 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
678 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000679 vassert(vta->archinfo_guest.endness == VexEndnessLE
680 || vta->archinfo_guest.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000681 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000682 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
683 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN ) == 8);
petarjb92a9542013-02-27 22:57:17 +0000684 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
685 break;
686
sewardjf13a16a2004-07-05 17:10:14 +0000687 default:
sewardj887a11a2004-07-05 17:26:47 +0000688 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000689 }
690
sewardjbc161a42011-06-07 21:28:38 +0000691 /* Set up result struct. */
692 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000693 res.status = VexTransOK;
694 res.n_sc_extents = 0;
695 res.offs_profInc = -1;
696 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000697
sewardj9df271d2004-12-31 22:37:42 +0000698 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000699 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000700 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000701 we are simulating one flavour of an architecture a different
702 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000703 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9b769162014-07-24 12:42:03 +0000704 /* ditto */
705 vassert(vta->archinfo_guest.endness == vta->archinfo_host.endness);
sewardj9df271d2004-12-31 22:37:42 +0000706 }
sewardj2a9ad022004-11-25 02:46:58 +0000707
sewardj2d6b14a2005-11-23 04:25:07 +0000708 vexAllocSanityCheck();
709
sewardjf48ac192004-10-29 00:41:29 +0000710 if (vex_traceflags & VEX_TRACE_FE)
711 vex_printf("\n------------------------"
712 " Front end "
713 "------------------------\n\n");
714
sewardjdd40fdf2006-12-24 02:20:24 +0000715 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000716 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000717 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000718 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000719 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000720 vta->guest_bytes,
721 vta->guest_bytes_addr,
722 vta->chase_into_ok,
sewardj9b769162014-07-24 12:42:03 +0000723 vta->archinfo_host.endness,
sewardj442e51a2012-12-06 18:08:04 +0000724 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000725 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000726 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000727 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000728 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000729 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000730 vta->preamble_function,
sewardj05f5e012014-05-04 10:52:11 +0000731 offB_CMSTART,
732 offB_CMLEN,
sewardjc6f970f2012-04-02 21:54:49 +0000733 offB_GUEST_IP,
734 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000735
sewardj2d6b14a2005-11-23 04:25:07 +0000736 vexAllocSanityCheck();
737
sewardjdd40fdf2006-12-24 02:20:24 +0000738 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000739 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000740 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000741 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000742 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000743 }
sewardjaa59f942004-10-09 09:34:36 +0000744
sewardj17c7f952005-12-15 14:02:34 +0000745 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
746 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
747 for (i = 0; i < vta->guest_extents->n_used; i++) {
748 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000749 }
750
sewardjaa59f942004-10-09 09:34:36 +0000751 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000752 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000753 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000754 vex_printf("can't show code due to extents > 1\n");
755 } else {
756 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000757 UChar* p = (UChar*)vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000758 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000759 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000760 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
761 guest_bytes_read );
762 for (i = 0; i < guest_bytes_read; i++) {
763 UInt b = (UInt)p[i];
764 vex_printf(" %02x", b );
765 sum = (sum << 1) ^ b;
766 }
767 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000768 }
sewardjaa59f942004-10-09 09:34:36 +0000769 }
770
771 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000772 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000773 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000774
sewardj2d6b14a2005-11-23 04:25:07 +0000775 vexAllocSanityCheck();
776
sewardjedf4d692004-08-17 13:52:58 +0000777 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000778 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000779 vta->guest_bytes_addr,
780 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000781 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000782 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000783
sewardjf48ac192004-10-29 00:41:29 +0000784 if (vex_traceflags & VEX_TRACE_OPT1) {
785 vex_printf("\n------------------------"
786 " After pre-instr IR optimisation "
787 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000788 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000789 vex_printf("\n");
790 }
791
sewardj2d6b14a2005-11-23 04:25:07 +0000792 vexAllocSanityCheck();
793
sewardjf13a16a2004-07-05 17:10:14 +0000794 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000795 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000796 irsb = vta->instrument1(vta->callback_opaque,
797 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000798 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000799 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000800 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000801 vexAllocSanityCheck();
802
sewardj17c7f952005-12-15 14:02:34 +0000803 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000804 irsb = vta->instrument2(vta->callback_opaque,
805 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000806 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000807 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000808 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000809
sewardjf48ac192004-10-29 00:41:29 +0000810 if (vex_traceflags & VEX_TRACE_INST) {
811 vex_printf("\n------------------------"
812 " After instrumentation "
813 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000814 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000815 vex_printf("\n");
816 }
817
sewardj17c7f952005-12-15 14:02:34 +0000818 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000819 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000820 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000821
sewardj9578a8b2004-11-04 19:44:48 +0000822 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000823 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000824 do_deadcode_BB( irsb );
825 irsb = cprop_BB( irsb );
826 do_deadcode_BB( irsb );
827 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000828 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000829 }
830
sewardj2d6b14a2005-11-23 04:25:07 +0000831 vexAllocSanityCheck();
832
sewardj9578a8b2004-11-04 19:44:48 +0000833 if (vex_traceflags & VEX_TRACE_OPT2) {
834 vex_printf("\n------------------------"
835 " After post-instr IR optimisation "
836 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000837 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000838 vex_printf("\n");
839 }
840
sewardjf9517d02005-11-28 13:39:37 +0000841 /* Turn it into virtual-registerised code. Build trees -- this
842 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000843 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000844
sewardjbe1b6ff2007-08-28 06:06:27 +0000845 if (vta->finaltidy) {
846 irsb = vta->finaltidy(irsb);
847 }
848
sewardj2d6b14a2005-11-23 04:25:07 +0000849 vexAllocSanityCheck();
850
sewardjf48ac192004-10-29 00:41:29 +0000851 if (vex_traceflags & VEX_TRACE_TREES) {
852 vex_printf("\n------------------------"
853 " After tree-building "
854 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000855 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000856 vex_printf("\n");
857 }
858
sewardje908c422005-02-04 21:18:16 +0000859 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000860 if (0) {
861 *(vta->host_bytes_used) = 0;
862 res.status = VexTransOK; return res;
863 }
sewardje908c422005-02-04 21:18:16 +0000864 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000865
sewardjf48ac192004-10-29 00:41:29 +0000866 if (vex_traceflags & VEX_TRACE_VCODE)
867 vex_printf("\n------------------------"
868 " Instruction selection "
869 "------------------------\n");
870
sewardjc6f970f2012-04-02 21:54:49 +0000871 /* No guest has its IP field at offset zero. If this fails it
872 means some transformation pass somewhere failed to update/copy
873 irsb->offsIP properly. */
874 vassert(irsb->offsIP >= 16);
875
876 vcode = iselSB ( irsb, vta->arch_host,
877 &vta->archinfo_host,
878 &vta->abiinfo_both,
879 offB_HOST_EvC_COUNTER,
880 offB_HOST_EvC_FAILADDR,
881 chainingAllowed,
882 vta->addProfInc,
883 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000884
sewardj2d6b14a2005-11-23 04:25:07 +0000885 vexAllocSanityCheck();
886
sewardjf48ac192004-10-29 00:41:29 +0000887 if (vex_traceflags & VEX_TRACE_VCODE)
888 vex_printf("\n");
889
sewardjf48ac192004-10-29 00:41:29 +0000890 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000891 for (i = 0; i < vcode->arr_used; i++) {
892 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000893 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000894 vex_printf("\n");
895 }
sewardjfbcaf332004-07-08 01:46:01 +0000896 vex_printf("\n");
897 }
sewardjfbcaf332004-07-08 01:46:01 +0000898
sewardjf13a16a2004-07-05 17:10:14 +0000899 /* Register allocate. */
900 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000901 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000902 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000903 genSpill, genReload, directReload,
904 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000905 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000906
sewardj2d6b14a2005-11-23 04:25:07 +0000907 vexAllocSanityCheck();
908
sewardjf48ac192004-10-29 00:41:29 +0000909 if (vex_traceflags & VEX_TRACE_RCODE) {
910 vex_printf("\n------------------------"
911 " Register-allocated code "
912 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000913 for (i = 0; i < rcode->arr_used; i++) {
914 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000915 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000916 vex_printf("\n");
917 }
sewardjfbcaf332004-07-08 01:46:01 +0000918 vex_printf("\n");
919 }
sewardjfbcaf332004-07-08 01:46:01 +0000920
sewardje908c422005-02-04 21:18:16 +0000921 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000922 if (0) {
923 *(vta->host_bytes_used) = 0;
924 res.status = VexTransOK; return res;
925 }
sewardje908c422005-02-04 21:18:16 +0000926 /* end HACK */
927
sewardj81bd5502004-07-21 18:49:27 +0000928 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000929 if (vex_traceflags & VEX_TRACE_ASM) {
930 vex_printf("\n------------------------"
931 " Assembly "
932 "------------------------\n\n");
933 }
934
sewardj81bd5502004-07-21 18:49:27 +0000935 out_used = 0; /* tracks along the host_bytes array */
936 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000937 HInstr* hi = rcode->arr[i];
938 Bool hi_isProfInc = False;
939 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
940 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000941 vex_printf("\n");
942 }
sewardjc6f970f2012-04-02 21:54:49 +0000943 j = emit( &hi_isProfInc,
sewardj9b769162014-07-24 12:42:03 +0000944 insn_bytes, sizeof insn_bytes, hi,
945 mode64, vta->archinfo_host.endness,
sewardjc6f970f2012-04-02 21:54:49 +0000946 vta->disp_cp_chain_me_to_slowEP,
947 vta->disp_cp_chain_me_to_fastEP,
948 vta->disp_cp_xindir,
949 vta->disp_cp_xassisted );
950 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000951 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000952 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000953 vex_printf("0%x ", (UInt)insn_bytes[k]);
954 else
955 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000956 vex_printf("\n\n");
957 }
sewardjc6f970f2012-04-02 21:54:49 +0000958 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000959 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000960 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000961 res.status = VexTransOutputFull;
962 return res;
sewardj81bd5502004-07-21 18:49:27 +0000963 }
sewardjc6f970f2012-04-02 21:54:49 +0000964 if (UNLIKELY(hi_isProfInc)) {
965 vassert(vta->addProfInc); /* else where did it come from? */
966 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
967 vassert(out_used >= 0);
968 res.offs_profInc = out_used;
969 }
970 { UChar* dst = &vta->host_bytes[out_used];
971 for (k = 0; k < j; k++) {
972 dst[k] = insn_bytes[k];
973 }
974 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000975 }
sewardj17c7f952005-12-15 14:02:34 +0000976 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000977 }
sewardj17c7f952005-12-15 14:02:34 +0000978 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000979
sewardj2d6b14a2005-11-23 04:25:07 +0000980 vexAllocSanityCheck();
981
982 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000983
sewardj65ea17e2012-12-28 09:01:59 +0000984 if (vex_traceflags) {
985 /* Print the expansion ratio for this SB. */
986 j = 0; /* total guest bytes */
987 for (i = 0; i < vta->guest_extents->n_used; i++) {
988 j += vta->guest_extents->len[i];
989 }
990 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
991 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
992 }
993
sewardjf48ac192004-10-29 00:41:29 +0000994 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000995 res.status = VexTransOK;
996 return res;
sewardj35421a32004-07-05 13:12:34 +0000997}
998
999
sewardjc6f970f2012-04-02 21:54:49 +00001000/* --------- Chain/Unchain XDirects. --------- */
1001
florian7d6f81d2014-09-22 21:43:37 +00001002VexInvalRange LibVEX_Chain ( VexArch arch_host,
1003 VexEndness endness_host,
1004 void* place_to_chain,
1005 const void* disp_cp_chain_me_EXPECTED,
1006 const void* place_to_jump_to )
sewardjc6f970f2012-04-02 21:54:49 +00001007{
sewardjc6f970f2012-04-02 21:54:49 +00001008 switch (arch_host) {
1009 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001010 return chainXDirect_X86(endness_host,
1011 place_to_chain,
1012 disp_cp_chain_me_EXPECTED,
1013 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +00001014 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001015 return chainXDirect_AMD64(endness_host,
1016 place_to_chain,
1017 disp_cp_chain_me_EXPECTED,
1018 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +00001019 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001020 return chainXDirect_ARM(endness_host,
1021 place_to_chain,
1022 disp_cp_chain_me_EXPECTED,
1023 place_to_jump_to);
sewardjbbcf1882014-01-12 12:49:10 +00001024 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001025 return chainXDirect_ARM64(endness_host,
1026 place_to_chain,
1027 disp_cp_chain_me_EXPECTED,
1028 place_to_jump_to);
florian8844a632012-04-13 04:04:06 +00001029 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001030 return chainXDirect_S390(endness_host,
1031 place_to_chain,
1032 disp_cp_chain_me_EXPECTED,
1033 place_to_jump_to);
sewardj3dee8492012-04-20 00:13:28 +00001034 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001035 return chainXDirect_PPC(endness_host,
1036 place_to_chain,
sewardj3dee8492012-04-20 00:13:28 +00001037 disp_cp_chain_me_EXPECTED,
1038 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001039 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001040 return chainXDirect_PPC(endness_host,
1041 place_to_chain,
sewardjf252de52012-04-20 10:42:24 +00001042 disp_cp_chain_me_EXPECTED,
1043 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001044 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001045 return chainXDirect_MIPS(endness_host,
1046 place_to_chain,
sewardjd0e5fe72012-06-07 08:51:02 +00001047 disp_cp_chain_me_EXPECTED,
1048 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001049 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001050 return chainXDirect_MIPS(endness_host,
1051 place_to_chain,
petarjb92a9542013-02-27 22:57:17 +00001052 disp_cp_chain_me_EXPECTED,
1053 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001054 default:
1055 vassert(0);
1056 }
sewardjc6f970f2012-04-02 21:54:49 +00001057}
1058
florian7d6f81d2014-09-22 21:43:37 +00001059VexInvalRange LibVEX_UnChain ( VexArch arch_host,
1060 VexEndness endness_host,
1061 void* place_to_unchain,
1062 const void* place_to_jump_to_EXPECTED,
1063 const void* disp_cp_chain_me )
sewardjc6f970f2012-04-02 21:54:49 +00001064{
sewardjc6f970f2012-04-02 21:54:49 +00001065 switch (arch_host) {
1066 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001067 return unchainXDirect_X86(endness_host,
1068 place_to_unchain,
1069 place_to_jump_to_EXPECTED,
1070 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001071 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001072 return unchainXDirect_AMD64(endness_host,
1073 place_to_unchain,
1074 place_to_jump_to_EXPECTED,
1075 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001076 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001077 return unchainXDirect_ARM(endness_host,
1078 place_to_unchain,
1079 place_to_jump_to_EXPECTED,
1080 disp_cp_chain_me);
sewardjc6acaa42014-02-19 17:42:59 +00001081 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001082 return unchainXDirect_ARM64(endness_host,
1083 place_to_unchain,
1084 place_to_jump_to_EXPECTED,
1085 disp_cp_chain_me);
florian8844a632012-04-13 04:04:06 +00001086 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001087 return unchainXDirect_S390(endness_host,
1088 place_to_unchain,
1089 place_to_jump_to_EXPECTED,
1090 disp_cp_chain_me);
sewardj3dee8492012-04-20 00:13:28 +00001091 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001092 return unchainXDirect_PPC(endness_host,
1093 place_to_unchain,
sewardj3dee8492012-04-20 00:13:28 +00001094 place_to_jump_to_EXPECTED,
1095 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001096 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001097 return unchainXDirect_PPC(endness_host,
1098 place_to_unchain,
sewardjf252de52012-04-20 10:42:24 +00001099 place_to_jump_to_EXPECTED,
1100 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001101 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001102 return unchainXDirect_MIPS(endness_host,
1103 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001104 place_to_jump_to_EXPECTED,
1105 disp_cp_chain_me, False/*!mode64*/);
1106 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001107 return unchainXDirect_MIPS(endness_host,
1108 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001109 place_to_jump_to_EXPECTED,
1110 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001111 default:
1112 vassert(0);
1113 }
sewardjc6f970f2012-04-02 21:54:49 +00001114}
1115
sewardj9b769162014-07-24 12:42:03 +00001116Int LibVEX_evCheckSzB ( VexArch arch_host,
1117 VexEndness endness_host )
sewardjc6f970f2012-04-02 21:54:49 +00001118{
1119 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1120 if (UNLIKELY(cached == 0)) {
1121 switch (arch_host) {
1122 case VexArchX86:
sewardj9b769162014-07-24 12:42:03 +00001123 cached = evCheckSzB_X86(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001124 case VexArchAMD64:
sewardj9b769162014-07-24 12:42:03 +00001125 cached = evCheckSzB_AMD64(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001126 case VexArchARM:
sewardj9b769162014-07-24 12:42:03 +00001127 cached = evCheckSzB_ARM(endness_host); break;
sewardjbbcf1882014-01-12 12:49:10 +00001128 case VexArchARM64:
sewardj9b769162014-07-24 12:42:03 +00001129 cached = evCheckSzB_ARM64(endness_host); break;
florian8844a632012-04-13 04:04:06 +00001130 case VexArchS390X:
sewardj9b769162014-07-24 12:42:03 +00001131 cached = evCheckSzB_S390(endness_host); break;
sewardj3dee8492012-04-20 00:13:28 +00001132 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001133 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001134 cached = evCheckSzB_PPC(endness_host); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001135 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001136 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001137 cached = evCheckSzB_MIPS(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001138 default:
1139 vassert(0);
1140 }
1141 }
1142 return cached;
1143}
1144
sewardj9b769162014-07-24 12:42:03 +00001145VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1146 VexEndness endness_host,
1147 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001148 const ULong* location_of_counter )
sewardjc6f970f2012-04-02 21:54:49 +00001149{
sewardjc6f970f2012-04-02 21:54:49 +00001150 switch (arch_host) {
1151 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001152 return patchProfInc_X86(endness_host, place_to_patch,
1153 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001154 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001155 return patchProfInc_AMD64(endness_host, place_to_patch,
1156 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001157 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001158 return patchProfInc_ARM(endness_host, place_to_patch,
1159 location_of_counter);
sewardj0ad37a92014-08-29 21:58:03 +00001160 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001161 return patchProfInc_ARM64(endness_host, place_to_patch,
1162 location_of_counter);
florian8844a632012-04-13 04:04:06 +00001163 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001164 return patchProfInc_S390(endness_host, place_to_patch,
1165 location_of_counter);
sewardj3dee8492012-04-20 00:13:28 +00001166 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001167 return patchProfInc_PPC(endness_host, place_to_patch,
sewardj3dee8492012-04-20 00:13:28 +00001168 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001169 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001170 return patchProfInc_PPC(endness_host, place_to_patch,
sewardjf252de52012-04-20 10:42:24 +00001171 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001172 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001173 return patchProfInc_MIPS(endness_host, place_to_patch,
sewardjd0e5fe72012-06-07 08:51:02 +00001174 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001175 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001176 return patchProfInc_MIPS(endness_host, place_to_patch,
petarjb92a9542013-02-27 22:57:17 +00001177 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001178 default:
1179 vassert(0);
1180 }
sewardjc6f970f2012-04-02 21:54:49 +00001181}
1182
1183
sewardj893aada2004-11-29 19:57:54 +00001184/* --------- Emulation warnings. --------- */
1185
florian1ff47562012-10-21 02:09:51 +00001186const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001187{
1188 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001189 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001190 return "none";
1191 case EmWarn_X86_x87exns:
1192 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001193 case EmWarn_X86_x87precision:
1194 return "Selection of non-80-bit x87 FP precision";
1195 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001196 return "Unmasking SSE FP exceptions";
1197 case EmWarn_X86_fz:
1198 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1199 case EmWarn_X86_daz:
1200 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001201 case EmWarn_X86_acFlag:
1202 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001203 case EmWarn_PPCexns:
1204 return "Unmasking PPC32/64 FP exceptions";
1205 case EmWarn_PPC64_redir_overflow:
1206 return "PPC64 function redirection stack overflow";
1207 case EmWarn_PPC64_redir_underflow:
1208 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001209 case EmWarn_S390X_fpext_rounding:
1210 return "The specified rounding mode cannot be supported. That\n"
1211 " feature requires the floating point extension facility.\n"
1212 " which is not available on this host. Continuing using\n"
1213 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001214 case EmWarn_S390X_invalid_rounding:
1215 return "The specified rounding mode is invalid.\n"
1216 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001217 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001218 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001219 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001220 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001221 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001222 return "Instruction ecag is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001223 case EmFail_S390X_fpext:
1224 return "Encountered an instruction that requires the floating "
1225 "point extension facility.\n"
1226 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001227 case EmFail_S390X_invalid_PFPO_rounding_mode:
1228 return "The rounding mode specified in GPR 0 for PFPO instruction"
1229 " is invalid";
1230 case EmFail_S390X_invalid_PFPO_function:
1231 return "The function code specified in GPR 0 for PFPO instruction"
1232 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001233 default:
florian6ef84be2012-08-26 03:20:07 +00001234 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001235 }
1236}
sewardj35421a32004-07-05 13:12:34 +00001237
sewardj5117ce12006-01-27 21:20:15 +00001238/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001239
1240const HChar* LibVEX_ppVexArch ( VexArch arch )
1241{
1242 switch (arch) {
1243 case VexArch_INVALID: return "INVALID";
1244 case VexArchX86: return "X86";
1245 case VexArchAMD64: return "AMD64";
1246 case VexArchARM: return "ARM";
sewardjbbcf1882014-01-12 12:49:10 +00001247 case VexArchARM64: return "ARM64";
sewardj0ec57c52005-02-01 15:24:10 +00001248 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001249 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001250 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001251 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001252 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001253 default: return "VexArch???";
1254 }
1255}
1256
sewardj9b769162014-07-24 12:42:03 +00001257const HChar* LibVEX_ppVexEndness ( VexEndness endness )
1258{
1259 switch (endness) {
1260 case VexEndness_INVALID: return "INVALID";
1261 case VexEndnessLE: return "LittleEndian";
1262 case VexEndnessBE: return "BigEndian";
1263 default: return "VexEndness???";
1264 }
1265}
1266
sewardj5117ce12006-01-27 21:20:15 +00001267const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001268{
florian55085f82012-11-21 00:36:55 +00001269 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001270 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001271}
1272
sewardj5117ce12006-01-27 21:20:15 +00001273
sewardj27e1dd62005-06-30 11:49:14 +00001274/* Write default settings info *vai. */
1275void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1276{
sewardj65902992014-05-03 21:20:56 +00001277 vex_bzero(vai, sizeof(*vai));
sewardj9b769162014-07-24 12:42:03 +00001278 vai->hwcaps = 0;
1279 vai->endness = VexEndness_INVALID;
1280 vai->ppc_icache_line_szB = 0;
1281 vai->ppc_dcbz_szB = 0;
1282 vai->ppc_dcbzl_szB = 0;
sewardj65902992014-05-03 21:20:56 +00001283 vai->arm64_dMinLine_lg2_szB = 0;
1284 vai->arm64_iMinLine_lg2_szB = 0;
florianf192a392012-10-07 19:44:40 +00001285 vai->hwcache_info.num_levels = 0;
1286 vai->hwcache_info.num_caches = 0;
sewardj65902992014-05-03 21:20:56 +00001287 vai->hwcache_info.caches = NULL;
florianf192a392012-10-07 19:44:40 +00001288 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001289}
1290
sewardjdd40fdf2006-12-24 02:20:24 +00001291/* Write default settings info *vbi. */
1292void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001293{
sewardj65902992014-05-03 21:20:56 +00001294 vex_bzero(vbi, sizeof(*vbi));
sewardjdd40fdf2006-12-24 02:20:24 +00001295 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001296 vbi->guest_amd64_assume_fs_is_zero = False;
1297 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001298 vbi->guest_ppc_zap_RZ_at_blr = False;
1299 vbi->guest_ppc_zap_RZ_at_bl = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +00001300 vbi->host_ppc_calls_use_fndescrs = False;
sewardjaca070a2006-10-17 00:28:22 +00001301}
1302
sewardj27e1dd62005-06-30 11:49:14 +00001303
sewardj5117ce12006-01-27 21:20:15 +00001304/* Return a string showing the hwcaps in a nice way. The string will
1305 be NULL for invalid combinations of flags, so these functions also
1306 serve as a way to validate hwcaps values. */
1307
florian55085f82012-11-21 00:36:55 +00001308static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001309{
mjw6c65c122013-08-27 10:19:03 +00001310 /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001311 switch (hwcaps) {
1312 case 0:
1313 return "x86-sse0";
mjw6c65c122013-08-27 10:19:03 +00001314 case VEX_HWCAPS_X86_MMXEXT:
1315 return "x86-mmxext";
1316 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1317 return "x86-mmxext-sse1";
1318 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1319 return "x86-mmxext-sse1-sse2";
1320 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001321 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001322 return "x86-mmxext-sse1-sse2-lzcnt";
1323 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001324 | VEX_HWCAPS_X86_SSE3:
mjw6c65c122013-08-27 10:19:03 +00001325 return "x86-mmxext-sse1-sse2-sse3";
1326 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001327 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001328 return "x86-mmxext-sse1-sse2-sse3-lzcnt";
sewardj536fbab2010-07-29 15:39:05 +00001329 default:
1330 return NULL;
1331 }
sewardj5117ce12006-01-27 21:20:15 +00001332}
1333
florian55085f82012-11-21 00:36:55 +00001334static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001335{
sewardje9d8a262009-07-01 08:06:34 +00001336 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1337 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001338 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001339 orthogonal. */
1340
1341 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001342 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1343 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001344 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1345 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1346 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001347 if (have_avx && !have_sse3)
1348 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001349 /* AVX2 or BMI without AVX */
1350 if ((have_avx2 || have_bmi) && !have_avx)
1351 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001352
1353 /* This isn't threadsafe. We might need to fix it at some point. */
1354 static HChar buf[100] = { 0 };
1355 if (buf[0] != 0) return buf; /* already constructed */
1356
1357 vex_bzero(buf, sizeof(buf));
1358
1359 HChar* p = &buf[0];
1360
1361 p = p + vex_sprintf(p, "%s", "amd64");
1362 if (hwcaps == 0) {
1363 /* special-case the baseline case */
1364 p = p + vex_sprintf(p, "%s", "-sse2");
1365 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001366 }
sewardj818c7302013-03-26 13:53:18 +00001367 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1368 p = p + vex_sprintf(p, "%s", "-cx16");
1369 }
1370 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1371 p = p + vex_sprintf(p, "%s", "-lzcnt");
1372 }
1373 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1374 p = p + vex_sprintf(p, "%s", "-rdtscp");
1375 }
1376 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1377 p = p + vex_sprintf(p, "%s", "-sse3");
1378 }
1379 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1380 p = p + vex_sprintf(p, "%s", "-avx");
1381 }
sewardjcc3d2192013-03-27 11:37:33 +00001382 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1383 p = p + vex_sprintf(p, "%s", "-avx2");
1384 }
1385 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1386 p = p + vex_sprintf(p, "%s", "-bmi");
1387 }
sewardj818c7302013-03-26 13:53:18 +00001388
1389 out:
1390 vassert(buf[sizeof(buf)-1] == 0);
1391 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001392}
1393
florian55085f82012-11-21 00:36:55 +00001394static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001395{
1396 /* Monotonic with complications. Basically V > F > baseline,
1397 but once you have F then you can have FX or GX too. */
1398 const UInt F = VEX_HWCAPS_PPC32_F;
1399 const UInt V = VEX_HWCAPS_PPC32_V;
1400 const UInt FX = VEX_HWCAPS_PPC32_FX;
1401 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001402 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001403 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
carll0c74bb52013-08-12 18:01:40 +00001404 const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001405 UInt c = hwcaps;
1406 if (c == 0) return "ppc32-int";
1407 if (c == F) return "ppc32-int-flt";
1408 if (c == (F|FX)) return "ppc32-int-flt-FX";
1409 if (c == (F|GX)) return "ppc32-int-flt-GX";
1410 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1411 if (c == (F|V)) return "ppc32-int-flt-vmx";
1412 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1413 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1414 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001415 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1416 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001417 if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1418 return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1419
sewardj5117ce12006-01-27 21:20:15 +00001420 return NULL;
1421}
1422
florian55085f82012-11-21 00:36:55 +00001423static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001424{
1425 /* Monotonic with complications. Basically V > baseline(==F),
1426 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001427 const UInt V = VEX_HWCAPS_PPC64_V;
1428 const UInt FX = VEX_HWCAPS_PPC64_FX;
1429 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001430 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001431 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
carll0c74bb52013-08-12 18:01:40 +00001432 const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001433 UInt c = hwcaps;
1434 if (c == 0) return "ppc64-int-flt";
1435 if (c == FX) return "ppc64-int-flt-FX";
1436 if (c == GX) return "ppc64-int-flt-GX";
1437 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1438 if (c == V) return "ppc64-int-flt-vmx";
1439 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1440 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1441 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001442 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1443 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001444 if (c == (V|FX|GX|VX|DFP|ISA2_07))
1445 return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
sewardj5117ce12006-01-27 21:20:15 +00001446 return NULL;
1447}
1448
florian55085f82012-11-21 00:36:55 +00001449static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001450{
sewardjec0d9a02010-08-22 12:54:56 +00001451 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1452 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1453 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1454 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1455 case 5:
1456 if (N)
1457 return NULL;
1458 if (vfp)
1459 return "ARMv5-vfp";
1460 else
1461 return "ARMv5";
1462 return NULL;
1463 case 6:
1464 if (N)
1465 return NULL;
1466 if (vfp)
1467 return "ARMv6-vfp";
1468 else
1469 return "ARMv6";
1470 return NULL;
1471 case 7:
1472 if (vfp) {
1473 if (N)
1474 return "ARMv7-vfp-neon";
1475 else
1476 return "ARMv7-vfp";
1477 } else {
1478 if (N)
1479 return "ARMv7-neon";
1480 else
1481 return "ARMv7";
1482 }
1483 default:
1484 return NULL;
1485 }
sewardj5117ce12006-01-27 21:20:15 +00001486 return NULL;
1487}
1488
sewardjbbcf1882014-01-12 12:49:10 +00001489static const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1490{
1491 /* Since there are no variants, just insist that hwcaps is zero,
1492 and declare it invalid otherwise. */
1493 if (hwcaps == 0)
1494 return "baseline";
1495 return NULL;
1496}
1497
florian55085f82012-11-21 00:36:55 +00001498static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001499{
sewardjd07b8562011-04-27 11:58:22 +00001500 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001501 static const struct {
1502 UInt hwcaps_bit;
1503 HChar name[6];
1504 } hwcaps_list[] = {
1505 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1506 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1507 { VEX_HWCAPS_S390X_GIE, "gie" },
1508 { VEX_HWCAPS_S390X_DFP, "dfp" },
1509 { VEX_HWCAPS_S390X_FGX, "fgx" },
1510 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1511 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1512 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1513 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1514 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1515 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001516 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001517 };
florian9061eb32012-12-09 17:53:45 +00001518#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1519 static HChar buf[sizeof prefix +
1520 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1521 1]; // '\0'
1522 HChar *p;
1523 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001524
1525 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001526
sewardj652b56a2011-04-13 15:38:17 +00001527 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1528
sewardjd07b8562011-04-27 11:58:22 +00001529 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001530 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1531 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1532 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1533 }
sewardj2019a972011-03-07 16:04:07 +00001534
sewardjd07b8562011-04-27 11:58:22 +00001535 /* If there are no facilities, add "zarch" */
1536 if (hwcaps == 0)
1537 vex_sprintf(p, "-%s", "zarch");
1538
1539 return buf;
sewardj2019a972011-03-07 16:04:07 +00001540}
1541
florian55085f82012-11-21 00:36:55 +00001542static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001543{
dejanjc3fee0d2013-07-25 09:08:03 +00001544 /* MIPS baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001545 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
dejanjc3fee0d2013-07-25 09:08:03 +00001546 /* MIPS baseline with dspr2. */
petarjbc7d6f42013-09-16 18:11:59 +00001547 if (VEX_MIPS_PROC_DSP2(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001548 return "MIPS-baseline-dspr2";
1549 }
1550 /* MIPS baseline with dsp. */
petarjbc7d6f42013-09-16 18:11:59 +00001551 if (VEX_MIPS_PROC_DSP(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001552 return "MIPS-baseline-dsp";
1553 }
1554 return "MIPS-baseline";
1555 }
1556
1557 /* Broadcom baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001558 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
dejanjc3fee0d2013-07-25 09:08:03 +00001559 return "Broadcom-baseline";
1560 }
1561
1562 /* Netlogic baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001563 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
dejanjc3fee0d2013-07-25 09:08:03 +00001564 return "Netlogic-baseline";
1565 }
1566
petarjbc7d6f42013-09-16 18:11:59 +00001567 /* Cavium baseline. */
1568 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1569 return "Cavium-baseline";
1570 }
1571
sewardjd0e5fe72012-06-07 08:51:02 +00001572 return NULL;
1573}
1574
petarjb92a9542013-02-27 22:57:17 +00001575static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1576{
1577 return "mips64-baseline";
1578}
1579
sewardj5117ce12006-01-27 21:20:15 +00001580/* ---- */
florian55085f82012-11-21 00:36:55 +00001581static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001582{
1583 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001584 case VexArchX86: return show_hwcaps_x86(hwcaps);
1585 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1586 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1587 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1588 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardjbbcf1882014-01-12 12:49:10 +00001589 case VexArchARM64: return show_hwcaps_arm64(hwcaps);
sewardjd0e5fe72012-06-07 08:51:02 +00001590 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1591 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001592 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001593 default: return NULL;
1594 }
1595}
1596
1597static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1598{
1599 return show_hwcaps(arch,hwcaps) != NULL;
1600}
1601
1602
sewardj35421a32004-07-05 13:12:34 +00001603/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001604/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001605/*---------------------------------------------------------------*/