blob: b26fc012f1390830df2e5e6d50cfd892cdc3b125 [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
sewardj7bd6ffe2005-08-03 16:07:36 +000013 Copyright (C) 2004-2005 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;
cerion92b64362005-12-13 12:02:26 +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 void (*ppInstr) ( HInstr*, Bool );
sewardj443cd9d2004-07-18 23:06:45 +0000195 void (*ppReg) ( HReg );
sewardj27e1dd62005-06-30 11:49:14 +0000196 HInstrArray* (*iselBB) ( IRBB*, VexArchInfo* );
sewardj17c7f952005-12-15 14:02:34 +0000197 Int (*emit) ( UChar*, Int, HInstr*, Bool, void* );
sewardjd9763622005-02-07 03:12:19 +0000198 IRExpr* (*specHelper) ( HChar*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000199 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000200
sewardj9e6491a2005-07-02 19:24:10 +0000201 DisOneInstrFn disInstrFn;
202
sewardjeeac8412004-11-02 00:26:55 +0000203 VexGuestLayout* guest_layout;
204 Bool host_is_bigendian = False;
205 IRBB* irbb;
206 HInstrArray* vcode;
207 HInstrArray* rcode;
208 Int i, j, k, out_used, guest_sizeB;
sewardjc716aea2006-01-17 01:48:46 +0000209 Int offB_TISTART, offB_TILEN;
sewardjeeac8412004-11-02 00:26:55 +0000210 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000211 IRType guest_word_type;
212 IRType host_word_type;
cerion92b64362005-12-13 12:02:26 +0000213 Bool mode64;
sewardjf13a16a2004-07-05 17:10:14 +0000214
sewardj49651f42004-10-28 22:11:04 +0000215 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000216 available_real_regs = NULL;
217 n_available_real_regs = 0;
218 isMove = NULL;
219 getRegUsage = NULL;
220 mapRegs = NULL;
221 genSpill = NULL;
222 genReload = NULL;
223 ppInstr = NULL;
224 ppReg = NULL;
225 iselBB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000226 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000227 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000228 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000229 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000230 guest_word_type = Ity_INVALID;
231 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000232 offB_TISTART = 0;
233 offB_TILEN = 0;
cerion92b64362005-12-13 12:02:26 +0000234 mode64 = False;
sewardj36ca5132004-07-24 13:12:23 +0000235
sewardj17c7f952005-12-15 14:02:34 +0000236 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000237
sewardj35421a32004-07-05 13:12:34 +0000238 vassert(vex_initdone);
sewardj2d6b14a2005-11-23 04:25:07 +0000239 vexSetAllocModeTEMP_and_clear();
240 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000241
sewardjf13a16a2004-07-05 17:10:14 +0000242 /* First off, check that the guest and host insn sets
243 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000244
sewardj17c7f952005-12-15 14:02:34 +0000245 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000246
sewardjbef170b2004-12-21 01:23:00 +0000247 case VexArchX86:
cerion92b64362005-12-13 12:02:26 +0000248 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000249 getAllocableRegs_X86 ( &n_available_real_regs,
250 &available_real_regs );
251 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
cerion92b64362005-12-13 12:02:26 +0000252 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_X86Instr;
253 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
254 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_X86;
255 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_X86;
256 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
sewardj2b515872004-07-05 20:50:45 +0000257 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000258 iselBB = iselBB_X86;
sewardj0528bb52005-12-15 15:45:20 +0000259 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000260 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000261 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000262 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000263 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjf13a16a2004-07-05 17:10:14 +0000264 break;
sewardj2a9ad022004-11-25 02:46:58 +0000265
sewardjc33671d2005-02-01 20:30:00 +0000266 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000267 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000268 getAllocableRegs_AMD64 ( &n_available_real_regs,
269 &available_real_regs );
270 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000271 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_AMD64Instr;
272 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
273 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_AMD64;
274 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_AMD64;
275 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000276 ppReg = (void(*)(HReg)) ppHRegAMD64;
277 iselBB = iselBB_AMD64;
sewardj0528bb52005-12-15 15:45:20 +0000278 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000279 host_is_bigendian = False;
280 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000281 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000282 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjc33671d2005-02-01 20:30:00 +0000283 break;
284
cerion487e4c92005-02-04 16:28:19 +0000285 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000286 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000287 getAllocableRegs_PPC ( &n_available_real_regs,
288 &available_real_regs, mode64 );
289 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
290 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
291 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
292 genSpill = (HInstr*(*)(HReg,Int,Bool)) genSpill_PPC;
293 genReload = (HInstr*(*)(HReg,Int,Bool)) genReload_PPC;
294 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
295 ppReg = (void(*)(HReg)) ppHRegPPC;
296 iselBB = iselBB_PPC;
297 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000298 host_is_bigendian = True;
299 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000300 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000301 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerion487e4c92005-02-04 16:28:19 +0000302 break;
303
cerionf0de28c2005-12-13 20:21:11 +0000304 case VexArchPPC64:
305 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000306 getAllocableRegs_PPC ( &n_available_real_regs,
307 &available_real_regs, mode64 );
308 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
309 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
310 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
311 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_PPC;
312 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_PPC;
313 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
314 ppReg = (void(*)(HReg)) ppHRegPPC;
315 iselBB = iselBB_PPC;
316 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000317 host_is_bigendian = True;
318 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000319 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000320 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerionf0de28c2005-12-13 20:21:11 +0000321 break;
322
sewardjf13a16a2004-07-05 17:10:14 +0000323 default:
sewardj887a11a2004-07-05 17:26:47 +0000324 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000325 }
326
sewardj2a9ad022004-11-25 02:46:58 +0000327
sewardj17c7f952005-12-15 14:02:34 +0000328 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000329
sewardjbef170b2004-12-21 01:23:00 +0000330 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000331 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000332 disInstrFn = disInstr_X86;
sewardj2a9ad022004-11-25 02:46:58 +0000333 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000334 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000335 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000336 guest_layout = &x86guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000337 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
338 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000339 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000340 vassert(0 == sizeof(VexGuestX86State) % 8);
sewardjce02aa72006-01-12 12:27:58 +0000341 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
342 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
343 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000344 break;
sewardj2a9ad022004-11-25 02:46:58 +0000345
sewardj44d494d2005-01-20 20:26:33 +0000346 case VexArchAMD64:
347 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000348 disInstrFn = disInstr_AMD64;
sewardj44d494d2005-01-20 20:26:33 +0000349 specHelper = guest_amd64_spechelper;
350 guest_sizeB = sizeof(VexGuestAMD64State);
351 guest_word_type = Ity_I64;
352 guest_layout = &amd64guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000353 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
354 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000355 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000356 vassert(0 == sizeof(VexGuestAMD64State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000357 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000358 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
359 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000360 break;
361
sewardjbef170b2004-12-21 01:23:00 +0000362 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000363 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000364 disInstrFn = NULL; /* HACK */
sewardj2a9ad022004-11-25 02:46:58 +0000365 specHelper = guest_arm_spechelper;
366 guest_sizeB = sizeof(VexGuestARMState);
367 guest_word_type = Ity_I32;
368 guest_layout = &armGuest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000369 offB_TISTART = 0; /* hack ... arm has bitrot */
370 offB_TILEN = 0; /* hack ... arm has bitrot */
sewardj5117ce12006-01-27 21:20:15 +0000371 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj2a9ad022004-11-25 02:46:58 +0000372 break;
373
cerionaabdfbf2005-01-29 12:56:15 +0000374 case VexArchPPC32:
375 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000376 disInstrFn = disInstr_PPC;
cerionaabdfbf2005-01-29 12:56:15 +0000377 specHelper = guest_ppc32_spechelper;
378 guest_sizeB = sizeof(VexGuestPPC32State);
379 guest_word_type = Ity_I32;
380 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000381 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
382 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000383 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000384 vassert(0 == sizeof(VexGuestPPC32State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000385 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000386 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
387 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000388 break;
389
cerionf0de28c2005-12-13 20:21:11 +0000390 case VexArchPPC64:
391 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000392 disInstrFn = disInstr_PPC;
cerionf0de28c2005-12-13 20:21:11 +0000393 specHelper = guest_ppc64_spechelper;
394 guest_sizeB = sizeof(VexGuestPPC64State);
395 guest_word_type = Ity_I64;
396 guest_layout = &ppc64Guest_layout;
397 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
398 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000399 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000400 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000401 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
402 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
403 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
404 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000405 break;
406
sewardjf13a16a2004-07-05 17:10:14 +0000407 default:
sewardj887a11a2004-07-05 17:26:47 +0000408 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000409 }
410
sewardj9df271d2004-12-31 22:37:42 +0000411 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000412 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000413 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000414 we are simulating one flavour of an architecture a different
415 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000416 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000417 }
sewardj2a9ad022004-11-25 02:46:58 +0000418
sewardj2d6b14a2005-11-23 04:25:07 +0000419 vexAllocSanityCheck();
420
sewardjf48ac192004-10-29 00:41:29 +0000421 if (vex_traceflags & VEX_TRACE_FE)
422 vex_printf("\n------------------------"
423 " Front end "
424 "------------------------\n\n");
425
sewardj17c7f952005-12-15 14:02:34 +0000426 irbb = bb_to_IR ( vta->guest_extents,
sewardjc716aea2006-01-17 01:48:46 +0000427 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000428 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000429 vta->guest_bytes,
430 vta->guest_bytes_addr,
431 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000432 host_is_bigendian,
sewardja5f55da2006-04-30 23:37:32 +0000433 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000434 &vta->archinfo_guest,
sewardjdb4738a2005-07-07 01:32:16 +0000435 guest_word_type,
sewardj17c7f952005-12-15 14:02:34 +0000436 vta->do_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000437 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000438 offB_TISTART,
sewardjc716aea2006-01-17 01:48:46 +0000439 offB_TILEN );
sewardjf13a16a2004-07-05 17:10:14 +0000440
sewardj2d6b14a2005-11-23 04:25:07 +0000441 vexAllocSanityCheck();
442
sewardjf13a16a2004-07-05 17:10:14 +0000443 if (irbb == NULL) {
444 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000445 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000446 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000447 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000448 }
sewardjaa59f942004-10-09 09:34:36 +0000449
sewardj17c7f952005-12-15 14:02:34 +0000450 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
451 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
452 for (i = 0; i < vta->guest_extents->n_used; i++) {
453 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000454 }
455
sewardjaa59f942004-10-09 09:34:36 +0000456 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000457 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000458 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000459 vex_printf("can't show code due to extents > 1\n");
460 } else {
461 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000462 UChar* p = (UChar*)vta->guest_bytes;
463 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
464 vex_printf(". 0 %llx %u\n.", vta->guest_bytes_addr, guest_bytes_read );
sewardj72c72812005-01-19 11:49:45 +0000465 for (i = 0; i < guest_bytes_read; i++)
cerionf0de28c2005-12-13 20:21:11 +0000466 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000467 vex_printf("\n\n");
468 }
sewardjaa59f942004-10-09 09:34:36 +0000469 }
470
471 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000472 sanityCheckIRBB( irbb, "initial IR",
473 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000474
sewardj2d6b14a2005-11-23 04:25:07 +0000475 vexAllocSanityCheck();
476
sewardjedf4d692004-08-17 13:52:58 +0000477 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000478 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
sewardj17c7f952005-12-15 14:02:34 +0000479 vta->guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000480 sanityCheckIRBB( irbb, "after initial iropt",
481 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000482
sewardjf48ac192004-10-29 00:41:29 +0000483 if (vex_traceflags & VEX_TRACE_OPT1) {
484 vex_printf("\n------------------------"
485 " After pre-instr IR optimisation "
486 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000487 ppIRBB ( irbb );
488 vex_printf("\n");
489 }
490
sewardj2d6b14a2005-11-23 04:25:07 +0000491 vexAllocSanityCheck();
492
sewardjf13a16a2004-07-05 17:10:14 +0000493 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000494 if (vta->instrument1)
sewardjc716aea2006-01-17 01:48:46 +0000495 irbb = vta->instrument1(vta->callback_opaque,
496 irbb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000497 vta->guest_extents,
498 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000499 vexAllocSanityCheck();
500
sewardj17c7f952005-12-15 14:02:34 +0000501 if (vta->instrument2)
sewardjc716aea2006-01-17 01:48:46 +0000502 irbb = vta->instrument2(vta->callback_opaque,
503 irbb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000504 vta->guest_extents,
505 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000506
sewardjf48ac192004-10-29 00:41:29 +0000507 if (vex_traceflags & VEX_TRACE_INST) {
508 vex_printf("\n------------------------"
509 " After instrumentation "
510 "------------------------\n\n");
511 ppIRBB ( irbb );
512 vex_printf("\n");
513 }
514
sewardj17c7f952005-12-15 14:02:34 +0000515 if (vta->instrument1 || vta->instrument2)
sewardjb9230752004-12-29 19:25:06 +0000516 sanityCheckIRBB( irbb, "after instrumentation",
517 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000518
sewardj9578a8b2004-11-04 19:44:48 +0000519 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000520 if (vta->instrument1 || vta->instrument2) {
sewardj9578a8b2004-11-04 19:44:48 +0000521 do_deadcode_BB( irbb );
522 irbb = cprop_BB( irbb );
523 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000524 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
525 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000526 }
527
sewardj2d6b14a2005-11-23 04:25:07 +0000528 vexAllocSanityCheck();
529
sewardj9578a8b2004-11-04 19:44:48 +0000530 if (vex_traceflags & VEX_TRACE_OPT2) {
531 vex_printf("\n------------------------"
532 " After post-instr IR optimisation "
533 "------------------------\n\n");
534 ppIRBB ( irbb );
535 vex_printf("\n");
536 }
537
sewardjf9517d02005-11-28 13:39:37 +0000538 /* Turn it into virtual-registerised code. Build trees -- this
539 also throws away any dead bindings. */
540 ado_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000541
sewardj2d6b14a2005-11-23 04:25:07 +0000542 vexAllocSanityCheck();
543
sewardjf48ac192004-10-29 00:41:29 +0000544 if (vex_traceflags & VEX_TRACE_TREES) {
545 vex_printf("\n------------------------"
546 " After tree-building "
547 "------------------------\n\n");
548 ppIRBB ( irbb );
549 vex_printf("\n");
550 }
551
sewardje908c422005-02-04 21:18:16 +0000552 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000553 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000554 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000555
sewardjf48ac192004-10-29 00:41:29 +0000556 if (vex_traceflags & VEX_TRACE_VCODE)
557 vex_printf("\n------------------------"
558 " Instruction selection "
559 "------------------------\n");
560
sewardj17c7f952005-12-15 14:02:34 +0000561 vcode = iselBB ( irbb, &vta->archinfo_host );
sewardjf13a16a2004-07-05 17:10:14 +0000562
sewardj2d6b14a2005-11-23 04:25:07 +0000563 vexAllocSanityCheck();
564
sewardjf48ac192004-10-29 00:41:29 +0000565 if (vex_traceflags & VEX_TRACE_VCODE)
566 vex_printf("\n");
567
sewardjf48ac192004-10-29 00:41:29 +0000568 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000569 for (i = 0; i < vcode->arr_used; i++) {
570 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000571 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000572 vex_printf("\n");
573 }
sewardjfbcaf332004-07-08 01:46:01 +0000574 vex_printf("\n");
575 }
sewardjfbcaf332004-07-08 01:46:01 +0000576
sewardjf13a16a2004-07-05 17:10:14 +0000577 /* Register allocate. */
578 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000579 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000580 isMove, getRegUsage, mapRegs,
581 genSpill, genReload, guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000582 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000583
sewardj2d6b14a2005-11-23 04:25:07 +0000584 vexAllocSanityCheck();
585
sewardjf48ac192004-10-29 00:41:29 +0000586 if (vex_traceflags & VEX_TRACE_RCODE) {
587 vex_printf("\n------------------------"
588 " Register-allocated code "
589 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000590 for (i = 0; i < rcode->arr_used; i++) {
591 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000592 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000593 vex_printf("\n");
594 }
sewardjfbcaf332004-07-08 01:46:01 +0000595 vex_printf("\n");
596 }
sewardjfbcaf332004-07-08 01:46:01 +0000597
sewardje908c422005-02-04 21:18:16 +0000598 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000599 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000600 /* end HACK */
601
sewardj81bd5502004-07-21 18:49:27 +0000602 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000603 if (vex_traceflags & VEX_TRACE_ASM) {
604 vex_printf("\n------------------------"
605 " Assembly "
606 "------------------------\n\n");
607 }
608
sewardj81bd5502004-07-21 18:49:27 +0000609 out_used = 0; /* tracks along the host_bytes array */
610 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000611 if (vex_traceflags & VEX_TRACE_ASM) {
cerion92b64362005-12-13 12:02:26 +0000612 ppInstr(rcode->arr[i], mode64);
sewardjbad34a92004-07-22 01:14:11 +0000613 vex_printf("\n");
614 }
sewardj17c7f952005-12-15 14:02:34 +0000615 j = (*emit)( insn_bytes, 32, rcode->arr[i], mode64, vta->dispatch );
sewardjf48ac192004-10-29 00:41:29 +0000616 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000617 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000618 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000619 vex_printf("0%x ", (UInt)insn_bytes[k]);
620 else
621 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000622 vex_printf("\n\n");
623 }
sewardj17c7f952005-12-15 14:02:34 +0000624 if (out_used + j > vta->host_bytes_size) {
sewardj2d6b14a2005-11-23 04:25:07 +0000625 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000626 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000627 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000628 }
629 for (k = 0; k < j; k++) {
sewardj17c7f952005-12-15 14:02:34 +0000630 vta->host_bytes[out_used] = insn_bytes[k];
sewardj81bd5502004-07-21 18:49:27 +0000631 out_used++;
632 }
sewardj17c7f952005-12-15 14:02:34 +0000633 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000634 }
sewardj17c7f952005-12-15 14:02:34 +0000635 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000636
sewardj2d6b14a2005-11-23 04:25:07 +0000637 vexAllocSanityCheck();
638
639 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000640
sewardjf48ac192004-10-29 00:41:29 +0000641 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000642 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000643}
644
645
sewardj893aada2004-11-29 19:57:54 +0000646/* --------- Emulation warnings. --------- */
647
648HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
649{
650 switch (ew) {
651 case EmWarn_NONE:
652 return "none";
653 case EmWarn_X86_x87exns:
654 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000655 case EmWarn_X86_x87precision:
656 return "Selection of non-80-bit x87 FP precision";
657 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000658 return "Unmasking SSE FP exceptions";
659 case EmWarn_X86_fz:
660 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
661 case EmWarn_X86_daz:
662 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000663 case EmWarn_X86_acFlag:
664 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +0000665 case EmWarn_PPCexns:
666 return "Unmasking PPC32/64 FP exceptions";
667 case EmWarn_PPC64_redir_overflow:
668 return "PPC64 function redirection stack overflow";
669 case EmWarn_PPC64_redir_underflow:
670 return "PPC64 function redirection stack underflow";
sewardj893aada2004-11-29 19:57:54 +0000671 default:
672 vpanic("LibVEX_EmWarn_string: unknown warning");
673 }
674}
sewardj35421a32004-07-05 13:12:34 +0000675
sewardj5117ce12006-01-27 21:20:15 +0000676/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +0000677
678const HChar* LibVEX_ppVexArch ( VexArch arch )
679{
680 switch (arch) {
681 case VexArch_INVALID: return "INVALID";
682 case VexArchX86: return "X86";
683 case VexArchAMD64: return "AMD64";
684 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000685 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +0000686 case VexArchPPC64: return "PPC64";
sewardjbef170b2004-12-21 01:23:00 +0000687 default: return "VexArch???";
688 }
689}
690
sewardj5117ce12006-01-27 21:20:15 +0000691const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +0000692{
sewardj5117ce12006-01-27 21:20:15 +0000693 HChar* str = show_hwcaps(arch,hwcaps);
694 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +0000695}
696
sewardj5117ce12006-01-27 21:20:15 +0000697
698
sewardj27e1dd62005-06-30 11:49:14 +0000699/* Write default settings info *vai. */
700void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
701{
sewardj5117ce12006-01-27 21:20:15 +0000702 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +0000703 vai->ppc_cache_line_szB = 0;
sewardj27e1dd62005-06-30 11:49:14 +0000704}
705
706
sewardj5117ce12006-01-27 21:20:15 +0000707/* Return a string showing the hwcaps in a nice way. The string will
708 be NULL for invalid combinations of flags, so these functions also
709 serve as a way to validate hwcaps values. */
710
711static HChar* show_hwcaps_x86 ( UInt hwcaps )
712{
713 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
714 if (hwcaps == 0)
715 return "x86-sse0";
716 if (hwcaps == VEX_HWCAPS_X86_SSE1)
717 return "x86-sse1";
718 if (hwcaps == (VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2))
719 return "x86-sse1-sse2";
720 if (hwcaps == (VEX_HWCAPS_X86_SSE1
721 | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3))
722 return "x86-sse1-sse2-sse3";
723
724 return False;
725}
726
727static HChar* show_hwcaps_amd64 ( UInt hwcaps )
728{
729 /* Monotonic, SSE3 > baseline. */
730 if (hwcaps == 0)
731 return "amd64-sse2";
732 if (hwcaps == VEX_HWCAPS_AMD64_SSE3)
733 return "amd64-sse3";
734 return False;
735}
736
737static HChar* show_hwcaps_ppc32 ( UInt hwcaps )
738{
739 /* Monotonic with complications. Basically V > F > baseline,
740 but once you have F then you can have FX or GX too. */
741 const UInt F = VEX_HWCAPS_PPC32_F;
742 const UInt V = VEX_HWCAPS_PPC32_V;
743 const UInt FX = VEX_HWCAPS_PPC32_FX;
744 const UInt GX = VEX_HWCAPS_PPC32_GX;
745 UInt c = hwcaps;
746 if (c == 0) return "ppc32-int";
747 if (c == F) return "ppc32-int-flt";
748 if (c == (F|FX)) return "ppc32-int-flt-FX";
749 if (c == (F|GX)) return "ppc32-int-flt-GX";
750 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
751 if (c == (F|V)) return "ppc32-int-flt-vmx";
752 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
753 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
754 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
755 return NULL;
756}
757
758static HChar* show_hwcaps_ppc64 ( UInt hwcaps )
759{
760 /* Monotonic with complications. Basically V > baseline(==F),
761 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +0000762 const UInt V = VEX_HWCAPS_PPC64_V;
763 const UInt FX = VEX_HWCAPS_PPC64_FX;
764 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj5117ce12006-01-27 21:20:15 +0000765 UInt c = hwcaps;
766 if (c == 0) return "ppc64-int-flt";
767 if (c == FX) return "ppc64-int-flt-FX";
768 if (c == GX) return "ppc64-int-flt-GX";
769 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
770 if (c == V) return "ppc64-int-flt-vmx";
771 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
772 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
773 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
774 return NULL;
775}
776
777static HChar* show_hwcaps_arm ( UInt hwcaps )
778{
779 if (hwcaps == 0) return "arm-baseline";
780 return NULL;
781}
782
783/* ---- */
784static HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
785{
786 switch (arch) {
sewardj3fd39672006-01-27 22:05:55 +0000787 case VexArchX86: return show_hwcaps_x86(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000788 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
789 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
790 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
sewardj3fd39672006-01-27 22:05:55 +0000791 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000792 default: return NULL;
793 }
794}
795
796static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
797{
798 return show_hwcaps(arch,hwcaps) != NULL;
799}
800
801
sewardj35421a32004-07-05 13:12:34 +0000802/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000803/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000804/*---------------------------------------------------------------*/