blob: 05ca8fa7061abe67d4f4a39ab8b69cc4cc7031d8 [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
sewardj25e54732012-08-05 15:36:51 +000010 Copyright (C) 2004-2012 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"
cerionaabdfbf2005-01-29 12:56:15 +000041#include "libvex_guest_ppc32.h"
cerionf0de28c2005-12-13 20:21:11 +000042#include "libvex_guest_ppc64.h"
sewardj2019a972011-03-07 16:04:07 +000043#include "libvex_guest_s390x.h"
sewardjd0e5fe72012-06-07 08:51:02 +000044#include "libvex_guest_mips32.h"
petarjb92a9542013-02-27 22:57:17 +000045#include "libvex_guest_mips64.h"
sewardjf13a16a2004-07-05 17:10:14 +000046
sewardjcef7d3e2009-07-02 12:21:59 +000047#include "main_globals.h"
48#include "main_util.h"
49#include "host_generic_regs.h"
50#include "ir_opt.h"
sewardj35421a32004-07-05 13:12:34 +000051
sewardjcef7d3e2009-07-02 12:21:59 +000052#include "host_x86_defs.h"
53#include "host_amd64_defs.h"
54#include "host_ppc_defs.h"
sewardj6c299f32009-12-31 18:00:12 +000055#include "host_arm_defs.h"
sewardj2019a972011-03-07 16:04:07 +000056#include "host_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000057#include "host_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000058
sewardjcef7d3e2009-07-02 12:21:59 +000059#include "guest_generic_bb_to_IR.h"
60#include "guest_x86_defs.h"
61#include "guest_amd64_defs.h"
62#include "guest_arm_defs.h"
63#include "guest_ppc_defs.h"
sewardj2019a972011-03-07 16:04:07 +000064#include "guest_s390_defs.h"
sewardjd0e5fe72012-06-07 08:51:02 +000065#include "guest_mips_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000066
sewardj69d98e32010-06-18 08:17:41 +000067#include "host_generic_simd128.h"
68
sewardj35421a32004-07-05 13:12:34 +000069
70/* This file contains the top level interface to the library. */
71
sewardj5117ce12006-01-27 21:20:15 +000072/* --------- fwds ... --------- */
73
74static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
florian55085f82012-11-21 00:36:55 +000075static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
sewardj5117ce12006-01-27 21:20:15 +000076
77
sewardj8bde7f12013-04-11 13:57:43 +000078/* --------- helpers --------- */
79
80__attribute__((noinline))
81static UInt udiv32 ( UInt x, UInt y ) { return x/y; }
82__attribute__((noinline))
83static Int sdiv32 ( Int x, Int y ) { return x/y; }
84
85
sewardj35421a32004-07-05 13:12:34 +000086/* --------- Initialise the library. --------- */
87
88/* Exported to library client. */
89
sewardj08613742004-10-25 13:01:45 +000090void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
91{
92 vcon->iropt_verbosity = 0;
93 vcon->iropt_level = 2;
philippec8e2f982012-08-01 22:04:13 +000094 vcon->iropt_register_updates = VexRegUpdUnwindregsAtMemAccess;
sewardj08613742004-10-25 13:01:45 +000095 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000096 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +000097 vcon->guest_chase_thresh = 10;
sewardj984d9b12010-01-15 10:53:21 +000098 vcon->guest_chase_cond = False;
sewardj08613742004-10-25 13:01:45 +000099}
100
101
102/* Exported to library client. */
103
sewardj887a11a2004-07-05 17:26:47 +0000104void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000105 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000106 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000107 void (*failure_exit) ( void ),
108 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000109 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000110 /* debug paranoia level */
111 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000112 /* Are we supporting valgrind checking? */
113 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000114 /* Control ... */
115 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000116)
117{
sewardj08613742004-10-25 13:01:45 +0000118 /* First off, do enough minimal setup so that the following
119 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000120 vex_failure_exit = failure_exit;
121 vex_log_bytes = log_bytes;
122
123 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000124 vassert(!vex_initdone);
125 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000126 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000127 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000128
129 vassert(vcon->iropt_verbosity >= 0);
130 vassert(vcon->iropt_level >= 0);
131 vassert(vcon->iropt_level <= 2);
132 vassert(vcon->iropt_unroll_thresh >= 0);
133 vassert(vcon->iropt_unroll_thresh <= 400);
134 vassert(vcon->guest_max_insns >= 1);
135 vassert(vcon->guest_max_insns <= 100);
136 vassert(vcon->guest_chase_thresh >= 0);
137 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj984d9b12010-01-15 10:53:21 +0000138 vassert(vcon->guest_chase_cond == True
139 || vcon->guest_chase_cond == False);
sewardj443cd9d2004-07-18 23:06:45 +0000140
sewardjea602bc2004-10-14 21:40:12 +0000141 /* Check that Vex has been built with sizes of basic types as
142 stated in priv/libvex_basictypes.h. Failure of any of these is
143 a serious configuration error and should be corrected
144 immediately. If any of these assertions fail you can fully
145 expect Vex not to work properly, if at all. */
146
147 vassert(1 == sizeof(UChar));
148 vassert(1 == sizeof(Char));
149 vassert(2 == sizeof(UShort));
150 vassert(2 == sizeof(Short));
151 vassert(4 == sizeof(UInt));
152 vassert(4 == sizeof(Int));
153 vassert(8 == sizeof(ULong));
154 vassert(8 == sizeof(Long));
155 vassert(4 == sizeof(Float));
156 vassert(8 == sizeof(Double));
157 vassert(1 == sizeof(Bool));
158 vassert(4 == sizeof(Addr32));
159 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000160 vassert(16 == sizeof(U128));
sewardj69d98e32010-06-18 08:17:41 +0000161 vassert(16 == sizeof(V128));
sewardjc9069f22012-06-01 16:09:50 +0000162 vassert(32 == sizeof(U256));
sewardjea602bc2004-10-14 21:40:12 +0000163
164 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
165 vassert(sizeof(void*) == sizeof(int*));
166 vassert(sizeof(void*) == sizeof(HWord));
167
sewardj97e87932005-02-07 00:00:50 +0000168 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
169 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
170
sewardjc6f970f2012-04-02 21:54:49 +0000171 /* These take a lot of space, so make sure we don't have
172 any unnoticed size regressions. */
173 if (VEX_HOST_WORDSIZE == 4) {
florian420bfa92012-06-02 20:29:22 +0000174 vassert(sizeof(IRExpr) == 16);
sewardjc6f970f2012-04-02 21:54:49 +0000175 vassert(sizeof(IRStmt) == 20 /* x86 */
176 || sizeof(IRStmt) == 24 /* arm */);
177 } else {
florian420bfa92012-06-02 20:29:22 +0000178 vassert(sizeof(IRExpr) == 32);
floriand6f38b32012-05-31 15:46:18 +0000179 vassert(sizeof(IRStmt) == 32);
sewardjc6f970f2012-04-02 21:54:49 +0000180 }
181
sewardj8bde7f12013-04-11 13:57:43 +0000182 /* Check that signed integer division on the host rounds towards
183 zero. If not, h_calc_sdiv32_w_arm_semantics() won't work
184 correctly. */
185 /* 100.0 / 7.0 == 14.2857 */
186 vassert(udiv32(100, 7) == 14);
187 vassert(sdiv32(100, 7) == 14);
188 vassert(sdiv32(-100, 7) == -14); /* and not -15 */
189 vassert(sdiv32(100, -7) == -14); /* ditto */
190 vassert(sdiv32(-100, -7) == 14); /* not sure what this proves */
191
sewardjea602bc2004-10-14 21:40:12 +0000192 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000193 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000194 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000195 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000196 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000197 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000198}
199
200
201/* --------- Make a translation. --------- */
202
203/* Exported to library client. */
204
sewardj17c7f952005-12-15 14:02:34 +0000205VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000206{
sewardj81bd5502004-07-21 18:49:27 +0000207 /* This the bundle of functions we need to do the back-end stuff
208 (insn selection, reg-alloc, assembly) whilst being insulated
209 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000210 HReg* available_real_regs;
211 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000212 Bool (*isMove) ( HInstr*, HReg*, HReg* );
213 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
214 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000215 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
216 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000217 HInstr* (*directReload) ( HInstr*, HReg, Short );
218 void (*ppInstr) ( HInstr*, Bool );
219 void (*ppReg) ( HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000220 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*, VexAbiInfo*,
221 Int, Int, Bool, Bool, Addr64 );
222 Int (*emit) ( /*MB_MOD*/Bool*,
223 UChar*, Int, HInstr*, Bool,
224 void*, void*, void*, void* );
florian1ff47562012-10-21 02:09:51 +0000225 IRExpr* (*specHelper) ( const HChar*, IRExpr**, IRStmt**, Int );
sewardj8d2291c2004-10-25 14:50:21 +0000226 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000227
sewardj9e6491a2005-07-02 19:24:10 +0000228 DisOneInstrFn disInstrFn;
229
sewardjeeac8412004-11-02 00:26:55 +0000230 VexGuestLayout* guest_layout;
231 Bool host_is_bigendian = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000232 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000233 HInstrArray* vcode;
234 HInstrArray* rcode;
235 Int i, j, k, out_used, guest_sizeB;
sewardjc6f970f2012-04-02 21:54:49 +0000236 Int offB_TISTART, offB_TILEN, offB_GUEST_IP, szB_GUEST_IP;
237 Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
petarjb92a9542013-02-27 22:57:17 +0000238 UChar insn_bytes[128];
sewardjcf787902004-11-03 09:08:33 +0000239 IRType guest_word_type;
240 IRType host_word_type;
sewardjc6f970f2012-04-02 21:54:49 +0000241 Bool mode64, chainingAllowed;
242 Addr64 max_ga;
sewardjf13a16a2004-07-05 17:10:14 +0000243
sewardj49651f42004-10-28 22:11:04 +0000244 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000245 available_real_regs = NULL;
246 n_available_real_regs = 0;
247 isMove = NULL;
248 getRegUsage = NULL;
249 mapRegs = NULL;
250 genSpill = NULL;
251 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000252 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000253 ppInstr = NULL;
254 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000255 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000256 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000257 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000258 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000259 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000260 guest_word_type = Ity_INVALID;
261 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000262 offB_TISTART = 0;
263 offB_TILEN = 0;
sewardjc6f970f2012-04-02 21:54:49 +0000264 offB_GUEST_IP = 0;
265 szB_GUEST_IP = 0;
266 offB_HOST_EvC_COUNTER = 0;
267 offB_HOST_EvC_FAILADDR = 0;
cerion92b64362005-12-13 12:02:26 +0000268 mode64 = False;
sewardjc6f970f2012-04-02 21:54:49 +0000269 chainingAllowed = False;
sewardj36ca5132004-07-24 13:12:23 +0000270
sewardj17c7f952005-12-15 14:02:34 +0000271 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000272
sewardj35421a32004-07-05 13:12:34 +0000273 vassert(vex_initdone);
sewardjc6f970f2012-04-02 21:54:49 +0000274 vassert(vta->needs_self_check != NULL);
275 vassert(vta->disp_cp_xassisted != NULL);
276 /* Both the chainers and the indir are either NULL or non-NULL. */
277 if (vta->disp_cp_chain_me_to_slowEP != NULL) {
278 vassert(vta->disp_cp_chain_me_to_fastEP != NULL);
279 vassert(vta->disp_cp_xindir != NULL);
280 chainingAllowed = True;
281 } else {
282 vassert(vta->disp_cp_chain_me_to_fastEP == NULL);
283 vassert(vta->disp_cp_xindir == NULL);
284 }
florian2eeeb9b2011-09-23 18:03:21 +0000285
sewardj2d6b14a2005-11-23 04:25:07 +0000286 vexSetAllocModeTEMP_and_clear();
287 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000288
sewardjf13a16a2004-07-05 17:10:14 +0000289 /* First off, check that the guest and host insn sets
290 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000291
sewardj17c7f952005-12-15 14:02:34 +0000292 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000293
sewardjbef170b2004-12-21 01:23:00 +0000294 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000295 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000296 getAllocableRegs_X86 ( &n_available_real_regs,
297 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000298 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000299 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
300 getRegUsage_X86Instr;
sewardjfb7373a2007-08-25 21:29:03 +0000301 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000302 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
303 genSpill_X86;
304 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
305 genReload_X86;
sewardjfb7373a2007-08-25 21:29:03 +0000306 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
307 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
308 ppReg = (void(*)(HReg)) ppHRegX86;
309 iselSB = iselSB_X86;
sewardjc6f970f2012-04-02 21:54:49 +0000310 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
311 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000312 emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000313 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000314 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000315 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardjf13a16a2004-07-05 17:10:14 +0000316 break;
sewardj2a9ad022004-11-25 02:46:58 +0000317
sewardjc33671d2005-02-01 20:30:00 +0000318 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000319 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000320 getAllocableRegs_AMD64 ( &n_available_real_regs,
321 &available_real_regs );
322 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000323 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool))
324 getRegUsage_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000325 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000326 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
327 genSpill_AMD64;
328 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool))
329 genReload_AMD64;
cerion92b64362005-12-13 12:02:26 +0000330 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000331 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000332 iselSB = iselSB_AMD64;
sewardjc6f970f2012-04-02 21:54:49 +0000333 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
334 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000335 emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000336 host_is_bigendian = False;
337 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000338 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardjc33671d2005-02-01 20:30:00 +0000339 break;
340
cerion487e4c92005-02-04 16:28:19 +0000341 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000342 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000343 getAllocableRegs_PPC ( &n_available_real_regs,
344 &available_real_regs, mode64 );
345 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
346 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
347 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000348 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
349 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000350 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
351 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000352 iselSB = iselSB_PPC;
sewardj3dee8492012-04-20 00:13:28 +0000353 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
354 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000355 emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000356 host_is_bigendian = True;
357 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000358 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
cerion487e4c92005-02-04 16:28:19 +0000359 break;
360
cerionf0de28c2005-12-13 20:21:11 +0000361 case VexArchPPC64:
362 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000363 getAllocableRegs_PPC ( &n_available_real_regs,
364 &available_real_regs, mode64 );
365 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
366 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
367 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
sewardj2a1ed8e2009-12-31 19:26:03 +0000368 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_PPC;
369 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000370 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
371 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000372 iselSB = iselSB_PPC;
sewardj9e1cf152012-04-20 02:18:31 +0000373 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
374 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000375 emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000376 host_is_bigendian = True;
377 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000378 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000379 break;
380
sewardj2019a972011-03-07 16:04:07 +0000381 case VexArchS390X:
382 mode64 = True;
383 getAllocableRegs_S390 ( &n_available_real_regs,
384 &available_real_regs, mode64 );
385 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_S390Instr;
386 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_S390Instr;
387 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_S390Instr;
388 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_S390;
389 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_S390;
390 ppInstr = (void(*)(HInstr*, Bool)) ppS390Instr;
391 ppReg = (void(*)(HReg)) ppHRegS390;
392 iselSB = iselSB_S390;
florian8844a632012-04-13 04:04:06 +0000393 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
394 void*,void*,void*,void*)) emit_S390Instr;
sewardj2019a972011-03-07 16:04:07 +0000395 host_is_bigendian = True;
396 host_word_type = Ity_I64;
397 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_host.hwcaps));
sewardj2019a972011-03-07 16:04:07 +0000398 break;
399
sewardj6c299f32009-12-31 18:00:12 +0000400 case VexArchARM:
sewardj2a1ed8e2009-12-31 19:26:03 +0000401 mode64 = False;
sewardj6c299f32009-12-31 18:00:12 +0000402 getAllocableRegs_ARM ( &n_available_real_regs,
403 &available_real_regs );
sewardj2a1ed8e2009-12-31 19:26:03 +0000404 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
405 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
406 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
407 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_ARM;
408 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_ARM;
409 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
410 ppReg = (void(*)(HReg)) ppHRegARM;
411 iselSB = iselSB_ARM;
sewardjc6f970f2012-04-02 21:54:49 +0000412 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
413 void*,void*,void*,void*))
sewardj010ac542011-05-29 09:29:18 +0000414 emit_ARMInstr;
sewardj6c299f32009-12-31 18:00:12 +0000415 host_is_bigendian = False;
416 host_word_type = Ity_I32;
417 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000418 break;
419
sewardjd0e5fe72012-06-07 08:51:02 +0000420 case VexArchMIPS32:
421 mode64 = False;
422 getAllocableRegs_MIPS ( &n_available_real_regs,
423 &available_real_regs, mode64 );
424 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
425 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
426 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
427 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
428 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
429 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
430 ppReg = (void(*)(HReg)) ppHRegMIPS;
431 iselSB = iselSB_MIPS;
432 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
433 void*,void*,void*,void*))
434 emit_MIPSInstr;
435#if defined(VKI_LITTLE_ENDIAN)
436 host_is_bigendian = False;
437#elif defined(VKI_BIG_ENDIAN)
438 host_is_bigendian = True;
439#endif
440 host_word_type = Ity_I32;
441 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_host.hwcaps));
442 break;
443
petarjb92a9542013-02-27 22:57:17 +0000444 case VexArchMIPS64:
445 mode64 = True;
446 getAllocableRegs_MIPS ( &n_available_real_regs,
447 &available_real_regs, mode64 );
448 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_MIPSInstr;
449 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_MIPSInstr;
450 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_MIPSInstr;
451 genSpill = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genSpill_MIPS;
452 genReload = (void(*)(HInstr**,HInstr**,HReg,Int,Bool)) genReload_MIPS;
453 ppInstr = (void(*)(HInstr*, Bool)) ppMIPSInstr;
454 ppReg = (void(*)(HReg)) ppHRegMIPS;
455 iselSB = iselSB_MIPS;
456 emit = (Int(*)(Bool*,UChar*,Int,HInstr*,Bool,
457 void*,void*,void*,void*))
458 emit_MIPSInstr;
459#if defined(VKI_LITTLE_ENDIAN)
460 host_is_bigendian = False;
461#elif defined(VKI_BIG_ENDIAN)
462 host_is_bigendian = True;
463#endif
464 host_word_type = Ity_I64;
465 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_host.hwcaps));
466 break;
467
sewardjf13a16a2004-07-05 17:10:14 +0000468 default:
sewardj6c299f32009-12-31 18:00:12 +0000469 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000470 }
471
sewardj2a9ad022004-11-25 02:46:58 +0000472
sewardj17c7f952005-12-15 14:02:34 +0000473 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000474
sewardjbef170b2004-12-21 01:23:00 +0000475 case VexArchX86:
sewardjc6f970f2012-04-02 21:54:49 +0000476 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
477 disInstrFn = disInstr_X86;
478 specHelper = guest_x86_spechelper;
479 guest_sizeB = sizeof(VexGuestX86State);
480 guest_word_type = Ity_I32;
481 guest_layout = &x86guest_layout;
482 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
483 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
484 offB_GUEST_IP = offsetof(VexGuestX86State,guest_EIP);
485 szB_GUEST_IP = sizeof( ((VexGuestX86State*)0)->guest_EIP );
486 offB_HOST_EvC_COUNTER = offsetof(VexGuestX86State,host_EvC_COUNTER);
487 offB_HOST_EvC_FAILADDR = offsetof(VexGuestX86State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000488 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000489 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardjce02aa72006-01-12 12:27:58 +0000490 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
491 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
492 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000493 break;
sewardj2a9ad022004-11-25 02:46:58 +0000494
sewardj44d494d2005-01-20 20:26:33 +0000495 case VexArchAMD64:
sewardjc6f970f2012-04-02 21:54:49 +0000496 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
497 disInstrFn = disInstr_AMD64;
498 specHelper = guest_amd64_spechelper;
499 guest_sizeB = sizeof(VexGuestAMD64State);
500 guest_word_type = Ity_I64;
501 guest_layout = &amd64guest_layout;
502 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
503 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
504 offB_GUEST_IP = offsetof(VexGuestAMD64State,guest_RIP);
505 szB_GUEST_IP = sizeof( ((VexGuestAMD64State*)0)->guest_RIP );
506 offB_HOST_EvC_COUNTER = offsetof(VexGuestAMD64State,host_EvC_COUNTER);
507 offB_HOST_EvC_FAILADDR = offsetof(VexGuestAMD64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000508 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000509 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000510 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000511 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
512 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000513 break;
514
cerionaabdfbf2005-01-29 12:56:15 +0000515 case VexArchPPC32:
sewardj3dee8492012-04-20 00:13:28 +0000516 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
517 disInstrFn = disInstr_PPC;
518 specHelper = guest_ppc32_spechelper;
519 guest_sizeB = sizeof(VexGuestPPC32State);
520 guest_word_type = Ity_I32;
521 guest_layout = &ppc32Guest_layout;
522 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
523 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
524 offB_GUEST_IP = offsetof(VexGuestPPC32State,guest_CIA);
525 szB_GUEST_IP = sizeof( ((VexGuestPPC32State*)0)->guest_CIA );
526 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC32State,host_EvC_COUNTER);
527 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC32State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000528 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000529 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000530 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000531 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
532 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000533 break;
534
cerionf0de28c2005-12-13 20:21:11 +0000535 case VexArchPPC64:
sewardj9e1cf152012-04-20 02:18:31 +0000536 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
537 disInstrFn = disInstr_PPC;
538 specHelper = guest_ppc64_spechelper;
539 guest_sizeB = sizeof(VexGuestPPC64State);
540 guest_word_type = Ity_I64;
541 guest_layout = &ppc64Guest_layout;
542 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
543 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
544 offB_GUEST_IP = offsetof(VexGuestPPC64State,guest_CIA);
545 szB_GUEST_IP = sizeof( ((VexGuestPPC64State*)0)->guest_CIA );
546 offB_HOST_EvC_COUNTER = offsetof(VexGuestPPC64State,host_EvC_COUNTER);
547 offB_HOST_EvC_FAILADDR = offsetof(VexGuestPPC64State,host_EvC_FAILADDR);
sewardj5117ce12006-01-27 21:20:15 +0000548 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000549 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000550 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
551 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
552 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
553 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000554 break;
555
sewardj2019a972011-03-07 16:04:07 +0000556 case VexArchS390X:
557 preciseMemExnsFn = guest_s390x_state_requires_precise_mem_exns;
558 disInstrFn = disInstr_S390;
559 specHelper = guest_s390x_spechelper;
560 guest_sizeB = sizeof(VexGuestS390XState);
561 guest_word_type = Ity_I64;
562 guest_layout = &s390xGuest_layout;
563 offB_TISTART = offsetof(VexGuestS390XState,guest_TISTART);
564 offB_TILEN = offsetof(VexGuestS390XState,guest_TILEN);
florian8844a632012-04-13 04:04:06 +0000565 offB_GUEST_IP = offsetof(VexGuestS390XState,guest_IA);
566 szB_GUEST_IP = sizeof( ((VexGuestS390XState*)0)->guest_IA);
567 offB_HOST_EvC_COUNTER = offsetof(VexGuestS390XState,host_EvC_COUNTER);
568 offB_HOST_EvC_FAILADDR = offsetof(VexGuestS390XState,host_EvC_FAILADDR);
sewardj2019a972011-03-07 16:04:07 +0000569 vassert(are_valid_hwcaps(VexArchS390X, vta->archinfo_guest.hwcaps));
570 vassert(0 == sizeof(VexGuestS390XState) % 16);
571 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TISTART ) == 8);
572 vassert(sizeof( ((VexGuestS390XState*)0)->guest_TILEN ) == 8);
573 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;
583 offB_TISTART = offsetof(VexGuestARMState,guest_TISTART);
584 offB_TILEN = offsetof(VexGuestARMState,guest_TILEN);
585 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));
590 vassert(0 == sizeof(VexGuestARMState) % 16);
591 vassert(sizeof( ((VexGuestARMState*)0)->guest_TISTART) == 4);
592 vassert(sizeof( ((VexGuestARMState*)0)->guest_TILEN ) == 4);
593 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
594 break;
595
sewardjd0e5fe72012-06-07 08:51:02 +0000596 case VexArchMIPS32:
597 preciseMemExnsFn = guest_mips32_state_requires_precise_mem_exns;
598 disInstrFn = disInstr_MIPS;
599 specHelper = guest_mips32_spechelper;
600 guest_sizeB = sizeof(VexGuestMIPS32State);
601 guest_word_type = Ity_I32;
602 guest_layout = &mips32Guest_layout;
603 offB_TISTART = offsetof(VexGuestMIPS32State,guest_TISTART);
604 offB_TILEN = offsetof(VexGuestMIPS32State,guest_TILEN);
605 offB_GUEST_IP = offsetof(VexGuestMIPS32State,guest_PC);
606 szB_GUEST_IP = sizeof( ((VexGuestMIPS32State*)0)->guest_PC );
607 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS32State,host_EvC_COUNTER);
608 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS32State,host_EvC_FAILADDR);
609 vassert(are_valid_hwcaps(VexArchMIPS32, vta->archinfo_guest.hwcaps));
610 vassert(0 == sizeof(VexGuestMIPS32State) % 16);
611 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_TISTART) == 4);
612 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_TILEN ) == 4);
613 vassert(sizeof( ((VexGuestMIPS32State*)0)->guest_NRADDR ) == 4);
614 break;
615
petarjb92a9542013-02-27 22:57:17 +0000616 case VexArchMIPS64:
617 preciseMemExnsFn = guest_mips64_state_requires_precise_mem_exns;
618 disInstrFn = disInstr_MIPS;
619 specHelper = guest_mips64_spechelper;
620 guest_sizeB = sizeof(VexGuestMIPS64State);
621 guest_word_type = Ity_I64;
622 guest_layout = &mips64Guest_layout;
623 offB_TISTART = offsetof(VexGuestMIPS64State,guest_TISTART);
624 offB_TILEN = offsetof(VexGuestMIPS64State,guest_TILEN);
625 offB_GUEST_IP = offsetof(VexGuestMIPS64State,guest_PC);
626 szB_GUEST_IP = sizeof( ((VexGuestMIPS64State*)0)->guest_PC );
627 offB_HOST_EvC_COUNTER = offsetof(VexGuestMIPS64State,host_EvC_COUNTER);
628 offB_HOST_EvC_FAILADDR = offsetof(VexGuestMIPS64State,host_EvC_FAILADDR);
629 vassert(are_valid_hwcaps(VexArchMIPS64, vta->archinfo_guest.hwcaps));
630 vassert(0 == sizeof(VexGuestMIPS64State) % 16);
631 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_TISTART) == 8);
632 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_TILEN ) == 8);
633 vassert(sizeof( ((VexGuestMIPS64State*)0)->guest_NRADDR ) == 8);
634 break;
635
sewardjf13a16a2004-07-05 17:10:14 +0000636 default:
sewardj887a11a2004-07-05 17:26:47 +0000637 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000638 }
639
sewardjbc161a42011-06-07 21:28:38 +0000640 /* Set up result struct. */
641 VexTranslateResult res;
sewardjfadbbe22012-04-24 11:49:03 +0000642 res.status = VexTransOK;
643 res.n_sc_extents = 0;
644 res.offs_profInc = -1;
645 res.n_guest_instrs = 0;
sewardjbc161a42011-06-07 21:28:38 +0000646
sewardj9df271d2004-12-31 22:37:42 +0000647 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000648 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000649 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000650 we are simulating one flavour of an architecture a different
651 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000652 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000653 }
sewardj2a9ad022004-11-25 02:46:58 +0000654
sewardj2d6b14a2005-11-23 04:25:07 +0000655 vexAllocSanityCheck();
656
sewardjf48ac192004-10-29 00:41:29 +0000657 if (vex_traceflags & VEX_TRACE_FE)
658 vex_printf("\n------------------------"
659 " Front end "
660 "------------------------\n\n");
661
sewardjdd40fdf2006-12-24 02:20:24 +0000662 irsb = bb_to_IR ( vta->guest_extents,
sewardjbc161a42011-06-07 21:28:38 +0000663 &res.n_sc_extents,
sewardjfadbbe22012-04-24 11:49:03 +0000664 &res.n_guest_instrs,
sewardjc716aea2006-01-17 01:48:46 +0000665 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000666 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000667 vta->guest_bytes,
668 vta->guest_bytes_addr,
669 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000670 host_is_bigendian,
sewardj442e51a2012-12-06 18:08:04 +0000671 vta->sigill_diag,
sewardja5f55da2006-04-30 23:37:32 +0000672 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000673 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000674 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000675 guest_word_type,
sewardjbc161a42011-06-07 21:28:38 +0000676 vta->needs_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000677 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000678 offB_TISTART,
sewardjc6f970f2012-04-02 21:54:49 +0000679 offB_TILEN,
680 offB_GUEST_IP,
681 szB_GUEST_IP );
sewardjf13a16a2004-07-05 17:10:14 +0000682
sewardj2d6b14a2005-11-23 04:25:07 +0000683 vexAllocSanityCheck();
684
sewardjdd40fdf2006-12-24 02:20:24 +0000685 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000686 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000687 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000688 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000689 res.status = VexTransAccessFail; return res;
sewardjf13a16a2004-07-05 17:10:14 +0000690 }
sewardjaa59f942004-10-09 09:34:36 +0000691
sewardj17c7f952005-12-15 14:02:34 +0000692 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
693 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
694 for (i = 0; i < vta->guest_extents->n_used; i++) {
695 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000696 }
697
sewardjaa59f942004-10-09 09:34:36 +0000698 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000699 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000700 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000701 vex_printf("can't show code due to extents > 1\n");
702 } else {
703 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000704 UChar* p = (UChar*)vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000705 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000706 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000707 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
708 guest_bytes_read );
709 for (i = 0; i < guest_bytes_read; i++) {
710 UInt b = (UInt)p[i];
711 vex_printf(" %02x", b );
712 sum = (sum << 1) ^ b;
713 }
714 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000715 }
sewardjaa59f942004-10-09 09:34:36 +0000716 }
717
718 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000719 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000720 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000721
sewardj2d6b14a2005-11-23 04:25:07 +0000722 vexAllocSanityCheck();
723
sewardjedf4d692004-08-17 13:52:58 +0000724 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000725 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardjec0d9a02010-08-22 12:54:56 +0000726 vta->guest_bytes_addr,
727 vta->arch_guest );
sewardjdd40fdf2006-12-24 02:20:24 +0000728 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000729 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000730
sewardjf48ac192004-10-29 00:41:29 +0000731 if (vex_traceflags & VEX_TRACE_OPT1) {
732 vex_printf("\n------------------------"
733 " After pre-instr IR optimisation "
734 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000735 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000736 vex_printf("\n");
737 }
738
sewardj2d6b14a2005-11-23 04:25:07 +0000739 vexAllocSanityCheck();
740
sewardjf13a16a2004-07-05 17:10:14 +0000741 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000742 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000743 irsb = vta->instrument1(vta->callback_opaque,
744 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000745 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000746 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000747 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000748 vexAllocSanityCheck();
749
sewardj17c7f952005-12-15 14:02:34 +0000750 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000751 irsb = vta->instrument2(vta->callback_opaque,
752 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000753 vta->guest_extents,
florian50481922012-10-07 21:58:07 +0000754 &vta->archinfo_host,
sewardj17c7f952005-12-15 14:02:34 +0000755 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000756
sewardjf48ac192004-10-29 00:41:29 +0000757 if (vex_traceflags & VEX_TRACE_INST) {
758 vex_printf("\n------------------------"
759 " After instrumentation "
760 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000761 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000762 vex_printf("\n");
763 }
764
sewardj17c7f952005-12-15 14:02:34 +0000765 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000766 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000767 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000768
sewardj9578a8b2004-11-04 19:44:48 +0000769 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000770 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000771 do_deadcode_BB( irsb );
772 irsb = cprop_BB( irsb );
773 do_deadcode_BB( irsb );
774 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000775 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000776 }
777
sewardj2d6b14a2005-11-23 04:25:07 +0000778 vexAllocSanityCheck();
779
sewardj9578a8b2004-11-04 19:44:48 +0000780 if (vex_traceflags & VEX_TRACE_OPT2) {
781 vex_printf("\n------------------------"
782 " After post-instr IR optimisation "
783 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000784 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000785 vex_printf("\n");
786 }
787
sewardjf9517d02005-11-28 13:39:37 +0000788 /* Turn it into virtual-registerised code. Build trees -- this
789 also throws away any dead bindings. */
florian62140c12013-01-20 03:51:04 +0000790 max_ga = ado_treebuild_BB( irsb, preciseMemExnsFn );
sewardjf48ac192004-10-29 00:41:29 +0000791
sewardjbe1b6ff2007-08-28 06:06:27 +0000792 if (vta->finaltidy) {
793 irsb = vta->finaltidy(irsb);
794 }
795
sewardj2d6b14a2005-11-23 04:25:07 +0000796 vexAllocSanityCheck();
797
sewardjf48ac192004-10-29 00:41:29 +0000798 if (vex_traceflags & VEX_TRACE_TREES) {
799 vex_printf("\n------------------------"
800 " After tree-building "
801 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000802 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000803 vex_printf("\n");
804 }
805
sewardje908c422005-02-04 21:18:16 +0000806 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000807 if (0) {
808 *(vta->host_bytes_used) = 0;
809 res.status = VexTransOK; return res;
810 }
sewardje908c422005-02-04 21:18:16 +0000811 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000812
sewardjf48ac192004-10-29 00:41:29 +0000813 if (vex_traceflags & VEX_TRACE_VCODE)
814 vex_printf("\n------------------------"
815 " Instruction selection "
816 "------------------------\n");
817
sewardjc6f970f2012-04-02 21:54:49 +0000818 /* No guest has its IP field at offset zero. If this fails it
819 means some transformation pass somewhere failed to update/copy
820 irsb->offsIP properly. */
821 vassert(irsb->offsIP >= 16);
822
823 vcode = iselSB ( irsb, vta->arch_host,
824 &vta->archinfo_host,
825 &vta->abiinfo_both,
826 offB_HOST_EvC_COUNTER,
827 offB_HOST_EvC_FAILADDR,
828 chainingAllowed,
829 vta->addProfInc,
830 max_ga );
sewardjf13a16a2004-07-05 17:10:14 +0000831
sewardj2d6b14a2005-11-23 04:25:07 +0000832 vexAllocSanityCheck();
833
sewardjf48ac192004-10-29 00:41:29 +0000834 if (vex_traceflags & VEX_TRACE_VCODE)
835 vex_printf("\n");
836
sewardjf48ac192004-10-29 00:41:29 +0000837 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000838 for (i = 0; i < vcode->arr_used; i++) {
839 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000840 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000841 vex_printf("\n");
842 }
sewardjfbcaf332004-07-08 01:46:01 +0000843 vex_printf("\n");
844 }
sewardjfbcaf332004-07-08 01:46:01 +0000845
sewardjf13a16a2004-07-05 17:10:14 +0000846 /* Register allocate. */
847 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000848 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000849 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000850 genSpill, genReload, directReload,
851 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000852 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000853
sewardj2d6b14a2005-11-23 04:25:07 +0000854 vexAllocSanityCheck();
855
sewardjf48ac192004-10-29 00:41:29 +0000856 if (vex_traceflags & VEX_TRACE_RCODE) {
857 vex_printf("\n------------------------"
858 " Register-allocated code "
859 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000860 for (i = 0; i < rcode->arr_used; i++) {
861 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000862 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000863 vex_printf("\n");
864 }
sewardjfbcaf332004-07-08 01:46:01 +0000865 vex_printf("\n");
866 }
sewardjfbcaf332004-07-08 01:46:01 +0000867
sewardje908c422005-02-04 21:18:16 +0000868 /* HACK */
sewardjbc161a42011-06-07 21:28:38 +0000869 if (0) {
870 *(vta->host_bytes_used) = 0;
871 res.status = VexTransOK; return res;
872 }
sewardje908c422005-02-04 21:18:16 +0000873 /* end HACK */
874
sewardj81bd5502004-07-21 18:49:27 +0000875 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000876 if (vex_traceflags & VEX_TRACE_ASM) {
877 vex_printf("\n------------------------"
878 " Assembly "
879 "------------------------\n\n");
880 }
881
sewardj81bd5502004-07-21 18:49:27 +0000882 out_used = 0; /* tracks along the host_bytes array */
883 for (i = 0; i < rcode->arr_used; i++) {
sewardjc6f970f2012-04-02 21:54:49 +0000884 HInstr* hi = rcode->arr[i];
885 Bool hi_isProfInc = False;
886 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
887 ppInstr(hi, mode64);
sewardjbad34a92004-07-22 01:14:11 +0000888 vex_printf("\n");
889 }
sewardjc6f970f2012-04-02 21:54:49 +0000890 j = emit( &hi_isProfInc,
891 insn_bytes, sizeof insn_bytes, hi, mode64,
892 vta->disp_cp_chain_me_to_slowEP,
893 vta->disp_cp_chain_me_to_fastEP,
894 vta->disp_cp_xindir,
895 vta->disp_cp_xassisted );
896 if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
sewardjbad34a92004-07-22 01:14:11 +0000897 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000898 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000899 vex_printf("0%x ", (UInt)insn_bytes[k]);
900 else
901 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000902 vex_printf("\n\n");
903 }
sewardjc6f970f2012-04-02 21:54:49 +0000904 if (UNLIKELY(out_used + j > vta->host_bytes_size)) {
sewardj2d6b14a2005-11-23 04:25:07 +0000905 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000906 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000907 res.status = VexTransOutputFull;
908 return res;
sewardj81bd5502004-07-21 18:49:27 +0000909 }
sewardjc6f970f2012-04-02 21:54:49 +0000910 if (UNLIKELY(hi_isProfInc)) {
911 vassert(vta->addProfInc); /* else where did it come from? */
912 vassert(res.offs_profInc == -1); /* there can be only one (tm) */
913 vassert(out_used >= 0);
914 res.offs_profInc = out_used;
915 }
916 { UChar* dst = &vta->host_bytes[out_used];
917 for (k = 0; k < j; k++) {
918 dst[k] = insn_bytes[k];
919 }
920 out_used += j;
sewardj81bd5502004-07-21 18:49:27 +0000921 }
sewardj17c7f952005-12-15 14:02:34 +0000922 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000923 }
sewardj17c7f952005-12-15 14:02:34 +0000924 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000925
sewardj2d6b14a2005-11-23 04:25:07 +0000926 vexAllocSanityCheck();
927
928 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000929
sewardj65ea17e2012-12-28 09:01:59 +0000930 if (vex_traceflags) {
931 /* Print the expansion ratio for this SB. */
932 j = 0; /* total guest bytes */
933 for (i = 0; i < vta->guest_extents->n_used; i++) {
934 j += vta->guest_extents->len[i];
935 }
936 if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
937 j, out_used, (10 * out_used) / (j == 0 ? 1 : j));
938 }
939
sewardjf48ac192004-10-29 00:41:29 +0000940 vex_traceflags = 0;
sewardjbc161a42011-06-07 21:28:38 +0000941 res.status = VexTransOK;
942 return res;
sewardj35421a32004-07-05 13:12:34 +0000943}
944
945
sewardjc6f970f2012-04-02 21:54:49 +0000946/* --------- Chain/Unchain XDirects. --------- */
947
948VexInvalRange LibVEX_Chain ( VexArch arch_host,
949 void* place_to_chain,
950 void* disp_cp_chain_me_EXPECTED,
951 void* place_to_jump_to )
952{
953 VexInvalRange (*chainXDirect)(void*, void*, void*) = NULL;
954 switch (arch_host) {
955 case VexArchX86:
956 chainXDirect = chainXDirect_X86; break;
957 case VexArchAMD64:
958 chainXDirect = chainXDirect_AMD64; break;
959 case VexArchARM:
960 chainXDirect = chainXDirect_ARM; break;
florian8844a632012-04-13 04:04:06 +0000961 case VexArchS390X:
962 chainXDirect = chainXDirect_S390; break;
sewardj3dee8492012-04-20 00:13:28 +0000963 case VexArchPPC32:
964 return chainXDirect_PPC(place_to_chain,
965 disp_cp_chain_me_EXPECTED,
966 place_to_jump_to, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +0000967 case VexArchPPC64:
968 return chainXDirect_PPC(place_to_chain,
969 disp_cp_chain_me_EXPECTED,
970 place_to_jump_to, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +0000971 case VexArchMIPS32:
972 return chainXDirect_MIPS(place_to_chain,
973 disp_cp_chain_me_EXPECTED,
974 place_to_jump_to, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +0000975 case VexArchMIPS64:
976 return chainXDirect_MIPS(place_to_chain,
977 disp_cp_chain_me_EXPECTED,
978 place_to_jump_to, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +0000979 default:
980 vassert(0);
981 }
982 vassert(chainXDirect);
983 VexInvalRange vir
984 = chainXDirect(place_to_chain, disp_cp_chain_me_EXPECTED,
985 place_to_jump_to);
986 return vir;
987}
988
989VexInvalRange LibVEX_UnChain ( VexArch arch_host,
990 void* place_to_unchain,
991 void* place_to_jump_to_EXPECTED,
992 void* disp_cp_chain_me )
993{
994 VexInvalRange (*unchainXDirect)(void*, void*, void*) = NULL;
995 switch (arch_host) {
996 case VexArchX86:
997 unchainXDirect = unchainXDirect_X86; break;
998 case VexArchAMD64:
999 unchainXDirect = unchainXDirect_AMD64; break;
1000 case VexArchARM:
1001 unchainXDirect = unchainXDirect_ARM; break;
florian8844a632012-04-13 04:04:06 +00001002 case VexArchS390X:
1003 unchainXDirect = unchainXDirect_S390; break;
sewardj3dee8492012-04-20 00:13:28 +00001004 case VexArchPPC32:
1005 return unchainXDirect_PPC(place_to_unchain,
1006 place_to_jump_to_EXPECTED,
1007 disp_cp_chain_me, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001008 case VexArchPPC64:
1009 return unchainXDirect_PPC(place_to_unchain,
1010 place_to_jump_to_EXPECTED,
1011 disp_cp_chain_me, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001012 case VexArchMIPS32:
1013 return unchainXDirect_MIPS(place_to_unchain,
petarjb92a9542013-02-27 22:57:17 +00001014 place_to_jump_to_EXPECTED,
1015 disp_cp_chain_me, False/*!mode64*/);
1016 case VexArchMIPS64:
1017 return unchainXDirect_MIPS(place_to_unchain,
1018 place_to_jump_to_EXPECTED,
1019 disp_cp_chain_me, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001020 default:
1021 vassert(0);
1022 }
1023 vassert(unchainXDirect);
1024 VexInvalRange vir
1025 = unchainXDirect(place_to_unchain, place_to_jump_to_EXPECTED,
1026 disp_cp_chain_me);
1027 return vir;
1028}
1029
1030Int LibVEX_evCheckSzB ( VexArch arch_host )
1031{
1032 static Int cached = 0; /* DO NOT MAKE NON-STATIC */
1033 if (UNLIKELY(cached == 0)) {
1034 switch (arch_host) {
1035 case VexArchX86:
1036 cached = evCheckSzB_X86(); break;
1037 case VexArchAMD64:
1038 cached = evCheckSzB_AMD64(); break;
1039 case VexArchARM:
1040 cached = evCheckSzB_ARM(); break;
florian8844a632012-04-13 04:04:06 +00001041 case VexArchS390X:
1042 cached = evCheckSzB_S390(); break;
sewardj3dee8492012-04-20 00:13:28 +00001043 case VexArchPPC32:
sewardjf252de52012-04-20 10:42:24 +00001044 case VexArchPPC64:
sewardj3dee8492012-04-20 00:13:28 +00001045 cached = evCheckSzB_PPC(); break;
sewardjd0e5fe72012-06-07 08:51:02 +00001046 case VexArchMIPS32:
petarjb92a9542013-02-27 22:57:17 +00001047 case VexArchMIPS64:
sewardjd0e5fe72012-06-07 08:51:02 +00001048 cached = evCheckSzB_MIPS(); break;
sewardjc6f970f2012-04-02 21:54:49 +00001049 default:
1050 vassert(0);
1051 }
1052 }
1053 return cached;
1054}
1055
1056VexInvalRange LibVEX_PatchProfInc ( VexArch arch_host,
1057 void* place_to_patch,
1058 ULong* location_of_counter )
1059{
1060 VexInvalRange (*patchProfInc)(void*,ULong*) = NULL;
1061 switch (arch_host) {
1062 case VexArchX86:
1063 patchProfInc = patchProfInc_X86; break;
1064 case VexArchAMD64:
1065 patchProfInc = patchProfInc_AMD64; break;
1066 case VexArchARM:
1067 patchProfInc = patchProfInc_ARM; break;
florian8844a632012-04-13 04:04:06 +00001068 case VexArchS390X:
1069 patchProfInc = patchProfInc_S390; break;
sewardj3dee8492012-04-20 00:13:28 +00001070 case VexArchPPC32:
1071 return patchProfInc_PPC(place_to_patch,
1072 location_of_counter, False/*!mode64*/);
sewardjf252de52012-04-20 10:42:24 +00001073 case VexArchPPC64:
1074 return patchProfInc_PPC(place_to_patch,
1075 location_of_counter, True/*mode64*/);
sewardjd0e5fe72012-06-07 08:51:02 +00001076 case VexArchMIPS32:
1077 return patchProfInc_MIPS(place_to_patch,
1078 location_of_counter, False/*!mode64*/);
petarjb92a9542013-02-27 22:57:17 +00001079 case VexArchMIPS64:
1080 return patchProfInc_MIPS(place_to_patch,
1081 location_of_counter, True/*!mode64*/);
sewardjc6f970f2012-04-02 21:54:49 +00001082 default:
1083 vassert(0);
1084 }
1085 vassert(patchProfInc);
1086 VexInvalRange vir
1087 = patchProfInc(place_to_patch, location_of_counter);
1088 return vir;
1089}
1090
1091
sewardj893aada2004-11-29 19:57:54 +00001092/* --------- Emulation warnings. --------- */
1093
florian1ff47562012-10-21 02:09:51 +00001094const HChar* LibVEX_EmNote_string ( VexEmNote ew )
sewardj893aada2004-11-29 19:57:54 +00001095{
1096 switch (ew) {
florian6ef84be2012-08-26 03:20:07 +00001097 case EmNote_NONE:
sewardj893aada2004-11-29 19:57:54 +00001098 return "none";
1099 case EmWarn_X86_x87exns:
1100 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +00001101 case EmWarn_X86_x87precision:
1102 return "Selection of non-80-bit x87 FP precision";
1103 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +00001104 return "Unmasking SSE FP exceptions";
1105 case EmWarn_X86_fz:
1106 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
1107 case EmWarn_X86_daz:
1108 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +00001109 case EmWarn_X86_acFlag:
1110 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +00001111 case EmWarn_PPCexns:
1112 return "Unmasking PPC32/64 FP exceptions";
1113 case EmWarn_PPC64_redir_overflow:
1114 return "PPC64 function redirection stack overflow";
1115 case EmWarn_PPC64_redir_underflow:
1116 return "PPC64 function redirection stack underflow";
florian4b8efad2012-09-02 18:07:08 +00001117 case EmWarn_S390X_fpext_rounding:
1118 return "The specified rounding mode cannot be supported. That\n"
1119 " feature requires the floating point extension facility.\n"
1120 " which is not available on this host. Continuing using\n"
1121 " the rounding mode from FPC. Results may differ!";
florianf0fa1be2012-09-18 20:24:38 +00001122 case EmWarn_S390X_invalid_rounding:
1123 return "The specified rounding mode is invalid.\n"
1124 " Continuing using 'round to nearest'. Results may differ!";
floriane75dafa2012-09-01 17:54:09 +00001125 case EmFail_S390X_stfle:
florian4e0083e2012-08-26 03:41:56 +00001126 return "Instruction stfle is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001127 case EmFail_S390X_stckf:
florianc5c669b2012-08-26 14:32:28 +00001128 return "Instruction stckf is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001129 case EmFail_S390X_ecag:
florian8c88cb62012-08-26 18:58:13 +00001130 return "Instruction ecag is not supported on this host";
floriane75dafa2012-09-01 17:54:09 +00001131 case EmFail_S390X_fpext:
1132 return "Encountered an instruction that requires the floating "
1133 "point extension facility.\n"
1134 " That facility is not available on this host";
florian78d5ef72013-05-11 15:02:58 +00001135 case EmFail_S390X_invalid_PFPO_rounding_mode:
1136 return "The rounding mode specified in GPR 0 for PFPO instruction"
1137 " is invalid";
1138 case EmFail_S390X_invalid_PFPO_function:
1139 return "The function code specified in GPR 0 for PFPO instruction"
1140 " is invalid";
sewardj893aada2004-11-29 19:57:54 +00001141 default:
florian6ef84be2012-08-26 03:20:07 +00001142 vpanic("LibVEX_EmNote_string: unknown warning");
sewardj893aada2004-11-29 19:57:54 +00001143 }
1144}
sewardj35421a32004-07-05 13:12:34 +00001145
sewardj5117ce12006-01-27 21:20:15 +00001146/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +00001147
1148const HChar* LibVEX_ppVexArch ( VexArch arch )
1149{
1150 switch (arch) {
1151 case VexArch_INVALID: return "INVALID";
1152 case VexArchX86: return "X86";
1153 case VexArchAMD64: return "AMD64";
1154 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +00001155 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +00001156 case VexArchPPC64: return "PPC64";
sewardj2019a972011-03-07 16:04:07 +00001157 case VexArchS390X: return "S390X";
sewardjd0e5fe72012-06-07 08:51:02 +00001158 case VexArchMIPS32: return "MIPS32";
petarjb92a9542013-02-27 22:57:17 +00001159 case VexArchMIPS64: return "MIPS64";
sewardjbef170b2004-12-21 01:23:00 +00001160 default: return "VexArch???";
1161 }
1162}
1163
sewardj5117ce12006-01-27 21:20:15 +00001164const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +00001165{
florian55085f82012-11-21 00:36:55 +00001166 const HChar* str = show_hwcaps(arch,hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001167 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +00001168}
1169
sewardj5117ce12006-01-27 21:20:15 +00001170
sewardj27e1dd62005-06-30 11:49:14 +00001171/* Write default settings info *vai. */
1172void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
1173{
sewardj5117ce12006-01-27 21:20:15 +00001174 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +00001175 vai->ppc_cache_line_szB = 0;
sewardje971c6a2010-09-03 15:49:57 +00001176 vai->ppc_dcbz_szB = 0;
1177 vai->ppc_dcbzl_szB = 0;
1178
florianf192a392012-10-07 19:44:40 +00001179 vai->hwcache_info.num_levels = 0;
1180 vai->hwcache_info.num_caches = 0;
1181 vai->hwcache_info.caches = NULL;
1182 vai->hwcache_info.icaches_maintain_coherence = True; // whatever
sewardj27e1dd62005-06-30 11:49:14 +00001183}
1184
sewardjdd40fdf2006-12-24 02:20:24 +00001185/* Write default settings info *vbi. */
1186void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +00001187{
sewardjdd40fdf2006-12-24 02:20:24 +00001188 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +00001189 vbi->guest_amd64_assume_fs_is_zero = False;
1190 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +00001191 vbi->guest_ppc_zap_RZ_at_blr = False;
1192 vbi->guest_ppc_zap_RZ_at_bl = NULL;
1193 vbi->guest_ppc_sc_continues_at_LR = False;
1194 vbi->host_ppc_calls_use_fndescrs = False;
1195 vbi->host_ppc32_regalign_int64_args = False;
sewardjaca070a2006-10-17 00:28:22 +00001196}
1197
sewardj27e1dd62005-06-30 11:49:14 +00001198
sewardj5117ce12006-01-27 21:20:15 +00001199/* Return a string showing the hwcaps in a nice way. The string will
1200 be NULL for invalid combinations of flags, so these functions also
1201 serve as a way to validate hwcaps values. */
1202
florian55085f82012-11-21 00:36:55 +00001203static const HChar* show_hwcaps_x86 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001204{
1205 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
sewardj536fbab2010-07-29 15:39:05 +00001206 switch (hwcaps) {
1207 case 0:
1208 return "x86-sse0";
1209 case VEX_HWCAPS_X86_SSE1:
1210 return "x86-sse1";
1211 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2:
1212 return "x86-sse1-sse2";
1213 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1214 | VEX_HWCAPS_X86_LZCNT:
1215 return "x86-sse1-sse2-lzcnt";
1216 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1217 | VEX_HWCAPS_X86_SSE3:
1218 return "x86-sse1-sse2-sse3";
1219 case VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2
1220 | VEX_HWCAPS_X86_SSE3 | VEX_HWCAPS_X86_LZCNT:
1221 return "x86-sse1-sse2-sse3-lzcnt";
1222 default:
1223 return NULL;
1224 }
sewardj5117ce12006-01-27 21:20:15 +00001225}
1226
florian55085f82012-11-21 00:36:55 +00001227static const HChar* show_hwcaps_amd64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001228{
sewardje9d8a262009-07-01 08:06:34 +00001229 /* SSE3 and CX16 are orthogonal and > baseline, although we really
1230 don't expect to come across anything which can do SSE3 but can't
sewardj536fbab2010-07-29 15:39:05 +00001231 do CX16. Still, we can handle that case. LZCNT is similarly
sewardj818c7302013-03-26 13:53:18 +00001232 orthogonal. */
1233
1234 /* Throw out obviously stupid cases: */
sewardj818c7302013-03-26 13:53:18 +00001235 Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
1236 Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
sewardjcc3d2192013-03-27 11:37:33 +00001237 Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
1238 Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
1239 /* AVX without SSE3 */
sewardj818c7302013-03-26 13:53:18 +00001240 if (have_avx && !have_sse3)
1241 return NULL;
sewardjcc3d2192013-03-27 11:37:33 +00001242 /* AVX2 or BMI without AVX */
1243 if ((have_avx2 || have_bmi) && !have_avx)
1244 return NULL;
sewardj818c7302013-03-26 13:53:18 +00001245
1246 /* This isn't threadsafe. We might need to fix it at some point. */
1247 static HChar buf[100] = { 0 };
1248 if (buf[0] != 0) return buf; /* already constructed */
1249
1250 vex_bzero(buf, sizeof(buf));
1251
1252 HChar* p = &buf[0];
1253
1254 p = p + vex_sprintf(p, "%s", "amd64");
1255 if (hwcaps == 0) {
1256 /* special-case the baseline case */
1257 p = p + vex_sprintf(p, "%s", "-sse2");
1258 goto out;
sewardj536fbab2010-07-29 15:39:05 +00001259 }
sewardj818c7302013-03-26 13:53:18 +00001260 if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
1261 p = p + vex_sprintf(p, "%s", "-cx16");
1262 }
1263 if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
1264 p = p + vex_sprintf(p, "%s", "-lzcnt");
1265 }
1266 if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
1267 p = p + vex_sprintf(p, "%s", "-rdtscp");
1268 }
1269 if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
1270 p = p + vex_sprintf(p, "%s", "-sse3");
1271 }
1272 if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
1273 p = p + vex_sprintf(p, "%s", "-avx");
1274 }
sewardjcc3d2192013-03-27 11:37:33 +00001275 if (hwcaps & VEX_HWCAPS_AMD64_AVX2) {
1276 p = p + vex_sprintf(p, "%s", "-avx2");
1277 }
1278 if (hwcaps & VEX_HWCAPS_AMD64_BMI) {
1279 p = p + vex_sprintf(p, "%s", "-bmi");
1280 }
sewardj818c7302013-03-26 13:53:18 +00001281
1282 out:
1283 vassert(buf[sizeof(buf)-1] == 0);
1284 return buf;
sewardj5117ce12006-01-27 21:20:15 +00001285}
1286
florian55085f82012-11-21 00:36:55 +00001287static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001288{
1289 /* Monotonic with complications. Basically V > F > baseline,
1290 but once you have F then you can have FX or GX too. */
1291 const UInt F = VEX_HWCAPS_PPC32_F;
1292 const UInt V = VEX_HWCAPS_PPC32_V;
1293 const UInt FX = VEX_HWCAPS_PPC32_FX;
1294 const UInt GX = VEX_HWCAPS_PPC32_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001295 const UInt VX = VEX_HWCAPS_PPC32_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001296 const UInt DFP = VEX_HWCAPS_PPC32_DFP;
sewardj5117ce12006-01-27 21:20:15 +00001297 UInt c = hwcaps;
1298 if (c == 0) return "ppc32-int";
1299 if (c == F) return "ppc32-int-flt";
1300 if (c == (F|FX)) return "ppc32-int-flt-FX";
1301 if (c == (F|GX)) return "ppc32-int-flt-GX";
1302 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
1303 if (c == (F|V)) return "ppc32-int-flt-vmx";
1304 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
1305 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
1306 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001307 if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP";
1308 if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP";
sewardj5117ce12006-01-27 21:20:15 +00001309 return NULL;
1310}
1311
florian55085f82012-11-21 00:36:55 +00001312static const HChar* show_hwcaps_ppc64 ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001313{
1314 /* Monotonic with complications. Basically V > baseline(==F),
1315 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +00001316 const UInt V = VEX_HWCAPS_PPC64_V;
1317 const UInt FX = VEX_HWCAPS_PPC64_FX;
1318 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj66d5ef22011-04-15 11:55:00 +00001319 const UInt VX = VEX_HWCAPS_PPC64_VX;
sewardjc66d6fa2012-04-02 21:24:12 +00001320 const UInt DFP = VEX_HWCAPS_PPC64_DFP;
sewardj5117ce12006-01-27 21:20:15 +00001321 UInt c = hwcaps;
1322 if (c == 0) return "ppc64-int-flt";
1323 if (c == FX) return "ppc64-int-flt-FX";
1324 if (c == GX) return "ppc64-int-flt-GX";
1325 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
1326 if (c == V) return "ppc64-int-flt-vmx";
1327 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
1328 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
1329 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
sewardjc66d6fa2012-04-02 21:24:12 +00001330 if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP";
1331 if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP";
sewardj5117ce12006-01-27 21:20:15 +00001332 return NULL;
1333}
1334
florian55085f82012-11-21 00:36:55 +00001335static const HChar* show_hwcaps_arm ( UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001336{
sewardjec0d9a02010-08-22 12:54:56 +00001337 Bool N = ((hwcaps & VEX_HWCAPS_ARM_NEON) != 0);
1338 Bool vfp = ((hwcaps & (VEX_HWCAPS_ARM_VFP |
1339 VEX_HWCAPS_ARM_VFP2 | VEX_HWCAPS_ARM_VFP3)) != 0);
1340 switch (VEX_ARM_ARCHLEVEL(hwcaps)) {
1341 case 5:
1342 if (N)
1343 return NULL;
1344 if (vfp)
1345 return "ARMv5-vfp";
1346 else
1347 return "ARMv5";
1348 return NULL;
1349 case 6:
1350 if (N)
1351 return NULL;
1352 if (vfp)
1353 return "ARMv6-vfp";
1354 else
1355 return "ARMv6";
1356 return NULL;
1357 case 7:
1358 if (vfp) {
1359 if (N)
1360 return "ARMv7-vfp-neon";
1361 else
1362 return "ARMv7-vfp";
1363 } else {
1364 if (N)
1365 return "ARMv7-neon";
1366 else
1367 return "ARMv7";
1368 }
1369 default:
1370 return NULL;
1371 }
sewardj5117ce12006-01-27 21:20:15 +00001372 return NULL;
1373}
1374
florian55085f82012-11-21 00:36:55 +00001375static const HChar* show_hwcaps_s390x ( UInt hwcaps )
sewardj2019a972011-03-07 16:04:07 +00001376{
sewardjd07b8562011-04-27 11:58:22 +00001377 static const HChar prefix[] = "s390x";
florian9061eb32012-12-09 17:53:45 +00001378 static const struct {
1379 UInt hwcaps_bit;
1380 HChar name[6];
1381 } hwcaps_list[] = {
1382 { VEX_HWCAPS_S390X_LDISP, "ldisp" },
1383 { VEX_HWCAPS_S390X_EIMM, "eimm" },
1384 { VEX_HWCAPS_S390X_GIE, "gie" },
1385 { VEX_HWCAPS_S390X_DFP, "dfp" },
1386 { VEX_HWCAPS_S390X_FGX, "fgx" },
1387 { VEX_HWCAPS_S390X_STFLE, "stfle" },
1388 { VEX_HWCAPS_S390X_ETF2, "etf2" },
1389 { VEX_HWCAPS_S390X_ETF3, "etf3" },
1390 { VEX_HWCAPS_S390X_STCKF, "stckf" },
1391 { VEX_HWCAPS_S390X_FPEXT, "fpext" },
1392 { VEX_HWCAPS_S390X_LSC, "lsc" },
florian78d5ef72013-05-11 15:02:58 +00001393 { VEX_HWCAPS_S390X_PFPO, "pfpo" },
sewardjd07b8562011-04-27 11:58:22 +00001394 };
florian9061eb32012-12-09 17:53:45 +00001395#define NUM_HWCAPS (sizeof hwcaps_list / sizeof hwcaps_list[0])
1396 static HChar buf[sizeof prefix +
1397 NUM_HWCAPS * (sizeof hwcaps_list[0].name + 1) +
1398 1]; // '\0'
1399 HChar *p;
1400 UInt i;
sewardjd07b8562011-04-27 11:58:22 +00001401
1402 if (buf[0] != '\0') return buf; /* already constructed */
sewardj2019a972011-03-07 16:04:07 +00001403
sewardj652b56a2011-04-13 15:38:17 +00001404 hwcaps = VEX_HWCAPS_S390X(hwcaps);
1405
sewardjd07b8562011-04-27 11:58:22 +00001406 p = buf + vex_sprintf(buf, "%s", prefix);
florian9061eb32012-12-09 17:53:45 +00001407 for (i = 0 ; i < NUM_HWCAPS; ++i) {
1408 if (hwcaps & hwcaps_list[i].hwcaps_bit)
1409 p = p + vex_sprintf(p, "-%s", hwcaps_list[i].name);
1410 }
sewardj2019a972011-03-07 16:04:07 +00001411
sewardjd07b8562011-04-27 11:58:22 +00001412 /* If there are no facilities, add "zarch" */
1413 if (hwcaps == 0)
1414 vex_sprintf(p, "-%s", "zarch");
1415
1416 return buf;
sewardj2019a972011-03-07 16:04:07 +00001417}
1418
florian55085f82012-11-21 00:36:55 +00001419static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
sewardjd0e5fe72012-06-07 08:51:02 +00001420{
dejanjc3fee0d2013-07-25 09:08:03 +00001421 /* MIPS baseline. */
1422 if (hwcaps && VEX_PRID_COMP_MIPS == VEX_PRID_COMP_MIPS) {
1423 /* MIPS baseline with dspr2. */
1424 if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
1425 return "MIPS-baseline-dspr2";
1426 }
1427 /* MIPS baseline with dsp. */
1428 if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
1429 return "MIPS-baseline-dsp";
1430 }
1431 return "MIPS-baseline";
1432 }
1433
1434 /* Broadcom baseline. */
1435 if (hwcaps && VEX_PRID_COMP_BROADCOM == VEX_PRID_COMP_BROADCOM) {
1436 /* Broadcom baseline with dspr2. */
1437 if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
1438 return "Broadcom-baseline-dspr2";
1439 }
1440 /* Broadcom baseline with dsp. */
1441 if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
1442 return "Broadcom-baseline-dsp";
1443 }
1444 return "Broadcom-baseline";
1445 }
1446
1447 /* Netlogic baseline. */
1448 if (hwcaps && VEX_PRID_COMP_NETLOGIC == VEX_PRID_COMP_NETLOGIC) {
1449 /* Netlogic baseline with dspr2. */
1450 if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
1451 return "Netlogic-baseline-dspr2";
1452 }
1453 /* Netlogic baseline with dsp. */
1454 if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
1455 return "Netlogic-baseline-dsp";
1456 }
1457 return "Netlogic-baseline";
1458 }
1459
sewardjd0e5fe72012-06-07 08:51:02 +00001460 return NULL;
1461}
1462
petarjb92a9542013-02-27 22:57:17 +00001463static const HChar* show_hwcaps_mips64 ( UInt hwcaps )
1464{
1465 return "mips64-baseline";
1466}
1467
sewardj5117ce12006-01-27 21:20:15 +00001468/* ---- */
florian55085f82012-11-21 00:36:55 +00001469static const HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
sewardj5117ce12006-01-27 21:20:15 +00001470{
1471 switch (arch) {
sewardjd0e5fe72012-06-07 08:51:02 +00001472 case VexArchX86: return show_hwcaps_x86(hwcaps);
1473 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
1474 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
1475 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
1476 case VexArchARM: return show_hwcaps_arm(hwcaps);
1477 case VexArchS390X: return show_hwcaps_s390x(hwcaps);
1478 case VexArchMIPS32: return show_hwcaps_mips32(hwcaps);
petarjb92a9542013-02-27 22:57:17 +00001479 case VexArchMIPS64: return show_hwcaps_mips64(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +00001480 default: return NULL;
1481 }
1482}
1483
1484static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
1485{
1486 return show_hwcaps(arch,hwcaps) != NULL;
1487}
1488
1489
sewardj35421a32004-07-05 13:12:34 +00001490/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001491/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +00001492/*---------------------------------------------------------------*/