blob: 2ca1df1f5c6b76e19188bc81f9ee855277d15b59 [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +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{
95 vcon->iropt_verbosity = 0;
96 vcon->iropt_level = 2;
philippec8e2f982012-08-01 22:04:13 +000097 vcon->iropt_register_updates = VexRegUpdUnwindregsAtMemAccess;
sewardj08613742004-10-25 13:01:45 +000098 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000099 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +0000100 vcon->guest_chase_thresh = 10;
sewardj984d9b12010-01-15 10:53:21 +0000101 vcon->guest_chase_cond = False;
sewardj08613742004-10-25 13:01:45 +0000102}
103
104
105/* Exported to library client. */
106
sewardj887a11a2004-07-05 17:26:47 +0000107void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000108 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000109 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000110 void (*failure_exit) ( void ),
111 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000112 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000113 /* debug paranoia level */
114 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000115 /* Are we supporting valgrind checking? */
116 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000117 /* Control ... */
118 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000119)
120{
sewardj08613742004-10-25 13:01:45 +0000121 /* First off, do enough minimal setup so that the following
122 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000123 vex_failure_exit = failure_exit;
124 vex_log_bytes = log_bytes;
125
126 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000127 vassert(!vex_initdone);
128 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000129 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000130 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000131
132 vassert(vcon->iropt_verbosity >= 0);
133 vassert(vcon->iropt_level >= 0);
134 vassert(vcon->iropt_level <= 2);
135 vassert(vcon->iropt_unroll_thresh >= 0);
136 vassert(vcon->iropt_unroll_thresh <= 400);
137 vassert(vcon->guest_max_insns >= 1);
138 vassert(vcon->guest_max_insns <= 100);
139 vassert(vcon->guest_chase_thresh >= 0);
140 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj984d9b12010-01-15 10:53:21 +0000141 vassert(vcon->guest_chase_cond == True
142 || vcon->guest_chase_cond == False);
sewardj443cd9d2004-07-18 23:06:45 +0000143
sewardjea602bc2004-10-14 21:40:12 +0000144 /* Check that Vex has been built with sizes of basic types as
145 stated in priv/libvex_basictypes.h. Failure of any of these is
146 a serious configuration error and should be corrected
147 immediately. If any of these assertions fail you can fully
148 expect Vex not to work properly, if at all. */
149
150 vassert(1 == sizeof(UChar));
151 vassert(1 == sizeof(Char));
152 vassert(2 == sizeof(UShort));
153 vassert(2 == sizeof(Short));
154 vassert(4 == sizeof(UInt));
155 vassert(4 == sizeof(Int));
156 vassert(8 == sizeof(ULong));
157 vassert(8 == sizeof(Long));
158 vassert(4 == sizeof(Float));
159 vassert(8 == sizeof(Double));
160 vassert(1 == sizeof(Bool));
161 vassert(4 == sizeof(Addr32));
162 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000163 vassert(16 == sizeof(U128));
sewardj69d98e32010-06-18 08:17:41 +0000164 vassert(16 == sizeof(V128));
sewardjc9069f22012-06-01 16:09:50 +0000165 vassert(32 == sizeof(U256));
sewardjea602bc2004-10-14 21:40:12 +0000166
167 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
168 vassert(sizeof(void*) == sizeof(int*));
169 vassert(sizeof(void*) == sizeof(HWord));
170
sewardj97e87932005-02-07 00:00:50 +0000171 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
172 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
173
sewardjc6f970f2012-04-02 21:54:49 +0000174 /* These take a lot of space, so make sure we don't have
175 any unnoticed size regressions. */
176 if (VEX_HOST_WORDSIZE == 4) {
florian420bfa92012-06-02 20:29:22 +0000177 vassert(sizeof(IRExpr) == 16);
sewardjc6f970f2012-04-02 21:54:49 +0000178 vassert(sizeof(IRStmt) == 20 /* x86 */
179 || sizeof(IRStmt) == 24 /* arm */);
180 } else {
florian420bfa92012-06-02 20:29:22 +0000181 vassert(sizeof(IRExpr) == 32);
floriand6f38b32012-05-31 15:46:18 +0000182 vassert(sizeof(IRStmt) == 32);
sewardjc6f970f2012-04-02 21:54:49 +0000183 }
184
sewardj8bde7f12013-04-11 13:57:43 +0000185 /* Check that signed integer division on the host rounds towards
186 zero. If not, h_calc_sdiv32_w_arm_semantics() won't work
187 correctly. */
188 /* 100.0 / 7.0 == 14.2857 */
189 vassert(udiv32(100, 7) == 14);
190 vassert(sdiv32(100, 7) == 14);
191 vassert(sdiv32(-100, 7) == -14); /* and not -15 */
192 vassert(sdiv32(100, -7) == -14); /* ditto */
193 vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
194
sewardjea602bc2004-10-14 21:40:12 +0000195 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000196 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000197 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000198 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000199 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000200 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000201}
202
203
204/* --------- Make a translation. --------- */
205
206/* Exported to library client. */
207
sewardj17c7f952005-12-15 14:02:34 +0000208VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000209{
sewardj81bd5502004-07-21 18:49:27 +0000210 /* This the bundle of functions we need to do the back-end stuff
211 (insn selection, reg-alloc, assembly) whilst being insulated
212 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000213 HReg* available_real_regs;
214 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000215 Bool (*isMove) ( HInstr*, HReg*, HReg* );
216 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
217 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000218 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
219 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000220 HInstr* (*directReload) ( HInstr*, HReg, Short );
221 void (*ppInstr) ( HInstr*, Bool );
222 void (*ppReg) ( HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000223 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
224 Int, Int, Bool, Bool, Addr64 );
225 Int (*emit) ( /*MB_MOD*/Bool*,
226 UChar*, Int, HInstr*, Bool,
227 void*, void*, void*, 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;
234 Bool host_is_bigendian = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000235 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000236 HInstrArray* vcode;
237 HInstrArray* rcode;
238 Int i, j, k, out_used, guest_sizeB;
sewardjc6f970f2012-04-02 21:54:49 +0000239 Int offB_TISTART, offB_TILEN, offB_GUEST_IP, szB_GUEST_IP;
240 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000241 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000242 IRType guest_word_type;
243 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000244 Bool mode64, chainingAllowed;
245 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000246
sewardj49651f42004-10-28 22:11:04 +0000247 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000248 available_real_regs = NULL;
249 n_available_real_regs = 0;
250 isMove = NULL;
251 getRegUsage = NULL;
252 mapRegs = NULL;
253 genSpill = NULL;
254 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000255 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000256 ppInstr = NULL;
257 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000258 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000259 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000260 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000261 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000262 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000263 guest_word_type = Ity_INVALID;
264 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000265 offB_TISTART = 0;
266 offB_TILEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000267 offB_GUEST_IP = 0;
268 szB_GUEST_IP = 0;
269 offB_HOST_EvC_COUNTER = 0;
270 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000271 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000272 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000273
sewardj17c7f952005-12-15 14:02:34 +0000274 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000275
sewardj35421a32004-07-05 13:12:34 +0000276 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000277 vassert(vta->needs_self_check != NULL);
278 vassert(vta->disp_cp_xassisted != NULL);
279 /* Both the chainers and the indir are either NULL or non-NULL. */
280 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
281 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
282 vassert(vta->disp_cp_xindir != NULL);
283 chainingAllowed = True;
284 } else {
285 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
286 vassert(vta->disp_cp_xindir == NULL);
287 }
florian2eeeb9b2011-09-23 18:03:21 +0000288
sewardj2d6b14a2005-11-23 04:25:07 +0000289 vexSetAllocModeTEMP_and_clear();
290 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000291
sewardjf13a16a2004-07-05 17:10:14 +0000292 /* First off, check that the guest and host insn sets
293 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000294
sewardj17c7f952005-12-15 14:02:34 +0000295 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000296
sewardjbef170b2004-12-21 01:23:00 +0000297 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000298 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000299 getAllocableRegs_X86 ( &n_available_real_regs,
300 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000301 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000302 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
303 getRegUsage_X86Instr;
sewardjfb7373a2007-08-25 21:29:03 +0000304 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000305 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
306 genSpill_X86;
307 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
308 genReload_X86;
sewardjfb7373a2007-08-25 21:29:03 +0000309 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
310 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
311 ppReg = (void(*)(HReg)) ppHRegX86;
312 iselSB = iselSB_X86;
sewardjc6f970f2012-04-02 21:54:49 +0000313 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
314 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000315 emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000316 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000317 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000318 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardjf13a16a2004-07-05 17:10:14 +0000319 break;
sewardj2a9ad022004-11-25 02:46:58 +0000320
sewardjc33671d2005-02-01 20:30:00 +0000321 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000322 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000323 getAllocableRegs_AMD64 ( &n_available_real_regs,
324 &available_real_regs );
325 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000326 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
327 getRegUsage_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000328 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000329 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
330 genSpill_AMD64;
331 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
332 genReload_AMD64;
cerion92b64362005-12-13 12:02:26 +0000333 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000334 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000335 iselSB = iselSB_AMD64;
sewardjc6f970f2012-04-02 21:54:49 +0000336 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
337 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000338 emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000339 host_is_bigendian = False;
340 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000341 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardjc33671d2005-02-01 20:30:00 +0000342 break;
343
cerion487e4c92005-02-04 16:28:19 +0000344 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000345 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000346 getAllocableRegs_PPC ( &n_available_real_regs,
347 &available_real_regs, mode64 );
348 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
349 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
350 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000351 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
352 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000353 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
354 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000355 iselSB = iselSB_PPC;
sewardj3dee8492012-04-20 00:13:28 +0000356 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
357 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000358 emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000359 host_is_bigendian = True;
360 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000361 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
cerion487e4c92005-02-04 16:28:19 +0000362 break;
363
cerionf0de28c2005-12-13 20:21:11 +0000364 case VexArchPPC64:
365 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000366 getAllocableRegs_PPC ( &n_available_real_regs,
367 &available_real_regs, mode64 );
368 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
369 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
370 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000371 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
372 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000373 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
374 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000375 iselSB = iselSB_PPC;
sewardj9e1cf152012-04-20 02:18:31 +0000376 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
377 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000378 emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000379 host_is_bigendian = True;
380 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000381 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000382 break;
383
sewardj2019a972011-03-07 16:04:07 +0000384 case VexArchS390X:
385 mode64 = True;
386 getAllocableRegs_S390 ( &n_available_real_regs,
387 &available_real_regs, mode64 );
388 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
389 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
390 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
391 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
392 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
393 ppInstr = (void(*)(HInstr*, Bool)) ppS390Instr;
394 ppReg = (void(*)(HReg)) ppHRegS390;
395 iselSB = iselSB_S390;
florian8844a632012-04-13 04:04:06 +0000396 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
397 void*,void*,void*,void*)) emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000398 host_is_bigendian = True;
399 host_word_type = Ity_I64;
400 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj2019a972011-03-07 16:04:07 +0000401 break;
402
sewardj6c299f32009-12-31 18:00:12 +0000403 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000404 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000405 getAllocableRegs_ARM ( &n_available_real_regs,
406 &available_real_regs );
sewardj2a1ed8e2009-12-31 19:26:03 +0000407 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
408 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
409 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
410 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
411 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
412 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
413 ppReg = (void(*)(HReg)) ppHRegARM;
414 iselSB = iselSB_ARM;
sewardjc6f970f2012-04-02 21:54:49 +0000415 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
416 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000417 emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000418 host_is_bigendian = False;
419 host_word_type = Ity_I32;
420 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000421 break;
422
sewardjbbcf1882014-01-12 12:49:10 +0000423 case VexArchARM64:
424 mode64 = True;
425 getAllocableRegs_ARM64 ( &n_available_real_regs,
426 &available_real_regs );
427 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARM64Instr;
428 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
429 getRegUsage_ARM64Instr;
430 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool))
431 mapRegs_ARM64Instr;
432 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
433 genSpill_ARM64;
434 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
435 genReload_ARM64;
436 ppInstr = (void(*)(HInstr*, Bool)) ppARM64Instr;
437 ppReg = (void(*)(HReg)) ppHRegARM64;
438 iselSB = iselSB_ARM64;
439 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
440 void*,void*,void*,void*))
441 emit_ARM64Instr;
442 host_is_bigendian = False;
443 host_word_type = Ity_I64;
444 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_host.hwcaps));
445 break;
446
sewardjd0e5fe72012-06-07 08:51:02 +0000447 case VexArchMIPS32:
448 mode64 = False;
449 getAllocableRegs_MIPS ( &n_available_real_regs,
450 &available_real_regs, mode64 );
451 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
452 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
453 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
454 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
455 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
456 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
457 ppReg = (void(*)(HReg)) ppHRegMIPS;
458 iselSB = iselSB_MIPS;
459 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
460 void*,void*,void*,void*))
461 emit_MIPSInstr;
sewardj74142b82013-08-08 10:28:59 +0000462# if defined(VKI_LITTLE_ENDIAN)
sewardjd0e5fe72012-06-07 08:51:02 +0000463 host_is_bigendian = False;
sewardj74142b82013-08-08 10:28:59 +0000464# elif defined(VKI_BIG_ENDIAN)
sewardjd0e5fe72012-06-07 08:51:02 +0000465 host_is_bigendian = True;
sewardj74142b82013-08-08 10:28:59 +0000466# endif
sewardjd0e5fe72012-06-07 08:51:02 +0000467 host_word_type = Ity_I32;
468 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
469 break;
470
petarjb92a9542013-02-27 22:57:17 +0000471 case VexArchMIPS64:
472 mode64 = True;
473 getAllocableRegs_MIPS ( &n_available_real_regs,
474 &available_real_regs, mode64 );
475 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
476 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
477 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
478 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
479 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
480 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
481 ppReg = (void(*)(HReg)) ppHRegMIPS;
482 iselSB = iselSB_MIPS;
483 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
484 void*,void*,void*,void*))
485 emit_MIPSInstr;
sewardj74142b82013-08-08 10:28:59 +0000486# if defined(VKI_LITTLE_ENDIAN)
petarjb92a9542013-02-27 22:57:17 +0000487 host_is_bigendian = False;
sewardj74142b82013-08-08 10:28:59 +0000488# elif defined(VKI_BIG_ENDIAN)
petarjb92a9542013-02-27 22:57:17 +0000489 host_is_bigendian = True;
sewardj74142b82013-08-08 10:28:59 +0000490# endif
petarjb92a9542013-02-27 22:57:17 +0000491 host_word_type = Ity_I64;
492 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
493 break;
494
sewardjf13a16a2004-07-05 17:10:14 +0000495 default:
sewardj6c299f32009-12-31 18:00:12 +0000496 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000497 }
498
sewardj2a9ad022004-11-25 02:46:58 +0000499
sewardj17c7f952005-12-15 14:02:34 +0000500 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000501
sewardjbef170b2004-12-21 01:23:00 +0000502 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000503 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
504 disInstrFn = disInstr_X86;
505 specHelper = guest_x86_spechelper;
506 guest_sizeB = sizeof(VexGuestX86State);
507 guest_word_type = Ity_I32;
508 guest_layout = &x86guest_layout;
509 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
510 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
511 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
512 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
513 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
514 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000515 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000516 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardjce02aa72006-01-12 12:27:58 +0000517 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
518 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
519 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000520 break;
sewardj2a9ad022004-11-25 02:46:58 +0000521
sewardj44d494d2005-01-20 20:26:33 +0000522 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000523 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
524 disInstrFn = disInstr_AMD64;
525 specHelper = guest_amd64_spechelper;
526 guest_sizeB = sizeof(VexGuestAMD64State);
527 guest_word_type = Ity_I64;
528 guest_layout = &amd64guest_layout;
529 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
530 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
531 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
532 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
533 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
534 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000535 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000536 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000537 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000538 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
539 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000540 break;
541
cerionaabdfbf2005-01-29 12:56:15 +0000542 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000543 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
544 disInstrFn = disInstr_PPC;
545 specHelper = guest_ppc32_spechelper;
546 guest_sizeB = sizeof(VexGuestPPC32State);
547 guest_word_type = Ity_I32;
548 guest_layout = &ppc32Guest_layout;
549 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
550 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
551 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
552 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
553 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
554 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000555 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000556 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000557 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000558 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
559 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000560 break;
561
cerionf0de28c2005-12-13 20:21:11 +0000562 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000563 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
564 disInstrFn = disInstr_PPC;
565 specHelper = guest_ppc64_spechelper;
566 guest_sizeB = sizeof(VexGuestPPC64State);
567 guest_word_type = Ity_I64;
568 guest_layout = &ppc64Guest_layout;
569 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
570 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
571 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
572 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
573 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
574 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000575 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000576 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000577 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
578 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
579 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
580 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000581 break;
582
sewardj2019a972011-03-07 16:04:07 +0000583 case VexArchS390X:
584 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
585 disInstrFn = disInstr_S390;
586 specHelper = guest_s390x_spechelper;
587 guest_sizeB = sizeof(VexGuestS390XState);
588 guest_word_type = Ity_I64;
589 guest_layout = &s390xGuest_layout;
590 offB_TISTART = offsetof(VexGuestS390XState,guest_TISTART);
591 offB_TILEN = offsetof(VexGuestS390XState,guest_TILEN);
florian8844a632012-04-13 04:04:06 +0000592 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
593 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
594 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
595 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000596 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
597 vassert(0 == sizeof(VexGuestS390XState) % 16);
598 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TISTART ) == 8);
599 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TILEN ) == 8);
600 vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
601 break;
602
sewardj6c299f32009-12-31 18:00:12 +0000603 case VexArchARM:
sewardjc6f970f2012-04-02 21:54:49 +0000604 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
605 disInstrFn = disInstr_ARM;
606 specHelper = guest_arm_spechelper;
607 guest_sizeB = sizeof(VexGuestARMState);
608 guest_word_type = Ity_I32;
609 guest_layout = &armGuest_layout;
610 offB_TISTART = offsetof(VexGuestARMState,guest_TISTART);
611 offB_TILEN = offsetof(VexGuestARMState,guest_TILEN);
612 offB_GUEST_IP = offsetof(VexGuestARMState,guest_R15T);
613 szB_GUEST_IP = sizeof( ((VexGuestARMState*)0)->guest_R15T );
614 offB_HOST_EvC_COUNTER = offsetof(VexGuestARMState,host_EvC_COUNTER);
615 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARMState,host_EvC_FAILADDR);
sewardj6c299f32009-12-31 18:00:12 +0000616 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
617 vassert(0 == sizeof(VexGuestARMState) % 16);
618 vassert(sizeof( ((VexGuestARMState*)0)->guest_TISTART) == 4);
619 vassert(sizeof( ((VexGuestARMState*)0)->guest_TILEN ) == 4);
620 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
621 break;
622
sewardjbbcf1882014-01-12 12:49:10 +0000623 case VexArchARM64:
624 preciseMemExnsFn = guest_arm64_state_requires_precise_mem_exns;
625 disInstrFn = disInstr_ARM64;
626 specHelper = guest_arm64_spechelper;
627 guest_sizeB = sizeof(VexGuestARM64State);
628 guest_word_type = Ity_I64;
629 guest_layout = &arm64Guest_layout;
630 offB_TISTART = offsetof(VexGuestARM64State,guest_TISTART);
631 offB_TILEN = offsetof(VexGuestARM64State,guest_TILEN);
632 offB_GUEST_IP = offsetof(VexGuestARM64State,guest_PC);
633 szB_GUEST_IP = sizeof( ((VexGuestARM64State*)0)->guest_PC );
634 offB_HOST_EvC_COUNTER = offsetof(VexGuestARM64State,host_EvC_COUNTER);
635 offB_HOST_EvC_FAILADDR = offsetof(VexGuestARM64State,host_EvC_FAILADDR);
636 vassert(are_valid_hwcaps(VexArchARM64, vta->archinfo_guest.hwcaps));
637 vassert(0 == sizeof(VexGuestARM64State) % 16);
638 vassert(sizeof( ((VexGuestARM64State*)0)->guest_TISTART) == 8);
639 vassert(sizeof( ((VexGuestARM64State*)0)->guest_TILEN ) == 8);
640 vassert(sizeof( ((VexGuestARM64State*)0)->guest_NRADDR ) == 8);
641 break;
642
sewardjd0e5fe72012-06-07 08:51:02 +0000643 case VexArchMIPS32:
644 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
645 disInstrFn = disInstr_MIPS;
646 specHelper = guest_mips32_spechelper;
647 guest_sizeB = sizeof(VexGuestMIPS32State);
648 guest_word_type = Ity_I32;
649 guest_layout = &mips32Guest_layout;
650 offB_TISTART = offsetof(VexGuestMIPS32State,guest_TISTART);
651 offB_TILEN = offsetof(VexGuestMIPS32State,guest_TILEN);
652 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
653 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
654 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
655 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
656 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
657 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
658 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_TISTART) == 4);
659 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_TILEN ) == 4);
660 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
661 break;
662
petarjb92a9542013-02-27 22:57:17 +0000663 case VexArchMIPS64:
664 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
665 disInstrFn = disInstr_MIPS;
666 specHelper = guest_mips64_spechelper;
667 guest_sizeB = sizeof(VexGuestMIPS64State);
668 guest_word_type = Ity_I64;
669 guest_layout = &mips64Guest_layout;
670 offB_TISTART = offsetof(VexGuestMIPS64State,guest_TISTART);
671 offB_TILEN = offsetof(VexGuestMIPS64State,guest_TILEN);
672 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
673 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
674 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
675 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
676 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
677 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
678 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_TISTART) == 8);
679 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_TILEN ) == 8);
680 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
681 break;
682
sewardjf13a16a2004-07-05 17:10:14 +0000683 default:
sewardj887a11a2004-07-05 17:26:47 +0000684 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000685 }
686
sewardjbc161a42011-06-07 21:28:38 +0000687 /* Set up result struct. */
688 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000689 res.status = VexTransOK;
690 res.n_sc_extents = 0;
691 res.offs_profInc = -1;
692 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000693
sewardj9df271d2004-12-31 22:37:42 +0000694 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000695 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000696 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000697 we are simulating one flavour of an architecture a different
698 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000699 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000700 }
sewardj2a9ad022004-11-25 02:46:58 +0000701
sewardj2d6b14a2005-11-23 04:25:07 +0000702 vexAllocSanityCheck();
703
sewardjf48ac192004-10-29 00:41:29 +0000704 if (vex_traceflags & VEX_TRACE_FE)
705 vex_printf("\n------------------------"
706 " Front end "
707 "------------------------\n\n");
708
sewardjdd40fdf2006-12-24 02:20:24 +0000709 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000710 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000711 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000712 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000713 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000714 vta->guest_bytes,
715 vta->guest_bytes_addr,
716 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000717 host_is_bigendian,
sewardj442e51a2012-12-06 18:08:04 +0000718 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000719 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000720 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000721 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000722 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000723 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000724 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000725 offB_TISTART,
sewardjc6f970f2012-04-02 21:54:49 +0000726 offB_TILEN,
727 offB_GUEST_IP,
728 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000729
sewardj2d6b14a2005-11-23 04:25:07 +0000730 vexAllocSanityCheck();
731
sewardjdd40fdf2006-12-24 02:20:24 +0000732 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000733 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000734 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000735 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000736 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000737 }
sewardjaa59f942004-10-09 09:34:36 +0000738
sewardj17c7f952005-12-15 14:02:34 +0000739 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
740 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
741 for (i = 0; i < vta->guest_extents->n_used; i++) {
742 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000743 }
744
sewardjaa59f942004-10-09 09:34:36 +0000745 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000746 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000747 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000748 vex_printf("can't show code due to extents > 1\n");
749 } else {
750 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000751 UChar* p = (UChar*)vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000752 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000753 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000754 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
755 guest_bytes_read );
756 for (i = 0; i < guest_bytes_read; i++) {
757 UInt b = (UInt)p[i];
758 vex_printf(" %02x", b );
759 sum = (sum << 1) ^ b;
760 }
761 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000762 }
sewardjaa59f942004-10-09 09:34:36 +0000763 }
764
765 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000766 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000767 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000768
sewardj2d6b14a2005-11-23 04:25:07 +0000769 vexAllocSanityCheck();
770
sewardjedf4d692004-08-17 13:52:58 +0000771 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000772 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000773 vta->guest_bytes_addr,
774 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000775 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000776 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000777
sewardjf48ac192004-10-29 00:41:29 +0000778 if (vex_traceflags & VEX_TRACE_OPT1) {
779 vex_printf("\n------------------------"
780 " After pre-instr IR optimisation "
781 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000782 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000783 vex_printf("\n");
784 }
785
sewardj2d6b14a2005-11-23 04:25:07 +0000786 vexAllocSanityCheck();
787
sewardjf13a16a2004-07-05 17:10:14 +0000788 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000789 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000790 irsb = vta->instrument1(vta->callback_opaque,
791 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000792 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000793 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000794 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000795 vexAllocSanityCheck();
796
sewardj17c7f952005-12-15 14:02:34 +0000797 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000798 irsb = vta->instrument2(vta->callback_opaque,
799 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000800 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000801 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000802 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000803
sewardjf48ac192004-10-29 00:41:29 +0000804 if (vex_traceflags & VEX_TRACE_INST) {
805 vex_printf("\n------------------------"
806 " After instrumentation "
807 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000808 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000809 vex_printf("\n");
810 }
811
sewardj17c7f952005-12-15 14:02:34 +0000812 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000813 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000814 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000815
sewardj9578a8b2004-11-04 19:44:48 +0000816 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000817 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000818 do_deadcode_BB( irsb );
819 irsb = cprop_BB( irsb );
820 do_deadcode_BB( irsb );
821 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000822 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000823 }
824
sewardj2d6b14a2005-11-23 04:25:07 +0000825 vexAllocSanityCheck();
826
sewardj9578a8b2004-11-04 19:44:48 +0000827 if (vex_traceflags & VEX_TRACE_OPT2) {
828 vex_printf("\n------------------------"
829 " After post-instr IR optimisation "
830 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000831 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000832 vex_printf("\n");
833 }
834
sewardjf9517d02005-11-28 13:39:37 +0000835 /* Turn it into virtual-registerised code. Build trees -- this
836 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000837 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000838
sewardjbe1b6ff2007-08-28 06:06:27 +0000839 if (vta->finaltidy) {
840 irsb = vta->finaltidy(irsb);
841 }
842
sewardj2d6b14a2005-11-23 04:25:07 +0000843 vexAllocSanityCheck();
844
sewardjf48ac192004-10-29 00:41:29 +0000845 if (vex_traceflags & VEX_TRACE_TREES) {
846 vex_printf("\n------------------------"
847 " After tree-building "
848 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000849 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000850 vex_printf("\n");
851 }
852
sewardje908c422005-02-04 21:18:16 +0000853 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000854 if (0) {
855 *(vta->host_bytes_used) = 0;
856 res.status = VexTransOK; return res;
857 }
sewardje908c422005-02-04 21:18:16 +0000858 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000859
sewardjf48ac192004-10-29 00:41:29 +0000860 if (vex_traceflags & VEX_TRACE_VCODE)
861 vex_printf("\n------------------------"
862 " Instruction selection "
863 "------------------------\n");
864
sewardjc6f970f2012-04-02 21:54:49 +0000865 /* No guest has its IP field at offset zero. If this fails it
866 means some transformation pass somewhere failed to update/copy
867 irsb->offsIP properly. */
868 vassert(irsb->offsIP >= 16);
869
870 vcode = iselSB ( irsb, vta->arch_host,
871 &vta->archinfo_host,
872 &vta->abiinfo_both,
873 offB_HOST_EvC_COUNTER,
874 offB_HOST_EvC_FAILADDR,
875 chainingAllowed,
876 vta->addProfInc,
877 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000878
sewardj2d6b14a2005-11-23 04:25:07 +0000879 vexAllocSanityCheck();
880
sewardjf48ac192004-10-29 00:41:29 +0000881 if (vex_traceflags & VEX_TRACE_VCODE)
882 vex_printf("\n");
883
sewardjf48ac192004-10-29 00:41:29 +0000884 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000885 for (i = 0; i < vcode->arr_used; i++) {
886 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000887 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000888 vex_printf("\n");
889 }
sewardjfbcaf332004-07-08 01:46:01 +0000890 vex_printf("\n");
891 }
sewardjfbcaf332004-07-08 01:46:01 +0000892
sewardjf13a16a2004-07-05 17:10:14 +0000893 /* Register allocate. */
894 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000895 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000896 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000897 genSpill, genReload, directReload,
898 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000899 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000900
sewardj2d6b14a2005-11-23 04:25:07 +0000901 vexAllocSanityCheck();
902
sewardjf48ac192004-10-29 00:41:29 +0000903 if (vex_traceflags & VEX_TRACE_RCODE) {
904 vex_printf("\n------------------------"
905 " Register-allocated code "
906 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000907 for (i = 0; i < rcode->arr_used; i++) {
908 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000909 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000910 vex_printf("\n");
911 }
sewardjfbcaf332004-07-08 01:46:01 +0000912 vex_printf("\n");
913 }
sewardjfbcaf332004-07-08 01:46:01 +0000914
sewardje908c422005-02-04 21:18:16 +0000915 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000916 if (0) {
917 *(vta->host_bytes_used) = 0;
918 res.status = VexTransOK; return res;
919 }
sewardje908c422005-02-04 21:18:16 +0000920 /* end HACK */
921
sewardj81bd5502004-07-21 18:49:27 +0000922 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000923 if (vex_traceflags & VEX_TRACE_ASM) {
924 vex_printf("\n------------------------"
925 " Assembly "
926 "------------------------\n\n");
927 }
928
sewardj81bd5502004-07-21 18:49:27 +0000929 out_used = 0; /* tracks along the host_bytes array */
930 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000931 HInstr* hi = rcode->arr[i];
932 Bool hi_isProfInc = False;
933 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
934 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000935 vex_printf("\n");
936 }
sewardjc6f970f2012-04-02 21:54:49 +0000937 j = emit( &hi_isProfInc,
938 insn_bytes, sizeof insn_bytes, hi, mode64,
939 vta->disp_cp_chain_me_to_slowEP,
940 vta->disp_cp_chain_me_to_fastEP,
941 vta->disp_cp_xindir,
942 vta->disp_cp_xassisted );
943 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000944 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000945 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000946 vex_printf("0%x ", (UInt)insn_bytes[k]);
947 else
948 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000949 vex_printf("\n\n");
950 }
sewardjc6f970f2012-04-02 21:54:49 +0000951 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000952 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000953 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000954 res.status = VexTransOutputFull;
955 return res;
sewardj81bd5502004-07-21 18:49:27 +0000956 }
sewardjc6f970f2012-04-02 21:54:49 +0000957 if (UNLIKELY(hi_isProfInc)) {
958 vassert(vta->addProfInc); /* else where did it come from? */
959 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
960 vassert(out_used >= 0);
961 res.offs_profInc = out_used;
962 }
963 { UChar* dst = &vta->host_bytes[out_used];
964 for (k = 0; k < j; k++) {
965 dst[k] = insn_bytes[k];
966 }
967 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000968 }
sewardj17c7f952005-12-15 14:02:34 +0000969 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000970 }
sewardj17c7f952005-12-15 14:02:34 +0000971 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000972
sewardj2d6b14a2005-11-23 04:25:07 +0000973 vexAllocSanityCheck();
974
975 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000976
sewardj65ea17e2012-12-28 09:01:59 +0000977 if (vex_traceflags) {
978 /* Print the expansion ratio for this SB. */
979 j = 0; /* total guest bytes */
980 for (i = 0; i < vta->guest_extents->n_used; i++) {
981 j += vta->guest_extents->len[i];
982 }
983 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
984 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
985 }
986
sewardjf48ac192004-10-29 00:41:29 +0000987 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000988 res.status = VexTransOK;
989 return res;
sewardj35421a32004-07-05 13:12:34 +0000990}
991
992
sewardjc6f970f2012-04-02 21:54:49 +0000993/* --------- Chain/Unchain XDirects. --------- */
994
995VexInvalRange LibVEX_Chain ( VexArch arch_host,
996 void* place_to_chain,
997 void* disp_cp_chain_me_EXPECTED,
998 void* place_to_jump_to )
999{
1000 VexInvalRange (*chainXDirect)(void*, void*, void*) = NULL;
1001 switch (arch_host) {
1002 case VexArchX86:
1003 chainXDirect = chainXDirect_X86; break;
1004 case VexArchAMD64:
1005 chainXDirect = chainXDirect_AMD64; break;
1006 case VexArchARM:
1007 chainXDirect = chainXDirect_ARM; break;
sewardjbbcf1882014-01-12 12:49:10 +00001008 case VexArchARM64:
1009 chainXDirect = chainXDirect_ARM64; break;
florian8844a632012-04-13 04:04:06 +00001010 case VexArchS390X:
1011 chainXDirect = chainXDirect_S390; break;
sewardj3dee8492012-04-20 00:13:28 +00001012 case VexArchPPC32:
1013 return chainXDirect_PPC(place_to_chain,
1014 disp_cp_chain_me_EXPECTED,
1015 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001016 case VexArchPPC64:
1017 return chainXDirect_PPC(place_to_chain,
1018 disp_cp_chain_me_EXPECTED,
1019 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001020 case VexArchMIPS32:
1021 return chainXDirect_MIPS(place_to_chain,
1022 disp_cp_chain_me_EXPECTED,
1023 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001024 case VexArchMIPS64:
1025 return chainXDirect_MIPS(place_to_chain,
1026 disp_cp_chain_me_EXPECTED,
1027 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001028 default:
1029 vassert(0);
1030 }
1031 vassert(chainXDirect);
1032 VexInvalRange vir
1033 = chainXDirect(place_to_chain, disp_cp_chain_me_EXPECTED,
1034 place_to_jump_to);
1035 return vir;
1036}
1037
1038VexInvalRange LibVEX_UnChain ( VexArch arch_host,
1039 void* place_to_unchain,
1040 void* place_to_jump_to_EXPECTED,
1041 void* disp_cp_chain_me )
1042{
1043 VexInvalRange (*unchainXDirect)(void*, void*, void*) = NULL;
1044 switch (arch_host) {
1045 case VexArchX86:
1046 unchainXDirect = unchainXDirect_X86; break;
1047 case VexArchAMD64:
1048 unchainXDirect = unchainXDirect_AMD64; break;
1049 case VexArchARM:
1050 unchainXDirect = unchainXDirect_ARM; break;
florian8844a632012-04-13 04:04:06 +00001051 case VexArchS390X:
1052 unchainXDirect = unchainXDirect_S390; break;
sewardj3dee8492012-04-20 00:13:28 +00001053 case VexArchPPC32:
1054 return unchainXDirect_PPC(place_to_unchain,
1055 place_to_jump_to_EXPECTED,
1056 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001057 case VexArchPPC64:
1058 return unchainXDirect_PPC(place_to_unchain,
1059 place_to_jump_to_EXPECTED,
1060 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001061 case VexArchMIPS32:
1062 return unchainXDirect_MIPS(place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001063 place_to_jump_to_EXPECTED,
1064 disp_cp_chain_me, False/*!mode64*/);
1065 case VexArchMIPS64:
1066 return unchainXDirect_MIPS(place_to_unchain,
1067 place_to_jump_to_EXPECTED,
1068 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001069 default:
1070 vassert(0);
1071 }
1072 vassert(unchainXDirect);
1073 VexInvalRange vir
1074 = unchainXDirect(place_to_unchain, place_to_jump_to_EXPECTED,
1075 disp_cp_chain_me);
1076 return vir;
1077}
1078
1079Int LibVEX_evCheckSzB ( VexArch arch_host )
1080{
1081 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1082 if (UNLIKELY(cached == 0)) {
1083 switch (arch_host) {
1084 case VexArchX86:
1085 cached = evCheckSzB_X86(); break;
1086 case VexArchAMD64:
1087 cached = evCheckSzB_AMD64(); break;
1088 case VexArchARM:
1089 cached = evCheckSzB_ARM(); break;
sewardjbbcf1882014-01-12 12:49:10 +00001090 case VexArchARM64:
1091 cached = evCheckSzB_ARM64(); break;
florian8844a632012-04-13 04:04:06 +00001092 case VexArchS390X:
1093 cached = evCheckSzB_S390(); break;
sewardj3dee8492012-04-20 00:13:28 +00001094 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001095 case VexArchPPC64:
sewardj3dee8492012-04-20 00:13:28 +00001096 cached = evCheckSzB_PPC(); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001097 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001098 case VexArchMIPS64:
sewardjd0e5fe72012-06-07 08:51:02 +00001099 cached = evCheckSzB_MIPS(); break;
sewardjc6f970f2012-04-02 21:54:49 +00001100 default:
1101 vassert(0);
1102 }
1103 }
1104 return cached;
1105}
1106
1107VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1108 void* place_to_patch,
1109 ULong* location_of_counter )
1110{
1111 VexInvalRange (*patchProfInc)(void*,ULong*) = NULL;
1112 switch (arch_host) {
1113 case VexArchX86:
1114 patchProfInc = patchProfInc_X86; break;
1115 case VexArchAMD64:
1116 patchProfInc = patchProfInc_AMD64; break;
1117 case VexArchARM:
1118 patchProfInc = patchProfInc_ARM; break;
florian8844a632012-04-13 04:04:06 +00001119 case VexArchS390X:
1120 patchProfInc = patchProfInc_S390; break;
sewardj3dee8492012-04-20 00:13:28 +00001121 case VexArchPPC32:
1122 return patchProfInc_PPC(place_to_patch,
1123 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001124 case VexArchPPC64:
1125 return patchProfInc_PPC(place_to_patch,
1126 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001127 case VexArchMIPS32:
1128 return patchProfInc_MIPS(place_to_patch,
1129 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001130 case VexArchMIPS64:
1131 return patchProfInc_MIPS(place_to_patch,
1132 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001133 default:
1134 vassert(0);
1135 }
1136 vassert(patchProfInc);
1137 VexInvalRange vir
1138 = patchProfInc(place_to_patch, location_of_counter);
1139 return vir;
1140}
1141
1142
sewardj893aada2004-11-29 19:57:54 +00001143/* --------- Emulation warnings. --------- */
1144
florian1ff47562012-10-21 02:09:51 +00001145const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001146{
1147 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001148 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001149 return "none";
1150 case EmWarn_X86_x87exns:
1151 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001152 case EmWarn_X86_x87precision:
1153 return "Selection of non-80-bit x87 FP precision";
1154 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001155 return "Unmasking SSE FP exceptions";
1156 case EmWarn_X86_fz:
1157 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1158 case EmWarn_X86_daz:
1159 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001160 case EmWarn_X86_acFlag:
1161 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001162 case EmWarn_PPCexns:
1163 return "Unmasking PPC32/64 FP exceptions";
1164 case EmWarn_PPC64_redir_overflow:
1165 return "PPC64 function redirection stack overflow";
1166 case EmWarn_PPC64_redir_underflow:
1167 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001168 case EmWarn_S390X_fpext_rounding:
1169 return "The specified rounding mode cannot be supported. That\n"
1170 " feature requires the floating point extension facility.\n"
1171 " which is not available on this host. Continuing using\n"
1172 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001173 case EmWarn_S390X_invalid_rounding:
1174 return "The specified rounding mode is invalid.\n"
1175 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001176 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001177 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001178 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001179 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001180 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001181 return "Instruction ecag is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001182 case EmFail_S390X_fpext:
1183 return "Encountered an instruction that requires the floating "
1184 "point extension facility.\n"
1185 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001186 case EmFail_S390X_invalid_PFPO_rounding_mode:
1187 return "The rounding mode specified in GPR 0 for PFPO instruction"
1188 " is invalid";
1189 case EmFail_S390X_invalid_PFPO_function:
1190 return "The function code specified in GPR 0 for PFPO instruction"
1191 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001192 default:
florian6ef84be2012-08-26 03:20:07 +00001193 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001194 }
1195}
sewardj35421a32004-07-05 13:12:34 +00001196
sewardj5117ce12006-01-27 21:20:15 +00001197/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001198
1199const HChar* LibVEX_ppVexArch ( VexArch arch )
1200{
1201 switch (arch) {
1202 case VexArch_INVALID: return "INVALID";
1203 case VexArchX86: return "X86";
1204 case VexArchAMD64: return "AMD64";
1205 case VexArchARM: return "ARM";
sewardjbbcf1882014-01-12 12:49:10 +00001206 case VexArchARM64: return "ARM64";
sewardj0ec57c52005-02-01 15:24:10 +00001207 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001208 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001209 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001210 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001211 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001212 default: return "VexArch???";
1213 }
1214}
1215
sewardj5117ce12006-01-27 21:20:15 +00001216const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001217{
florian55085f82012-11-21 00:36:55 +00001218 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001219 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001220}
1221
sewardj5117ce12006-01-27 21:20:15 +00001222
sewardj27e1dd62005-06-30 11:49:14 +00001223/* Write default settings info *vai. */
1224void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1225{
florian9138b172013-08-03 19:36:55 +00001226 vai->hwcaps = 0;
1227 vai->ppc_icache_line_szB = 0;
1228 vai->ppc_dcbz_szB = 0;
1229 vai->ppc_dcbzl_szB = 0;
sewardje971c6a2010-09-03 15:49:57 +00001230
florianf192a392012-10-07 19:44:40 +00001231 vai->hwcache_info.num_levels = 0;
1232 vai->hwcache_info.num_caches = 0;
1233 vai->hwcache_info.caches = NULL;
1234 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001235}
1236
sewardjdd40fdf2006-12-24 02:20:24 +00001237/* Write default settings info *vbi. */
1238void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001239{
sewardjdd40fdf2006-12-24 02:20:24 +00001240 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001241 vbi->guest_amd64_assume_fs_is_zero = False;
1242 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001243 vbi->guest_ppc_zap_RZ_at_blr = False;
1244 vbi->guest_ppc_zap_RZ_at_bl = NULL;
1245 vbi->guest_ppc_sc_continues_at_LR = False;
1246 vbi->host_ppc_calls_use_fndescrs = False;
1247 vbi->host_ppc32_regalign_int64_args = False;
sewardjaca070a2006-10-17 00:28:22 +00001248}
1249
sewardj27e1dd62005-06-30 11:49:14 +00001250
sewardj5117ce12006-01-27 21:20:15 +00001251/* Return a string showing the hwcaps in a nice way. The string will
1252 be NULL for invalid combinations of flags, so these functions also
1253 serve as a way to validate hwcaps values. */
1254
florian55085f82012-11-21 00:36:55 +00001255static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001256{
mjw6c65c122013-08-27 10:19:03 +00001257 /* Monotonic, LZCNT > SSE3 > SSE2 > SSE1 > MMXEXT > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001258 switch (hwcaps) {
1259 case 0:
1260 return "x86-sse0";
mjw6c65c122013-08-27 10:19:03 +00001261 case VEX_HWCAPS_X86_MMXEXT:
1262 return "x86-mmxext";
1263 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1:
1264 return "x86-mmxext-sse1";
1265 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1266 return "x86-mmxext-sse1-sse2";
1267 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001268 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001269 return "x86-mmxext-sse1-sse2-lzcnt";
1270 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001271 | VEX_HWCAPS_X86_SSE3:
mjw6c65c122013-08-27 10:19:03 +00001272 return "x86-mmxext-sse1-sse2-sse3";
1273 case VEX_HWCAPS_X86_MMXEXT | VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
sewardj536fbab2010-07-29 15:39:05 +00001274 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
mjw6c65c122013-08-27 10:19:03 +00001275 return "x86-mmxext-sse1-sse2-sse3-lzcnt";
sewardj536fbab2010-07-29 15:39:05 +00001276 default:
1277 return NULL;
1278 }
sewardj5117ce12006-01-27 21:20:15 +00001279}
1280
florian55085f82012-11-21 00:36:55 +00001281static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001282{
sewardje9d8a262009-07-01 08:06:34 +00001283 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1284 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001285 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001286 orthogonal. */
1287
1288 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001289 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1290 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001291 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1292 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1293 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001294 if (have_avx && !have_sse3)
1295 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001296 /* AVX2 or BMI without AVX */
1297 if ((have_avx2 || have_bmi) && !have_avx)
1298 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001299
1300 /* This isn't threadsafe. We might need to fix it at some point. */
1301 static HChar buf[100] = { 0 };
1302 if (buf[0] != 0) return buf; /* already constructed */
1303
1304 vex_bzero(buf, sizeof(buf));
1305
1306 HChar* p = &buf[0];
1307
1308 p = p + vex_sprintf(p, "%s", "amd64");
1309 if (hwcaps == 0) {
1310 /* special-case the baseline case */
1311 p = p + vex_sprintf(p, "%s", "-sse2");
1312 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001313 }
sewardj818c7302013-03-26 13:53:18 +00001314 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1315 p = p + vex_sprintf(p, "%s", "-cx16");
1316 }
1317 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1318 p = p + vex_sprintf(p, "%s", "-lzcnt");
1319 }
1320 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1321 p = p + vex_sprintf(p, "%s", "-rdtscp");
1322 }
1323 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1324 p = p + vex_sprintf(p, "%s", "-sse3");
1325 }
1326 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1327 p = p + vex_sprintf(p, "%s", "-avx");
1328 }
sewardjcc3d2192013-03-27 11:37:33 +00001329 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1330 p = p + vex_sprintf(p, "%s", "-avx2");
1331 }
1332 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1333 p = p + vex_sprintf(p, "%s", "-bmi");
1334 }
sewardj818c7302013-03-26 13:53:18 +00001335
1336 out:
1337 vassert(buf[sizeof(buf)-1] == 0);
1338 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001339}
1340
florian55085f82012-11-21 00:36:55 +00001341static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001342{
1343 /* Monotonic with complications. Basically V > F > baseline,
1344 but once you have F then you can have FX or GX too. */
1345 const UInt F = VEX_HWCAPS_PPC32_F;
1346 const UInt V = VEX_HWCAPS_PPC32_V;
1347 const UInt FX = VEX_HWCAPS_PPC32_FX;
1348 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001349 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001350 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
carll0c74bb52013-08-12 18:01:40 +00001351 const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001352 UInt c = hwcaps;
1353 if (c == 0) return "ppc32-int";
1354 if (c == F) return "ppc32-int-flt";
1355 if (c == (F|FX)) return "ppc32-int-flt-FX";
1356 if (c == (F|GX)) return "ppc32-int-flt-GX";
1357 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1358 if (c == (F|V)) return "ppc32-int-flt-vmx";
1359 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1360 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1361 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001362 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1363 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001364 if (c == (F|V|FX|GX|VX|DFP|ISA2_07))
1365 return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
1366
sewardj5117ce12006-01-27 21:20:15 +00001367 return NULL;
1368}
1369
florian55085f82012-11-21 00:36:55 +00001370static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001371{
1372 /* Monotonic with complications. Basically V > baseline(==F),
1373 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001374 const UInt V = VEX_HWCAPS_PPC64_V;
1375 const UInt FX = VEX_HWCAPS_PPC64_FX;
1376 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001377 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001378 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
carll0c74bb52013-08-12 18:01:40 +00001379 const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07;
sewardj5117ce12006-01-27 21:20:15 +00001380 UInt c = hwcaps;
1381 if (c == 0) return "ppc64-int-flt";
1382 if (c == FX) return "ppc64-int-flt-FX";
1383 if (c == GX) return "ppc64-int-flt-GX";
1384 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1385 if (c == V) return "ppc64-int-flt-vmx";
1386 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1387 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1388 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001389 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1390 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
carll0c74bb52013-08-12 18:01:40 +00001391 if (c == (V|FX|GX|VX|DFP|ISA2_07))
1392 return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07";
sewardj5117ce12006-01-27 21:20:15 +00001393 return NULL;
1394}
1395
florian55085f82012-11-21 00:36:55 +00001396static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001397{
sewardjec0d9a02010-08-22 12:54:56 +00001398 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1399 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1400 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1401 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1402 case 5:
1403 if (N)
1404 return NULL;
1405 if (vfp)
1406 return "ARMv5-vfp";
1407 else
1408 return "ARMv5";
1409 return NULL;
1410 case 6:
1411 if (N)
1412 return NULL;
1413 if (vfp)
1414 return "ARMv6-vfp";
1415 else
1416 return "ARMv6";
1417 return NULL;
1418 case 7:
1419 if (vfp) {
1420 if (N)
1421 return "ARMv7-vfp-neon";
1422 else
1423 return "ARMv7-vfp";
1424 } else {
1425 if (N)
1426 return "ARMv7-neon";
1427 else
1428 return "ARMv7";
1429 }
1430 default:
1431 return NULL;
1432 }
sewardj5117ce12006-01-27 21:20:15 +00001433 return NULL;
1434}
1435
sewardjbbcf1882014-01-12 12:49:10 +00001436static const HChar* show_hwcaps_arm64 ( UInt hwcaps )
1437{
1438 /* Since there are no variants, just insist that hwcaps is zero,
1439 and declare it invalid otherwise. */
1440 if (hwcaps == 0)
1441 return "baseline";
1442 return NULL;
1443}
1444
florian55085f82012-11-21 00:36:55 +00001445static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001446{
sewardjd07b8562011-04-27 11:58:22 +00001447 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001448 static const struct {
1449 UInt hwcaps_bit;
1450 HChar name[6];
1451 } hwcaps_list[] = {
1452 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1453 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1454 { VEX_HWCAPS_S390X_GIE, "gie" },
1455 { VEX_HWCAPS_S390X_DFP, "dfp" },
1456 { VEX_HWCAPS_S390X_FGX, "fgx" },
1457 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1458 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1459 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1460 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1461 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1462 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001463 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001464 };
florian9061eb32012-12-09 17:53:45 +00001465#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1466 static HChar buf[sizeof prefix +
1467 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1468 1]; // '\0'
1469 HChar *p;
1470 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001471
1472 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001473
sewardj652b56a2011-04-13 15:38:17 +00001474 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1475
sewardjd07b8562011-04-27 11:58:22 +00001476 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001477 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1478 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1479 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1480 }
sewardj2019a972011-03-07 16:04:07 +00001481
sewardjd07b8562011-04-27 11:58:22 +00001482 /* If there are no facilities, add "zarch" */
1483 if (hwcaps == 0)
1484 vex_sprintf(p, "-%s", "zarch");
1485
1486 return buf;
sewardj2019a972011-03-07 16:04:07 +00001487}
1488
florian55085f82012-11-21 00:36:55 +00001489static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001490{
dejanjc3fee0d2013-07-25 09:08:03 +00001491 /* MIPS baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001492 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_MIPS) {
dejanjc3fee0d2013-07-25 09:08:03 +00001493 /* MIPS baseline with dspr2. */
petarjbc7d6f42013-09-16 18:11:59 +00001494 if (VEX_MIPS_PROC_DSP2(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001495 return "MIPS-baseline-dspr2";
1496 }
1497 /* MIPS baseline with dsp. */
petarjbc7d6f42013-09-16 18:11:59 +00001498 if (VEX_MIPS_PROC_DSP(hwcaps)) {
dejanjc3fee0d2013-07-25 09:08:03 +00001499 return "MIPS-baseline-dsp";
1500 }
1501 return "MIPS-baseline";
1502 }
1503
1504 /* Broadcom baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001505 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_BROADCOM) {
dejanjc3fee0d2013-07-25 09:08:03 +00001506 return "Broadcom-baseline";
1507 }
1508
1509 /* Netlogic baseline. */
petarjbc7d6f42013-09-16 18:11:59 +00001510 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_NETLOGIC) {
dejanjc3fee0d2013-07-25 09:08:03 +00001511 return "Netlogic-baseline";
1512 }
1513
petarjbc7d6f42013-09-16 18:11:59 +00001514 /* Cavium baseline. */
1515 if (VEX_MIPS_COMP_ID(hwcaps) == VEX_PRID_COMP_CAVIUM) {
1516 return "Cavium-baseline";
1517 }
1518
sewardjd0e5fe72012-06-07 08:51:02 +00001519 return NULL;
1520}
1521
petarjb92a9542013-02-27 22:57:17 +00001522static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1523{
1524 return "mips64-baseline";
1525}
1526
sewardj5117ce12006-01-27 21:20:15 +00001527/* ---- */
florian55085f82012-11-21 00:36:55 +00001528static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001529{
1530 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001531 case VexArchX86: return show_hwcaps_x86(hwcaps);
1532 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1533 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1534 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1535 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardjbbcf1882014-01-12 12:49:10 +00001536 case VexArchARM64: return show_hwcaps_arm64(hwcaps);
sewardjd0e5fe72012-06-07 08:51:02 +00001537 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1538 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001539 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001540 default: return NULL;
1541 }
1542}
1543
1544static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1545{
1546 return show_hwcaps(arch,hwcaps) != NULL;
1547}
1548
1549
sewardj35421a32004-07-05 13:12:34 +00001550/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001551/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001552/*---------------------------------------------------------------*/