blob: e8426a43258f89f2bb677021389c53432a5fc8fc [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
carll1f5fe1f2014-08-07 23:25:23 +00003/*--- Begin main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex.h"
florian33b02432012-08-25 21:48:04 +000037#include "libvex_emnote.h"
sewardj81ec4182004-10-25 23:15:52 +000038#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000039#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000040#include "libvex_guest_arm.h"
sewardjbbcf1882014-01-12 12:49:10 +000041#include "libvex_guest_arm64.h"
cerionaabdfbf2005-01-29 12:56:15 +000042#include "libvex_guest_ppc32.h"
cerionf0de28c2005-12-13 20:21:11 +000043#include "libvex_guest_ppc64.h"
sewardj2019a972011-03-07 16:04:07 +000044#include "libvex_guest_s390x.h"
sewardjd0e5fe72012-06-07 08:51:02 +000045#include "libvex_guest_mips32.h"
petarjb92a9542013-02-27 22:57:17 +000046#include "libvex_guest_mips64.h"
sewardjf13a16a2004-07-05 17:10:14 +000047
sewardjcef7d3e2009-07-02 12:21:59 +000048#include "main_globals.h"
49#include "main_util.h"
50#include "host_generic_regs.h"
51#include "ir_opt.h"
sewardj35421a32004-07-05 13:12:34 +000052
sewardjcef7d3e2009-07-02 12:21:59 +000053#include "host_x86_defs.h"
54#include "host_amd64_defs.h"
55#include "host_ppc_defs.h"
sewardj6c299f32009-12-31 18:00:12 +000056#include "host_arm_defs.h"
sewardjbbcf1882014-01-12 12:49:10 +000057#include "host_arm64_defs.h"
sewardj2019a972011-03-07 16:04:07 +000058#include "host_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000059#include "host_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000060
sewardjcef7d3e2009-07-02 12:21:59 +000061#include "guest_generic_bb_to_IR.h"
62#include "guest_x86_defs.h"
63#include "guest_amd64_defs.h"
64#include "guest_arm_defs.h"
sewardjbbcf1882014-01-12 12:49:10 +000065#include "guest_arm64_defs.h"
sewardjcef7d3e2009-07-02 12:21:59 +000066#include "guest_ppc_defs.h"
sewardj2019a972011-03-07 16:04:07 +000067#include "guest_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000068#include "guest_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000069
sewardj69d98e32010-06-18 08:17:41 +000070#include "host_generic_simd128.h"
71
sewardj35421a32004-07-05 13:12:34 +000072
73/* This file contains the top level interface to the library. */
74
sewardj5117ce12006-01-27 21:20:15 +000075/* --------- fwds ... --------- */
76
77static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
florian55085f82012-11-21 00:36:55 +000078static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
sewardj5117ce12006-01-27 21:20:15 +000079
80
sewardj8bde7f12013-04-11 13:57:43 +000081/* --------- helpers --------- */
82
83__attribute__((noinline))
84static UInt udiv32 ( UInt x, UInt y ) { return x/y; }
85__attribute__((noinline))
86static Int sdiv32 ( Int x, Int y ) { return x/y; }
87
88
sewardj35421a32004-07-05 13:12:34 +000089/* --------- Initialise the library. --------- */
90
91/* Exported to library client. */
92
sewardj08613742004-10-25 13:01:45 +000093void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
94{
sewardj65902992014-05-03 21:20:56 +000095 vex_bzero(vcon, sizeof(*vcon));
sewardj08613742004-10-25 13:01:45 +000096 vcon->iropt_verbosity = 0;
97 vcon->iropt_level = 2;
philippec8e2f982012-08-01 22:04:13 +000098 vcon->iropt_register_updates = VexRegUpdUnwindregsAtMemAccess;
sewardj08613742004-10-25 13:01:45 +000099 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +0000100 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +0000101 vcon->guest_chase_thresh = 10;
sewardj984d9b12010-01-15 10:53:21 +0000102 vcon->guest_chase_cond = False;
sewardj08613742004-10-25 13:01:45 +0000103}
104
105
106/* Exported to library client. */
107
sewardj887a11a2004-07-05 17:26:47 +0000108void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000109 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000110 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000111 void (*failure_exit) ( void ),
112 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000113 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000114 /* debug paranoia level */
115 Int debuglevel,
sewardj08613742004-10-25 13:01:45 +0000116 /* Control ... */
florianf72c2c12014-09-05 21:52:29 +0000117 const VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000118)
119{
sewardj08613742004-10-25 13:01:45 +0000120 /* First off, do enough minimal setup so that the following
121 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000122 vex_failure_exit = failure_exit;
123 vex_log_bytes = log_bytes;
124
125 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000126 vassert(!vex_initdone);
127 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000128 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000129 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000130
131 vassert(vcon->iropt_verbosity >= 0);
132 vassert(vcon->iropt_level >= 0);
133 vassert(vcon->iropt_level <= 2);
134 vassert(vcon->iropt_unroll_thresh >= 0);
135 vassert(vcon->iropt_unroll_thresh <= 400);
136 vassert(vcon->guest_max_insns >= 1);
137 vassert(vcon->guest_max_insns <= 100);
138 vassert(vcon->guest_chase_thresh >= 0);
139 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj984d9b12010-01-15 10:53:21 +0000140 vassert(vcon->guest_chase_cond == True
141 || vcon->guest_chase_cond == False);
sewardj443cd9d2004-07-18 23:06:45 +0000142
sewardjea602bc2004-10-14 21:40:12 +0000143 /* Check that Vex has been built with sizes of basic types as
144 stated in priv/libvex_basictypes.h. Failure of any of these is
145 a serious configuration error and should be corrected
146 immediately. If any of these assertions fail you can fully
147 expect Vex not to work properly, if at all. */
148
149 vassert(1 == sizeof(UChar));
150 vassert(1 == sizeof(Char));
151 vassert(2 == sizeof(UShort));
152 vassert(2 == sizeof(Short));
153 vassert(4 == sizeof(UInt));
154 vassert(4 == sizeof(Int));
155 vassert(8 == sizeof(ULong));
156 vassert(8 == sizeof(Long));
157 vassert(4 == sizeof(Float));
158 vassert(8 == sizeof(Double));
159 vassert(1 == sizeof(Bool));
160 vassert(4 == sizeof(Addr32));
161 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000162 vassert(16 == sizeof(U128));
sewardj69d98e32010-06-18 08:17:41 +0000163 vassert(16 == sizeof(V128));
sewardjc9069f22012-06-01 16:09:50 +0000164 vassert(32 == sizeof(U256));
sewardjea602bc2004-10-14 21:40:12 +0000165
166 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
167 vassert(sizeof(void*) == sizeof(int*));
168 vassert(sizeof(void*) == sizeof(HWord));
169
sewardj97e87932005-02-07 00:00:50 +0000170 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
171 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
172
sewardjc6f970f2012-04-02 21:54:49 +0000173 /* These take a lot of space, so make sure we don't have
174 any unnoticed size regressions. */
175 if (VEX_HOST_WORDSIZE == 4) {
florian420bfa92012-06-02 20:29:22 +0000176 vassert(sizeof(IRExpr) == 16);
sewardjc6f970f2012-04-02 21:54:49 +0000177 vassert(sizeof(IRStmt) == 20 /* x86 */
178 || sizeof(IRStmt) == 24 /* arm */);
179 } else {
florian420bfa92012-06-02 20:29:22 +0000180 vassert(sizeof(IRExpr) == 32);
floriand6f38b32012-05-31 15:46:18 +0000181 vassert(sizeof(IRStmt) == 32);
sewardjc6f970f2012-04-02 21:54:49 +0000182 }
183
sewardj8bde7f12013-04-11 13:57:43 +0000184 /* Check that signed integer division on the host rounds towards
185 zero. If not, h_calc_sdiv32_w_arm_semantics() won't work
186 correctly. */
187 /* 100.0 / 7.0 == 14.2857 */
188 vassert(udiv32(100, 7) == 14);
189 vassert(sdiv32(100, 7) == 14);
190 vassert(sdiv32(-100, 7) == -14); /* and not -15 */
191 vassert(sdiv32(100, -7) == -14); /* ditto */
192 vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
193
sewardjea602bc2004-10-14 21:40:12 +0000194 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000195 vex_debuglevel = debuglevel;
sewardj08613742004-10-25 13:01:45 +0000196 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000197 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000198 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000199}
200
201
202/* --------- Make a translation. --------- */
203
204/* Exported to library client. */
205
sewardj17c7f952005-12-15 14:02:34 +0000206VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000207{
sewardj81bd5502004-07-21 18:49:27 +0000208 /* This the bundle of functions we need to do the back-end stuff
209 (insn selection, reg-alloc, assembly) whilst being insulated
210 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000211 HReg* available_real_regs;
212 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000213 Bool (*isMove) ( HInstr*, HReg*, HReg* );
214 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
215 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000216 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
217 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000218 HInstr* (*directReload) ( HInstr*, HReg, Short );
219 void (*ppInstr) ( HInstr*, Bool );
220 void (*ppReg) ( HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000221 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
222 Int, Int, Bool, Bool, Addr64 );
223 Int (*emit) ( /*MB_MOD*/Bool*,
sewardj9b769162014-07-24 12:42:03 +0000224 UChar*, Int, HInstr*, Bool, VexEndness,
florian8462d112014-09-24 15:18:09 +0000225 const void*, const void*, const void*,
226 const void* );
florian1ff47562012-10-21 02:09:51 +0000227 IRExpr* (*specHelper) ( const HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000228 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000229
sewardj9e6491a2005-07-02 19:24:10 +0000230 DisOneInstrFn disInstrFn;
231
sewardjeeac8412004-11-02 00:26:55 +0000232 VexGuestLayout* guest_layout;
sewardjdd40fdf2006-12-24 02:20:24 +0000233 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000234 HInstrArray* vcode;
235 HInstrArray* rcode;
236 Int i, j, k, out_used, guest_sizeB;
sewardj05f5e012014-05-04 10:52:11 +0000237 Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
sewardjc6f970f2012-04-02 21:54:49 +0000238 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000239 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000240 IRType guest_word_type;
241 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000242 Bool mode64, chainingAllowed;
243 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000244
sewardj49651f42004-10-28 22:11:04 +0000245 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000246 available_real_regs = NULL;
247 n_available_real_regs = 0;
248 isMove = NULL;
249 getRegUsage = NULL;
250 mapRegs = NULL;
251 genSpill = NULL;
252 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000253 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000254 ppInstr = NULL;
255 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000256 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000257 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000258 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000259 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000260 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000261 guest_word_type = Ity_INVALID;
262 host_word_type = Ity_INVALID;
sewardj05f5e012014-05-04 10:52:11 +0000263 offB_CMSTART = 0;
264 offB_CMLEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000265 offB_GUEST_IP = 0;
266 szB_GUEST_IP = 0;
267 offB_HOST_EvC_COUNTER = 0;
268 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000269 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000270 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000271
sewardj17c7f952005-12-15 14:02:34 +0000272 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000273
sewardj35421a32004-07-05 13:12:34 +0000274 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000275 vassert(vta->needs_self_check != NULL);
276 vassert(vta->disp_cp_xassisted != NULL);
277 /* Both the chainers and the indir are either NULL or non-NULL. */
278 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
279 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
280 vassert(vta->disp_cp_xindir != NULL);
281 chainingAllowed = True;
282 } else {
283 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
284 vassert(vta->disp_cp_xindir == NULL);
285 }
florian2eeeb9b2011-09-23 18:03:21 +0000286
sewardj2d6b14a2005-11-23 04:25:07 +0000287 vexSetAllocModeTEMP_and_clear();
288 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000289
sewardjf13a16a2004-07-05 17:10:14 +0000290 /* First off, check that the guest and host insn sets
291 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000292
sewardj17c7f952005-12-15 14:02:34 +0000293 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000294
sewardjbef170b2004-12-21 01:23:00 +0000295 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000296 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000297 getAllocableRegs_X86 ( &n_available_real_regs,
298 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000299 isMove = (__typeof__(isMove)) isMove_X86Instr;
300 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_X86Instr;
301 mapRegs = (__typeof__(mapRegs)) mapRegs_X86Instr;
302 genSpill = (__typeof__(genSpill)) genSpill_X86;
303 genReload = (__typeof__(genReload)) genReload_X86;
304 directReload = (__typeof__(directReload)) directReload_X86;
305 ppInstr = (__typeof__(ppInstr)) ppX86Instr;
306 ppReg = (__typeof__(ppReg)) ppHRegX86;
sewardjfb7373a2007-08-25 21:29:03 +0000307 iselSB = iselSB_X86;
florianb66ad462014-10-07 22:13:47 +0000308 emit = (__typeof__(emit)) emit_X86Instr;
sewardjcf787902004-11-03 09:08:33 +0000309 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000310 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000311 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjf13a16a2004-07-05 17:10:14 +0000312 break;
sewardj2a9ad022004-11-25 02:46:58 +0000313
sewardjc33671d2005-02-01 20:30:00 +0000314 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000315 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000316 getAllocableRegs_AMD64 ( &n_available_real_regs,
317 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000318 isMove = (__typeof__(isMove)) isMove_AMD64Instr;
319 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_AMD64Instr;
320 mapRegs = (__typeof__(mapRegs)) mapRegs_AMD64Instr;
321 genSpill = (__typeof__(genSpill)) genSpill_AMD64;
322 genReload = (__typeof__(genReload)) genReload_AMD64;
323 ppInstr = (__typeof__(ppInstr)) ppAMD64Instr;
324 ppReg = (__typeof__(ppReg)) ppHRegAMD64;
325 iselSB = iselSB_AMD64;
326 emit = (__typeof__(emit)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000327 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000328 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000329 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjc33671d2005-02-01 20:30:00 +0000330 break;
331
cerion487e4c92005-02-04 16:28:19 +0000332 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000333 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000334 getAllocableRegs_PPC ( &n_available_real_regs,
335 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000336 isMove = (__typeof__(isMove)) isMove_PPCInstr;
337 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
338 mapRegs = (__typeof__(mapRegs)) mapRegs_PPCInstr;
339 genSpill = (__typeof__(genSpill)) genSpill_PPC;
340 genReload = (__typeof__(genReload)) genReload_PPC;
341 ppInstr = (__typeof__(ppInstr)) ppPPCInstr;
342 ppReg = (__typeof__(ppReg)) ppHRegPPC;
343 iselSB = iselSB_PPC;
344 emit = (__typeof__(emit)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000345 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000346 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000347 vassert(vta->archinfo_host.endness == VexEndnessBE);
cerion487e4c92005-02-04 16:28:19 +0000348 break;
349
cerionf0de28c2005-12-13 20:21:11 +0000350 case VexArchPPC64:
351 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000352 getAllocableRegs_PPC ( &n_available_real_regs,
353 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000354 isMove = (__typeof__(isMove)) isMove_PPCInstr;
355 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_PPCInstr;
356 mapRegs = (__typeof__(mapRegs)) mapRegs_PPCInstr;
357 genSpill = (__typeof__(genSpill)) genSpill_PPC;
358 genReload = (__typeof__(genReload)) genReload_PPC;
359 ppInstr = (__typeof__(ppInstr)) ppPPCInstr;
360 ppReg = (__typeof__(ppReg)) ppHRegPPC;
361 iselSB = iselSB_PPC;
362 emit = (__typeof__(emit)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000363 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000364 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000365 vassert(vta->archinfo_host.endness == VexEndnessBE ||
366 vta->archinfo_host.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000367 break;
368
sewardj2019a972011-03-07 16:04:07 +0000369 case VexArchS390X:
370 mode64 = True;
371 getAllocableRegs_S390 ( &n_available_real_regs,
372 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000373 isMove = (__typeof__(isMove)) isMove_S390Instr;
374 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_S390Instr;
375 mapRegs = (__typeof__(mapRegs)) mapRegs_S390Instr;
376 genSpill = (__typeof__(genSpill)) genSpill_S390;
377 genReload = (__typeof__(genReload)) genReload_S390;
florian017c0d52014-10-07 21:57:05 +0000378 // fixs390: consider implementing directReload_S390
florianb66ad462014-10-07 22:13:47 +0000379 ppInstr = (__typeof__(ppInstr)) ppS390Instr;
380 ppReg = (__typeof__(ppReg)) ppHRegS390;
381 iselSB = iselSB_S390;
382 emit = (__typeof__(emit)) emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000383 host_word_type = Ity_I64;
384 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000385 vassert(vta->archinfo_host.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000386 break;
387
sewardj6c299f32009-12-31 18:00:12 +0000388 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000389 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000390 getAllocableRegs_ARM ( &n_available_real_regs,
391 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000392 isMove = (__typeof__(isMove)) isMove_ARMInstr;
393 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_ARMInstr;
394 mapRegs = (__typeof__(mapRegs)) mapRegs_ARMInstr;
395 genSpill = (__typeof__(genSpill)) genSpill_ARM;
396 genReload = (__typeof__(genReload)) genReload_ARM;
397 ppInstr = (__typeof__(ppInstr)) ppARMInstr;
398 ppReg = (__typeof__(ppReg)) ppHRegARM;
399 iselSB = iselSB_ARM;
400 emit = (__typeof__(emit)) emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000401 host_word_type = Ity_I32;
402 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000403 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000404 break;
405
sewardjbbcf1882014-01-12 12:49:10 +0000406 case VexArchARM64:
407 mode64 = True;
408 getAllocableRegs_ARM64 ( &n_available_real_regs,
409 &available_real_regs );
florianb66ad462014-10-07 22:13:47 +0000410 isMove = (__typeof__(isMove)) isMove_ARM64Instr;
411 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_ARM64Instr;
412 mapRegs = (__typeof__(mapRegs)) mapRegs_ARM64Instr;
413 genSpill = (__typeof__(genSpill)) genSpill_ARM64;
414 genReload = (__typeof__(genReload)) genReload_ARM64;
415 ppInstr = (__typeof__(ppInstr)) ppARM64Instr;
416 ppReg = (__typeof__(ppReg)) ppHRegARM64;
417 iselSB = iselSB_ARM64;
418 emit = (__typeof__(emit)) emit_ARM64Instr;
sewardjbbcf1882014-01-12 12:49:10 +0000419 host_word_type = Ity_I64;
420 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000421 vassert(vta->archinfo_host.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000422 break;
423
sewardjd0e5fe72012-06-07 08:51:02 +0000424 case VexArchMIPS32:
425 mode64 = False;
426 getAllocableRegs_MIPS ( &n_available_real_regs,
427 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000428 isMove = (__typeof__(isMove)) isMove_MIPSInstr;
429 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
430 mapRegs = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
431 genSpill = (__typeof__(genSpill)) genSpill_MIPS;
432 genReload = (__typeof__(genReload)) genReload_MIPS;
433 ppInstr = (__typeof__(ppInstr)) ppMIPSInstr;
434 ppReg = (__typeof__(ppReg)) ppHRegMIPS;
435 iselSB = iselSB_MIPS;
436 emit = (__typeof__(emit)) emit_MIPSInstr;
sewardjd0e5fe72012-06-07 08:51:02 +0000437 host_word_type = Ity_I32;
438 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000439 vassert(vta->archinfo_host.endness == VexEndnessLE
440 || vta->archinfo_host.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000441 break;
442
petarjb92a9542013-02-27 22:57:17 +0000443 case VexArchMIPS64:
444 mode64 = True;
445 getAllocableRegs_MIPS ( &n_available_real_regs,
446 &available_real_regs, mode64 );
florianb66ad462014-10-07 22:13:47 +0000447 isMove = (__typeof__(isMove)) isMove_MIPSInstr;
448 getRegUsage = (__typeof__(getRegUsage)) getRegUsage_MIPSInstr;
449 mapRegs = (__typeof__(mapRegs)) mapRegs_MIPSInstr;
450 genSpill = (__typeof__(genSpill)) genSpill_MIPS;
451 genReload = (__typeof__(genReload)) genReload_MIPS;
452 ppInstr = (__typeof__(ppInstr)) ppMIPSInstr;
453 ppReg = (__typeof__(ppReg)) ppHRegMIPS;
454 iselSB = iselSB_MIPS;
455 emit = (__typeof__(emit)) emit_MIPSInstr;
petarjb92a9542013-02-27 22:57:17 +0000456 host_word_type = Ity_I64;
457 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000458 vassert(vta->archinfo_host.endness == VexEndnessLE
459 || vta->archinfo_host.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000460 break;
461
sewardjf13a16a2004-07-05 17:10:14 +0000462 default:
sewardj6c299f32009-12-31 18:00:12 +0000463 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000464 }
465
sewardj2a9ad022004-11-25 02:46:58 +0000466
sewardj17c7f952005-12-15 14:02:34 +0000467 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000468
sewardjbef170b2004-12-21 01:23:00 +0000469 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000470 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
471 disInstrFn = disInstr_X86;
472 specHelper = guest_x86_spechelper;
473 guest_sizeB = sizeof(VexGuestX86State);
474 guest_word_type = Ity_I32;
475 guest_layout = &x86guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000476 offB_CMSTART = offsetof(VexGuestX86State,guest_CMSTART);
477 offB_CMLEN = offsetof(VexGuestX86State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000478 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
479 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
480 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
481 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000482 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000483 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000484 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000485 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMSTART) == 4);
486 vassert(sizeof( ((VexGuestX86State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000487 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000488 break;
sewardj2a9ad022004-11-25 02:46:58 +0000489
sewardj44d494d2005-01-20 20:26:33 +0000490 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000491 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
492 disInstrFn = disInstr_AMD64;
493 specHelper = guest_amd64_spechelper;
494 guest_sizeB = sizeof(VexGuestAMD64State);
495 guest_word_type = Ity_I64;
496 guest_layout = &amd64guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000497 offB_CMSTART = offsetof(VexGuestAMD64State,guest_CMSTART);
498 offB_CMLEN = offsetof(VexGuestAMD64State,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000499 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
500 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
501 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
502 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000503 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000504 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000505 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000506 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMSTART ) == 8);
507 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_CMLEN ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000508 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000509 break;
510
cerionaabdfbf2005-01-29 12:56:15 +0000511 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000512 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
513 disInstrFn = disInstr_PPC;
514 specHelper = guest_ppc32_spechelper;
515 guest_sizeB = sizeof(VexGuestPPC32State);
516 guest_word_type = Ity_I32;
517 guest_layout = &ppc32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000518 offB_CMSTART = offsetof(VexGuestPPC32State,guest_CMSTART);
519 offB_CMLEN = offsetof(VexGuestPPC32State,guest_CMLEN);
sewardj3dee8492012-04-20 00:13:28 +0000520 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
521 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
522 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
523 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000524 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000525 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj6c299f32009-12-31 18:00:12 +0000526 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000527 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMSTART ) == 4);
528 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_CMLEN ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000529 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000530 break;
531
cerionf0de28c2005-12-13 20:21:11 +0000532 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000533 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
534 disInstrFn = disInstr_PPC;
535 specHelper = guest_ppc64_spechelper;
536 guest_sizeB = sizeof(VexGuestPPC64State);
537 guest_word_type = Ity_I64;
538 guest_layout = &ppc64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000539 offB_CMSTART = offsetof(VexGuestPPC64State,guest_CMSTART);
540 offB_CMLEN = offsetof(VexGuestPPC64State,guest_CMLEN);
sewardj9e1cf152012-04-20 02:18:31 +0000541 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
542 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
543 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
544 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000545 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
carll1f5fe1f2014-08-07 23:25:23 +0000546 vassert(vta->archinfo_guest.endness == VexEndnessBE ||
547 vta->archinfo_guest.endness == VexEndnessLE );
cerionf0de28c2005-12-13 20:21:11 +0000548 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000549 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMSTART ) == 8);
550 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_CMLEN ) == 8);
sewardj3fd39672006-01-27 22:05:55 +0000551 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
552 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000553 break;
554
sewardj2019a972011-03-07 16:04:07 +0000555 case VexArchS390X:
556 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
557 disInstrFn = disInstr_S390;
558 specHelper = guest_s390x_spechelper;
559 guest_sizeB = sizeof(VexGuestS390XState);
560 guest_word_type = Ity_I64;
561 guest_layout = &s390xGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000562 offB_CMSTART = offsetof(VexGuestS390XState,guest_CMSTART);
563 offB_CMLEN = offsetof(VexGuestS390XState,guest_CMLEN);
florian8844a632012-04-13 04:04:06 +0000564 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
565 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
566 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
567 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000568 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000569 vassert(vta->archinfo_guest.endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +0000570 vassert(0 == sizeof(VexGuestS390XState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000571 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMSTART ) == 8);
572 vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN ) == 8);
sewardj2019a972011-03-07 16:04:07 +0000573 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
574 break;
575
sewardj6c299f32009-12-31 18:00:12 +0000576 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000577 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
578 disInstrFn = disInstr_ARM;
579 specHelper = guest_arm_spechelper;
580 guest_sizeB = sizeof(VexGuestARMState);
581 guest_word_type = Ity_I32;
582 guest_layout = &armGuest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000583 offB_CMSTART = offsetof(VexGuestARMState,guest_CMSTART);
584 offB_CMLEN = offsetof(VexGuestARMState,guest_CMLEN);
sewardjc6f970f2012-04-02 21:54:49 +0000585 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
586 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
587 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
588 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000589 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000590 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardj6c299f32009-12-31 18:00:12 +0000591 vassert(0 == sizeof(VexGuestARMState) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000592 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMSTART) == 4);
593 vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN ) == 4);
sewardj6c299f32009-12-31 18:00:12 +0000594 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
595 break;
596
sewardjbbcf1882014-01-12 12:49:10 +0000597 case VexArchARM64:
598 preciseMemExnsFn = guest_arm64_state_requires_precise_mem_exns;
599 disInstrFn = disInstr_ARM64;
600 specHelper = guest_arm64_spechelper;
601 guest_sizeB = sizeof(VexGuestARM64State);
602 guest_word_type = Ity_I64;
603 guest_layout = &arm64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000604 offB_CMSTART = offsetof(VexGuestARM64State,guest_CMSTART);
605 offB_CMLEN = offsetof(VexGuestARM64State,guest_CMLEN);
sewardjbbcf1882014-01-12 12:49:10 +0000606 offB_GUEST_IP = offsetof(VexGuestARM64State,guest_PC);
607 szB_GUEST_IP = sizeof( ((VexGuestARM64State*)0)->guest_PC );
608 offB_HOST_EvC_COUNTER = offsetof(VexGuestARM64State,host_EvC_COUNTER);
609 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
610 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000611 vassert(vta->archinfo_guest.endness == VexEndnessLE);
sewardjbbcf1882014-01-12 12:49:10 +0000612 vassert(0 == sizeof(VexGuestARM64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000613 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMSTART) == 8);
614 vassert(sizeof( ((VexGuestARM64State*)0)->guest_CMLEN ) == 8);
sewardjbbcf1882014-01-12 12:49:10 +0000615 vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
616 break;
617
sewardjd0e5fe72012-06-07 08:51:02 +0000618 case VexArchMIPS32:
619 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
620 disInstrFn = disInstr_MIPS;
621 specHelper = guest_mips32_spechelper;
622 guest_sizeB = sizeof(VexGuestMIPS32State);
623 guest_word_type = Ity_I32;
624 guest_layout = &mips32Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000625 offB_CMSTART = offsetof(VexGuestMIPS32State,guest_CMSTART);
626 offB_CMLEN = offsetof(VexGuestMIPS32State,guest_CMLEN);
sewardjd0e5fe72012-06-07 08:51:02 +0000627 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
628 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
629 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
630 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
631 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000632 vassert(vta->archinfo_guest.endness == VexEndnessLE
633 || vta->archinfo_guest.endness == VexEndnessBE);
sewardjd0e5fe72012-06-07 08:51:02 +0000634 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000635 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMSTART) == 4);
636 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_CMLEN ) == 4);
sewardjd0e5fe72012-06-07 08:51:02 +0000637 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
638 break;
639
petarjb92a9542013-02-27 22:57:17 +0000640 case VexArchMIPS64:
641 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
642 disInstrFn = disInstr_MIPS;
643 specHelper = guest_mips64_spechelper;
644 guest_sizeB = sizeof(VexGuestMIPS64State);
645 guest_word_type = Ity_I64;
646 guest_layout = &mips64Guest_layout;
sewardj05f5e012014-05-04 10:52:11 +0000647 offB_CMSTART = offsetof(VexGuestMIPS64State,guest_CMSTART);
648 offB_CMLEN = offsetof(VexGuestMIPS64State,guest_CMLEN);
petarjb92a9542013-02-27 22:57:17 +0000649 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
650 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
651 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
652 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
653 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
sewardj9b769162014-07-24 12:42:03 +0000654 vassert(vta->archinfo_guest.endness == VexEndnessLE
655 || vta->archinfo_guest.endness == VexEndnessBE);
petarjb92a9542013-02-27 22:57:17 +0000656 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
sewardj05f5e012014-05-04 10:52:11 +0000657 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMSTART) == 8);
658 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_CMLEN ) == 8);
petarjb92a9542013-02-27 22:57:17 +0000659 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
660 break;
661
sewardjf13a16a2004-07-05 17:10:14 +0000662 default:
sewardj887a11a2004-07-05 17:26:47 +0000663 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000664 }
665
sewardjbc161a42011-06-07 21:28:38 +0000666 /* Set up result struct. */
667 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000668 res.status = VexTransOK;
669 res.n_sc_extents = 0;
670 res.offs_profInc = -1;
671 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000672
sewardj9df271d2004-12-31 22:37:42 +0000673 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000674 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000675 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000676 we are simulating one flavour of an architecture a different
677 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000678 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9b769162014-07-24 12:42:03 +0000679 /* ditto */
680 vassert(vta->archinfo_guest.endness == vta->archinfo_host.endness);
sewardj9df271d2004-12-31 22:37:42 +0000681 }
sewardj2a9ad022004-11-25 02:46:58 +0000682
sewardj2d6b14a2005-11-23 04:25:07 +0000683 vexAllocSanityCheck();
684
sewardjf48ac192004-10-29 00:41:29 +0000685 if (vex_traceflags & VEX_TRACE_FE)
686 vex_printf("\n------------------------"
687 " Front end "
688 "------------------------\n\n");
689
sewardjdd40fdf2006-12-24 02:20:24 +0000690 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000691 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000692 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000693 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000694 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000695 vta->guest_bytes,
696 vta->guest_bytes_addr,
697 vta->chase_into_ok,
sewardj9b769162014-07-24 12:42:03 +0000698 vta->archinfo_host.endness,
sewardj442e51a2012-12-06 18:08:04 +0000699 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000700 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000701 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000702 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000703 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000704 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000705 vta->preamble_function,
sewardj05f5e012014-05-04 10:52:11 +0000706 offB_CMSTART,
707 offB_CMLEN,
sewardjc6f970f2012-04-02 21:54:49 +0000708 offB_GUEST_IP,
709 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000710
sewardj2d6b14a2005-11-23 04:25:07 +0000711 vexAllocSanityCheck();
712
sewardjdd40fdf2006-12-24 02:20:24 +0000713 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000714 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000715 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000716 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000717 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000718 }
sewardjaa59f942004-10-09 09:34:36 +0000719
sewardj17c7f952005-12-15 14:02:34 +0000720 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
721 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
722 for (i = 0; i < vta->guest_extents->n_used; i++) {
723 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000724 }
725
sewardjaa59f942004-10-09 09:34:36 +0000726 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000727 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000728 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000729 vex_printf("can't show code due to extents > 1\n");
730 } else {
731 /* HACK */
florian8462d112014-09-24 15:18:09 +0000732 const UChar* p = vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000733 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000734 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000735 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
736 guest_bytes_read );
737 for (i = 0; i < guest_bytes_read; i++) {
738 UInt b = (UInt)p[i];
739 vex_printf(" %02x", b );
740 sum = (sum << 1) ^ b;
741 }
742 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000743 }
sewardjaa59f942004-10-09 09:34:36 +0000744 }
745
746 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000747 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000748 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000749
sewardj2d6b14a2005-11-23 04:25:07 +0000750 vexAllocSanityCheck();
751
sewardjedf4d692004-08-17 13:52:58 +0000752 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000753 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000754 vta->guest_bytes_addr,
755 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000756 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000757 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000758
sewardjf48ac192004-10-29 00:41:29 +0000759 if (vex_traceflags & VEX_TRACE_OPT1) {
760 vex_printf("\n------------------------"
761 " After pre-instr IR optimisation "
762 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000763 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000764 vex_printf("\n");
765 }
766
sewardj2d6b14a2005-11-23 04:25:07 +0000767 vexAllocSanityCheck();
768
sewardjf13a16a2004-07-05 17:10:14 +0000769 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000770 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000771 irsb = vta->instrument1(vta->callback_opaque,
772 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000773 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000774 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000775 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000776 vexAllocSanityCheck();
777
sewardj17c7f952005-12-15 14:02:34 +0000778 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000779 irsb = vta->instrument2(vta->callback_opaque,
780 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000781 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000782 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000783 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000784
sewardjf48ac192004-10-29 00:41:29 +0000785 if (vex_traceflags & VEX_TRACE_INST) {
786 vex_printf("\n------------------------"
787 " After instrumentation "
788 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000789 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000790 vex_printf("\n");
791 }
792
sewardj17c7f952005-12-15 14:02:34 +0000793 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000794 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000795 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000796
sewardj9578a8b2004-11-04 19:44:48 +0000797 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000798 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000799 do_deadcode_BB( irsb );
800 irsb = cprop_BB( irsb );
801 do_deadcode_BB( irsb );
802 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000803 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000804 }
805
sewardj2d6b14a2005-11-23 04:25:07 +0000806 vexAllocSanityCheck();
807
sewardj9578a8b2004-11-04 19:44:48 +0000808 if (vex_traceflags & VEX_TRACE_OPT2) {
809 vex_printf("\n------------------------"
810 " After post-instr IR optimisation "
811 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000812 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000813 vex_printf("\n");
814 }
815
sewardjf9517d02005-11-28 13:39:37 +0000816 /* Turn it into virtual-registerised code. Build trees -- this
817 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000818 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000819
sewardjbe1b6ff2007-08-28 06:06:27 +0000820 if (vta->finaltidy) {
821 irsb = vta->finaltidy(irsb);
822 }
823
sewardj2d6b14a2005-11-23 04:25:07 +0000824 vexAllocSanityCheck();
825
sewardjf48ac192004-10-29 00:41:29 +0000826 if (vex_traceflags & VEX_TRACE_TREES) {
827 vex_printf("\n------------------------"
828 " After tree-building "
829 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000830 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000831 vex_printf("\n");
832 }
833
sewardje908c422005-02-04 21:18:16 +0000834 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000835 if (0) {
836 *(vta->host_bytes_used) = 0;
837 res.status = VexTransOK; return res;
838 }
sewardje908c422005-02-04 21:18:16 +0000839 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000840
sewardjf48ac192004-10-29 00:41:29 +0000841 if (vex_traceflags & VEX_TRACE_VCODE)
842 vex_printf("\n------------------------"
843 " Instruction selection "
844 "------------------------\n");
845
sewardjc6f970f2012-04-02 21:54:49 +0000846 /* No guest has its IP field at offset zero. If this fails it
847 means some transformation pass somewhere failed to update/copy
848 irsb->offsIP properly. */
849 vassert(irsb->offsIP >= 16);
850
851 vcode = iselSB ( irsb, vta->arch_host,
852 &vta->archinfo_host,
853 &vta->abiinfo_both,
854 offB_HOST_EvC_COUNTER,
855 offB_HOST_EvC_FAILADDR,
856 chainingAllowed,
857 vta->addProfInc,
858 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000859
sewardj2d6b14a2005-11-23 04:25:07 +0000860 vexAllocSanityCheck();
861
sewardjf48ac192004-10-29 00:41:29 +0000862 if (vex_traceflags & VEX_TRACE_VCODE)
863 vex_printf("\n");
864
sewardjf48ac192004-10-29 00:41:29 +0000865 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000866 for (i = 0; i < vcode->arr_used; i++) {
867 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000868 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000869 vex_printf("\n");
870 }
sewardjfbcaf332004-07-08 01:46:01 +0000871 vex_printf("\n");
872 }
sewardjfbcaf332004-07-08 01:46:01 +0000873
sewardjf13a16a2004-07-05 17:10:14 +0000874 /* Register allocate. */
875 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000876 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000877 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000878 genSpill, genReload, directReload,
879 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000880 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000881
sewardj2d6b14a2005-11-23 04:25:07 +0000882 vexAllocSanityCheck();
883
sewardjf48ac192004-10-29 00:41:29 +0000884 if (vex_traceflags & VEX_TRACE_RCODE) {
885 vex_printf("\n------------------------"
886 " Register-allocated code "
887 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000888 for (i = 0; i < rcode->arr_used; i++) {
889 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000890 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000891 vex_printf("\n");
892 }
sewardjfbcaf332004-07-08 01:46:01 +0000893 vex_printf("\n");
894 }
sewardjfbcaf332004-07-08 01:46:01 +0000895
sewardje908c422005-02-04 21:18:16 +0000896 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000897 if (0) {
898 *(vta->host_bytes_used) = 0;
899 res.status = VexTransOK; return res;
900 }
sewardje908c422005-02-04 21:18:16 +0000901 /* end HACK */
902
sewardj81bd5502004-07-21 18:49:27 +0000903 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000904 if (vex_traceflags & VEX_TRACE_ASM) {
905 vex_printf("\n------------------------"
906 " Assembly "
907 "------------------------\n\n");
908 }
909
sewardj81bd5502004-07-21 18:49:27 +0000910 out_used = 0; /* tracks along the host_bytes array */
911 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000912 HInstr* hi = rcode->arr[i];
913 Bool hi_isProfInc = False;
914 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
915 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000916 vex_printf("\n");
917 }
sewardjc6f970f2012-04-02 21:54:49 +0000918 j = emit( &hi_isProfInc,
sewardj9b769162014-07-24 12:42:03 +0000919 insn_bytes, sizeof insn_bytes, hi,
920 mode64, vta->archinfo_host.endness,
sewardjc6f970f2012-04-02 21:54:49 +0000921 vta->disp_cp_chain_me_to_slowEP,
922 vta->disp_cp_chain_me_to_fastEP,
923 vta->disp_cp_xindir,
924 vta->disp_cp_xassisted );
925 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000926 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000927 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000928 vex_printf("0%x ", (UInt)insn_bytes[k]);
929 else
930 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000931 vex_printf("\n\n");
932 }
sewardjc6f970f2012-04-02 21:54:49 +0000933 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000934 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000935 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000936 res.status = VexTransOutputFull;
937 return res;
sewardj81bd5502004-07-21 18:49:27 +0000938 }
sewardjc6f970f2012-04-02 21:54:49 +0000939 if (UNLIKELY(hi_isProfInc)) {
940 vassert(vta->addProfInc); /* else where did it come from? */
941 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
942 vassert(out_used >= 0);
943 res.offs_profInc = out_used;
944 }
945 { UChar* dst = &vta->host_bytes[out_used];
946 for (k = 0; k < j; k++) {
947 dst[k] = insn_bytes[k];
948 }
949 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000950 }
sewardj17c7f952005-12-15 14:02:34 +0000951 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000952 }
sewardj17c7f952005-12-15 14:02:34 +0000953 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000954
sewardj2d6b14a2005-11-23 04:25:07 +0000955 vexAllocSanityCheck();
956
957 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000958
sewardj65ea17e2012-12-28 09:01:59 +0000959 if (vex_traceflags) {
960 /* Print the expansion ratio for this SB. */
961 j = 0; /* total guest bytes */
962 for (i = 0; i < vta->guest_extents->n_used; i++) {
963 j += vta->guest_extents->len[i];
964 }
965 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
966 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
967 }
968
sewardjf48ac192004-10-29 00:41:29 +0000969 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000970 res.status = VexTransOK;
971 return res;
sewardj35421a32004-07-05 13:12:34 +0000972}
973
974
sewardjc6f970f2012-04-02 21:54:49 +0000975/* --------- Chain/Unchain XDirects. --------- */
976
florian7d6f81d2014-09-22 21:43:37 +0000977VexInvalRange LibVEX_Chain ( VexArch arch_host,
978 VexEndness endness_host,
979 void* place_to_chain,
980 const void* disp_cp_chain_me_EXPECTED,
981 const void* place_to_jump_to )
sewardjc6f970f2012-04-02 21:54:49 +0000982{
sewardjc6f970f2012-04-02 21:54:49 +0000983 switch (arch_host) {
984 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +0000985 return chainXDirect_X86(endness_host,
986 place_to_chain,
987 disp_cp_chain_me_EXPECTED,
988 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +0000989 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +0000990 return chainXDirect_AMD64(endness_host,
991 place_to_chain,
992 disp_cp_chain_me_EXPECTED,
993 place_to_jump_to);
sewardjc6f970f2012-04-02 21:54:49 +0000994 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +0000995 return chainXDirect_ARM(endness_host,
996 place_to_chain,
997 disp_cp_chain_me_EXPECTED,
998 place_to_jump_to);
sewardjbbcf1882014-01-12 12:49:10 +0000999 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001000 return chainXDirect_ARM64(endness_host,
1001 place_to_chain,
1002 disp_cp_chain_me_EXPECTED,
1003 place_to_jump_to);
florian8844a632012-04-13 04:04:06 +00001004 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001005 return chainXDirect_S390(endness_host,
1006 place_to_chain,
1007 disp_cp_chain_me_EXPECTED,
1008 place_to_jump_to);
sewardj3dee8492012-04-20 00:13:28 +00001009 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001010 return chainXDirect_PPC(endness_host,
1011 place_to_chain,
sewardj3dee8492012-04-20 00:13:28 +00001012 disp_cp_chain_me_EXPECTED,
1013 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001014 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001015 return chainXDirect_PPC(endness_host,
1016 place_to_chain,
sewardjf252de52012-04-20 10:42:24 +00001017 disp_cp_chain_me_EXPECTED,
1018 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001019 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001020 return chainXDirect_MIPS(endness_host,
1021 place_to_chain,
sewardjd0e5fe72012-06-07 08:51:02 +00001022 disp_cp_chain_me_EXPECTED,
1023 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001024 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001025 return chainXDirect_MIPS(endness_host,
1026 place_to_chain,
petarjb92a9542013-02-27 22:57:17 +00001027 disp_cp_chain_me_EXPECTED,
1028 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001029 default:
1030 vassert(0);
1031 }
sewardjc6f970f2012-04-02 21:54:49 +00001032}
1033
florian7d6f81d2014-09-22 21:43:37 +00001034VexInvalRange LibVEX_UnChain ( VexArch arch_host,
1035 VexEndness endness_host,
1036 void* place_to_unchain,
1037 const void* place_to_jump_to_EXPECTED,
1038 const void* disp_cp_chain_me )
sewardjc6f970f2012-04-02 21:54:49 +00001039{
sewardjc6f970f2012-04-02 21:54:49 +00001040 switch (arch_host) {
1041 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001042 return unchainXDirect_X86(endness_host,
1043 place_to_unchain,
1044 place_to_jump_to_EXPECTED,
1045 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001046 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001047 return unchainXDirect_AMD64(endness_host,
1048 place_to_unchain,
1049 place_to_jump_to_EXPECTED,
1050 disp_cp_chain_me);
sewardjc6f970f2012-04-02 21:54:49 +00001051 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001052 return unchainXDirect_ARM(endness_host,
1053 place_to_unchain,
1054 place_to_jump_to_EXPECTED,
1055 disp_cp_chain_me);
sewardjc6acaa42014-02-19 17:42:59 +00001056 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001057 return unchainXDirect_ARM64(endness_host,
1058 place_to_unchain,
1059 place_to_jump_to_EXPECTED,
1060 disp_cp_chain_me);
florian8844a632012-04-13 04:04:06 +00001061 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001062 return unchainXDirect_S390(endness_host,
1063 place_to_unchain,
1064 place_to_jump_to_EXPECTED,
1065 disp_cp_chain_me);
sewardj3dee8492012-04-20 00:13:28 +00001066 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001067 return unchainXDirect_PPC(endness_host,
1068 place_to_unchain,
sewardj3dee8492012-04-20 00:13:28 +00001069 place_to_jump_to_EXPECTED,
1070 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001071 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001072 return unchainXDirect_PPC(endness_host,
1073 place_to_unchain,
sewardjf252de52012-04-20 10:42:24 +00001074 place_to_jump_to_EXPECTED,
1075 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001076 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001077 return unchainXDirect_MIPS(endness_host,
1078 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001079 place_to_jump_to_EXPECTED,
1080 disp_cp_chain_me, False/*!mode64*/);
1081 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001082 return unchainXDirect_MIPS(endness_host,
1083 place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001084 place_to_jump_to_EXPECTED,
1085 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001086 default:
1087 vassert(0);
1088 }
sewardjc6f970f2012-04-02 21:54:49 +00001089}
1090
sewardj9b769162014-07-24 12:42:03 +00001091Int LibVEX_evCheckSzB ( VexArch arch_host,
1092 VexEndness endness_host )
sewardjc6f970f2012-04-02 21:54:49 +00001093{
1094 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1095 if (UNLIKELY(cached == 0)) {
1096 switch (arch_host) {
1097 case VexArchX86:
sewardj9b769162014-07-24 12:42:03 +00001098 cached = evCheckSzB_X86(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001099 case VexArchAMD64:
sewardj9b769162014-07-24 12:42:03 +00001100 cached = evCheckSzB_AMD64(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001101 case VexArchARM:
sewardj9b769162014-07-24 12:42:03 +00001102 cached = evCheckSzB_ARM(endness_host); break;
sewardjbbcf1882014-01-12 12:49:10 +00001103 case VexArchARM64:
sewardj9b769162014-07-24 12:42:03 +00001104 cached = evCheckSzB_ARM64(endness_host); break;
florian8844a632012-04-13 04:04:06 +00001105 case VexArchS390X:
sewardj9b769162014-07-24 12:42:03 +00001106 cached = evCheckSzB_S390(endness_host); break;
sewardj3dee8492012-04-20 00:13:28 +00001107 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001108 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001109 cached = evCheckSzB_PPC(endness_host); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001110 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001111 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001112 cached = evCheckSzB_MIPS(endness_host); break;
sewardjc6f970f2012-04-02 21:54:49 +00001113 default:
1114 vassert(0);
1115 }
1116 }
1117 return cached;
1118}
1119
sewardj9b769162014-07-24 12:42:03 +00001120VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1121 VexEndness endness_host,
1122 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001123 const ULong* location_of_counter )
sewardjc6f970f2012-04-02 21:54:49 +00001124{
sewardjc6f970f2012-04-02 21:54:49 +00001125 switch (arch_host) {
1126 case VexArchX86:
florian7d6f81d2014-09-22 21:43:37 +00001127 return patchProfInc_X86(endness_host, place_to_patch,
1128 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001129 case VexArchAMD64:
florian7d6f81d2014-09-22 21:43:37 +00001130 return patchProfInc_AMD64(endness_host, place_to_patch,
1131 location_of_counter);
sewardjc6f970f2012-04-02 21:54:49 +00001132 case VexArchARM:
florian7d6f81d2014-09-22 21:43:37 +00001133 return patchProfInc_ARM(endness_host, place_to_patch,
1134 location_of_counter);
sewardj0ad37a92014-08-29 21:58:03 +00001135 case VexArchARM64:
florian7d6f81d2014-09-22 21:43:37 +00001136 return patchProfInc_ARM64(endness_host, place_to_patch,
1137 location_of_counter);
florian8844a632012-04-13 04:04:06 +00001138 case VexArchS390X:
florian7d6f81d2014-09-22 21:43:37 +00001139 return patchProfInc_S390(endness_host, place_to_patch,
1140 location_of_counter);
sewardj3dee8492012-04-20 00:13:28 +00001141 case VexArchPPC32:
sewardj9b769162014-07-24 12:42:03 +00001142 return patchProfInc_PPC(endness_host, place_to_patch,
sewardj3dee8492012-04-20 00:13:28 +00001143 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001144 case VexArchPPC64:
sewardj9b769162014-07-24 12:42:03 +00001145 return patchProfInc_PPC(endness_host, place_to_patch,
sewardjf252de52012-04-20 10:42:24 +00001146 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001147 case VexArchMIPS32:
sewardj9b769162014-07-24 12:42:03 +00001148 return patchProfInc_MIPS(endness_host, place_to_patch,
sewardjd0e5fe72012-06-07 08:51:02 +00001149 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001150 case VexArchMIPS64:
sewardj9b769162014-07-24 12:42:03 +00001151 return patchProfInc_MIPS(endness_host, place_to_patch,
petarjb92a9542013-02-27 22:57:17 +00001152 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001153 default:
1154 vassert(0);
1155 }
sewardjc6f970f2012-04-02 21:54:49 +00001156}
1157
1158
sewardj893aada2004-11-29 19:57:54 +00001159/* --------- Emulation warnings. --------- */
1160
florian1ff47562012-10-21 02:09:51 +00001161const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001162{
1163 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001164 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001165 return "none";
1166 case EmWarn_X86_x87exns:
1167 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001168 case EmWarn_X86_x87precision:
1169 return "Selection of non-80-bit x87 FP precision";
1170 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001171 return "Unmasking SSE FP exceptions";
1172 case EmWarn_X86_fz:
1173 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1174 case EmWarn_X86_daz:
1175 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001176 case EmWarn_X86_acFlag:
1177 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001178 case EmWarn_PPCexns:
1179 return "Unmasking PPC32/64 FP exceptions";
1180 case EmWarn_PPC64_redir_overflow:
1181 return "PPC64 function redirection stack overflow";
1182 case EmWarn_PPC64_redir_underflow:
1183 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001184 case EmWarn_S390X_fpext_rounding:
1185 return "The specified rounding mode cannot be supported. That\n"
1186 " feature requires the floating point extension facility.\n"
1187 " which is not available on this host. Continuing using\n"
1188 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001189 case EmWarn_S390X_invalid_rounding:
1190 return "The specified rounding mode is invalid.\n"
1191 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001192 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001193 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001194 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001195 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001196 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001197 return "Instruction ecag is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001198 case EmFail_S390X_fpext:
1199 return "Encountered an instruction that requires the floating "
1200 "point extension facility.\n"
1201 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001202 case EmFail_S390X_invalid_PFPO_rounding_mode:
1203 return "The rounding mode specified in GPR 0 for PFPO instruction"
1204 " is invalid";
1205 case EmFail_S390X_invalid_PFPO_function:
1206 return "The function code specified in GPR 0 for PFPO instruction"
1207 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001208 default:
florian6ef84be2012-08-26 03:20:07 +00001209 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001210 }
1211}
sewardj35421a32004-07-05 13:12:34 +00001212
sewardj5117ce12006-01-27 21:20:15 +00001213/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001214
1215const HChar* LibVEX_ppVexArch ( VexArch arch )
1216{
1217 switch (arch) {
1218 case VexArch_INVALID: return "INVALID";
1219 case VexArchX86: return "X86";
1220 case VexArchAMD64: return "AMD64";
1221 case VexArchARM: return "ARM";
sewardjbbcf1882014-01-12 12:49:10 +00001222 case VexArchARM64: return "ARM64";
sewardj0ec57c52005-02-01 15:24:10 +00001223 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001224 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001225 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001226 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001227 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001228 default: return "VexArch???";
1229 }
1230}
1231
sewardj9b769162014-07-24 12:42:03 +00001232const HChar* LibVEX_ppVexEndness ( VexEndness endness )
1233{
1234 switch (endness) {
1235 case VexEndness_INVALID: return "INVALID";
1236 case VexEndnessLE: return "LittleEndian";
1237 case VexEndnessBE: return "BigEndian";
1238 default: return "VexEndness???";
1239 }
1240}
1241
sewardj5117ce12006-01-27 21:20:15 +00001242const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001243{
florian55085f82012-11-21 00:36:55 +00001244 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001245 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001246}
1247
sewardj5117ce12006-01-27 21:20:15 +00001248
sewardj27e1dd62005-06-30 11:49:14 +00001249/* Write default settings info *vai. */
1250void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1251{
sewardj65902992014-05-03 21:20:56 +00001252 vex_bzero(vai, sizeof(*vai));
sewardj9b769162014-07-24 12:42:03 +00001253 vai->hwcaps = 0;
1254 vai->endness = VexEndness_INVALID;
1255 vai->ppc_icache_line_szB = 0;
1256 vai->ppc_dcbz_szB = 0;
1257 vai->ppc_dcbzl_szB = 0;
sewardj65902992014-05-03 21:20:56 +00001258 vai->arm64_dMinLine_lg2_szB = 0;
1259 vai->arm64_iMinLine_lg2_szB = 0;
florianf192a392012-10-07 19:44:40 +00001260 vai->hwcache_info.num_levels = 0;
1261 vai->hwcache_info.num_caches = 0;
sewardj65902992014-05-03 21:20:56 +00001262 vai->hwcache_info.caches = NULL;
florianf192a392012-10-07 19:44:40 +00001263 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001264}
1265
sewardjdd40fdf2006-12-24 02:20:24 +00001266/* Write default settings info *vbi. */
1267void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001268{
sewardj65902992014-05-03 21:20:56 +00001269 vex_bzero(vbi, sizeof(*vbi));
sewardjdd40fdf2006-12-24 02:20:24 +00001270 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001271 vbi->guest_amd64_assume_fs_is_zero = False;
1272 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001273 vbi->guest_ppc_zap_RZ_at_blr = False;
1274 vbi->guest_ppc_zap_RZ_at_bl = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +00001275 vbi->host_ppc_calls_use_fndescrs = False;
sewardjaca070a2006-10-17 00:28:22 +00001276}
1277
sewardj27e1dd62005-06-30 11:49:14 +00001278
sewardj5117ce12006-01-27 21:20:15 +00001279/* Return a string showing the hwcaps in a nice way. The string will
1280 be NULL for invalid combinations of flags, so these functions also
1281 serve as a way to validate hwcaps values. */
1282
florian55085f82012-11-21 00:36:55 +00001283static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001284{
mjw6c65c122013-08-27 10:19:03 +00001285 /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001286 switch (hwcaps) {
1287 case 0:
1288 return "x86-sse0";
mjw6c65c122013-08-27 10:19:03 +00001289 case VEX_HWCAPS_X86_MMXEXT:
1290 return "x86-mmxext";
1291 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1292 return "x86-mmxext-sse1";
1293 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1294 return "x86-mmxext-sse1-sse2";
1295 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001296 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001297 return "x86-mmxext-sse1-sse2-lzcnt";
1298 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001299 | VEX_HWCAPS_X86_SSE3:
mjw6c65c122013-08-27 10:19:03 +00001300 return "x86-mmxext-sse1-sse2-sse3";
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 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001303 return "x86-mmxext-sse1-sse2-sse3-lzcnt";
sewardj536fbab2010-07-29 15:39:05 +00001304 default:
1305 return NULL;
1306 }
sewardj5117ce12006-01-27 21:20:15 +00001307}
1308
florian55085f82012-11-21 00:36:55 +00001309static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001310{
sewardje9d8a262009-07-01 08:06:34 +00001311 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1312 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001313 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001314 orthogonal. */
1315
1316 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001317 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1318 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001319 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1320 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1321 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001322 if (have_avx && !have_sse3)
1323 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001324 /* AVX2 or BMI without AVX */
1325 if ((have_avx2 || have_bmi) && !have_avx)
1326 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001327
1328 /* This isn't threadsafe. We might need to fix it at some point. */
1329 static HChar buf[100] = { 0 };
1330 if (buf[0] != 0) return buf; /* already constructed */
1331
1332 vex_bzero(buf, sizeof(buf));
1333
1334 HChar* p = &buf[0];
1335
1336 p = p + vex_sprintf(p, "%s", "amd64");
1337 if (hwcaps == 0) {
1338 /* special-case the baseline case */
1339 p = p + vex_sprintf(p, "%s", "-sse2");
1340 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001341 }
sewardj818c7302013-03-26 13:53:18 +00001342 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1343 p = p + vex_sprintf(p, "%s", "-cx16");
1344 }
1345 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1346 p = p + vex_sprintf(p, "%s", "-lzcnt");
1347 }
1348 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1349 p = p + vex_sprintf(p, "%s", "-rdtscp");
1350 }
1351 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1352 p = p + vex_sprintf(p, "%s", "-sse3");
1353 }
1354 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1355 p = p + vex_sprintf(p, "%s", "-avx");
1356 }
sewardjcc3d2192013-03-27 11:37:33 +00001357 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1358 p = p + vex_sprintf(p, "%s", "-avx2");
1359 }
1360 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1361 p = p + vex_sprintf(p, "%s", "-bmi");
1362 }
sewardj818c7302013-03-26 13:53:18 +00001363
1364 out:
1365 vassert(buf[sizeof(buf)-1] == 0);
1366 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001367}
1368
florian55085f82012-11-21 00:36:55 +00001369static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001370{
1371 /* Monotonic with complications. Basically V > F > baseline,
1372 but once you have F then you can have FX or GX too. */
1373 const UInt F = VEX_HWCAPS_PPC32_F;
1374 const UInt V = VEX_HWCAPS_PPC32_V;
1375 const UInt FX = VEX_HWCAPS_PPC32_FX;
1376 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001377 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001378 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
carll0c74bb52013-08-12 18:01:40 +00001379 const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001380 UInt c = hwcaps;
1381 if (c == 0) return "ppc32-int";
1382 if (c == F) return "ppc32-int-flt";
1383 if (c == (F|FX)) return "ppc32-int-flt-FX";
1384 if (c == (F|GX)) return "ppc32-int-flt-GX";
1385 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1386 if (c == (F|V)) return "ppc32-int-flt-vmx";
1387 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1388 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1389 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001390 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1391 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001392 if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1393 return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1394
sewardj5117ce12006-01-27 21:20:15 +00001395 return NULL;
1396}
1397
florian55085f82012-11-21 00:36:55 +00001398static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001399{
1400 /* Monotonic with complications. Basically V > baseline(==F),
1401 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001402 const UInt V = VEX_HWCAPS_PPC64_V;
1403 const UInt FX = VEX_HWCAPS_PPC64_FX;
1404 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001405 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001406 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
carll0c74bb52013-08-12 18:01:40 +00001407 const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001408 UInt c = hwcaps;
1409 if (c == 0) return "ppc64-int-flt";
1410 if (c == FX) return "ppc64-int-flt-FX";
1411 if (c == GX) return "ppc64-int-flt-GX";
1412 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1413 if (c == V) return "ppc64-int-flt-vmx";
1414 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1415 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1416 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001417 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1418 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001419 if (c == (V|FX|GX|VX|DFP|ISA2_07))
1420 return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
sewardj5117ce12006-01-27 21:20:15 +00001421 return NULL;
1422}
1423
florian55085f82012-11-21 00:36:55 +00001424static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001425{
sewardjec0d9a02010-08-22 12:54:56 +00001426 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1427 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1428 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1429 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1430 case 5:
1431 if (N)
1432 return NULL;
1433 if (vfp)
1434 return "ARMv5-vfp";
1435 else
1436 return "ARMv5";
1437 return NULL;
1438 case 6:
1439 if (N)
1440 return NULL;
1441 if (vfp)
1442 return "ARMv6-vfp";
1443 else
1444 return "ARMv6";
1445 return NULL;
1446 case 7:
1447 if (vfp) {
1448 if (N)
1449 return "ARMv7-vfp-neon";
1450 else
1451 return "ARMv7-vfp";
1452 } else {
1453 if (N)
1454 return "ARMv7-neon";
1455 else
1456 return "ARMv7";
1457 }
1458 default:
1459 return NULL;
1460 }
sewardj5117ce12006-01-27 21:20:15 +00001461 return NULL;
1462}
1463
sewardjbbcf1882014-01-12 12:49:10 +00001464static const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1465{
1466 /* Since there are no variants, just insist that hwcaps is zero,
1467 and declare it invalid otherwise. */
1468 if (hwcaps == 0)
1469 return "baseline";
1470 return NULL;
1471}
1472
florian55085f82012-11-21 00:36:55 +00001473static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001474{
sewardjd07b8562011-04-27 11:58:22 +00001475 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001476 static const struct {
1477 UInt hwcaps_bit;
1478 HChar name[6];
1479 } hwcaps_list[] = {
1480 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1481 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1482 { VEX_HWCAPS_S390X_GIE, "gie" },
1483 { VEX_HWCAPS_S390X_DFP, "dfp" },
1484 { VEX_HWCAPS_S390X_FGX, "fgx" },
1485 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1486 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1487 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1488 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1489 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1490 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001491 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001492 };
florian9061eb32012-12-09 17:53:45 +00001493#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1494 static HChar buf[sizeof prefix +
1495 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1496 1]; // '\0'
1497 HChar *p;
1498 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001499
1500 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001501
sewardj652b56a2011-04-13 15:38:17 +00001502 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1503
sewardjd07b8562011-04-27 11:58:22 +00001504 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001505 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1506 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1507 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1508 }
sewardj2019a972011-03-07 16:04:07 +00001509
sewardjd07b8562011-04-27 11:58:22 +00001510 /* If there are no facilities, add "zarch" */
1511 if (hwcaps == 0)
1512 vex_sprintf(p, "-%s", "zarch");
1513
1514 return buf;
sewardj2019a972011-03-07 16:04:07 +00001515}
1516
florian55085f82012-11-21 00:36:55 +00001517static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001518{
dejanjc3fee0d2013-07-25 09:08:03 +00001519 /* MIPS baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001520 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
dejanjc3fee0d2013-07-25 09:08:03 +00001521 /* MIPS baseline with dspr2. */
petarjbc7d6f42013-09-16 18:11:59 +00001522 if (VEX_MIPS_PROC_DSP2(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001523 return "MIPS-baseline-dspr2";
1524 }
1525 /* MIPS baseline with dsp. */
petarjbc7d6f42013-09-16 18:11:59 +00001526 if (VEX_MIPS_PROC_DSP(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001527 return "MIPS-baseline-dsp";
1528 }
1529 return "MIPS-baseline";
1530 }
1531
1532 /* Broadcom baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001533 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
dejanjc3fee0d2013-07-25 09:08:03 +00001534 return "Broadcom-baseline";
1535 }
1536
1537 /* Netlogic baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001538 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
dejanjc3fee0d2013-07-25 09:08:03 +00001539 return "Netlogic-baseline";
1540 }
1541
petarjbc7d6f42013-09-16 18:11:59 +00001542 /* Cavium baseline. */
1543 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1544 return "Cavium-baseline";
1545 }
1546
sewardjd0e5fe72012-06-07 08:51:02 +00001547 return NULL;
1548}
1549
petarjb92a9542013-02-27 22:57:17 +00001550static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1551{
1552 return "mips64-baseline";
1553}
1554
sewardj5117ce12006-01-27 21:20:15 +00001555/* ---- */
florian55085f82012-11-21 00:36:55 +00001556static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001557{
1558 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001559 case VexArchX86: return show_hwcaps_x86(hwcaps);
1560 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1561 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1562 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1563 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardjbbcf1882014-01-12 12:49:10 +00001564 case VexArchARM64: return show_hwcaps_arm64(hwcaps);
sewardjd0e5fe72012-06-07 08:51:02 +00001565 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1566 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001567 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001568 default: return NULL;
1569 }
1570}
1571
1572static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1573{
1574 return show_hwcaps(arch,hwcaps) != NULL;
1575}
1576
1577
sewardj35421a32004-07-05 13:12:34 +00001578/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001579/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001580/*---------------------------------------------------------------*/