blob: a50f3f7c75c82609308149b98b331a9bdd3faa5b [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;
floriand8c64e02014-10-08 08:54:44 +0000213 Bool (*isMove) ( const HInstr*, HReg*, HReg* );
214 void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000215 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 );
floriand8c64e02014-10-08 08:54:44 +0000219 void (*ppInstr) ( const HInstr*, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000220 void (*ppReg) ( HReg );
floriand8c64e02014-10-08 08:54:44 +0000221 HInstrArray* (*iselSB) ( IRSB*, VexArch, const VexArchInfo*,
222 const VexAbiInfo*, Int, Int, Bool, Bool,
223 Addr64 );
sewardjc6f970f2012-04-02 21:54:49 +0000224 Int (*emit) ( /*MB_MOD*/Bool*,
floriand8c64e02014-10-08 08:54:44 +0000225 UChar*, Int, const HInstr*, Bool, VexEndness,
florian8462d112014-09-24 15:18:09 +0000226 const void*, const void*, const void*,
227 const void* );
florian1ff47562012-10-21 02:09:51 +0000228 IRExpr* (*specHelper) ( const HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000229 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000230
sewardj9e6491a2005-07-02 19:24:10 +0000231 DisOneInstrFn disInstrFn;
232
sewardjeeac8412004-11-02 00:26:55 +0000233 VexGuestLayout* guest_layout;
sewardjdd40fdf2006-12-24 02:20:24 +0000234 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000235 HInstrArray* vcode;
236 HInstrArray* rcode;
237 Int i, j, k, out_used, guest_sizeB;
sewardj05f5e012014-05-04 10:52:11 +0000238 Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
sewardjc6f970f2012-04-02 21:54:49 +0000239 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000240 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000241 IRType guest_word_type;
242 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000243 Bool mode64, chainingAllowed;
244 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000245
sewardj49651f42004-10-28 22:11:04 +0000246 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000247 available_real_regs = NULL;
248 n_available_real_regs = 0;
249 isMove = NULL;
250 getRegUsage = NULL;
251 mapRegs = NULL;
252 genSpill = NULL;
253 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000254 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000255 ppInstr = NULL;
256 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000257 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000258 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000259 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000260 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000261 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000262 guest_word_type = Ity_INVALID;
263 host_word_type = Ity_INVALID;
sewardj05f5e012014-05-04 10:52:11 +0000264 offB_CMSTART = 0;
265 offB_CMLEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000266 offB_GUEST_IP = 0;
267 szB_GUEST_IP = 0;
268 offB_HOST_EvC_COUNTER = 0;
269 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000270 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000271 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000272
sewardj17c7f952005-12-15 14:02:34 +0000273 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000274
sewardj35421a32004-07-05 13:12:34 +0000275 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000276 vassert(vta->needs_self_check != NULL);
277 vassert(vta->disp_cp_xassisted != NULL);
278 /* Both the chainers and the indir are either NULL or non-NULL. */
279 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
280 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
281 vassert(vta->disp_cp_xindir != NULL);
282 chainingAllowed = True;
283 } else {
284 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
285 vassert(vta->disp_cp_xindir == NULL);
286 }
florian2eeeb9b2011-09-23 18:03:21 +0000287
sewardj2d6b14a2005-11-23 04:25:07 +0000288 vexSetAllocModeTEMP_and_clear();
289 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000290
sewardjf13a16a2004-07-05 17:10:14 +0000291 /* First off, check that the guest and host insn sets
292 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000293
sewardj17c7f952005-12-15 14:02:34 +0000294 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000295
sewardjbef170b2004-12-21 01:23:00 +0000296 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000297 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000298 getAllocableRegs_X86 ( &n_available_real_regs,
299 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000300 isMove = (__typeof__(isMove)) isMove_X86Instr;
301 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_X86Instr;
302 mapRegs = (__typeof__(mapRegs)) mapRegs_X86Instr;
303 genSpill = (__typeof__(genSpill)) genSpill_X86;
304 genReload = (__typeof__(genReload)) genReload_X86;
305 directReload = (__typeof__(directReload)) directReload_X86;
306 ppInstr = (__typeof__(ppInstr)) ppX86Instr;
307 ppReg = (__typeof__(ppReg)) ppHRegX86;
sewardjfb7373a2007-08-25 21:29:03 +0000308 iselSB = iselSB_X86;
florianb66ad462014-10-07 22:13:47 +0000309 emit = (__typeof__(emit)) emit_X86Instr;
sewardjcf787902004-11-03 09:08:33 +0000310 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000311 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000312 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjf13a16a2004-07-05 17:10:14 +0000313 break;
sewardj2a9ad022004-11-25 02:46:58 +0000314
sewardjc33671d2005-02-01 20:30:00 +0000315 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000316 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000317 getAllocableRegs_AMD64 ( &n_available_real_regs,
318 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000319 isMove = (__typeof__(isMove)) isMove_AMD64Instr;
320 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_AMD64Instr;
321 mapRegs = (__typeof__(mapRegs)) mapRegs_AMD64Instr;
322 genSpill = (__typeof__(genSpill)) genSpill_AMD64;
323 genReload = (__typeof__(genReload)) genReload_AMD64;
324 ppInstr = (__typeof__(ppInstr)) ppAMD64Instr;
325 ppReg = (__typeof__(ppReg)) ppHRegAMD64;
326 iselSB = iselSB_AMD64;
327 emit = (__typeof__(emit)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000328 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000329 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000330 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjc33671d2005-02-01 20:30:00 +0000331 break;
332
cerion487e4c92005-02-04 16:28:19 +0000333 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000334 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000335 getAllocableRegs_PPC ( &n_available_real_regs,
336 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000337 isMove = (__typeof__(isMove)) isMove_PPCInstr;
338 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
339 mapRegs = (__typeof__(mapRegs)) mapRegs_PPCInstr;
340 genSpill = (__typeof__(genSpill)) genSpill_PPC;
341 genReload = (__typeof__(genReload)) genReload_PPC;
342 ppInstr = (__typeof__(ppInstr)) ppPPCInstr;
343 ppReg = (__typeof__(ppReg)) ppHRegPPC;
344 iselSB = iselSB_PPC;
345 emit = (__typeof__(emit)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000346 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000347 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000348 vassert(vta->archinfo_host.endness == VexEndnessBE);
cerion487e4c92005-02-04 16:28:19 +0000349 break;
350
cerionf0de28c2005-12-13 20:21:11 +0000351 case VexArchPPC64:
352 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000353 getAllocableRegs_PPC ( &n_available_real_regs,
354 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000355 isMove = (__typeof__(isMove)) isMove_PPCInstr;
356 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
357 mapRegs = (__typeof__(mapRegs)) mapRegs_PPCInstr;
358 genSpill = (__typeof__(genSpill)) genSpill_PPC;
359 genReload = (__typeof__(genReload)) genReload_PPC;
360 ppInstr = (__typeof__(ppInstr)) ppPPCInstr;
361 ppReg = (__typeof__(ppReg)) ppHRegPPC;
362 iselSB = iselSB_PPC;
363 emit = (__typeof__(emit)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000364 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000365 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000366 vassert(vta->archinfo_host.endness == VexEndnessBE ||
367 vta->archinfo_host.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000368 break;
369
sewardj2019a972011-03-07 16:04:07 +0000370 case VexArchS390X:
371 mode64 = True;
372 getAllocableRegs_S390 ( &n_available_real_regs,
373 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000374 isMove = (__typeof__(isMove)) isMove_S390Instr;
375 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_S390Instr;
376 mapRegs = (__typeof__(mapRegs)) mapRegs_S390Instr;
377 genSpill = (__typeof__(genSpill)) genSpill_S390;
378 genReload = (__typeof__(genReload)) genReload_S390;
florian017c0d52014-10-07 21:57:05 +0000379 // fixs390: consider implementing directReload_S390
florianb66ad462014-10-07 22:13:47 +0000380 ppInstr = (__typeof__(ppInstr)) ppS390Instr;
381 ppReg = (__typeof__(ppReg)) ppHRegS390;
382 iselSB = iselSB_S390;
383 emit = (__typeof__(emit)) emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000384 host_word_type = Ity_I64;
385 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000386 vassert(vta->archinfo_host.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000387 break;
388
sewardj6c299f32009-12-31 18:00:12 +0000389 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000390 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000391 getAllocableRegs_ARM ( &n_available_real_regs,
392 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000393 isMove = (__typeof__(isMove)) isMove_ARMInstr;
394 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_ARMInstr;
395 mapRegs = (__typeof__(mapRegs)) mapRegs_ARMInstr;
396 genSpill = (__typeof__(genSpill)) genSpill_ARM;
397 genReload = (__typeof__(genReload)) genReload_ARM;
398 ppInstr = (__typeof__(ppInstr)) ppARMInstr;
399 ppReg = (__typeof__(ppReg)) ppHRegARM;
400 iselSB = iselSB_ARM;
401 emit = (__typeof__(emit)) emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000402 host_word_type = Ity_I32;
403 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000404 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000405 break;
406
sewardjbbcf1882014-01-12 12:49:10 +0000407 case VexArchARM64:
408 mode64 = True;
409 getAllocableRegs_ARM64 ( &n_available_real_regs,
410 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000411 isMove = (__typeof__(isMove)) isMove_ARM64Instr;
412 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_ARM64Instr;
413 mapRegs = (__typeof__(mapRegs)) mapRegs_ARM64Instr;
414 genSpill = (__typeof__(genSpill)) genSpill_ARM64;
415 genReload = (__typeof__(genReload)) genReload_ARM64;
416 ppInstr = (__typeof__(ppInstr)) ppARM64Instr;
417 ppReg = (__typeof__(ppReg)) ppHRegARM64;
418 iselSB = iselSB_ARM64;
419 emit = (__typeof__(emit)) emit_ARM64Instr;
sewardjbbcf1882014-01-12 12:49:10 +0000420 host_word_type = Ity_I64;
421 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000422 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000423 break;
424
sewardjd0e5fe72012-06-07 08:51:02 +0000425 case VexArchMIPS32:
426 mode64 = False;
427 getAllocableRegs_MIPS ( &n_available_real_regs,
428 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000429 isMove = (__typeof__(isMove)) isMove_MIPSInstr;
430 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
431 mapRegs = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
432 genSpill = (__typeof__(genSpill)) genSpill_MIPS;
433 genReload = (__typeof__(genReload)) genReload_MIPS;
434 ppInstr = (__typeof__(ppInstr)) ppMIPSInstr;
435 ppReg = (__typeof__(ppReg)) ppHRegMIPS;
436 iselSB = iselSB_MIPS;
437 emit = (__typeof__(emit)) emit_MIPSInstr;
sewardjd0e5fe72012-06-07 08:51:02 +0000438 host_word_type = Ity_I32;
439 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000440 vassert(vta->archinfo_host.endness == VexEndnessLE
441 || vta->archinfo_host.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000442 break;
443
petarjb92a9542013-02-27 22:57:17 +0000444 case VexArchMIPS64:
445 mode64 = True;
446 getAllocableRegs_MIPS ( &n_available_real_regs,
447 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000448 isMove = (__typeof__(isMove)) isMove_MIPSInstr;
449 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
450 mapRegs = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
451 genSpill = (__typeof__(genSpill)) genSpill_MIPS;
452 genReload = (__typeof__(genReload)) genReload_MIPS;
453 ppInstr = (__typeof__(ppInstr)) ppMIPSInstr;
454 ppReg = (__typeof__(ppReg)) ppHRegMIPS;
455 iselSB = iselSB_MIPS;
456 emit = (__typeof__(emit)) emit_MIPSInstr;
petarjb92a9542013-02-27 22:57:17 +0000457 host_word_type = Ity_I64;
458 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000459 vassert(vta->archinfo_host.endness == VexEndnessLE
460 || vta->archinfo_host.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000461 break;
462
sewardjf13a16a2004-07-05 17:10:14 +0000463 default:
sewardj6c299f32009-12-31 18:00:12 +0000464 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000465 }
466
sewardj2a9ad022004-11-25 02:46:58 +0000467
sewardj17c7f952005-12-15 14:02:34 +0000468 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000469
sewardjbef170b2004-12-21 01:23:00 +0000470 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000471 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
472 disInstrFn = disInstr_X86;
473 specHelper = guest_x86_spechelper;
474 guest_sizeB = sizeof(VexGuestX86State);
475 guest_word_type = Ity_I32;
476 guest_layout = &x86guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000477 offB_CMSTART = offsetof(VexGuestX86State,guest_CMSTART);
478 offB_CMLEN = offsetof(VexGuestX86State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000479 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
480 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
481 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
482 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000483 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000484 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000485 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000486 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
487 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000488 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000489 break;
sewardj2a9ad022004-11-25 02:46:58 +0000490
sewardj44d494d2005-01-20 20:26:33 +0000491 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000492 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
493 disInstrFn = disInstr_AMD64;
494 specHelper = guest_amd64_spechelper;
495 guest_sizeB = sizeof(VexGuestAMD64State);
496 guest_word_type = Ity_I64;
497 guest_layout = &amd64guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000498 offB_CMSTART = offsetof(VexGuestAMD64State,guest_CMSTART);
499 offB_CMLEN = offsetof(VexGuestAMD64State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000500 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
501 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
502 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
503 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000504 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000505 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000506 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000507 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
508 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000509 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000510 break;
511
cerionaabdfbf2005-01-29 12:56:15 +0000512 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000513 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
514 disInstrFn = disInstr_PPC;
515 specHelper = guest_ppc32_spechelper;
516 guest_sizeB = sizeof(VexGuestPPC32State);
517 guest_word_type = Ity_I32;
518 guest_layout = &ppc32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000519 offB_CMSTART = offsetof(VexGuestPPC32State,guest_CMSTART);
520 offB_CMLEN = offsetof(VexGuestPPC32State,guest_CMLEN);
sewardj3dee8492012-04-20 00:13:28 +0000521 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
522 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
523 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
524 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000525 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000526 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj6c299f32009-12-31 18:00:12 +0000527 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000528 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
529 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000530 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000531 break;
532
cerionf0de28c2005-12-13 20:21:11 +0000533 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000534 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
535 disInstrFn = disInstr_PPC;
536 specHelper = guest_ppc64_spechelper;
537 guest_sizeB = sizeof(VexGuestPPC64State);
538 guest_word_type = Ity_I64;
539 guest_layout = &ppc64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000540 offB_CMSTART = offsetof(VexGuestPPC64State,guest_CMSTART);
541 offB_CMLEN = offsetof(VexGuestPPC64State,guest_CMLEN);
sewardj9e1cf152012-04-20 02:18:31 +0000542 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
543 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
544 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
545 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000546 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000547 vassert(vta->archinfo_guest.endness == VexEndnessBE ||
548 vta->archinfo_guest.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000549 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000550 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART ) == 8);
551 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN ) == 8);
sewardj3fd39672006-01-27 22:05:55 +0000552 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
553 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000554 break;
555
sewardj2019a972011-03-07 16:04:07 +0000556 case VexArchS390X:
557 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
558 disInstrFn = disInstr_S390;
559 specHelper = guest_s390x_spechelper;
560 guest_sizeB = sizeof(VexGuestS390XState);
561 guest_word_type = Ity_I64;
562 guest_layout = &s390xGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000563 offB_CMSTART = offsetof(VexGuestS390XState,guest_CMSTART);
564 offB_CMLEN = offsetof(VexGuestS390XState,guest_CMLEN);
florian8844a632012-04-13 04:04:06 +0000565 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
566 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
567 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
568 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000569 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000570 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000571 vassert(0 == sizeof(VexGuestS390XState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000572 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART ) == 8);
573 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN ) == 8);
sewardj2019a972011-03-07 16:04:07 +0000574 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
575 break;
576
sewardj6c299f32009-12-31 18:00:12 +0000577 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000578 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
579 disInstrFn = disInstr_ARM;
580 specHelper = guest_arm_spechelper;
581 guest_sizeB = sizeof(VexGuestARMState);
582 guest_word_type = Ity_I32;
583 guest_layout = &armGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000584 offB_CMSTART = offsetof(VexGuestARMState,guest_CMSTART);
585 offB_CMLEN = offsetof(VexGuestARMState,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000586 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
587 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
588 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
589 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000590 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000591 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000592 vassert(0 == sizeof(VexGuestARMState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000593 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
594 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN ) == 4);
sewardj6c299f32009-12-31 18:00:12 +0000595 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
596 break;
597
sewardjbbcf1882014-01-12 12:49:10 +0000598 case VexArchARM64:
599 preciseMemExnsFn = guest_arm64_state_requires_precise_mem_exns;
600 disInstrFn = disInstr_ARM64;
601 specHelper = guest_arm64_spechelper;
602 guest_sizeB = sizeof(VexGuestARM64State);
603 guest_word_type = Ity_I64;
604 guest_layout = &arm64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000605 offB_CMSTART = offsetof(VexGuestARM64State,guest_CMSTART);
606 offB_CMLEN = offsetof(VexGuestARM64State,guest_CMLEN);
sewardjbbcf1882014-01-12 12:49:10 +0000607 offB_GUEST_IP = offsetof(VexGuestARM64State,guest_PC);
608 szB_GUEST_IP = sizeof( ((VexGuestARM64State*)0)->guest_PC );
609 offB_HOST_EvC_COUNTER = offsetof(VexGuestARM64State,host_EvC_COUNTER);
610 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
611 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000612 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000613 vassert(0 == sizeof(VexGuestARM64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000614 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
615 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN ) == 8);
sewardjbbcf1882014-01-12 12:49:10 +0000616 vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
617 break;
618
sewardjd0e5fe72012-06-07 08:51:02 +0000619 case VexArchMIPS32:
620 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
621 disInstrFn = disInstr_MIPS;
622 specHelper = guest_mips32_spechelper;
623 guest_sizeB = sizeof(VexGuestMIPS32State);
624 guest_word_type = Ity_I32;
625 guest_layout = &mips32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000626 offB_CMSTART = offsetof(VexGuestMIPS32State,guest_CMSTART);
627 offB_CMLEN = offsetof(VexGuestMIPS32State,guest_CMLEN);
sewardjd0e5fe72012-06-07 08:51:02 +0000628 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
629 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
630 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
631 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
632 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000633 vassert(vta->archinfo_guest.endness == VexEndnessLE
634 || vta->archinfo_guest.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000635 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000636 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
637 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN ) == 4);
sewardjd0e5fe72012-06-07 08:51:02 +0000638 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
639 break;
640
petarjb92a9542013-02-27 22:57:17 +0000641 case VexArchMIPS64:
642 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
643 disInstrFn = disInstr_MIPS;
644 specHelper = guest_mips64_spechelper;
645 guest_sizeB = sizeof(VexGuestMIPS64State);
646 guest_word_type = Ity_I64;
647 guest_layout = &mips64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000648 offB_CMSTART = offsetof(VexGuestMIPS64State,guest_CMSTART);
649 offB_CMLEN = offsetof(VexGuestMIPS64State,guest_CMLEN);
petarjb92a9542013-02-27 22:57:17 +0000650 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
651 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
652 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
653 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
654 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000655 vassert(vta->archinfo_guest.endness == VexEndnessLE
656 || vta->archinfo_guest.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000657 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000658 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
659 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN ) == 8);
petarjb92a9542013-02-27 22:57:17 +0000660 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
661 break;
662
sewardjf13a16a2004-07-05 17:10:14 +0000663 default:
sewardj887a11a2004-07-05 17:26:47 +0000664 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000665 }
666
sewardjbc161a42011-06-07 21:28:38 +0000667 /* Set up result struct. */
668 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000669 res.status = VexTransOK;
670 res.n_sc_extents = 0;
671 res.offs_profInc = -1;
672 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000673
sewardj9df271d2004-12-31 22:37:42 +0000674 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000675 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000676 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000677 we are simulating one flavour of an architecture a different
678 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000679 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9b769162014-07-24 12:42:03 +0000680 /* ditto */
681 vassert(vta->archinfo_guest.endness == vta->archinfo_host.endness);
sewardj9df271d2004-12-31 22:37:42 +0000682 }
sewardj2a9ad022004-11-25 02:46:58 +0000683
sewardj2d6b14a2005-11-23 04:25:07 +0000684 vexAllocSanityCheck();
685
sewardjf48ac192004-10-29 00:41:29 +0000686 if (vex_traceflags & VEX_TRACE_FE)
687 vex_printf("\n------------------------"
688 " Front end "
689 "------------------------\n\n");
690
sewardjdd40fdf2006-12-24 02:20:24 +0000691 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000692 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000693 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000694 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000695 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000696 vta->guest_bytes,
697 vta->guest_bytes_addr,
698 vta->chase_into_ok,
sewardj9b769162014-07-24 12:42:03 +0000699 vta->archinfo_host.endness,
sewardj442e51a2012-12-06 18:08:04 +0000700 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000701 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000702 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000703 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000704 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000705 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000706 vta->preamble_function,
sewardj05f5e012014-05-04 10:52:11 +0000707 offB_CMSTART,
708 offB_CMLEN,
sewardjc6f970f2012-04-02 21:54:49 +0000709 offB_GUEST_IP,
710 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000711
sewardj2d6b14a2005-11-23 04:25:07 +0000712 vexAllocSanityCheck();
713
sewardjdd40fdf2006-12-24 02:20:24 +0000714 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000715 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000716 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000717 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000718 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000719 }
sewardjaa59f942004-10-09 09:34:36 +0000720
sewardj17c7f952005-12-15 14:02:34 +0000721 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
722 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
723 for (i = 0; i < vta->guest_extents->n_used; i++) {
724 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000725 }
726
sewardjaa59f942004-10-09 09:34:36 +0000727 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000728 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000729 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000730 vex_printf("can't show code due to extents > 1\n");
731 } else {
732 /* HACK */
florian8462d112014-09-24 15:18:09 +0000733 const UChar* p = vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000734 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000735 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000736 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
737 guest_bytes_read );
738 for (i = 0; i < guest_bytes_read; i++) {
739 UInt b = (UInt)p[i];
740 vex_printf(" %02x", b );
741 sum = (sum << 1) ^ b;
742 }
743 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000744 }
sewardjaa59f942004-10-09 09:34:36 +0000745 }
746
747 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000748 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000749 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000750
sewardj2d6b14a2005-11-23 04:25:07 +0000751 vexAllocSanityCheck();
752
sewardjedf4d692004-08-17 13:52:58 +0000753 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000754 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000755 vta->guest_bytes_addr,
756 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000757 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000758 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000759
sewardjf48ac192004-10-29 00:41:29 +0000760 if (vex_traceflags & VEX_TRACE_OPT1) {
761 vex_printf("\n------------------------"
762 " After pre-instr IR optimisation "
763 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000764 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000765 vex_printf("\n");
766 }
767
sewardj2d6b14a2005-11-23 04:25:07 +0000768 vexAllocSanityCheck();
769
sewardjf13a16a2004-07-05 17:10:14 +0000770 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000771 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000772 irsb = vta->instrument1(vta->callback_opaque,
773 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000774 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000775 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000776 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000777 vexAllocSanityCheck();
778
sewardj17c7f952005-12-15 14:02:34 +0000779 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000780 irsb = vta->instrument2(vta->callback_opaque,
781 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000782 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000783 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000784 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000785
sewardjf48ac192004-10-29 00:41:29 +0000786 if (vex_traceflags & VEX_TRACE_INST) {
787 vex_printf("\n------------------------"
788 " After instrumentation "
789 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000790 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000791 vex_printf("\n");
792 }
793
sewardj17c7f952005-12-15 14:02:34 +0000794 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000795 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000796 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000797
sewardj9578a8b2004-11-04 19:44:48 +0000798 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000799 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000800 do_deadcode_BB( irsb );
801 irsb = cprop_BB( irsb );
802 do_deadcode_BB( irsb );
803 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000804 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000805 }
806
sewardj2d6b14a2005-11-23 04:25:07 +0000807 vexAllocSanityCheck();
808
sewardj9578a8b2004-11-04 19:44:48 +0000809 if (vex_traceflags & VEX_TRACE_OPT2) {
810 vex_printf("\n------------------------"
811 " After post-instr IR optimisation "
812 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000813 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000814 vex_printf("\n");
815 }
816
sewardjf9517d02005-11-28 13:39:37 +0000817 /* Turn it into virtual-registerised code. Build trees -- this
818 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000819 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000820
sewardjbe1b6ff2007-08-28 06:06:27 +0000821 if (vta->finaltidy) {
822 irsb = vta->finaltidy(irsb);
823 }
824
sewardj2d6b14a2005-11-23 04:25:07 +0000825 vexAllocSanityCheck();
826
sewardjf48ac192004-10-29 00:41:29 +0000827 if (vex_traceflags & VEX_TRACE_TREES) {
828 vex_printf("\n------------------------"
829 " After tree-building "
830 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000831 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000832 vex_printf("\n");
833 }
834
sewardje908c422005-02-04 21:18:16 +0000835 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000836 if (0) {
837 *(vta->host_bytes_used) = 0;
838 res.status = VexTransOK; return res;
839 }
sewardje908c422005-02-04 21:18:16 +0000840 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000841
sewardjf48ac192004-10-29 00:41:29 +0000842 if (vex_traceflags & VEX_TRACE_VCODE)
843 vex_printf("\n------------------------"
844 " Instruction selection "
845 "------------------------\n");
846
sewardjc6f970f2012-04-02 21:54:49 +0000847 /* No guest has its IP field at offset zero. If this fails it
848 means some transformation pass somewhere failed to update/copy
849 irsb->offsIP properly. */
850 vassert(irsb->offsIP >= 16);
851
852 vcode = iselSB ( irsb, vta->arch_host,
853 &vta->archinfo_host,
854 &vta->abiinfo_both,
855 offB_HOST_EvC_COUNTER,
856 offB_HOST_EvC_FAILADDR,
857 chainingAllowed,
858 vta->addProfInc,
859 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000860
sewardj2d6b14a2005-11-23 04:25:07 +0000861 vexAllocSanityCheck();
862
sewardjf48ac192004-10-29 00:41:29 +0000863 if (vex_traceflags & VEX_TRACE_VCODE)
864 vex_printf("\n");
865
sewardjf48ac192004-10-29 00:41:29 +0000866 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000867 for (i = 0; i < vcode->arr_used; i++) {
868 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000869 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000870 vex_printf("\n");
871 }
sewardjfbcaf332004-07-08 01:46:01 +0000872 vex_printf("\n");
873 }
sewardjfbcaf332004-07-08 01:46:01 +0000874
sewardjf13a16a2004-07-05 17:10:14 +0000875 /* Register allocate. */
876 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000877 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000878 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000879 genSpill, genReload, directReload,
880 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000881 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000882
sewardj2d6b14a2005-11-23 04:25:07 +0000883 vexAllocSanityCheck();
884
sewardjf48ac192004-10-29 00:41:29 +0000885 if (vex_traceflags & VEX_TRACE_RCODE) {
886 vex_printf("\n------------------------"
887 " Register-allocated code "
888 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000889 for (i = 0; i < rcode->arr_used; i++) {
890 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000891 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000892 vex_printf("\n");
893 }
sewardjfbcaf332004-07-08 01:46:01 +0000894 vex_printf("\n");
895 }
sewardjfbcaf332004-07-08 01:46:01 +0000896
sewardje908c422005-02-04 21:18:16 +0000897 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000898 if (0) {
899 *(vta->host_bytes_used) = 0;
900 res.status = VexTransOK; return res;
901 }
sewardje908c422005-02-04 21:18:16 +0000902 /* end HACK */
903
sewardj81bd5502004-07-21 18:49:27 +0000904 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000905 if (vex_traceflags & VEX_TRACE_ASM) {
906 vex_printf("\n------------------------"
907 " Assembly "
908 "------------------------\n\n");
909 }
910
sewardj81bd5502004-07-21 18:49:27 +0000911 out_used = 0; /* tracks along the host_bytes array */
912 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000913 HInstr* hi = rcode->arr[i];
914 Bool hi_isProfInc = False;
915 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
916 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000917 vex_printf("\n");
918 }
sewardjc6f970f2012-04-02 21:54:49 +0000919 j = emit( &hi_isProfInc,
sewardj9b769162014-07-24 12:42:03 +0000920 insn_bytes, sizeof insn_bytes, hi,
921 mode64, vta->archinfo_host.endness,
sewardjc6f970f2012-04-02 21:54:49 +0000922 vta->disp_cp_chain_me_to_slowEP,
923 vta->disp_cp_chain_me_to_fastEP,
924 vta->disp_cp_xindir,
925 vta->disp_cp_xassisted );
926 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000927 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000928 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000929 vex_printf("0%x ", (UInt)insn_bytes[k]);
930 else
931 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000932 vex_printf("\n\n");
933 }
sewardjc6f970f2012-04-02 21:54:49 +0000934 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000935 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000936 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000937 res.status = VexTransOutputFull;
938 return res;
sewardj81bd5502004-07-21 18:49:27 +0000939 }
sewardjc6f970f2012-04-02 21:54:49 +0000940 if (UNLIKELY(hi_isProfInc)) {
941 vassert(vta->addProfInc); /* else where did it come from? */
942 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
943 vassert(out_used >= 0);
944 res.offs_profInc = out_used;
945 }
946 { UChar* dst = &vta->host_bytes[out_used];
947 for (k = 0; k < j; k++) {
948 dst[k] = insn_bytes[k];
949 }
950 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000951 }
sewardj17c7f952005-12-15 14:02:34 +0000952 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000953 }
sewardj17c7f952005-12-15 14:02:34 +0000954 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000955
sewardj2d6b14a2005-11-23 04:25:07 +0000956 vexAllocSanityCheck();
957
958 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000959
sewardj65ea17e2012-12-28 09:01:59 +0000960 if (vex_traceflags) {
961 /* Print the expansion ratio for this SB. */
962 j = 0; /* total guest bytes */
963 for (i = 0; i < vta->guest_extents->n_used; i++) {
964 j += vta->guest_extents->len[i];
965 }
966 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
967 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
968 }
969
sewardjf48ac192004-10-29 00:41:29 +0000970 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000971 res.status = VexTransOK;
972 return res;
sewardj35421a32004-07-05 13:12:34 +0000973}
974
975
sewardjc6f970f2012-04-02 21:54:49 +0000976/* --------- Chain/Unchain XDirects. --------- */
977
florian7d6f81d2014-09-22 21:43:37 +0000978VexInvalRange LibVEX_Chain ( VexArch arch_host,
979 VexEndness endness_host,
980 void* place_to_chain,
981 const void* disp_cp_chain_me_EXPECTED,
982 const void* place_to_jump_to )
sewardjc6f970f2012-04-02 21:54:49 +0000983{
sewardjc6f970f2012-04-02 21:54:49 +0000984 switch (arch_host) {
985 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +0000986 return chainXDirect_X86(endness_host,
987 place_to_chain,
988 disp_cp_chain_me_EXPECTED,
989 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +0000990 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +0000991 return chainXDirect_AMD64(endness_host,
992 place_to_chain,
993 disp_cp_chain_me_EXPECTED,
994 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +0000995 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +0000996 return chainXDirect_ARM(endness_host,
997 place_to_chain,
998 disp_cp_chain_me_EXPECTED,
999 place_to_jump_to);
sewardjbbcf1882014-01-12 12:49:10 +00001000 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001001 return chainXDirect_ARM64(endness_host,
1002 place_to_chain,
1003 disp_cp_chain_me_EXPECTED,
1004 place_to_jump_to);
florian8844a632012-04-13 04:04:06 +00001005 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001006 return chainXDirect_S390(endness_host,
1007 place_to_chain,
1008 disp_cp_chain_me_EXPECTED,
1009 place_to_jump_to);
sewardj3dee8492012-04-20 00:13:28 +00001010 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001011 return chainXDirect_PPC(endness_host,
1012 place_to_chain,
sewardj3dee8492012-04-20 00:13:28 +00001013 disp_cp_chain_me_EXPECTED,
1014 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001015 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001016 return chainXDirect_PPC(endness_host,
1017 place_to_chain,
sewardjf252de52012-04-20 10:42:24 +00001018 disp_cp_chain_me_EXPECTED,
1019 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001020 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001021 return chainXDirect_MIPS(endness_host,
1022 place_to_chain,
sewardjd0e5fe72012-06-07 08:51:02 +00001023 disp_cp_chain_me_EXPECTED,
1024 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001025 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001026 return chainXDirect_MIPS(endness_host,
1027 place_to_chain,
petarjb92a9542013-02-27 22:57:17 +00001028 disp_cp_chain_me_EXPECTED,
1029 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001030 default:
1031 vassert(0);
1032 }
sewardjc6f970f2012-04-02 21:54:49 +00001033}
1034
florian7d6f81d2014-09-22 21:43:37 +00001035VexInvalRange LibVEX_UnChain ( VexArch arch_host,
1036 VexEndness endness_host,
1037 void* place_to_unchain,
1038 const void* place_to_jump_to_EXPECTED,
1039 const void* disp_cp_chain_me )
sewardjc6f970f2012-04-02 21:54:49 +00001040{
sewardjc6f970f2012-04-02 21:54:49 +00001041 switch (arch_host) {
1042 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001043 return unchainXDirect_X86(endness_host,
1044 place_to_unchain,
1045 place_to_jump_to_EXPECTED,
1046 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001047 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001048 return unchainXDirect_AMD64(endness_host,
1049 place_to_unchain,
1050 place_to_jump_to_EXPECTED,
1051 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001052 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001053 return unchainXDirect_ARM(endness_host,
1054 place_to_unchain,
1055 place_to_jump_to_EXPECTED,
1056 disp_cp_chain_me);
sewardjc6acaa42014-02-19 17:42:59 +00001057 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001058 return unchainXDirect_ARM64(endness_host,
1059 place_to_unchain,
1060 place_to_jump_to_EXPECTED,
1061 disp_cp_chain_me);
florian8844a632012-04-13 04:04:06 +00001062 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001063 return unchainXDirect_S390(endness_host,
1064 place_to_unchain,
1065 place_to_jump_to_EXPECTED,
1066 disp_cp_chain_me);
sewardj3dee8492012-04-20 00:13:28 +00001067 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001068 return unchainXDirect_PPC(endness_host,
1069 place_to_unchain,
sewardj3dee8492012-04-20 00:13:28 +00001070 place_to_jump_to_EXPECTED,
1071 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001072 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001073 return unchainXDirect_PPC(endness_host,
1074 place_to_unchain,
sewardjf252de52012-04-20 10:42:24 +00001075 place_to_jump_to_EXPECTED,
1076 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001077 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001078 return unchainXDirect_MIPS(endness_host,
1079 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001080 place_to_jump_to_EXPECTED,
1081 disp_cp_chain_me, False/*!mode64*/);
1082 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001083 return unchainXDirect_MIPS(endness_host,
1084 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001085 place_to_jump_to_EXPECTED,
1086 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001087 default:
1088 vassert(0);
1089 }
sewardjc6f970f2012-04-02 21:54:49 +00001090}
1091
sewardj9b769162014-07-24 12:42:03 +00001092Int LibVEX_evCheckSzB ( VexArch arch_host,
1093 VexEndness endness_host )
sewardjc6f970f2012-04-02 21:54:49 +00001094{
1095 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1096 if (UNLIKELY(cached == 0)) {
1097 switch (arch_host) {
1098 case VexArchX86:
sewardj9b769162014-07-24 12:42:03 +00001099 cached = evCheckSzB_X86(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001100 case VexArchAMD64:
sewardj9b769162014-07-24 12:42:03 +00001101 cached = evCheckSzB_AMD64(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001102 case VexArchARM:
sewardj9b769162014-07-24 12:42:03 +00001103 cached = evCheckSzB_ARM(endness_host); break;
sewardjbbcf1882014-01-12 12:49:10 +00001104 case VexArchARM64:
sewardj9b769162014-07-24 12:42:03 +00001105 cached = evCheckSzB_ARM64(endness_host); break;
florian8844a632012-04-13 04:04:06 +00001106 case VexArchS390X:
sewardj9b769162014-07-24 12:42:03 +00001107 cached = evCheckSzB_S390(endness_host); break;
sewardj3dee8492012-04-20 00:13:28 +00001108 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001109 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001110 cached = evCheckSzB_PPC(endness_host); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001111 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001112 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001113 cached = evCheckSzB_MIPS(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001114 default:
1115 vassert(0);
1116 }
1117 }
1118 return cached;
1119}
1120
sewardj9b769162014-07-24 12:42:03 +00001121VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1122 VexEndness endness_host,
1123 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001124 const ULong* location_of_counter )
sewardjc6f970f2012-04-02 21:54:49 +00001125{
sewardjc6f970f2012-04-02 21:54:49 +00001126 switch (arch_host) {
1127 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001128 return patchProfInc_X86(endness_host, place_to_patch,
1129 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001130 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001131 return patchProfInc_AMD64(endness_host, place_to_patch,
1132 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001133 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001134 return patchProfInc_ARM(endness_host, place_to_patch,
1135 location_of_counter);
sewardj0ad37a92014-08-29 21:58:03 +00001136 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001137 return patchProfInc_ARM64(endness_host, place_to_patch,
1138 location_of_counter);
florian8844a632012-04-13 04:04:06 +00001139 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001140 return patchProfInc_S390(endness_host, place_to_patch,
1141 location_of_counter);
sewardj3dee8492012-04-20 00:13:28 +00001142 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001143 return patchProfInc_PPC(endness_host, place_to_patch,
sewardj3dee8492012-04-20 00:13:28 +00001144 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001145 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001146 return patchProfInc_PPC(endness_host, place_to_patch,
sewardjf252de52012-04-20 10:42:24 +00001147 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001148 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001149 return patchProfInc_MIPS(endness_host, place_to_patch,
sewardjd0e5fe72012-06-07 08:51:02 +00001150 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001151 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001152 return patchProfInc_MIPS(endness_host, place_to_patch,
petarjb92a9542013-02-27 22:57:17 +00001153 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001154 default:
1155 vassert(0);
1156 }
sewardjc6f970f2012-04-02 21:54:49 +00001157}
1158
1159
sewardj893aada2004-11-29 19:57:54 +00001160/* --------- Emulation warnings. --------- */
1161
florian1ff47562012-10-21 02:09:51 +00001162const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001163{
1164 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001165 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001166 return "none";
1167 case EmWarn_X86_x87exns:
1168 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001169 case EmWarn_X86_x87precision:
1170 return "Selection of non-80-bit x87 FP precision";
1171 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001172 return "Unmasking SSE FP exceptions";
1173 case EmWarn_X86_fz:
1174 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1175 case EmWarn_X86_daz:
1176 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001177 case EmWarn_X86_acFlag:
1178 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001179 case EmWarn_PPCexns:
1180 return "Unmasking PPC32/64 FP exceptions";
1181 case EmWarn_PPC64_redir_overflow:
1182 return "PPC64 function redirection stack overflow";
1183 case EmWarn_PPC64_redir_underflow:
1184 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001185 case EmWarn_S390X_fpext_rounding:
1186 return "The specified rounding mode cannot be supported. That\n"
florian2a4de0b2014-12-05 18:28:29 +00001187 " feature requires the floating point extension facility\n"
florian4b8efad2012-09-02 18:07:08 +00001188 " which is not available on this host. Continuing using\n"
1189 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001190 case EmWarn_S390X_invalid_rounding:
1191 return "The specified rounding mode is invalid.\n"
1192 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001193 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001194 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001195 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001196 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001197 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001198 return "Instruction ecag is not supported on this host";
florianad00ea92014-12-05 18:55:39 +00001199 case EmFail_S390X_pfpo:
1200 return "Instruction pfpo is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001201 case EmFail_S390X_fpext:
1202 return "Encountered an instruction that requires the floating "
1203 "point extension facility.\n"
1204 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001205 case EmFail_S390X_invalid_PFPO_rounding_mode:
florian2a4de0b2014-12-05 18:28:29 +00001206 return "The rounding mode in GPR 0 for the PFPO instruction"
florian78d5ef72013-05-11 15:02:58 +00001207 " is invalid";
1208 case EmFail_S390X_invalid_PFPO_function:
florian2a4de0b2014-12-05 18:28:29 +00001209 return "The function code in GPR 0 for the PFPO instruction"
florian78d5ef72013-05-11 15:02:58 +00001210 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001211 default:
florian6ef84be2012-08-26 03:20:07 +00001212 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001213 }
1214}
sewardj35421a32004-07-05 13:12:34 +00001215
sewardj5117ce12006-01-27 21:20:15 +00001216/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001217
1218const HChar* LibVEX_ppVexArch ( VexArch arch )
1219{
1220 switch (arch) {
1221 case VexArch_INVALID: return "INVALID";
1222 case VexArchX86: return "X86";
1223 case VexArchAMD64: return "AMD64";
1224 case VexArchARM: return "ARM";
sewardjbbcf1882014-01-12 12:49:10 +00001225 case VexArchARM64: return "ARM64";
sewardj0ec57c52005-02-01 15:24:10 +00001226 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001227 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001228 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001229 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001230 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001231 default: return "VexArch???";
1232 }
1233}
1234
sewardj9b769162014-07-24 12:42:03 +00001235const HChar* LibVEX_ppVexEndness ( VexEndness endness )
1236{
1237 switch (endness) {
1238 case VexEndness_INVALID: return "INVALID";
1239 case VexEndnessLE: return "LittleEndian";
1240 case VexEndnessBE: return "BigEndian";
1241 default: return "VexEndness???";
1242 }
1243}
1244
sewardj5117ce12006-01-27 21:20:15 +00001245const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001246{
florian55085f82012-11-21 00:36:55 +00001247 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001248 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001249}
1250
sewardj5117ce12006-01-27 21:20:15 +00001251
sewardj27e1dd62005-06-30 11:49:14 +00001252/* Write default settings info *vai. */
1253void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1254{
sewardj65902992014-05-03 21:20:56 +00001255 vex_bzero(vai, sizeof(*vai));
sewardj9b769162014-07-24 12:42:03 +00001256 vai->hwcaps = 0;
1257 vai->endness = VexEndness_INVALID;
1258 vai->ppc_icache_line_szB = 0;
1259 vai->ppc_dcbz_szB = 0;
1260 vai->ppc_dcbzl_szB = 0;
sewardj65902992014-05-03 21:20:56 +00001261 vai->arm64_dMinLine_lg2_szB = 0;
1262 vai->arm64_iMinLine_lg2_szB = 0;
florianf192a392012-10-07 19:44:40 +00001263 vai->hwcache_info.num_levels = 0;
1264 vai->hwcache_info.num_caches = 0;
sewardj65902992014-05-03 21:20:56 +00001265 vai->hwcache_info.caches = NULL;
florianf192a392012-10-07 19:44:40 +00001266 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001267}
1268
sewardjdd40fdf2006-12-24 02:20:24 +00001269/* Write default settings info *vbi. */
1270void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001271{
sewardj65902992014-05-03 21:20:56 +00001272 vex_bzero(vbi, sizeof(*vbi));
sewardjdd40fdf2006-12-24 02:20:24 +00001273 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001274 vbi->guest_amd64_assume_fs_is_zero = False;
1275 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001276 vbi->guest_ppc_zap_RZ_at_blr = False;
1277 vbi->guest_ppc_zap_RZ_at_bl = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +00001278 vbi->host_ppc_calls_use_fndescrs = False;
sewardjaca070a2006-10-17 00:28:22 +00001279}
1280
sewardj27e1dd62005-06-30 11:49:14 +00001281
sewardj5117ce12006-01-27 21:20:15 +00001282/* Return a string showing the hwcaps in a nice way. The string will
1283 be NULL for invalid combinations of flags, so these functions also
1284 serve as a way to validate hwcaps values. */
1285
florian55085f82012-11-21 00:36:55 +00001286static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001287{
mjw6c65c122013-08-27 10:19:03 +00001288 /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001289 switch (hwcaps) {
1290 case 0:
1291 return "x86-sse0";
mjw6c65c122013-08-27 10:19:03 +00001292 case VEX_HWCAPS_X86_MMXEXT:
1293 return "x86-mmxext";
1294 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1295 return "x86-mmxext-sse1";
1296 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1297 return "x86-mmxext-sse1-sse2";
1298 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001299 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001300 return "x86-mmxext-sse1-sse2-lzcnt";
1301 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001302 | VEX_HWCAPS_X86_SSE3:
mjw6c65c122013-08-27 10:19:03 +00001303 return "x86-mmxext-sse1-sse2-sse3";
1304 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001305 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001306 return "x86-mmxext-sse1-sse2-sse3-lzcnt";
sewardj536fbab2010-07-29 15:39:05 +00001307 default:
1308 return NULL;
1309 }
sewardj5117ce12006-01-27 21:20:15 +00001310}
1311
florian55085f82012-11-21 00:36:55 +00001312static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001313{
sewardje9d8a262009-07-01 08:06:34 +00001314 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1315 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001316 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001317 orthogonal. */
1318
1319 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001320 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1321 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001322 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1323 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1324 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001325 if (have_avx && !have_sse3)
1326 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001327 /* AVX2 or BMI without AVX */
1328 if ((have_avx2 || have_bmi) && !have_avx)
1329 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001330
1331 /* This isn't threadsafe. We might need to fix it at some point. */
1332 static HChar buf[100] = { 0 };
1333 if (buf[0] != 0) return buf; /* already constructed */
1334
1335 vex_bzero(buf, sizeof(buf));
1336
1337 HChar* p = &buf[0];
1338
1339 p = p + vex_sprintf(p, "%s", "amd64");
1340 if (hwcaps == 0) {
1341 /* special-case the baseline case */
1342 p = p + vex_sprintf(p, "%s", "-sse2");
1343 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001344 }
sewardj818c7302013-03-26 13:53:18 +00001345 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1346 p = p + vex_sprintf(p, "%s", "-cx16");
1347 }
1348 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1349 p = p + vex_sprintf(p, "%s", "-lzcnt");
1350 }
1351 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1352 p = p + vex_sprintf(p, "%s", "-rdtscp");
1353 }
1354 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1355 p = p + vex_sprintf(p, "%s", "-sse3");
1356 }
1357 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1358 p = p + vex_sprintf(p, "%s", "-avx");
1359 }
sewardjcc3d2192013-03-27 11:37:33 +00001360 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1361 p = p + vex_sprintf(p, "%s", "-avx2");
1362 }
1363 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1364 p = p + vex_sprintf(p, "%s", "-bmi");
1365 }
sewardj818c7302013-03-26 13:53:18 +00001366
1367 out:
1368 vassert(buf[sizeof(buf)-1] == 0);
1369 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001370}
1371
florian55085f82012-11-21 00:36:55 +00001372static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001373{
1374 /* Monotonic with complications. Basically V > F > baseline,
1375 but once you have F then you can have FX or GX too. */
1376 const UInt F = VEX_HWCAPS_PPC32_F;
1377 const UInt V = VEX_HWCAPS_PPC32_V;
1378 const UInt FX = VEX_HWCAPS_PPC32_FX;
1379 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001380 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001381 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
carll0c74bb52013-08-12 18:01:40 +00001382 const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001383 UInt c = hwcaps;
1384 if (c == 0) return "ppc32-int";
1385 if (c == F) return "ppc32-int-flt";
1386 if (c == (F|FX)) return "ppc32-int-flt-FX";
1387 if (c == (F|GX)) return "ppc32-int-flt-GX";
1388 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1389 if (c == (F|V)) return "ppc32-int-flt-vmx";
1390 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1391 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1392 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001393 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1394 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001395 if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1396 return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1397
sewardj5117ce12006-01-27 21:20:15 +00001398 return NULL;
1399}
1400
florian55085f82012-11-21 00:36:55 +00001401static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001402{
1403 /* Monotonic with complications. Basically V > baseline(==F),
1404 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001405 const UInt V = VEX_HWCAPS_PPC64_V;
1406 const UInt FX = VEX_HWCAPS_PPC64_FX;
1407 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001408 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001409 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
carll0c74bb52013-08-12 18:01:40 +00001410 const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001411 UInt c = hwcaps;
1412 if (c == 0) return "ppc64-int-flt";
1413 if (c == FX) return "ppc64-int-flt-FX";
1414 if (c == GX) return "ppc64-int-flt-GX";
1415 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1416 if (c == V) return "ppc64-int-flt-vmx";
1417 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1418 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1419 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001420 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1421 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001422 if (c == (V|FX|GX|VX|DFP|ISA2_07))
1423 return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
sewardj5117ce12006-01-27 21:20:15 +00001424 return NULL;
1425}
1426
florian55085f82012-11-21 00:36:55 +00001427static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001428{
sewardjec0d9a02010-08-22 12:54:56 +00001429 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1430 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1431 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1432 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1433 case 5:
1434 if (N)
1435 return NULL;
1436 if (vfp)
1437 return "ARMv5-vfp";
1438 else
1439 return "ARMv5";
1440 return NULL;
1441 case 6:
1442 if (N)
1443 return NULL;
1444 if (vfp)
1445 return "ARMv6-vfp";
1446 else
1447 return "ARMv6";
1448 return NULL;
1449 case 7:
1450 if (vfp) {
1451 if (N)
1452 return "ARMv7-vfp-neon";
1453 else
1454 return "ARMv7-vfp";
1455 } else {
1456 if (N)
1457 return "ARMv7-neon";
1458 else
1459 return "ARMv7";
1460 }
1461 default:
1462 return NULL;
1463 }
sewardj5117ce12006-01-27 21:20:15 +00001464 return NULL;
1465}
1466
sewardjbbcf1882014-01-12 12:49:10 +00001467static const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1468{
1469 /* Since there are no variants, just insist that hwcaps is zero,
1470 and declare it invalid otherwise. */
1471 if (hwcaps == 0)
1472 return "baseline";
1473 return NULL;
1474}
1475
florian55085f82012-11-21 00:36:55 +00001476static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001477{
sewardjd07b8562011-04-27 11:58:22 +00001478 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001479 static const struct {
1480 UInt hwcaps_bit;
1481 HChar name[6];
1482 } hwcaps_list[] = {
1483 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1484 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1485 { VEX_HWCAPS_S390X_GIE, "gie" },
1486 { VEX_HWCAPS_S390X_DFP, "dfp" },
1487 { VEX_HWCAPS_S390X_FGX, "fgx" },
1488 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1489 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1490 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1491 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1492 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1493 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001494 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001495 };
florian9061eb32012-12-09 17:53:45 +00001496#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1497 static HChar buf[sizeof prefix +
1498 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1499 1]; // '\0'
1500 HChar *p;
1501 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001502
1503 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001504
sewardj652b56a2011-04-13 15:38:17 +00001505 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1506
sewardjd07b8562011-04-27 11:58:22 +00001507 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001508 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1509 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1510 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1511 }
sewardj2019a972011-03-07 16:04:07 +00001512
sewardjd07b8562011-04-27 11:58:22 +00001513 /* If there are no facilities, add "zarch" */
1514 if (hwcaps == 0)
1515 vex_sprintf(p, "-%s", "zarch");
1516
1517 return buf;
sewardj2019a972011-03-07 16:04:07 +00001518}
1519
florian55085f82012-11-21 00:36:55 +00001520static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001521{
dejanjc3fee0d2013-07-25 09:08:03 +00001522 /* MIPS baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001523 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
dejanjc3fee0d2013-07-25 09:08:03 +00001524 /* MIPS baseline with dspr2. */
petarjbc7d6f42013-09-16 18:11:59 +00001525 if (VEX_MIPS_PROC_DSP2(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001526 return "MIPS-baseline-dspr2";
1527 }
1528 /* MIPS baseline with dsp. */
petarjbc7d6f42013-09-16 18:11:59 +00001529 if (VEX_MIPS_PROC_DSP(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001530 return "MIPS-baseline-dsp";
1531 }
1532 return "MIPS-baseline";
1533 }
1534
1535 /* Broadcom baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001536 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
dejanjc3fee0d2013-07-25 09:08:03 +00001537 return "Broadcom-baseline";
1538 }
1539
1540 /* Netlogic baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001541 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
dejanjc3fee0d2013-07-25 09:08:03 +00001542 return "Netlogic-baseline";
1543 }
1544
petarjbc7d6f42013-09-16 18:11:59 +00001545 /* Cavium baseline. */
1546 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1547 return "Cavium-baseline";
1548 }
1549
sewardjd0e5fe72012-06-07 08:51:02 +00001550 return NULL;
1551}
1552
petarjb92a9542013-02-27 22:57:17 +00001553static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1554{
1555 return "mips64-baseline";
1556}
1557
sewardj5117ce12006-01-27 21:20:15 +00001558/* ---- */
florian55085f82012-11-21 00:36:55 +00001559static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001560{
1561 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001562 case VexArchX86: return show_hwcaps_x86(hwcaps);
1563 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1564 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1565 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1566 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardjbbcf1882014-01-12 12:49:10 +00001567 case VexArchARM64: return show_hwcaps_arm64(hwcaps);
sewardjd0e5fe72012-06-07 08:51:02 +00001568 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1569 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001570 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001571 default: return NULL;
1572 }
1573}
1574
1575static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1576{
1577 return show_hwcaps(arch,hwcaps) != NULL;
1578}
1579
1580
sewardj35421a32004-07-05 13:12:34 +00001581/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001582/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001583/*---------------------------------------------------------------*/