blob: 6586304f948c381f51335920e6a6f1c6885dd7f7 [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardjc0ee2ed2004-07-27 10:29:41 +00004/*--- This file (main/vex_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
sewardja26d8202008-02-11 11:35:40 +000013 Copyright (C) 2004-2008 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
sewardjc0ee2ed2004-07-27 10:29:41 +000055#include "main/vex_globals.h"
56#include "main/vex_util.h"
57#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000058#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000059
sewardj2a9ad022004-11-25 02:46:58 +000060#include "host-x86/hdefs.h"
sewardjc33671d2005-02-01 20:30:00 +000061#include "host-amd64/hdefs.h"
ceriond0eae2d2005-12-23 11:43:01 +000062#include "host-ppc/hdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000063
sewardj9e6491a2005-07-02 19:24:10 +000064#include "guest-generic/bb_to_IR.h"
sewardj2a9ad022004-11-25 02:46:58 +000065#include "guest-x86/gdefs.h"
sewardj44d494d2005-01-20 20:26:33 +000066#include "guest-amd64/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000067#include "guest-arm/gdefs.h"
ceriond0eae2d2005-12-23 11:43:01 +000068#include "guest-ppc/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000069
sewardj35421a32004-07-05 13:12:34 +000070
71/* This file contains the top level interface to the library. */
72
sewardj5117ce12006-01-27 21:20:15 +000073/* --------- fwds ... --------- */
74
75static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps );
76static HChar* show_hwcaps ( VexArch arch, UInt hwcaps );
77
78
sewardj35421a32004-07-05 13:12:34 +000079/* --------- Initialise the library. --------- */
80
81/* Exported to library client. */
82
sewardjd887b862005-01-17 18:34:34 +000083const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000084{
85return
86#include "main/vex_svnversion.h"
87 ;
88}
89
90
91/* Exported to library client. */
92
sewardj08613742004-10-25 13:01:45 +000093void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
94{
95 vcon->iropt_verbosity = 0;
96 vcon->iropt_level = 2;
97 vcon->iropt_precise_memory_exns = False;
98 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000099 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +0000100 vcon->guest_chase_thresh = 10;
101}
102
103
104/* Exported to library client. */
105
sewardj887a11a2004-07-05 17:26:47 +0000106void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000107 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000108 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000109 void (*failure_exit) ( void ),
110 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000111 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000112 /* debug paranoia level */
113 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000114 /* Are we supporting valgrind checking? */
115 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000116 /* Control ... */
117 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000118)
119{
sewardj08613742004-10-25 13:01:45 +0000120 /* First off, do enough minimal setup so that the following
121 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000122 vex_failure_exit = failure_exit;
123 vex_log_bytes = log_bytes;
124
125 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000126 vassert(!vex_initdone);
127 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000128 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000129 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000130
131 vassert(vcon->iropt_verbosity >= 0);
132 vassert(vcon->iropt_level >= 0);
133 vassert(vcon->iropt_level <= 2);
134 vassert(vcon->iropt_unroll_thresh >= 0);
135 vassert(vcon->iropt_unroll_thresh <= 400);
136 vassert(vcon->guest_max_insns >= 1);
137 vassert(vcon->guest_max_insns <= 100);
138 vassert(vcon->guest_chase_thresh >= 0);
139 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
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));
sewardjea602bc2004-10-14 21:40:12 +0000161
162 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
163 vassert(sizeof(void*) == sizeof(int*));
164 vassert(sizeof(void*) == sizeof(HWord));
165
sewardj97e87932005-02-07 00:00:50 +0000166 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
167 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
168
sewardjea602bc2004-10-14 21:40:12 +0000169 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000170 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000171 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000172 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000173 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000174 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000175}
176
177
178/* --------- Make a translation. --------- */
179
180/* Exported to library client. */
181
sewardj17c7f952005-12-15 14:02:34 +0000182VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta )
sewardj35421a32004-07-05 13:12:34 +0000183{
sewardj81bd5502004-07-21 18:49:27 +0000184 /* This the bundle of functions we need to do the back-end stuff
185 (insn selection, reg-alloc, assembly) whilst being insulated
186 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000187 HReg* available_real_regs;
188 Int n_available_real_regs;
sewardjfb7373a2007-08-25 21:29:03 +0000189 Bool (*isMove) ( HInstr*, HReg*, HReg* );
190 void (*getRegUsage) ( HRegUsage*, HInstr*, Bool );
191 void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
192 HInstr* (*genSpill) ( HReg, Int, Bool );
193 HInstr* (*genReload) ( HReg, Int, Bool );
194 HInstr* (*directReload) ( HInstr*, HReg, Short );
195 void (*ppInstr) ( HInstr*, Bool );
196 void (*ppReg) ( HReg );
197 HInstrArray* (*iselSB) ( IRSB*, VexArch, VexArchInfo*,
198 VexAbiInfo* );
199 Int (*emit) ( UChar*, Int, HInstr*, Bool, void* );
200 IRExpr* (*specHelper) ( HChar*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000201 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000202
sewardj9e6491a2005-07-02 19:24:10 +0000203 DisOneInstrFn disInstrFn;
204
sewardjeeac8412004-11-02 00:26:55 +0000205 VexGuestLayout* guest_layout;
206 Bool host_is_bigendian = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000207 IRSB* irsb;
sewardjeeac8412004-11-02 00:26:55 +0000208 HInstrArray* vcode;
209 HInstrArray* rcode;
210 Int i, j, k, out_used, guest_sizeB;
sewardjc716aea2006-01-17 01:48:46 +0000211 Int offB_TISTART, offB_TILEN;
sewardjeeac8412004-11-02 00:26:55 +0000212 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000213 IRType guest_word_type;
214 IRType host_word_type;
cerion92b64362005-12-13 12:02:26 +0000215 Bool mode64;
sewardjf13a16a2004-07-05 17:10:14 +0000216
sewardj49651f42004-10-28 22:11:04 +0000217 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000218 available_real_regs = NULL;
219 n_available_real_regs = 0;
220 isMove = NULL;
221 getRegUsage = NULL;
222 mapRegs = NULL;
223 genSpill = NULL;
224 genReload = NULL;
sewardjfb7373a2007-08-25 21:29:03 +0000225 directReload = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000226 ppInstr = NULL;
227 ppReg = NULL;
sewardjdd40fdf2006-12-24 02:20:24 +0000228 iselSB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000229 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000230 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000231 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000232 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000233 guest_word_type = Ity_INVALID;
234 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000235 offB_TISTART = 0;
236 offB_TILEN = 0;
cerion92b64362005-12-13 12:02:26 +0000237 mode64 = False;
sewardj36ca5132004-07-24 13:12:23 +0000238
sewardj17c7f952005-12-15 14:02:34 +0000239 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000240
sewardj35421a32004-07-05 13:12:34 +0000241 vassert(vex_initdone);
sewardj2d6b14a2005-11-23 04:25:07 +0000242 vexSetAllocModeTEMP_and_clear();
243 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000244
sewardjf13a16a2004-07-05 17:10:14 +0000245 /* First off, check that the guest and host insn sets
246 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000247
sewardj17c7f952005-12-15 14:02:34 +0000248 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000249
sewardjbef170b2004-12-21 01:23:00 +0000250 case VexArchX86:
sewardjfb7373a2007-08-25 21:29:03 +0000251 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000252 getAllocableRegs_X86 ( &n_available_real_regs,
253 &available_real_regs );
sewardjfb7373a2007-08-25 21:29:03 +0000254 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
255 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_X86Instr;
256 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
257 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_X86;
258 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_X86;
259 directReload = (HInstr*(*)(HInstr*,HReg,Short)) directReload_X86;
260 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
261 ppReg = (void(*)(HReg)) ppHRegX86;
262 iselSB = iselSB_X86;
263 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000264 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000265 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000266 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000267 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjf13a16a2004-07-05 17:10:14 +0000268 break;
sewardj2a9ad022004-11-25 02:46:58 +0000269
sewardjc33671d2005-02-01 20:30:00 +0000270 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000271 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000272 getAllocableRegs_AMD64 ( &n_available_real_regs,
273 &available_real_regs );
274 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000275 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_AMD64Instr;
276 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
277 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_AMD64;
278 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_AMD64;
279 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000280 ppReg = (void(*)(HReg)) ppHRegAMD64;
sewardjdd40fdf2006-12-24 02:20:24 +0000281 iselSB = iselSB_AMD64;
sewardj0528bb52005-12-15 15:45:20 +0000282 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000283 host_is_bigendian = False;
284 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000285 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000286 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjc33671d2005-02-01 20:30:00 +0000287 break;
288
cerion487e4c92005-02-04 16:28:19 +0000289 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000290 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000291 getAllocableRegs_PPC ( &n_available_real_regs,
292 &available_real_regs, mode64 );
293 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
294 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
295 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
296 genSpill = (HInstr*(*)(HReg,Int,Bool)) genSpill_PPC;
297 genReload = (HInstr*(*)(HReg,Int,Bool)) genReload_PPC;
298 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
299 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000300 iselSB = iselSB_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000301 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000302 host_is_bigendian = True;
303 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000304 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000305 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerion487e4c92005-02-04 16:28:19 +0000306 break;
307
cerionf0de28c2005-12-13 20:21:11 +0000308 case VexArchPPC64:
309 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000310 getAllocableRegs_PPC ( &n_available_real_regs,
311 &available_real_regs, mode64 );
312 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
313 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
314 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
315 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_PPC;
316 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_PPC;
317 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
318 ppReg = (void(*)(HReg)) ppHRegPPC;
sewardjdd40fdf2006-12-24 02:20:24 +0000319 iselSB = iselSB_PPC;
cerion5b2325f2005-12-23 00:55:09 +0000320 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000321 host_is_bigendian = True;
322 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000323 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000324 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerionf0de28c2005-12-13 20:21:11 +0000325 break;
326
sewardjf13a16a2004-07-05 17:10:14 +0000327 default:
sewardj887a11a2004-07-05 17:26:47 +0000328 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000329 }
330
sewardj2a9ad022004-11-25 02:46:58 +0000331
sewardj17c7f952005-12-15 14:02:34 +0000332 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000333
sewardjbef170b2004-12-21 01:23:00 +0000334 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000335 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000336 disInstrFn = disInstr_X86;
sewardj2a9ad022004-11-25 02:46:58 +0000337 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000338 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000339 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000340 guest_layout = &x86guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000341 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
342 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000343 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000344 vassert(0 == sizeof(VexGuestX86State) % 8);
sewardjce02aa72006-01-12 12:27:58 +0000345 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
346 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
347 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000348 break;
sewardj2a9ad022004-11-25 02:46:58 +0000349
sewardj44d494d2005-01-20 20:26:33 +0000350 case VexArchAMD64:
351 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000352 disInstrFn = disInstr_AMD64;
sewardj44d494d2005-01-20 20:26:33 +0000353 specHelper = guest_amd64_spechelper;
354 guest_sizeB = sizeof(VexGuestAMD64State);
355 guest_word_type = Ity_I64;
356 guest_layout = &amd64guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000357 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
358 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000359 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000360 vassert(0 == sizeof(VexGuestAMD64State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000361 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000362 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
363 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000364 break;
365
sewardjbef170b2004-12-21 01:23:00 +0000366 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000367 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000368 disInstrFn = NULL; /* HACK */
sewardj2a9ad022004-11-25 02:46:58 +0000369 specHelper = guest_arm_spechelper;
370 guest_sizeB = sizeof(VexGuestARMState);
371 guest_word_type = Ity_I32;
372 guest_layout = &armGuest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000373 offB_TISTART = 0; /* hack ... arm has bitrot */
374 offB_TILEN = 0; /* hack ... arm has bitrot */
sewardj5117ce12006-01-27 21:20:15 +0000375 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj2a9ad022004-11-25 02:46:58 +0000376 break;
377
cerionaabdfbf2005-01-29 12:56:15 +0000378 case VexArchPPC32:
379 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000380 disInstrFn = disInstr_PPC;
cerionaabdfbf2005-01-29 12:56:15 +0000381 specHelper = guest_ppc32_spechelper;
382 guest_sizeB = sizeof(VexGuestPPC32State);
383 guest_word_type = Ity_I32;
384 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000385 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
386 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000387 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000388 vassert(0 == sizeof(VexGuestPPC32State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000389 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000390 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
391 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000392 break;
393
cerionf0de28c2005-12-13 20:21:11 +0000394 case VexArchPPC64:
395 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000396 disInstrFn = disInstr_PPC;
cerionf0de28c2005-12-13 20:21:11 +0000397 specHelper = guest_ppc64_spechelper;
398 guest_sizeB = sizeof(VexGuestPPC64State);
399 guest_word_type = Ity_I64;
400 guest_layout = &ppc64Guest_layout;
401 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
402 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000403 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000404 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000405 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
406 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
407 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
408 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000409 break;
410
sewardjf13a16a2004-07-05 17:10:14 +0000411 default:
sewardj887a11a2004-07-05 17:26:47 +0000412 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000413 }
414
sewardj9df271d2004-12-31 22:37:42 +0000415 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000416 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000417 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000418 we are simulating one flavour of an architecture a different
419 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000420 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000421 }
sewardj2a9ad022004-11-25 02:46:58 +0000422
sewardj2d6b14a2005-11-23 04:25:07 +0000423 vexAllocSanityCheck();
424
sewardjf48ac192004-10-29 00:41:29 +0000425 if (vex_traceflags & VEX_TRACE_FE)
426 vex_printf("\n------------------------"
427 " Front end "
428 "------------------------\n\n");
429
sewardjdd40fdf2006-12-24 02:20:24 +0000430 irsb = bb_to_IR ( vta->guest_extents,
sewardjc716aea2006-01-17 01:48:46 +0000431 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000432 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000433 vta->guest_bytes,
434 vta->guest_bytes_addr,
435 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000436 host_is_bigendian,
sewardja5f55da2006-04-30 23:37:32 +0000437 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000438 &vta->archinfo_guest,
sewardjdd40fdf2006-12-24 02:20:24 +0000439 &vta->abiinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000440 guest_word_type,
sewardj17c7f952005-12-15 14:02:34 +0000441 vta->do_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000442 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000443 offB_TISTART,
sewardjc716aea2006-01-17 01:48:46 +0000444 offB_TILEN );
sewardjf13a16a2004-07-05 17:10:14 +0000445
sewardj2d6b14a2005-11-23 04:25:07 +0000446 vexAllocSanityCheck();
447
sewardjdd40fdf2006-12-24 02:20:24 +0000448 if (irsb == NULL) {
sewardjf13a16a2004-07-05 17:10:14 +0000449 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000450 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000451 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000452 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000453 }
sewardjaa59f942004-10-09 09:34:36 +0000454
sewardj17c7f952005-12-15 14:02:34 +0000455 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
456 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
457 for (i = 0; i < vta->guest_extents->n_used; i++) {
458 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000459 }
460
sewardjaa59f942004-10-09 09:34:36 +0000461 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000462 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000463 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000464 vex_printf("can't show code due to extents > 1\n");
465 } else {
466 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000467 UChar* p = (UChar*)vta->guest_bytes;
468 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
469 vex_printf(". 0 %llx %u\n.", vta->guest_bytes_addr, guest_bytes_read );
sewardj72c72812005-01-19 11:49:45 +0000470 for (i = 0; i < guest_bytes_read; i++)
cerionf0de28c2005-12-13 20:21:11 +0000471 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000472 vex_printf("\n\n");
473 }
sewardjaa59f942004-10-09 09:34:36 +0000474 }
475
476 /* Sanity check the initial IR. */
sewardjdd40fdf2006-12-24 02:20:24 +0000477 sanityCheckIRSB( irsb, "initial IR",
sewardjb9230752004-12-29 19:25:06 +0000478 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000479
sewardj2d6b14a2005-11-23 04:25:07 +0000480 vexAllocSanityCheck();
481
sewardjedf4d692004-08-17 13:52:58 +0000482 /* Clean it up, hopefully a lot. */
sewardjdd40fdf2006-12-24 02:20:24 +0000483 irsb = do_iropt_BB ( irsb, specHelper, preciseMemExnsFn,
sewardj17c7f952005-12-15 14:02:34 +0000484 vta->guest_bytes_addr );
sewardjdd40fdf2006-12-24 02:20:24 +0000485 sanityCheckIRSB( irsb, "after initial iropt",
sewardjb9230752004-12-29 19:25:06 +0000486 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000487
sewardjf48ac192004-10-29 00:41:29 +0000488 if (vex_traceflags & VEX_TRACE_OPT1) {
489 vex_printf("\n------------------------"
490 " After pre-instr IR optimisation "
491 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000492 ppIRSB ( irsb );
sewardjedf4d692004-08-17 13:52:58 +0000493 vex_printf("\n");
494 }
495
sewardj2d6b14a2005-11-23 04:25:07 +0000496 vexAllocSanityCheck();
497
sewardjf13a16a2004-07-05 17:10:14 +0000498 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000499 if (vta->instrument1)
sewardjdd40fdf2006-12-24 02:20:24 +0000500 irsb = vta->instrument1(vta->callback_opaque,
501 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000502 vta->guest_extents,
503 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000504 vexAllocSanityCheck();
505
sewardj17c7f952005-12-15 14:02:34 +0000506 if (vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000507 irsb = vta->instrument2(vta->callback_opaque,
508 irsb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000509 vta->guest_extents,
510 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000511
sewardjf48ac192004-10-29 00:41:29 +0000512 if (vex_traceflags & VEX_TRACE_INST) {
513 vex_printf("\n------------------------"
514 " After instrumentation "
515 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000516 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000517 vex_printf("\n");
518 }
519
sewardj17c7f952005-12-15 14:02:34 +0000520 if (vta->instrument1 || vta->instrument2)
sewardjdd40fdf2006-12-24 02:20:24 +0000521 sanityCheckIRSB( irsb, "after instrumentation",
sewardjb9230752004-12-29 19:25:06 +0000522 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000523
sewardj9578a8b2004-11-04 19:44:48 +0000524 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000525 if (vta->instrument1 || vta->instrument2) {
sewardjdd40fdf2006-12-24 02:20:24 +0000526 do_deadcode_BB( irsb );
527 irsb = cprop_BB( irsb );
528 do_deadcode_BB( irsb );
529 sanityCheckIRSB( irsb, "after post-instrumentation cleanup",
sewardjb9230752004-12-29 19:25:06 +0000530 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000531 }
532
sewardj2d6b14a2005-11-23 04:25:07 +0000533 vexAllocSanityCheck();
534
sewardj9578a8b2004-11-04 19:44:48 +0000535 if (vex_traceflags & VEX_TRACE_OPT2) {
536 vex_printf("\n------------------------"
537 " After post-instr IR optimisation "
538 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000539 ppIRSB ( irsb );
sewardj9578a8b2004-11-04 19:44:48 +0000540 vex_printf("\n");
541 }
542
sewardjf9517d02005-11-28 13:39:37 +0000543 /* Turn it into virtual-registerised code. Build trees -- this
544 also throws away any dead bindings. */
sewardjdd40fdf2006-12-24 02:20:24 +0000545 ado_treebuild_BB( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000546
sewardjbe1b6ff2007-08-28 06:06:27 +0000547 if (vta->finaltidy) {
548 irsb = vta->finaltidy(irsb);
549 }
550
sewardj2d6b14a2005-11-23 04:25:07 +0000551 vexAllocSanityCheck();
552
sewardjf48ac192004-10-29 00:41:29 +0000553 if (vex_traceflags & VEX_TRACE_TREES) {
554 vex_printf("\n------------------------"
555 " After tree-building "
556 "------------------------\n\n");
sewardjdd40fdf2006-12-24 02:20:24 +0000557 ppIRSB ( irsb );
sewardjf48ac192004-10-29 00:41:29 +0000558 vex_printf("\n");
559 }
560
sewardje908c422005-02-04 21:18:16 +0000561 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000562 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000563 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000564
sewardjf48ac192004-10-29 00:41:29 +0000565 if (vex_traceflags & VEX_TRACE_VCODE)
566 vex_printf("\n------------------------"
567 " Instruction selection "
568 "------------------------\n");
569
sewardjdd40fdf2006-12-24 02:20:24 +0000570 vcode = iselSB ( irsb, vta->arch_host, &vta->archinfo_host,
571 &vta->abiinfo_both );
sewardjf13a16a2004-07-05 17:10:14 +0000572
sewardj2d6b14a2005-11-23 04:25:07 +0000573 vexAllocSanityCheck();
574
sewardjf48ac192004-10-29 00:41:29 +0000575 if (vex_traceflags & VEX_TRACE_VCODE)
576 vex_printf("\n");
577
sewardjf48ac192004-10-29 00:41:29 +0000578 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000579 for (i = 0; i < vcode->arr_used; i++) {
580 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000581 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000582 vex_printf("\n");
583 }
sewardjfbcaf332004-07-08 01:46:01 +0000584 vex_printf("\n");
585 }
sewardjfbcaf332004-07-08 01:46:01 +0000586
sewardjf13a16a2004-07-05 17:10:14 +0000587 /* Register allocate. */
588 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000589 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000590 isMove, getRegUsage, mapRegs,
sewardjfb7373a2007-08-25 21:29:03 +0000591 genSpill, genReload, directReload,
592 guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000593 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000594
sewardj2d6b14a2005-11-23 04:25:07 +0000595 vexAllocSanityCheck();
596
sewardjf48ac192004-10-29 00:41:29 +0000597 if (vex_traceflags & VEX_TRACE_RCODE) {
598 vex_printf("\n------------------------"
599 " Register-allocated code "
600 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000601 for (i = 0; i < rcode->arr_used; i++) {
602 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000603 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000604 vex_printf("\n");
605 }
sewardjfbcaf332004-07-08 01:46:01 +0000606 vex_printf("\n");
607 }
sewardjfbcaf332004-07-08 01:46:01 +0000608
sewardje908c422005-02-04 21:18:16 +0000609 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000610 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000611 /* end HACK */
612
sewardj81bd5502004-07-21 18:49:27 +0000613 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000614 if (vex_traceflags & VEX_TRACE_ASM) {
615 vex_printf("\n------------------------"
616 " Assembly "
617 "------------------------\n\n");
618 }
619
sewardj81bd5502004-07-21 18:49:27 +0000620 out_used = 0; /* tracks along the host_bytes array */
621 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000622 if (vex_traceflags & VEX_TRACE_ASM) {
cerion92b64362005-12-13 12:02:26 +0000623 ppInstr(rcode->arr[i], mode64);
sewardjbad34a92004-07-22 01:14:11 +0000624 vex_printf("\n");
625 }
sewardj17c7f952005-12-15 14:02:34 +0000626 j = (*emit)( insn_bytes, 32, rcode->arr[i], mode64, vta->dispatch );
sewardjf48ac192004-10-29 00:41:29 +0000627 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000628 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000629 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000630 vex_printf("0%x ", (UInt)insn_bytes[k]);
631 else
632 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000633 vex_printf("\n\n");
634 }
sewardj17c7f952005-12-15 14:02:34 +0000635 if (out_used + j > vta->host_bytes_size) {
sewardj2d6b14a2005-11-23 04:25:07 +0000636 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000637 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000638 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000639 }
640 for (k = 0; k < j; k++) {
sewardj17c7f952005-12-15 14:02:34 +0000641 vta->host_bytes[out_used] = insn_bytes[k];
sewardj81bd5502004-07-21 18:49:27 +0000642 out_used++;
643 }
sewardj17c7f952005-12-15 14:02:34 +0000644 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000645 }
sewardj17c7f952005-12-15 14:02:34 +0000646 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000647
sewardj2d6b14a2005-11-23 04:25:07 +0000648 vexAllocSanityCheck();
649
650 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000651
sewardjf48ac192004-10-29 00:41:29 +0000652 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000653 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000654}
655
656
sewardj893aada2004-11-29 19:57:54 +0000657/* --------- Emulation warnings. --------- */
658
659HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
660{
661 switch (ew) {
662 case EmWarn_NONE:
663 return "none";
664 case EmWarn_X86_x87exns:
665 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000666 case EmWarn_X86_x87precision:
667 return "Selection of non-80-bit x87 FP precision";
668 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000669 return "Unmasking SSE FP exceptions";
670 case EmWarn_X86_fz:
671 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
672 case EmWarn_X86_daz:
673 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000674 case EmWarn_X86_acFlag:
675 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +0000676 case EmWarn_PPCexns:
677 return "Unmasking PPC32/64 FP exceptions";
678 case EmWarn_PPC64_redir_overflow:
679 return "PPC64 function redirection stack overflow";
680 case EmWarn_PPC64_redir_underflow:
681 return "PPC64 function redirection stack underflow";
sewardj893aada2004-11-29 19:57:54 +0000682 default:
683 vpanic("LibVEX_EmWarn_string: unknown warning");
684 }
685}
sewardj35421a32004-07-05 13:12:34 +0000686
sewardj5117ce12006-01-27 21:20:15 +0000687/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +0000688
689const HChar* LibVEX_ppVexArch ( VexArch arch )
690{
691 switch (arch) {
692 case VexArch_INVALID: return "INVALID";
693 case VexArchX86: return "X86";
694 case VexArchAMD64: return "AMD64";
695 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000696 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +0000697 case VexArchPPC64: return "PPC64";
sewardjbef170b2004-12-21 01:23:00 +0000698 default: return "VexArch???";
699 }
700}
701
sewardj5117ce12006-01-27 21:20:15 +0000702const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +0000703{
sewardj5117ce12006-01-27 21:20:15 +0000704 HChar* str = show_hwcaps(arch,hwcaps);
705 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +0000706}
707
sewardj5117ce12006-01-27 21:20:15 +0000708
sewardj27e1dd62005-06-30 11:49:14 +0000709/* Write default settings info *vai. */
710void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
711{
sewardj5117ce12006-01-27 21:20:15 +0000712 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +0000713 vai->ppc_cache_line_szB = 0;
sewardj27e1dd62005-06-30 11:49:14 +0000714}
715
sewardjdd40fdf2006-12-24 02:20:24 +0000716/* Write default settings info *vbi. */
717void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi )
sewardjaca070a2006-10-17 00:28:22 +0000718{
sewardjdd40fdf2006-12-24 02:20:24 +0000719 vbi->guest_stack_redzone_size = 0;
sewardj2e28ac42008-12-04 00:05:12 +0000720 vbi->guest_amd64_assume_fs_is_zero = False;
721 vbi->guest_amd64_assume_gs_is_0x60 = False;
sewardjdd40fdf2006-12-24 02:20:24 +0000722 vbi->guest_ppc_zap_RZ_at_blr = False;
723 vbi->guest_ppc_zap_RZ_at_bl = NULL;
724 vbi->guest_ppc_sc_continues_at_LR = False;
725 vbi->host_ppc_calls_use_fndescrs = False;
726 vbi->host_ppc32_regalign_int64_args = False;
sewardjaca070a2006-10-17 00:28:22 +0000727}
728
sewardj27e1dd62005-06-30 11:49:14 +0000729
sewardj5117ce12006-01-27 21:20:15 +0000730/* Return a string showing the hwcaps in a nice way. The string will
731 be NULL for invalid combinations of flags, so these functions also
732 serve as a way to validate hwcaps values. */
733
734static HChar* show_hwcaps_x86 ( UInt hwcaps )
735{
736 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
737 if (hwcaps == 0)
738 return "x86-sse0";
739 if (hwcaps == VEX_HWCAPS_X86_SSE1)
740 return "x86-sse1";
741 if (hwcaps == (VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2))
742 return "x86-sse1-sse2";
743 if (hwcaps == (VEX_HWCAPS_X86_SSE1
744 | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3))
745 return "x86-sse1-sse2-sse3";
746
747 return False;
748}
749
750static HChar* show_hwcaps_amd64 ( UInt hwcaps )
751{
752 /* Monotonic, SSE3 > baseline. */
753 if (hwcaps == 0)
754 return "amd64-sse2";
755 if (hwcaps == VEX_HWCAPS_AMD64_SSE3)
756 return "amd64-sse3";
757 return False;
758}
759
760static HChar* show_hwcaps_ppc32 ( UInt hwcaps )
761{
762 /* Monotonic with complications. Basically V > F > baseline,
763 but once you have F then you can have FX or GX too. */
764 const UInt F = VEX_HWCAPS_PPC32_F;
765 const UInt V = VEX_HWCAPS_PPC32_V;
766 const UInt FX = VEX_HWCAPS_PPC32_FX;
767 const UInt GX = VEX_HWCAPS_PPC32_GX;
768 UInt c = hwcaps;
769 if (c == 0) return "ppc32-int";
770 if (c == F) return "ppc32-int-flt";
771 if (c == (F|FX)) return "ppc32-int-flt-FX";
772 if (c == (F|GX)) return "ppc32-int-flt-GX";
773 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
774 if (c == (F|V)) return "ppc32-int-flt-vmx";
775 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
776 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
777 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
778 return NULL;
779}
780
781static HChar* show_hwcaps_ppc64 ( UInt hwcaps )
782{
783 /* Monotonic with complications. Basically V > baseline(==F),
784 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +0000785 const UInt V = VEX_HWCAPS_PPC64_V;
786 const UInt FX = VEX_HWCAPS_PPC64_FX;
787 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj5117ce12006-01-27 21:20:15 +0000788 UInt c = hwcaps;
789 if (c == 0) return "ppc64-int-flt";
790 if (c == FX) return "ppc64-int-flt-FX";
791 if (c == GX) return "ppc64-int-flt-GX";
792 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
793 if (c == V) return "ppc64-int-flt-vmx";
794 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
795 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
796 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
797 return NULL;
798}
799
800static HChar* show_hwcaps_arm ( UInt hwcaps )
801{
802 if (hwcaps == 0) return "arm-baseline";
803 return NULL;
804}
805
806/* ---- */
807static HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
808{
809 switch (arch) {
sewardj3fd39672006-01-27 22:05:55 +0000810 case VexArchX86: return show_hwcaps_x86(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000811 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
812 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
813 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
sewardj3fd39672006-01-27 22:05:55 +0000814 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000815 default: return NULL;
816 }
817}
818
819static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
820{
821 return show_hwcaps(arch,hwcaps) != NULL;
822}
823
824
sewardj35421a32004-07-05 13:12:34 +0000825/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000826/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000827/*---------------------------------------------------------------*/