blob: 5eddba483536366c9ea309cdafc409d45337a1dc [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardjcef7d3e2009-07-02 12:21:59 +00004/*--- This file (main_main.c) is ---*/
sewardjdbcfae72005-08-02 11:14:04 +00005/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/
sewardj35421a32004-07-05 13:12:34 +00006/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjf8ed9d82004-11-12 17:40:23 +00009/*
10 This file is part of LibVEX, a library for dynamic binary
11 instrumentation and translation.
12
sewardjcef7d3e2009-07-02 12:21:59 +000013 Copyright (C) 2004-2009 OpenWorks LLP. All rights reserved.
sewardjf8ed9d82004-11-12 17:40:23 +000014
sewardj7bd6ffe2005-08-03 16:07:36 +000015 This library is made available under a dual licensing scheme.
sewardjf8ed9d82004-11-12 17:40:23 +000016
sewardj7bd6ffe2005-08-03 16:07:36 +000017 If you link LibVEX against other code all of which is itself
18 licensed under the GNU General Public License, version 2 dated June
19 1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
20 v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL
21 is missing, you can obtain a copy of the GPL v2 from the Free
22 Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 02110-1301, USA.
24
25 For any other uses of LibVEX, you must first obtain a commercial
26 license from OpenWorks LLP. Please contact info@open-works.co.uk
27 for information about commercial licensing.
28
29 This software is provided by OpenWorks LLP "as is" and any express
30 or implied warranties, including, but not limited to, the implied
31 warranties of merchantability and fitness for a particular purpose
32 are disclaimed. In no event shall OpenWorks LLP be liable for any
33 direct, indirect, incidental, special, exemplary, or consequential
34 damages (including, but not limited to, procurement of substitute
35 goods or services; loss of use, data, or profits; or business
36 interruption) however caused and on any theory of liability,
37 whether in contract, strict liability, or tort (including
38 negligence or otherwise) arising in any way out of the use of this
39 software, even if advised of the possibility of such damage.
sewardjf8ed9d82004-11-12 17:40:23 +000040
41 Neither the names of the U.S. Department of Energy nor the
42 University of California nor the names of its contributors may be
43 used to endorse or promote products derived from this software
44 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000045*/
46
sewardj887a11a2004-07-05 17:26:47 +000047#include "libvex.h"
sewardj893aada2004-11-29 19:57:54 +000048#include "libvex_emwarn.h"
sewardj81ec4182004-10-25 23:15:52 +000049#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000050#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000051#include "libvex_guest_arm.h"
cerionaabdfbf2005-01-29 12:56:15 +000052#include "libvex_guest_ppc32.h"
cerionf0de28c2005-12-13 20:21:11 +000053#include "libvex_guest_ppc64.h"
sewardjf13a16a2004-07-05 17:10:14 +000054
sewardjcef7d3e2009-07-02 12:21:59 +000055#include "main_globals.h"
56#include "main_util.h"
57#include "host_generic_regs.h"
58#include "ir_opt.h"
sewardj35421a32004-07-05 13:12:34 +000059
sewardjcef7d3e2009-07-02 12:21:59 +000060#include "host_x86_defs.h"
61#include "host_amd64_defs.h"
62#include "host_ppc_defs.h"
sewardj6c299f32009-12-31 18:00:12 +000063#include "host_arm_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000064
sewardjcef7d3e2009-07-02 12:21:59 +000065#include "guest_generic_bb_to_IR.h"
66#include "guest_x86_defs.h"
67#include "guest_amd64_defs.h"
68#include "guest_arm_defs.h"
69#include "guest_ppc_defs.h"
sewardj2a9ad022004-11-25 02:46:58 +000070
sewardj35421a32004-07-05 13:12:34 +000071
72/* This file contains the top level interface to the library. */
73
sewardj5117ce12006-01-27 21:20:15 +000074/* --------- fwds ... --------- */
75
76static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
77static HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
78
79
sewardj35421a32004-07-05 13:12:34 +000080/* --------- Initialise the library. --------- */
81
82/* Exported to library client. */
83
sewardj08613742004-10-25 13:01:45 +000084void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
85{
86 vcon->iropt_verbosity = 0;
87 vcon->iropt_level = 2;
88 vcon->iropt_precise_memory_exns = False;
89 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000090 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +000091 vcon->guest_chase_thresh = 10;
92}
93
94
95/* Exported to library client. */
96
sewardj887a11a2004-07-05 17:26:47 +000097void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000098 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000099 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000100 void (*failure_exit) ( void ),
101 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000102 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000103 /* debug paranoia level */
104 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000105 /* Are we supporting valgrind checking? */
106 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000107 /* Control ... */
108 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000109)
110{
sewardj08613742004-10-25 13:01:45 +0000111 /* First off, do enough minimal setup so that the following
112 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000113 vex_failure_exit = failure_exit;
114 vex_log_bytes = log_bytes;
115
116 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000117 vassert(!vex_initdone);
118 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000119 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000120 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000121
122 vassert(vcon->iropt_verbosity >= 0);
123 vassert(vcon->iropt_level >= 0);
124 vassert(vcon->iropt_level <= 2);
125 vassert(vcon->iropt_unroll_thresh >= 0);
126 vassert(vcon->iropt_unroll_thresh <= 400);
127 vassert(vcon->guest_max_insns >= 1);
128 vassert(vcon->guest_max_insns <= 100);
129 vassert(vcon->guest_chase_thresh >= 0);
130 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000131
sewardjea602bc2004-10-14 21:40:12 +0000132 /* Check that Vex has been built with sizes of basic types as
133 stated in priv/libvex_basictypes.h. Failure of any of these is
134 a serious configuration error and should be corrected
135 immediately. If any of these assertions fail you can fully
136 expect Vex not to work properly, if at all. */
137
138 vassert(1 == sizeof(UChar));
139 vassert(1 == sizeof(Char));
140 vassert(2 == sizeof(UShort));
141 vassert(2 == sizeof(Short));
142 vassert(4 == sizeof(UInt));
143 vassert(4 == sizeof(Int));
144 vassert(8 == sizeof(ULong));
145 vassert(8 == sizeof(Long));
146 vassert(4 == sizeof(Float));
147 vassert(8 == sizeof(Double));
148 vassert(1 == sizeof(Bool));
149 vassert(4 == sizeof(Addr32));
150 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000151 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000152
153 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
154 vassert(sizeof(void*) == sizeof(int*));
155 vassert(sizeof(void*) == sizeof(HWord));
156
sewardj97e87932005-02-07 00:00:50 +0000157 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
158 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
159
sewardjea602bc2004-10-14 21:40:12 +0000160 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000161 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000162 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000163 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000164 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000165 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000166}
167
168
169/* --------- Make a translation. --------- */
170
171/* Exported to library client. */
172
sewardj17c7f952005-12-15 14:02:34 +0000173VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000174{
sewardj81bd5502004-07-21 18:49:27 +0000175 /* This the bundle of functions we need to do the back-end stuff
176 (insn selection, reg-alloc, assembly) whilst being insulated
177 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000178 HReg* available_real_regs;
179 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000180 Bool (*isMove) ( HInstr*, HReg*, HReg* );
181 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
182 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +0000183 void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
184 void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
sewardjfb7373a2007-08-25 21:29:03 +0000185 HInstr* (*directReload) ( HInstr*, HReg, Short );
186 void (*ppInstr) ( HInstr*, Bool );
187 void (*ppReg) ( HReg );
188 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*,
189 VexAbiInfo* );
190 Int (*emit) ( UChar*, Int, HInstr*, Bool, void* );
191 IRExpr* (*specHelper) ( HChar*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000192 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000193
sewardj9e6491a2005-07-02 19:24:10 +0000194 DisOneInstrFn disInstrFn;
195
sewardjeeac8412004-11-02 00:26:55 +0000196 VexGuestLayout* guest_layout;
197 Bool host_is_bigendian = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000198 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000199 HInstrArray* vcode;
200 HInstrArray* rcode;
201 Int i, j, k, out_used, guest_sizeB;
sewardjc716aea2006-01-17 01:48:46 +0000202 Int offB_TISTART, offB_TILEN;
sewardjeeac8412004-11-02 00:26:55 +0000203 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000204 IRType guest_word_type;
205 IRType host_word_type;
cerion92b64362005-12-13 12:02:26 +0000206 Bool mode64;
sewardjf13a16a2004-07-05 17:10:14 +0000207
sewardj49651f42004-10-28 22:11:04 +0000208 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000209 available_real_regs = NULL;
210 n_available_real_regs = 0;
211 isMove = NULL;
212 getRegUsage = NULL;
213 mapRegs = NULL;
214 genSpill = NULL;
215 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000216 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000217 ppInstr = NULL;
218 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000219 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000220 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000221 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000222 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000223 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000224 guest_word_type = Ity_INVALID;
225 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000226 offB_TISTART = 0;
227 offB_TILEN = 0;
cerion92b64362005-12-13 12:02:26 +0000228 mode64 = False;
sewardj36ca5132004-07-24 13:12:23 +0000229
sewardj17c7f952005-12-15 14:02:34 +0000230 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000231
sewardj35421a32004-07-05 13:12:34 +0000232 vassert(vex_initdone);
sewardj2d6b14a2005-11-23 04:25:07 +0000233 vexSetAllocModeTEMP_and_clear();
234 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000235
sewardjf13a16a2004-07-05 17:10:14 +0000236 /* First off, check that the guest and host insn sets
237 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000238
sewardj17c7f952005-12-15 14:02:34 +0000239 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000240
sewardjbef170b2004-12-21 01:23:00 +0000241 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000242 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000243 getAllocableRegs_X86 ( &n_available_real_regs,
244 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000245 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
246 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_X86Instr;
247 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
248 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_X86;
249 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_X86;
250 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
251 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
252 ppReg = (void(*)(HReg)) ppHRegX86;
253 iselSB = iselSB_X86;
254 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000255 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000256 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000257 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000258 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjf13a16a2004-07-05 17:10:14 +0000259 break;
sewardj2a9ad022004-11-25 02:46:58 +0000260
sewardjc33671d2005-02-01 20:30:00 +0000261 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000262 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000263 getAllocableRegs_AMD64 ( &n_available_real_regs,
264 &available_real_regs );
265 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000266 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_AMD64Instr;
267 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
268 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_AMD64;
269 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_AMD64;
270 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000271 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000272 iselSB = iselSB_AMD64;
sewardj0528bb52005-12-15 15:45:20 +0000273 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000274 host_is_bigendian = False;
275 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000276 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000277 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjc33671d2005-02-01 20:30:00 +0000278 break;
279
cerion487e4c92005-02-04 16:28:19 +0000280 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000281 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000282 getAllocableRegs_PPC ( &n_available_real_regs,
283 &available_real_regs, mode64 );
284 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
285 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
286 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
287 genSpill = (HInstr*(*)(HReg,Int,Bool)) genSpill_PPC;
288 genReload = (HInstr*(*)(HReg,Int,Bool)) genReload_PPC;
289 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
290 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000291 iselSB = iselSB_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000292 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000293 host_is_bigendian = True;
294 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000295 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000296 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerion487e4c92005-02-04 16:28:19 +0000297 break;
298
cerionf0de28c2005-12-13 20:21:11 +0000299 case VexArchPPC64:
300 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000301 getAllocableRegs_PPC ( &n_available_real_regs,
302 &available_real_regs, mode64 );
303 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
304 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
305 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
306 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_PPC;
307 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_PPC;
308 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
309 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000310 iselSB = iselSB_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000311 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000312 host_is_bigendian = True;
313 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000314 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000315 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerionf0de28c2005-12-13 20:21:11 +0000316 break;
317
sewardj6c299f32009-12-31 18:00:12 +0000318 case VexArchARM:
319 mode64 = False;
320 getAllocableRegs_ARM ( &n_available_real_regs,
321 &available_real_regs );
322 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_ARMInstr;
323 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_ARMInstr;
324 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_ARMInstr;
325 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_ARM;
326 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_ARM;
327 ppInstr = (void(*)(HInstr*, Bool)) ppARMInstr;
328 ppReg = (void(*)(HReg)) ppHRegARM;
329 iselSB = iselSB_ARM;
330 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_ARMInstr;
331 host_is_bigendian = False;
332 host_word_type = Ity_I32;
333 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_host.hwcaps));
334 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
335 break;
336
sewardjf13a16a2004-07-05 17:10:14 +0000337 default:
sewardj6c299f32009-12-31 18:00:12 +0000338 vpanic("LibVEX_Translate: unsupported host insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000339 }
340
sewardj2a9ad022004-11-25 02:46:58 +0000341
sewardj17c7f952005-12-15 14:02:34 +0000342 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000343
sewardjbef170b2004-12-21 01:23:00 +0000344 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000345 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000346 disInstrFn = disInstr_X86;
sewardj2a9ad022004-11-25 02:46:58 +0000347 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000348 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000349 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000350 guest_layout = &x86guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000351 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
352 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000353 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000354 vassert(0 == sizeof(VexGuestX86State) % 16);
sewardjce02aa72006-01-12 12:27:58 +0000355 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
356 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
357 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000358 break;
sewardj2a9ad022004-11-25 02:46:58 +0000359
sewardj44d494d2005-01-20 20:26:33 +0000360 case VexArchAMD64:
361 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000362 disInstrFn = disInstr_AMD64;
sewardj44d494d2005-01-20 20:26:33 +0000363 specHelper = guest_amd64_spechelper;
364 guest_sizeB = sizeof(VexGuestAMD64State);
365 guest_word_type = Ity_I64;
366 guest_layout = &amd64guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000367 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
368 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000369 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000370 vassert(0 == sizeof(VexGuestAMD64State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000371 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000372 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
373 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000374 break;
375
cerionaabdfbf2005-01-29 12:56:15 +0000376 case VexArchPPC32:
377 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000378 disInstrFn = disInstr_PPC;
cerionaabdfbf2005-01-29 12:56:15 +0000379 specHelper = guest_ppc32_spechelper;
380 guest_sizeB = sizeof(VexGuestPPC32State);
381 guest_word_type = Ity_I32;
382 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000383 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
384 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000385 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardj6c299f32009-12-31 18:00:12 +0000386 vassert(0 == sizeof(VexGuestPPC32State) % 16);
sewardjdb4738a2005-07-07 01:32:16 +0000387 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000388 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
389 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000390 break;
391
cerionf0de28c2005-12-13 20:21:11 +0000392 case VexArchPPC64:
393 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000394 disInstrFn = disInstr_PPC;
cerionf0de28c2005-12-13 20:21:11 +0000395 specHelper = guest_ppc64_spechelper;
396 guest_sizeB = sizeof(VexGuestPPC64State);
397 guest_word_type = Ity_I64;
398 guest_layout = &ppc64Guest_layout;
399 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
400 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000401 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000402 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000403 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
404 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
405 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
406 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000407 break;
408
sewardj6c299f32009-12-31 18:00:12 +0000409 case VexArchARM:
410 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
411 disInstrFn = disInstr_ARM;
412 specHelper = guest_arm_spechelper;
413 guest_sizeB = sizeof(VexGuestARMState);
414 guest_word_type = Ity_I32;
415 guest_layout = &armGuest_layout;
416 offB_TISTART = offsetof(VexGuestARMState,guest_TISTART);
417 offB_TILEN = offsetof(VexGuestARMState,guest_TILEN);
418 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
419 vassert(0 == sizeof(VexGuestARMState) % 16);
420 vassert(sizeof( ((VexGuestARMState*)0)->guest_TISTART) == 4);
421 vassert(sizeof( ((VexGuestARMState*)0)->guest_TILEN ) == 4);
422 vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
423 break;
424
sewardjf13a16a2004-07-05 17:10:14 +0000425 default:
sewardj887a11a2004-07-05 17:26:47 +0000426 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000427 }
428
sewardj9df271d2004-12-31 22:37:42 +0000429 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000430 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000431 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000432 we are simulating one flavour of an architecture a different
433 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000434 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000435 }
sewardj2a9ad022004-11-25 02:46:58 +0000436
sewardj2d6b14a2005-11-23 04:25:07 +0000437 vexAllocSanityCheck();
438
sewardjf48ac192004-10-29 00:41:29 +0000439 if (vex_traceflags & VEX_TRACE_FE)
440 vex_printf("\n------------------------"
441 " Front end "
442 "------------------------\n\n");
443
sewardjdd40fdf2006-12-24 02:20:24 +0000444 irsb = bb_to_IR ( vta->guest_extents,
sewardjc716aea2006-01-17 01:48:46 +0000445 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000446 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000447 vta->guest_bytes,
448 vta->guest_bytes_addr,
449 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000450 host_is_bigendian,
sewardja5f55da2006-04-30 23:37:32 +0000451 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000452 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000453 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000454 guest_word_type,
sewardj17c7f952005-12-15 14:02:34 +0000455 vta->do_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000456 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000457 offB_TISTART,
sewardjc716aea2006-01-17 01:48:46 +0000458 offB_TILEN );
sewardjf13a16a2004-07-05 17:10:14 +0000459
sewardj2d6b14a2005-11-23 04:25:07 +0000460 vexAllocSanityCheck();
461
sewardjdd40fdf2006-12-24 02:20:24 +0000462 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000463 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000464 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000465 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000466 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000467 }
sewardjaa59f942004-10-09 09:34:36 +0000468
sewardj17c7f952005-12-15 14:02:34 +0000469 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
470 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
471 for (i = 0; i < vta->guest_extents->n_used; i++) {
472 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000473 }
474
sewardjaa59f942004-10-09 09:34:36 +0000475 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000476 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000477 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000478 vex_printf("can't show code due to extents > 1\n");
479 } else {
480 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000481 UChar* p = (UChar*)vta->guest_bytes;
sewardj01f8cce2009-08-31 08:50:02 +0000482 UInt sum = 0;
sewardj17c7f952005-12-15 14:02:34 +0000483 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
sewardj01f8cce2009-08-31 08:50:02 +0000484 vex_printf("GuestBytes %llx %u ", vta->guest_bytes_addr,
485 guest_bytes_read );
486 for (i = 0; i < guest_bytes_read; i++) {
487 UInt b = (UInt)p[i];
488 vex_printf(" %02x", b );
489 sum = (sum << 1) ^ b;
490 }
491 vex_printf(" %08x\n\n", sum);
sewardj72c72812005-01-19 11:49:45 +0000492 }
sewardjaa59f942004-10-09 09:34:36 +0000493 }
494
495 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000496 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000497 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000498
sewardj2d6b14a2005-11-23 04:25:07 +0000499 vexAllocSanityCheck();
500
sewardjedf4d692004-08-17 13:52:58 +0000501 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000502 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardj17c7f952005-12-15 14:02:34 +0000503 vta->guest_bytes_addr );
sewardjdd40fdf2006-12-24 02:20:24 +0000504 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000505 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000506
sewardjf48ac192004-10-29 00:41:29 +0000507 if (vex_traceflags & VEX_TRACE_OPT1) {
508 vex_printf("\n------------------------"
509 " After pre-instr IR optimisation "
510 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000511 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000512 vex_printf("\n");
513 }
514
sewardj2d6b14a2005-11-23 04:25:07 +0000515 vexAllocSanityCheck();
516
sewardjf13a16a2004-07-05 17:10:14 +0000517 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000518 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000519 irsb = vta->instrument1(vta->callback_opaque,
520 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000521 vta->guest_extents,
522 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000523 vexAllocSanityCheck();
524
sewardj17c7f952005-12-15 14:02:34 +0000525 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000526 irsb = vta->instrument2(vta->callback_opaque,
527 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000528 vta->guest_extents,
529 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000530
sewardjf48ac192004-10-29 00:41:29 +0000531 if (vex_traceflags & VEX_TRACE_INST) {
532 vex_printf("\n------------------------"
533 " After instrumentation "
534 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000535 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000536 vex_printf("\n");
537 }
538
sewardj17c7f952005-12-15 14:02:34 +0000539 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000540 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000541 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000542
sewardj9578a8b2004-11-04 19:44:48 +0000543 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000544 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000545 do_deadcode_BB( irsb );
546 irsb = cprop_BB( irsb );
547 do_deadcode_BB( irsb );
548 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000549 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000550 }
551
sewardj2d6b14a2005-11-23 04:25:07 +0000552 vexAllocSanityCheck();
553
sewardj9578a8b2004-11-04 19:44:48 +0000554 if (vex_traceflags & VEX_TRACE_OPT2) {
555 vex_printf("\n------------------------"
556 " After post-instr IR optimisation "
557 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000558 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000559 vex_printf("\n");
560 }
561
sewardjf9517d02005-11-28 13:39:37 +0000562 /* Turn it into virtual-registerised code. Build trees -- this
563 also throws away any dead bindings. */
sewardjdd40fdf2006-12-24 02:20:24 +0000564 ado_treebuild_BB( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000565
sewardjbe1b6ff2007-08-28 06:06:27 +0000566 if (vta->finaltidy) {
567 irsb = vta->finaltidy(irsb);
568 }
569
sewardj2d6b14a2005-11-23 04:25:07 +0000570 vexAllocSanityCheck();
571
sewardjf48ac192004-10-29 00:41:29 +0000572 if (vex_traceflags & VEX_TRACE_TREES) {
573 vex_printf("\n------------------------"
574 " After tree-building "
575 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000576 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000577 vex_printf("\n");
578 }
579
sewardje908c422005-02-04 21:18:16 +0000580 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000581 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000582 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000583
sewardjf48ac192004-10-29 00:41:29 +0000584 if (vex_traceflags & VEX_TRACE_VCODE)
585 vex_printf("\n------------------------"
586 " Instruction selection "
587 "------------------------\n");
588
sewardjdd40fdf2006-12-24 02:20:24 +0000589 vcode = iselSB ( irsb, vta->arch_host, &vta->archinfo_host,
590 &vta->abiinfo_both );
sewardjf13a16a2004-07-05 17:10:14 +0000591
sewardj2d6b14a2005-11-23 04:25:07 +0000592 vexAllocSanityCheck();
593
sewardjf48ac192004-10-29 00:41:29 +0000594 if (vex_traceflags & VEX_TRACE_VCODE)
595 vex_printf("\n");
596
sewardjf48ac192004-10-29 00:41:29 +0000597 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000598 for (i = 0; i < vcode->arr_used; i++) {
599 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000600 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000601 vex_printf("\n");
602 }
sewardjfbcaf332004-07-08 01:46:01 +0000603 vex_printf("\n");
604 }
sewardjfbcaf332004-07-08 01:46:01 +0000605
sewardjf13a16a2004-07-05 17:10:14 +0000606 /* Register allocate. */
607 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000608 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000609 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000610 genSpill, genReload, directReload,
611 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000612 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000613
sewardj2d6b14a2005-11-23 04:25:07 +0000614 vexAllocSanityCheck();
615
sewardjf48ac192004-10-29 00:41:29 +0000616 if (vex_traceflags & VEX_TRACE_RCODE) {
617 vex_printf("\n------------------------"
618 " Register-allocated code "
619 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000620 for (i = 0; i < rcode->arr_used; i++) {
621 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000622 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000623 vex_printf("\n");
624 }
sewardjfbcaf332004-07-08 01:46:01 +0000625 vex_printf("\n");
626 }
sewardjfbcaf332004-07-08 01:46:01 +0000627
sewardje908c422005-02-04 21:18:16 +0000628 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000629 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000630 /* end HACK */
631
sewardj81bd5502004-07-21 18:49:27 +0000632 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000633 if (vex_traceflags & VEX_TRACE_ASM) {
634 vex_printf("\n------------------------"
635 " Assembly "
636 "------------------------\n\n");
637 }
638
sewardj81bd5502004-07-21 18:49:27 +0000639 out_used = 0; /* tracks along the host_bytes array */
640 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000641 if (vex_traceflags & VEX_TRACE_ASM) {
cerion92b64362005-12-13 12:02:26 +0000642 ppInstr(rcode->arr[i], mode64);
sewardjbad34a92004-07-22 01:14:11 +0000643 vex_printf("\n");
644 }
sewardj17c7f952005-12-15 14:02:34 +0000645 j = (*emit)( insn_bytes, 32, rcode->arr[i], mode64, vta->dispatch );
sewardjf48ac192004-10-29 00:41:29 +0000646 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000647 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000648 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000649 vex_printf("0%x ", (UInt)insn_bytes[k]);
650 else
651 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000652 vex_printf("\n\n");
653 }
sewardj17c7f952005-12-15 14:02:34 +0000654 if (out_used + j > vta->host_bytes_size) {
sewardj2d6b14a2005-11-23 04:25:07 +0000655 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000656 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000657 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000658 }
659 for (k = 0; k < j; k++) {
sewardj17c7f952005-12-15 14:02:34 +0000660 vta->host_bytes[out_used] = insn_bytes[k];
sewardj81bd5502004-07-21 18:49:27 +0000661 out_used++;
662 }
sewardj17c7f952005-12-15 14:02:34 +0000663 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000664 }
sewardj17c7f952005-12-15 14:02:34 +0000665 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000666
sewardj2d6b14a2005-11-23 04:25:07 +0000667 vexAllocSanityCheck();
668
669 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000670
sewardjf48ac192004-10-29 00:41:29 +0000671 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000672 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000673}
674
675
sewardj893aada2004-11-29 19:57:54 +0000676/* --------- Emulation warnings. --------- */
677
678HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
679{
680 switch (ew) {
681 case EmWarn_NONE:
682 return "none";
683 case EmWarn_X86_x87exns:
684 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000685 case EmWarn_X86_x87precision:
686 return "Selection of non-80-bit x87 FP precision";
687 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000688 return "Unmasking SSE FP exceptions";
689 case EmWarn_X86_fz:
690 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
691 case EmWarn_X86_daz:
692 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000693 case EmWarn_X86_acFlag:
694 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +0000695 case EmWarn_PPCexns:
696 return "Unmasking PPC32/64 FP exceptions";
697 case EmWarn_PPC64_redir_overflow:
698 return "PPC64 function redirection stack overflow";
699 case EmWarn_PPC64_redir_underflow:
700 return "PPC64 function redirection stack underflow";
sewardj893aada2004-11-29 19:57:54 +0000701 default:
702 vpanic("LibVEX_EmWarn_string: unknown warning");
703 }
704}
sewardj35421a32004-07-05 13:12:34 +0000705
sewardj5117ce12006-01-27 21:20:15 +0000706/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +0000707
708const HChar* LibVEX_ppVexArch ( VexArch arch )
709{
710 switch (arch) {
711 case VexArch_INVALID: return "INVALID";
712 case VexArchX86: return "X86";
713 case VexArchAMD64: return "AMD64";
714 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000715 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +0000716 case VexArchPPC64: return "PPC64";
sewardjbef170b2004-12-21 01:23:00 +0000717 default: return "VexArch???";
718 }
719}
720
sewardj5117ce12006-01-27 21:20:15 +0000721const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +0000722{
sewardj5117ce12006-01-27 21:20:15 +0000723 HChar* str = show_hwcaps(arch,hwcaps);
724 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +0000725}
726
sewardj5117ce12006-01-27 21:20:15 +0000727
sewardj27e1dd62005-06-30 11:49:14 +0000728/* Write default settings info *vai. */
729void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
730{
sewardj5117ce12006-01-27 21:20:15 +0000731 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +0000732 vai->ppc_cache_line_szB = 0;
sewardj27e1dd62005-06-30 11:49:14 +0000733}
734
sewardjdd40fdf2006-12-24 02:20:24 +0000735/* Write default settings info *vbi. */
736void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +0000737{
sewardjdd40fdf2006-12-24 02:20:24 +0000738 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +0000739 vbi->guest_amd64_assume_fs_is_zero = False;
740 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000741 vbi->guest_ppc_zap_RZ_at_blr = False;
742 vbi->guest_ppc_zap_RZ_at_bl = NULL;
743 vbi->guest_ppc_sc_continues_at_LR = False;
744 vbi->host_ppc_calls_use_fndescrs = False;
745 vbi->host_ppc32_regalign_int64_args = False;
sewardjaca070a2006-10-17 00:28:22 +0000746}
747
sewardj27e1dd62005-06-30 11:49:14 +0000748
sewardj5117ce12006-01-27 21:20:15 +0000749/* Return a string showing the hwcaps in a nice way. The string will
750 be NULL for invalid combinations of flags, so these functions also
751 serve as a way to validate hwcaps values. */
752
753static HChar* show_hwcaps_x86 ( UInt hwcaps )
754{
755 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
756 if (hwcaps == 0)
757 return "x86-sse0";
758 if (hwcaps == VEX_HWCAPS_X86_SSE1)
759 return "x86-sse1";
760 if (hwcaps == (VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2))
761 return "x86-sse1-sse2";
762 if (hwcaps == (VEX_HWCAPS_X86_SSE1
763 | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3))
764 return "x86-sse1-sse2-sse3";
765
sewardje9d8a262009-07-01 08:06:34 +0000766 return NULL;
sewardj5117ce12006-01-27 21:20:15 +0000767}
768
769static HChar* show_hwcaps_amd64 ( UInt hwcaps )
770{
sewardje9d8a262009-07-01 08:06:34 +0000771 /* SSE3 and CX16 are orthogonal and > baseline, although we really
772 don't expect to come across anything which can do SSE3 but can't
773 do CX16. Still, we can handle that case. */
774 const UInt SSE3 = VEX_HWCAPS_AMD64_SSE3;
775 const UInt CX16 = VEX_HWCAPS_AMD64_CX16;
776 UInt c = hwcaps;
777 if (c == 0) return "amd64-sse2";
778 if (c == SSE3) return "amd64-sse3";
779 if (c == CX16) return "amd64-sse2-cx16";
780 if (c == (SSE3|CX16)) return "amd64-sse3-cx16";
781 return NULL;
sewardj5117ce12006-01-27 21:20:15 +0000782}
783
784static HChar* show_hwcaps_ppc32 ( UInt hwcaps )
785{
786 /* Monotonic with complications. Basically V > F > baseline,
787 but once you have F then you can have FX or GX too. */
788 const UInt F = VEX_HWCAPS_PPC32_F;
789 const UInt V = VEX_HWCAPS_PPC32_V;
790 const UInt FX = VEX_HWCAPS_PPC32_FX;
791 const UInt GX = VEX_HWCAPS_PPC32_GX;
792 UInt c = hwcaps;
793 if (c == 0) return "ppc32-int";
794 if (c == F) return "ppc32-int-flt";
795 if (c == (F|FX)) return "ppc32-int-flt-FX";
796 if (c == (F|GX)) return "ppc32-int-flt-GX";
797 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
798 if (c == (F|V)) return "ppc32-int-flt-vmx";
799 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
800 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
801 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
802 return NULL;
803}
804
805static HChar* show_hwcaps_ppc64 ( UInt hwcaps )
806{
807 /* Monotonic with complications. Basically V > baseline(==F),
808 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +0000809 const UInt V = VEX_HWCAPS_PPC64_V;
810 const UInt FX = VEX_HWCAPS_PPC64_FX;
811 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj5117ce12006-01-27 21:20:15 +0000812 UInt c = hwcaps;
813 if (c == 0) return "ppc64-int-flt";
814 if (c == FX) return "ppc64-int-flt-FX";
815 if (c == GX) return "ppc64-int-flt-GX";
816 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
817 if (c == V) return "ppc64-int-flt-vmx";
818 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
819 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
820 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
821 return NULL;
822}
823
824static HChar* show_hwcaps_arm ( UInt hwcaps )
825{
826 if (hwcaps == 0) return "arm-baseline";
827 return NULL;
828}
829
830/* ---- */
831static HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
832{
833 switch (arch) {
sewardj3fd39672006-01-27 22:05:55 +0000834 case VexArchX86: return show_hwcaps_x86(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000835 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
836 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
837 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
sewardj3fd39672006-01-27 22:05:55 +0000838 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000839 default: return NULL;
840 }
841}
842
843static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
844{
845 return show_hwcaps(arch,hwcaps) != NULL;
846}
847
848
sewardj35421a32004-07-05 13:12:34 +0000849/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000850/*--- end main_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000851/*---------------------------------------------------------------*/