blob: a590774abb7fe4d5aea54add6ebdc1c39e8b17af [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
sewardja33e9a42006-06-05 23:13:19 +000013 Copyright (C) 2004-2006 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 );
sewardjaca070a2006-10-17 00:28:22 +0000196 HInstrArray* (*iselBB) ( IRBB*, VexArch, VexArchInfo*,
197 VexMiscInfo* );
sewardj17c7f952005-12-15 14:02:34 +0000198 Int (*emit) ( UChar*, Int, HInstr*, Bool, void* );
sewardjd9763622005-02-07 03:12:19 +0000199 IRExpr* (*specHelper) ( HChar*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000200 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000201
sewardj9e6491a2005-07-02 19:24:10 +0000202 DisOneInstrFn disInstrFn;
203
sewardjeeac8412004-11-02 00:26:55 +0000204 VexGuestLayout* guest_layout;
205 Bool host_is_bigendian = False;
206 IRBB* irbb;
207 HInstrArray* vcode;
208 HInstrArray* rcode;
209 Int i, j, k, out_used, guest_sizeB;
sewardjc716aea2006-01-17 01:48:46 +0000210 Int offB_TISTART, offB_TILEN;
sewardjeeac8412004-11-02 00:26:55 +0000211 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000212 IRType guest_word_type;
213 IRType host_word_type;
cerion92b64362005-12-13 12:02:26 +0000214 Bool mode64;
sewardjf13a16a2004-07-05 17:10:14 +0000215
sewardj49651f42004-10-28 22:11:04 +0000216 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000217 available_real_regs = NULL;
218 n_available_real_regs = 0;
219 isMove = NULL;
220 getRegUsage = NULL;
221 mapRegs = NULL;
222 genSpill = NULL;
223 genReload = NULL;
224 ppInstr = NULL;
225 ppReg = NULL;
226 iselBB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000227 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000228 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000229 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000230 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000231 guest_word_type = Ity_INVALID;
232 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000233 offB_TISTART = 0;
234 offB_TILEN = 0;
cerion92b64362005-12-13 12:02:26 +0000235 mode64 = False;
sewardj36ca5132004-07-24 13:12:23 +0000236
sewardj17c7f952005-12-15 14:02:34 +0000237 vex_traceflags = vta->traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000238
sewardj35421a32004-07-05 13:12:34 +0000239 vassert(vex_initdone);
sewardj2d6b14a2005-11-23 04:25:07 +0000240 vexSetAllocModeTEMP_and_clear();
241 vexAllocSanityCheck();
sewardj2a9ad022004-11-25 02:46:58 +0000242
sewardjf13a16a2004-07-05 17:10:14 +0000243 /* First off, check that the guest and host insn sets
244 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000245
sewardj17c7f952005-12-15 14:02:34 +0000246 switch (vta->arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000247
sewardjbef170b2004-12-21 01:23:00 +0000248 case VexArchX86:
cerion92b64362005-12-13 12:02:26 +0000249 mode64 = False;
sewardjf13a16a2004-07-05 17:10:14 +0000250 getAllocableRegs_X86 ( &n_available_real_regs,
251 &available_real_regs );
252 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
cerion92b64362005-12-13 12:02:26 +0000253 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_X86Instr;
254 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_X86Instr;
255 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_X86;
256 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_X86;
257 ppInstr = (void(*)(HInstr*, Bool)) ppX86Instr;
sewardj2b515872004-07-05 20:50:45 +0000258 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000259 iselBB = iselBB_X86;
sewardj0528bb52005-12-15 15:45:20 +0000260 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000261 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000262 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000263 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000264 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjf13a16a2004-07-05 17:10:14 +0000265 break;
sewardj2a9ad022004-11-25 02:46:58 +0000266
sewardjc33671d2005-02-01 20:30:00 +0000267 case VexArchAMD64:
cerion92b64362005-12-13 12:02:26 +0000268 mode64 = True;
sewardjc33671d2005-02-01 20:30:00 +0000269 getAllocableRegs_AMD64 ( &n_available_real_regs,
270 &available_real_regs );
271 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
cerion92b64362005-12-13 12:02:26 +0000272 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_AMD64Instr;
273 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_AMD64Instr;
274 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_AMD64;
275 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_AMD64;
276 ppInstr = (void(*)(HInstr*, Bool)) ppAMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000277 ppReg = (void(*)(HReg)) ppHRegAMD64;
278 iselBB = iselBB_AMD64;
sewardj0528bb52005-12-15 15:45:20 +0000279 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_AMD64Instr;
sewardjc33671d2005-02-01 20:30:00 +0000280 host_is_bigendian = False;
281 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000282 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000283 vassert(vta->dispatch != NULL); /* jump-to-dispatcher scheme */
sewardjc33671d2005-02-01 20:30:00 +0000284 break;
285
cerion487e4c92005-02-04 16:28:19 +0000286 case VexArchPPC32:
cerion92b64362005-12-13 12:02:26 +0000287 mode64 = False;
cerion5b2325f2005-12-23 00:55:09 +0000288 getAllocableRegs_PPC ( &n_available_real_regs,
289 &available_real_regs, mode64 );
290 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
291 getRegUsage = (void(*)(HRegUsage*,HInstr*,Bool)) getRegUsage_PPCInstr;
292 mapRegs = (void(*)(HRegRemap*,HInstr*,Bool)) mapRegs_PPCInstr;
293 genSpill = (HInstr*(*)(HReg,Int,Bool)) genSpill_PPC;
294 genReload = (HInstr*(*)(HReg,Int,Bool)) genReload_PPC;
295 ppInstr = (void(*)(HInstr*,Bool)) ppPPCInstr;
296 ppReg = (void(*)(HReg)) ppHRegPPC;
297 iselBB = iselBB_PPC;
298 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerion487e4c92005-02-04 16:28:19 +0000299 host_is_bigendian = True;
300 host_word_type = Ity_I32;
sewardj5117ce12006-01-27 21:20:15 +0000301 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000302 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerion487e4c92005-02-04 16:28:19 +0000303 break;
304
cerionf0de28c2005-12-13 20:21:11 +0000305 case VexArchPPC64:
306 mode64 = True;
cerion5b2325f2005-12-23 00:55:09 +0000307 getAllocableRegs_PPC ( &n_available_real_regs,
308 &available_real_regs, mode64 );
309 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPCInstr;
310 getRegUsage = (void(*)(HRegUsage*,HInstr*, Bool)) getRegUsage_PPCInstr;
311 mapRegs = (void(*)(HRegRemap*,HInstr*, Bool)) mapRegs_PPCInstr;
312 genSpill = (HInstr*(*)(HReg,Int, Bool)) genSpill_PPC;
313 genReload = (HInstr*(*)(HReg,Int, Bool)) genReload_PPC;
314 ppInstr = (void(*)(HInstr*, Bool)) ppPPCInstr;
315 ppReg = (void(*)(HReg)) ppHRegPPC;
316 iselBB = iselBB_PPC;
317 emit = (Int(*)(UChar*,Int,HInstr*,Bool,void*)) emit_PPCInstr;
cerionf0de28c2005-12-13 20:21:11 +0000318 host_is_bigendian = True;
319 host_word_type = Ity_I64;
sewardj5117ce12006-01-27 21:20:15 +0000320 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_host.hwcaps));
sewardj17c7f952005-12-15 14:02:34 +0000321 vassert(vta->dispatch == NULL); /* return-to-dispatcher scheme */
cerionf0de28c2005-12-13 20:21:11 +0000322 break;
323
sewardjf13a16a2004-07-05 17:10:14 +0000324 default:
sewardj887a11a2004-07-05 17:26:47 +0000325 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000326 }
327
sewardj2a9ad022004-11-25 02:46:58 +0000328
sewardj17c7f952005-12-15 14:02:34 +0000329 switch (vta->arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000330
sewardjbef170b2004-12-21 01:23:00 +0000331 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000332 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000333 disInstrFn = disInstr_X86;
sewardj2a9ad022004-11-25 02:46:58 +0000334 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000335 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000336 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000337 guest_layout = &x86guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000338 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
339 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000340 vassert(are_valid_hwcaps(VexArchX86, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000341 vassert(0 == sizeof(VexGuestX86State) % 8);
sewardjce02aa72006-01-12 12:27:58 +0000342 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART) == 4);
343 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
344 vassert(sizeof( ((VexGuestX86State*)0)->guest_NRADDR ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000345 break;
sewardj2a9ad022004-11-25 02:46:58 +0000346
sewardj44d494d2005-01-20 20:26:33 +0000347 case VexArchAMD64:
348 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000349 disInstrFn = disInstr_AMD64;
sewardj44d494d2005-01-20 20:26:33 +0000350 specHelper = guest_amd64_spechelper;
351 guest_sizeB = sizeof(VexGuestAMD64State);
352 guest_word_type = Ity_I64;
353 guest_layout = &amd64guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000354 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
355 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000356 vassert(are_valid_hwcaps(VexArchAMD64, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000357 vassert(0 == sizeof(VexGuestAMD64State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000358 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
sewardjce02aa72006-01-12 12:27:58 +0000359 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
360 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NRADDR ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000361 break;
362
sewardjbef170b2004-12-21 01:23:00 +0000363 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000364 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000365 disInstrFn = NULL; /* HACK */
sewardj2a9ad022004-11-25 02:46:58 +0000366 specHelper = guest_arm_spechelper;
367 guest_sizeB = sizeof(VexGuestARMState);
368 guest_word_type = Ity_I32;
369 guest_layout = &armGuest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000370 offB_TISTART = 0; /* hack ... arm has bitrot */
371 offB_TILEN = 0; /* hack ... arm has bitrot */
sewardj5117ce12006-01-27 21:20:15 +0000372 vassert(are_valid_hwcaps(VexArchARM, vta->archinfo_guest.hwcaps));
sewardj2a9ad022004-11-25 02:46:58 +0000373 break;
374
cerionaabdfbf2005-01-29 12:56:15 +0000375 case VexArchPPC32:
376 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000377 disInstrFn = disInstr_PPC;
cerionaabdfbf2005-01-29 12:56:15 +0000378 specHelper = guest_ppc32_spechelper;
379 guest_sizeB = sizeof(VexGuestPPC32State);
380 guest_word_type = Ity_I32;
381 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000382 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
383 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000384 vassert(are_valid_hwcaps(VexArchPPC32, vta->archinfo_guest.hwcaps));
sewardje74f6f72005-08-05 02:55:36 +0000385 vassert(0 == sizeof(VexGuestPPC32State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000386 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
sewardjce02aa72006-01-12 12:27:58 +0000387 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
388 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NRADDR ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000389 break;
390
cerionf0de28c2005-12-13 20:21:11 +0000391 case VexArchPPC64:
392 preciseMemExnsFn = guest_ppc64_state_requires_precise_mem_exns;
cerion5b2325f2005-12-23 00:55:09 +0000393 disInstrFn = disInstr_PPC;
cerionf0de28c2005-12-13 20:21:11 +0000394 specHelper = guest_ppc64_spechelper;
395 guest_sizeB = sizeof(VexGuestPPC64State);
396 guest_word_type = Ity_I64;
397 guest_layout = &ppc64Guest_layout;
398 offB_TISTART = offsetof(VexGuestPPC64State,guest_TISTART);
399 offB_TILEN = offsetof(VexGuestPPC64State,guest_TILEN);
sewardj5117ce12006-01-27 21:20:15 +0000400 vassert(are_valid_hwcaps(VexArchPPC64, vta->archinfo_guest.hwcaps));
cerionf0de28c2005-12-13 20:21:11 +0000401 vassert(0 == sizeof(VexGuestPPC64State) % 16);
sewardj3fd39672006-01-27 22:05:55 +0000402 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8);
403 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8);
404 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8);
405 vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR_GPR2) == 8);
cerionf0de28c2005-12-13 20:21:11 +0000406 break;
407
sewardjf13a16a2004-07-05 17:10:14 +0000408 default:
sewardj887a11a2004-07-05 17:26:47 +0000409 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000410 }
411
sewardj9df271d2004-12-31 22:37:42 +0000412 /* yet more sanity checks ... */
sewardj17c7f952005-12-15 14:02:34 +0000413 if (vta->arch_guest == vta->arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000414 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000415 we are simulating one flavour of an architecture a different
416 flavour of the same architecture, which is pretty strange. */
sewardj5117ce12006-01-27 21:20:15 +0000417 vassert(vta->archinfo_guest.hwcaps == vta->archinfo_host.hwcaps);
sewardj9df271d2004-12-31 22:37:42 +0000418 }
sewardj2a9ad022004-11-25 02:46:58 +0000419
sewardj2d6b14a2005-11-23 04:25:07 +0000420 vexAllocSanityCheck();
421
sewardjf48ac192004-10-29 00:41:29 +0000422 if (vex_traceflags & VEX_TRACE_FE)
423 vex_printf("\n------------------------"
424 " Front end "
425 "------------------------\n\n");
426
sewardj17c7f952005-12-15 14:02:34 +0000427 irbb = bb_to_IR ( vta->guest_extents,
sewardjc716aea2006-01-17 01:48:46 +0000428 vta->callback_opaque,
sewardj9e6491a2005-07-02 19:24:10 +0000429 disInstrFn,
sewardj17c7f952005-12-15 14:02:34 +0000430 vta->guest_bytes,
431 vta->guest_bytes_addr,
432 vta->chase_into_ok,
sewardj9e6491a2005-07-02 19:24:10 +0000433 host_is_bigendian,
sewardja5f55da2006-04-30 23:37:32 +0000434 vta->arch_guest,
sewardj17c7f952005-12-15 14:02:34 +0000435 &vta->archinfo_guest,
sewardjaca070a2006-10-17 00:28:22 +0000436 &vta->miscinfo_both,
sewardjdb4738a2005-07-07 01:32:16 +0000437 guest_word_type,
sewardj17c7f952005-12-15 14:02:34 +0000438 vta->do_self_check,
sewardjc716aea2006-01-17 01:48:46 +0000439 vta->preamble_function,
sewardjdb4738a2005-07-07 01:32:16 +0000440 offB_TISTART,
sewardjc716aea2006-01-17 01:48:46 +0000441 offB_TILEN );
sewardjf13a16a2004-07-05 17:10:14 +0000442
sewardj2d6b14a2005-11-23 04:25:07 +0000443 vexAllocSanityCheck();
444
sewardjf13a16a2004-07-05 17:10:14 +0000445 if (irbb == NULL) {
446 /* Access failure. */
sewardj2d6b14a2005-11-23 04:25:07 +0000447 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000448 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000449 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000450 }
sewardjaa59f942004-10-09 09:34:36 +0000451
sewardj17c7f952005-12-15 14:02:34 +0000452 vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
453 vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
454 for (i = 0; i < vta->guest_extents->n_used; i++) {
455 vassert(vta->guest_extents->len[i] < 10000); /* sanity */
sewardj72c72812005-01-19 11:49:45 +0000456 }
457
sewardjaa59f942004-10-09 09:34:36 +0000458 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000459 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj17c7f952005-12-15 14:02:34 +0000460 if (vta->guest_extents->n_used > 1) {
sewardj72c72812005-01-19 11:49:45 +0000461 vex_printf("can't show code due to extents > 1\n");
462 } else {
463 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000464 UChar* p = (UChar*)vta->guest_bytes;
465 UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
466 vex_printf(". 0 %llx %u\n.", vta->guest_bytes_addr, guest_bytes_read );
sewardj72c72812005-01-19 11:49:45 +0000467 for (i = 0; i < guest_bytes_read; i++)
cerionf0de28c2005-12-13 20:21:11 +0000468 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000469 vex_printf("\n\n");
470 }
sewardjaa59f942004-10-09 09:34:36 +0000471 }
472
473 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000474 sanityCheckIRBB( irbb, "initial IR",
475 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000476
sewardj2d6b14a2005-11-23 04:25:07 +0000477 vexAllocSanityCheck();
478
sewardjedf4d692004-08-17 13:52:58 +0000479 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000480 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
sewardj17c7f952005-12-15 14:02:34 +0000481 vta->guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000482 sanityCheckIRBB( irbb, "after initial iropt",
483 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000484
sewardjf48ac192004-10-29 00:41:29 +0000485 if (vex_traceflags & VEX_TRACE_OPT1) {
486 vex_printf("\n------------------------"
487 " After pre-instr IR optimisation "
488 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000489 ppIRBB ( irbb );
490 vex_printf("\n");
491 }
492
sewardj2d6b14a2005-11-23 04:25:07 +0000493 vexAllocSanityCheck();
494
sewardjf13a16a2004-07-05 17:10:14 +0000495 /* Get the thing instrumented. */
sewardj17c7f952005-12-15 14:02:34 +0000496 if (vta->instrument1)
sewardjc716aea2006-01-17 01:48:46 +0000497 irbb = vta->instrument1(vta->callback_opaque,
498 irbb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000499 vta->guest_extents,
500 guest_word_type, host_word_type);
sewardj2d6b14a2005-11-23 04:25:07 +0000501 vexAllocSanityCheck();
502
sewardj17c7f952005-12-15 14:02:34 +0000503 if (vta->instrument2)
sewardjc716aea2006-01-17 01:48:46 +0000504 irbb = vta->instrument2(vta->callback_opaque,
505 irbb, guest_layout,
sewardj17c7f952005-12-15 14:02:34 +0000506 vta->guest_extents,
507 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000508
sewardjf48ac192004-10-29 00:41:29 +0000509 if (vex_traceflags & VEX_TRACE_INST) {
510 vex_printf("\n------------------------"
511 " After instrumentation "
512 "------------------------\n\n");
513 ppIRBB ( irbb );
514 vex_printf("\n");
515 }
516
sewardj17c7f952005-12-15 14:02:34 +0000517 if (vta->instrument1 || vta->instrument2)
sewardjb9230752004-12-29 19:25:06 +0000518 sanityCheckIRBB( irbb, "after instrumentation",
519 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000520
sewardj9578a8b2004-11-04 19:44:48 +0000521 /* Do a post-instrumentation cleanup pass. */
sewardj17c7f952005-12-15 14:02:34 +0000522 if (vta->instrument1 || vta->instrument2) {
sewardj9578a8b2004-11-04 19:44:48 +0000523 do_deadcode_BB( irbb );
524 irbb = cprop_BB( irbb );
525 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000526 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
527 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000528 }
529
sewardj2d6b14a2005-11-23 04:25:07 +0000530 vexAllocSanityCheck();
531
sewardj9578a8b2004-11-04 19:44:48 +0000532 if (vex_traceflags & VEX_TRACE_OPT2) {
533 vex_printf("\n------------------------"
534 " After post-instr IR optimisation "
535 "------------------------\n\n");
536 ppIRBB ( irbb );
537 vex_printf("\n");
538 }
539
sewardjf9517d02005-11-28 13:39:37 +0000540 /* Turn it into virtual-registerised code. Build trees -- this
541 also throws away any dead bindings. */
542 ado_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000543
sewardj2d6b14a2005-11-23 04:25:07 +0000544 vexAllocSanityCheck();
545
sewardjf48ac192004-10-29 00:41:29 +0000546 if (vex_traceflags & VEX_TRACE_TREES) {
547 vex_printf("\n------------------------"
548 " After tree-building "
549 "------------------------\n\n");
550 ppIRBB ( irbb );
551 vex_printf("\n");
552 }
553
sewardje908c422005-02-04 21:18:16 +0000554 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000555 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000556 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000557
sewardjf48ac192004-10-29 00:41:29 +0000558 if (vex_traceflags & VEX_TRACE_VCODE)
559 vex_printf("\n------------------------"
560 " Instruction selection "
561 "------------------------\n");
562
sewardjaca070a2006-10-17 00:28:22 +0000563 vcode = iselBB ( irbb, vta->arch_host, &vta->archinfo_host,
564 &vta->miscinfo_both );
sewardjf13a16a2004-07-05 17:10:14 +0000565
sewardj2d6b14a2005-11-23 04:25:07 +0000566 vexAllocSanityCheck();
567
sewardjf48ac192004-10-29 00:41:29 +0000568 if (vex_traceflags & VEX_TRACE_VCODE)
569 vex_printf("\n");
570
sewardjf48ac192004-10-29 00:41:29 +0000571 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000572 for (i = 0; i < vcode->arr_used; i++) {
573 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000574 ppInstr(vcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000575 vex_printf("\n");
576 }
sewardjfbcaf332004-07-08 01:46:01 +0000577 vex_printf("\n");
578 }
sewardjfbcaf332004-07-08 01:46:01 +0000579
sewardjf13a16a2004-07-05 17:10:14 +0000580 /* Register allocate. */
581 rcode = doRegisterAllocation ( vcode, available_real_regs,
cerionf0de28c2005-12-13 20:21:11 +0000582 n_available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000583 isMove, getRegUsage, mapRegs,
584 genSpill, genReload, guest_sizeB,
cerion92b64362005-12-13 12:02:26 +0000585 ppInstr, ppReg, mode64 );
sewardjf13a16a2004-07-05 17:10:14 +0000586
sewardj2d6b14a2005-11-23 04:25:07 +0000587 vexAllocSanityCheck();
588
sewardjf48ac192004-10-29 00:41:29 +0000589 if (vex_traceflags & VEX_TRACE_RCODE) {
590 vex_printf("\n------------------------"
591 " Register-allocated code "
592 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000593 for (i = 0; i < rcode->arr_used; i++) {
594 vex_printf("%3d ", i);
cerion92b64362005-12-13 12:02:26 +0000595 ppInstr(rcode->arr[i], mode64);
sewardj1f40a0a2004-07-21 12:28:07 +0000596 vex_printf("\n");
597 }
sewardjfbcaf332004-07-08 01:46:01 +0000598 vex_printf("\n");
599 }
sewardjfbcaf332004-07-08 01:46:01 +0000600
sewardje908c422005-02-04 21:18:16 +0000601 /* HACK */
sewardj17c7f952005-12-15 14:02:34 +0000602 if (0) { *(vta->host_bytes_used) = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000603 /* end HACK */
604
sewardj81bd5502004-07-21 18:49:27 +0000605 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000606 if (vex_traceflags & VEX_TRACE_ASM) {
607 vex_printf("\n------------------------"
608 " Assembly "
609 "------------------------\n\n");
610 }
611
sewardj81bd5502004-07-21 18:49:27 +0000612 out_used = 0; /* tracks along the host_bytes array */
613 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000614 if (vex_traceflags & VEX_TRACE_ASM) {
cerion92b64362005-12-13 12:02:26 +0000615 ppInstr(rcode->arr[i], mode64);
sewardjbad34a92004-07-22 01:14:11 +0000616 vex_printf("\n");
617 }
sewardj17c7f952005-12-15 14:02:34 +0000618 j = (*emit)( insn_bytes, 32, rcode->arr[i], mode64, vta->dispatch );
sewardjf48ac192004-10-29 00:41:29 +0000619 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000620 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000621 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000622 vex_printf("0%x ", (UInt)insn_bytes[k]);
623 else
624 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000625 vex_printf("\n\n");
626 }
sewardj17c7f952005-12-15 14:02:34 +0000627 if (out_used + j > vta->host_bytes_size) {
sewardj2d6b14a2005-11-23 04:25:07 +0000628 vexSetAllocModeTEMP_and_clear();
sewardjf48ac192004-10-29 00:41:29 +0000629 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000630 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000631 }
632 for (k = 0; k < j; k++) {
sewardj17c7f952005-12-15 14:02:34 +0000633 vta->host_bytes[out_used] = insn_bytes[k];
sewardj81bd5502004-07-21 18:49:27 +0000634 out_used++;
635 }
sewardj17c7f952005-12-15 14:02:34 +0000636 vassert(out_used <= vta->host_bytes_size);
sewardj81bd5502004-07-21 18:49:27 +0000637 }
sewardj17c7f952005-12-15 14:02:34 +0000638 *(vta->host_bytes_used) = out_used;
sewardj81bd5502004-07-21 18:49:27 +0000639
sewardj2d6b14a2005-11-23 04:25:07 +0000640 vexAllocSanityCheck();
641
642 vexSetAllocModeTEMP_and_clear();
sewardjf13a16a2004-07-05 17:10:14 +0000643
sewardjf48ac192004-10-29 00:41:29 +0000644 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000645 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000646}
647
648
sewardj893aada2004-11-29 19:57:54 +0000649/* --------- Emulation warnings. --------- */
650
651HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
652{
653 switch (ew) {
654 case EmWarn_NONE:
655 return "none";
656 case EmWarn_X86_x87exns:
657 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000658 case EmWarn_X86_x87precision:
659 return "Selection of non-80-bit x87 FP precision";
660 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000661 return "Unmasking SSE FP exceptions";
662 case EmWarn_X86_fz:
663 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
664 case EmWarn_X86_daz:
665 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000666 case EmWarn_X86_acFlag:
667 return "Setting %eflags.ac (setting noted but ignored)";
sewardj9dd9cf12006-01-20 14:13:55 +0000668 case EmWarn_PPCexns:
669 return "Unmasking PPC32/64 FP exceptions";
670 case EmWarn_PPC64_redir_overflow:
671 return "PPC64 function redirection stack overflow";
672 case EmWarn_PPC64_redir_underflow:
673 return "PPC64 function redirection stack underflow";
sewardj893aada2004-11-29 19:57:54 +0000674 default:
675 vpanic("LibVEX_EmWarn_string: unknown warning");
676 }
677}
sewardj35421a32004-07-05 13:12:34 +0000678
sewardj5117ce12006-01-27 21:20:15 +0000679/* ------------------ Arch/HwCaps stuff. ------------------ */
sewardjbef170b2004-12-21 01:23:00 +0000680
681const HChar* LibVEX_ppVexArch ( VexArch arch )
682{
683 switch (arch) {
684 case VexArch_INVALID: return "INVALID";
685 case VexArchX86: return "X86";
686 case VexArchAMD64: return "AMD64";
687 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000688 case VexArchPPC32: return "PPC32";
cerionf0de28c2005-12-13 20:21:11 +0000689 case VexArchPPC64: return "PPC64";
sewardjbef170b2004-12-21 01:23:00 +0000690 default: return "VexArch???";
691 }
692}
693
sewardj5117ce12006-01-27 21:20:15 +0000694const HChar* LibVEX_ppVexHwCaps ( VexArch arch, UInt hwcaps )
sewardjbef170b2004-12-21 01:23:00 +0000695{
sewardj5117ce12006-01-27 21:20:15 +0000696 HChar* str = show_hwcaps(arch,hwcaps);
697 return str ? str : "INVALID";
sewardjbef170b2004-12-21 01:23:00 +0000698}
699
sewardj5117ce12006-01-27 21:20:15 +0000700
sewardj27e1dd62005-06-30 11:49:14 +0000701/* Write default settings info *vai. */
702void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
703{
sewardj5117ce12006-01-27 21:20:15 +0000704 vai->hwcaps = 0;
cerion5b2325f2005-12-23 00:55:09 +0000705 vai->ppc_cache_line_szB = 0;
sewardj27e1dd62005-06-30 11:49:14 +0000706}
707
sewardjaca070a2006-10-17 00:28:22 +0000708/* Write default settings info *vmi. */
709void LibVEX_default_VexMiscInfo ( /*OUT*/VexMiscInfo* vmi )
710{
711 vmi->guest_stack_redzone_size = 0;
712 vmi->guest_ppc_zap_RZ_at_blr = False;
713 vmi->guest_ppc_zap_RZ_at_bl = NULL;
714 vmi->guest_ppc_sc_continues_at_LR = False;
715 vmi->host_ppc_calls_use_fndescrs = False;
716 vmi->host_ppc32_regalign_int64_args = False;
717}
718
sewardj27e1dd62005-06-30 11:49:14 +0000719
sewardj5117ce12006-01-27 21:20:15 +0000720/* Return a string showing the hwcaps in a nice way. The string will
721 be NULL for invalid combinations of flags, so these functions also
722 serve as a way to validate hwcaps values. */
723
724static HChar* show_hwcaps_x86 ( UInt hwcaps )
725{
726 /* Monotonic, SSE3 > SSE2 > SSE1 > baseline. */
727 if (hwcaps == 0)
728 return "x86-sse0";
729 if (hwcaps == VEX_HWCAPS_X86_SSE1)
730 return "x86-sse1";
731 if (hwcaps == (VEX_HWCAPS_X86_SSE1 | VEX_HWCAPS_X86_SSE2))
732 return "x86-sse1-sse2";
733 if (hwcaps == (VEX_HWCAPS_X86_SSE1
734 | VEX_HWCAPS_X86_SSE2 | VEX_HWCAPS_X86_SSE3))
735 return "x86-sse1-sse2-sse3";
736
737 return False;
738}
739
740static HChar* show_hwcaps_amd64 ( UInt hwcaps )
741{
742 /* Monotonic, SSE3 > baseline. */
743 if (hwcaps == 0)
744 return "amd64-sse2";
745 if (hwcaps == VEX_HWCAPS_AMD64_SSE3)
746 return "amd64-sse3";
747 return False;
748}
749
750static HChar* show_hwcaps_ppc32 ( UInt hwcaps )
751{
752 /* Monotonic with complications. Basically V > F > baseline,
753 but once you have F then you can have FX or GX too. */
754 const UInt F = VEX_HWCAPS_PPC32_F;
755 const UInt V = VEX_HWCAPS_PPC32_V;
756 const UInt FX = VEX_HWCAPS_PPC32_FX;
757 const UInt GX = VEX_HWCAPS_PPC32_GX;
758 UInt c = hwcaps;
759 if (c == 0) return "ppc32-int";
760 if (c == F) return "ppc32-int-flt";
761 if (c == (F|FX)) return "ppc32-int-flt-FX";
762 if (c == (F|GX)) return "ppc32-int-flt-GX";
763 if (c == (F|FX|GX)) return "ppc32-int-flt-FX-GX";
764 if (c == (F|V)) return "ppc32-int-flt-vmx";
765 if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX";
766 if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX";
767 if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX";
768 return NULL;
769}
770
771static HChar* show_hwcaps_ppc64 ( UInt hwcaps )
772{
773 /* Monotonic with complications. Basically V > baseline(==F),
774 but once you have F then you can have FX or GX too. */
sewardj3fd39672006-01-27 22:05:55 +0000775 const UInt V = VEX_HWCAPS_PPC64_V;
776 const UInt FX = VEX_HWCAPS_PPC64_FX;
777 const UInt GX = VEX_HWCAPS_PPC64_GX;
sewardj5117ce12006-01-27 21:20:15 +0000778 UInt c = hwcaps;
779 if (c == 0) return "ppc64-int-flt";
780 if (c == FX) return "ppc64-int-flt-FX";
781 if (c == GX) return "ppc64-int-flt-GX";
782 if (c == (FX|GX)) return "ppc64-int-flt-FX-GX";
783 if (c == V) return "ppc64-int-flt-vmx";
784 if (c == (V|FX)) return "ppc64-int-flt-vmx-FX";
785 if (c == (V|GX)) return "ppc64-int-flt-vmx-GX";
786 if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX";
787 return NULL;
788}
789
790static HChar* show_hwcaps_arm ( UInt hwcaps )
791{
792 if (hwcaps == 0) return "arm-baseline";
793 return NULL;
794}
795
796/* ---- */
797static HChar* show_hwcaps ( VexArch arch, UInt hwcaps )
798{
799 switch (arch) {
sewardj3fd39672006-01-27 22:05:55 +0000800 case VexArchX86: return show_hwcaps_x86(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000801 case VexArchAMD64: return show_hwcaps_amd64(hwcaps);
802 case VexArchPPC32: return show_hwcaps_ppc32(hwcaps);
803 case VexArchPPC64: return show_hwcaps_ppc64(hwcaps);
sewardj3fd39672006-01-27 22:05:55 +0000804 case VexArchARM: return show_hwcaps_arm(hwcaps);
sewardj5117ce12006-01-27 21:20:15 +0000805 default: return NULL;
806 }
807}
808
809static Bool are_valid_hwcaps ( VexArch arch, UInt hwcaps )
810{
811 return show_hwcaps(arch,hwcaps) != NULL;
812}
813
814
sewardj35421a32004-07-05 13:12:34 +0000815/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000816/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000817/*---------------------------------------------------------------*/