blob: fcde08143b1588cf80411a308f81b8ae73de1903 [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 ---*/
sewardj35421a32004-07-05 13:12:34 +00005/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
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
13 Copyright (C) 2004 OpenWorks, LLP.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; Version 2 dated June 1991 of the
18 license.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
23 for damages. See the GNU General Public License for more details.
24
25 Neither the names of the U.S. Department of Energy nor the
26 University of California nor the names of its contributors may be
27 used to endorse or promote products derived from this software
28 without prior written permission.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 USA.
34*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex.h"
sewardj893aada2004-11-29 19:57:54 +000037#include "libvex_emwarn.h"
sewardj81ec4182004-10-25 23:15:52 +000038#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000039#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000040#include "libvex_guest_arm.h"
sewardjf13a16a2004-07-05 17:10:14 +000041
sewardjc0ee2ed2004-07-27 10:29:41 +000042#include "main/vex_globals.h"
43#include "main/vex_util.h"
44#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000045#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000046
sewardj2a9ad022004-11-25 02:46:58 +000047#include "host-x86/hdefs.h"
48
49#include "guest-x86/gdefs.h"
sewardj44d494d2005-01-20 20:26:33 +000050#include "guest-amd64/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000051#include "guest-arm/gdefs.h"
52
sewardj35421a32004-07-05 13:12:34 +000053
54/* This file contains the top level interface to the library. */
55
56/* --------- Initialise the library. --------- */
57
58/* Exported to library client. */
59
sewardjd887b862005-01-17 18:34:34 +000060const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000061{
62return
63#include "main/vex_svnversion.h"
64 ;
65}
66
67
68/* Exported to library client. */
69
sewardj08613742004-10-25 13:01:45 +000070void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
71{
72 vcon->iropt_verbosity = 0;
73 vcon->iropt_level = 2;
74 vcon->iropt_precise_memory_exns = False;
75 vcon->iropt_unroll_thresh = 120;
76 vcon->guest_max_insns = 50;
77 vcon->guest_chase_thresh = 10;
78}
79
80
81/* Exported to library client. */
82
sewardj887a11a2004-07-05 17:26:47 +000083void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000084 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000085 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000086 void (*failure_exit) ( void ),
87 /* logging output function */
88 void (*log_bytes) ( Char*, Int nbytes ),
89 /* debug paranoia level */
90 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +000091 /* Are we supporting valgrind checking? */
92 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +000093 /* Control ... */
94 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +000095)
96{
sewardj08613742004-10-25 13:01:45 +000097 /* First off, do enough minimal setup so that the following
98 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +000099 vex_failure_exit = failure_exit;
100 vex_log_bytes = log_bytes;
101
102 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000103 vassert(!vex_initdone);
104 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000105 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000106 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000107
108 vassert(vcon->iropt_verbosity >= 0);
109 vassert(vcon->iropt_level >= 0);
110 vassert(vcon->iropt_level <= 2);
111 vassert(vcon->iropt_unroll_thresh >= 0);
112 vassert(vcon->iropt_unroll_thresh <= 400);
113 vassert(vcon->guest_max_insns >= 1);
114 vassert(vcon->guest_max_insns <= 100);
115 vassert(vcon->guest_chase_thresh >= 0);
116 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000117
sewardj81ec4182004-10-25 23:15:52 +0000118 /* All the guest state structs must have an 8-aligned size. */
119 vassert(0 == sizeof(VexGuestX86State) % 8);
120
sewardjea602bc2004-10-14 21:40:12 +0000121 /* Check that Vex has been built with sizes of basic types as
122 stated in priv/libvex_basictypes.h. Failure of any of these is
123 a serious configuration error and should be corrected
124 immediately. If any of these assertions fail you can fully
125 expect Vex not to work properly, if at all. */
126
127 vassert(1 == sizeof(UChar));
128 vassert(1 == sizeof(Char));
129 vassert(2 == sizeof(UShort));
130 vassert(2 == sizeof(Short));
131 vassert(4 == sizeof(UInt));
132 vassert(4 == sizeof(Int));
133 vassert(8 == sizeof(ULong));
134 vassert(8 == sizeof(Long));
135 vassert(4 == sizeof(Float));
136 vassert(8 == sizeof(Double));
137 vassert(1 == sizeof(Bool));
138 vassert(4 == sizeof(Addr32));
139 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000140 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000141
142 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
143 vassert(sizeof(void*) == sizeof(int*));
144 vassert(sizeof(void*) == sizeof(HWord));
145
146 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000147 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000148 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000149 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000150 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000151 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000152}
153
154
155/* --------- Make a translation. --------- */
156
157/* Exported to library client. */
158
sewardjd887b862005-01-17 18:34:34 +0000159VexTranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000160 /* The instruction sets we are translating from and to. */
sewardjbef170b2004-12-21 01:23:00 +0000161 VexArch arch_guest,
162 VexSubArch subarch_guest,
163 VexArch arch_host,
164 VexSubArch subarch_host,
sewardj35421a32004-07-05 13:12:34 +0000165 /* IN: the block to translate, and its guest address. */
sewardjbef170b2004-12-21 01:23:00 +0000166 UChar* guest_bytes,
167 Addr64 guest_bytes_addr,
168 Bool (*chase_into_ok) ( Addr64 ),
sewardj72c72812005-01-19 11:49:45 +0000169 /* OUT: which bits of guest code actually got translated */
170 VexGuestExtents* guest_extents,
sewardj35421a32004-07-05 13:12:34 +0000171 /* IN: a place to put the resulting code, and its size */
sewardjbef170b2004-12-21 01:23:00 +0000172 UChar* host_bytes,
173 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000174 /* OUT: how much of the output area is used. */
sewardjbef170b2004-12-21 01:23:00 +0000175 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000176 /* IN: optionally, two instrumentation functions. */
sewardjbef170b2004-12-21 01:23:00 +0000177 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
178 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
179 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000180 /* IN: optionally, an access check function for guest code. */
sewardjbef170b2004-12-21 01:23:00 +0000181 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000182 /* IN: debug: trace vex activity at various points */
sewardjbef170b2004-12-21 01:23:00 +0000183 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000184)
185{
sewardj81bd5502004-07-21 18:49:27 +0000186 /* This the bundle of functions we need to do the back-end stuff
187 (insn selection, reg-alloc, assembly) whilst being insulated
188 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000189 HReg* available_real_regs;
190 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000191 Bool (*isMove) (HInstr*, HReg*, HReg*);
192 void (*getRegUsage) (HRegUsage*, HInstr*);
193 void (*mapRegs) (HRegRemap*, HInstr*);
194 HInstr* (*genSpill) ( HReg, Int );
195 HInstr* (*genReload) ( HReg, Int );
196 void (*ppInstr) ( HInstr* );
197 void (*ppReg) ( HReg );
sewardj9df271d2004-12-31 22:37:42 +0000198 HInstrArray* (*iselBB) ( IRBB*, VexSubArch );
sewardj72c72812005-01-19 11:49:45 +0000199 IRBB* (*bbToIR) ( UChar*, Addr64,
200 VexGuestExtents*,
sewardj5bd4d162004-11-10 13:02:48 +0000201 Bool(*)(Addr64),
sewardj72c72812005-01-19 11:49:45 +0000202 Bool(*)(Addr64),
203 Bool, VexSubArch );
sewardj81bd5502004-07-21 18:49:27 +0000204 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000205 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000206 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000207
sewardjeeac8412004-11-02 00:26:55 +0000208 VexGuestLayout* guest_layout;
209 Bool host_is_bigendian = False;
210 IRBB* irbb;
211 HInstrArray* vcode;
212 HInstrArray* rcode;
213 Int i, j, k, out_used, guest_sizeB;
214 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000215 IRType guest_word_type;
216 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000217
sewardj49651f42004-10-28 22:11:04 +0000218 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000219 available_real_regs = NULL;
220 n_available_real_regs = 0;
221 isMove = NULL;
222 getRegUsage = NULL;
223 mapRegs = NULL;
224 genSpill = NULL;
225 genReload = NULL;
226 ppInstr = NULL;
227 ppReg = NULL;
228 iselBB = NULL;
229 bbToIR = NULL;
230 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000231 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000232 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000233 guest_word_type = Ity_INVALID;
234 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000235
sewardjf48ac192004-10-29 00:41:29 +0000236 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000237
sewardj35421a32004-07-05 13:12:34 +0000238 vassert(vex_initdone);
sewardjd887b862005-01-17 18:34:34 +0000239 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000240
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
sewardjbef170b2004-12-21 01:23:00 +0000245 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000246
sewardjbef170b2004-12-21 01:23:00 +0000247 case VexArchX86:
sewardjf13a16a2004-07-05 17:10:14 +0000248 getAllocableRegs_X86 ( &n_available_real_regs,
249 &available_real_regs );
250 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
251 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
252 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
253 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
254 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000255 ppInstr = (void(*)(HInstr*)) ppX86Instr;
256 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000257 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000258 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000259 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000260 host_word_type = Ity_I32;
sewardj9df271d2004-12-31 22:37:42 +0000261 vassert(subarch_host == VexSubArchX86_sse0
262 || subarch_host == VexSubArchX86_sse1
263 || subarch_host == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000264 break;
sewardj2a9ad022004-11-25 02:46:58 +0000265
sewardjf13a16a2004-07-05 17:10:14 +0000266 default:
sewardj887a11a2004-07-05 17:26:47 +0000267 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000268 }
269
sewardj2a9ad022004-11-25 02:46:58 +0000270
sewardjbef170b2004-12-21 01:23:00 +0000271 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000272
sewardjbef170b2004-12-21 01:23:00 +0000273 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000274 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000275 bbToIR = bbToIR_X86;
276 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000277 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000278 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000279 guest_layout = &x86guest_layout;
sewardj9df271d2004-12-31 22:37:42 +0000280 vassert(subarch_guest == VexSubArchX86_sse0
281 || subarch_guest == VexSubArchX86_sse1
282 || subarch_guest == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000283 break;
sewardj2a9ad022004-11-25 02:46:58 +0000284
sewardj44d494d2005-01-20 20:26:33 +0000285 case VexArchAMD64:
286 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
287 bbToIR = bbToIR_AMD64;
288 specHelper = guest_amd64_spechelper;
289 guest_sizeB = sizeof(VexGuestAMD64State);
290 guest_word_type = Ity_I64;
291 guest_layout = &amd64guest_layout;
292 vassert(subarch_guest == VexSubArch_NONE);
293 break;
294
sewardjbef170b2004-12-21 01:23:00 +0000295 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000296 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000297 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000298 specHelper = guest_arm_spechelper;
299 guest_sizeB = sizeof(VexGuestARMState);
300 guest_word_type = Ity_I32;
301 guest_layout = &armGuest_layout;
sewardj44d494d2005-01-20 20:26:33 +0000302 vassert(subarch_guest == VexSubArchARM_v4);
sewardj2a9ad022004-11-25 02:46:58 +0000303 break;
304
sewardjf13a16a2004-07-05 17:10:14 +0000305 default:
sewardj887a11a2004-07-05 17:26:47 +0000306 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000307 }
308
sewardj9df271d2004-12-31 22:37:42 +0000309 /* yet more sanity checks ... */
310 if (arch_guest == VexArchX86 && arch_host == VexArchX86) {
311 /* doesn't necessarily have to be true, but if it isn't it means
312 we are simulating one flavour of x86 on a different one, which
313 is pretty strange. */
314 vassert(subarch_guest == subarch_host);
315 }
sewardj2a9ad022004-11-25 02:46:58 +0000316
sewardjf48ac192004-10-29 00:41:29 +0000317 if (vex_traceflags & VEX_TRACE_FE)
318 vex_printf("\n------------------------"
319 " Front end "
320 "------------------------\n\n");
321
sewardjf13a16a2004-07-05 17:10:14 +0000322 irbb = bbToIR ( guest_bytes,
sewardj72c72812005-01-19 11:49:45 +0000323 guest_bytes_addr,
324 guest_extents,
325 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000326 chase_into_ok,
sewardj72c72812005-01-19 11:49:45 +0000327 host_is_bigendian,
sewardj9df271d2004-12-31 22:37:42 +0000328 subarch_guest );
sewardjf13a16a2004-07-05 17:10:14 +0000329
330 if (irbb == NULL) {
331 /* Access failure. */
sewardjd887b862005-01-17 18:34:34 +0000332 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000333 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000334 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000335 }
sewardjaa59f942004-10-09 09:34:36 +0000336
sewardj72c72812005-01-19 11:49:45 +0000337 vassert(guest_extents->n_used >= 1 && guest_extents->n_used <= 3);
338 vassert(guest_extents->base[0] == guest_bytes_addr);
339 for (i = 0; i < guest_extents->n_used; i++) {
340 vassert(guest_extents->len[i] < 10000); /* sanity */
341 }
342
sewardjaa59f942004-10-09 09:34:36 +0000343 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000344 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj72c72812005-01-19 11:49:45 +0000345 if (guest_extents->n_used > 1) {
346 vex_printf("can't show code due to extents > 1\n");
347 } else {
348 /* HACK */
349 UChar* p = (UChar*)guest_bytes;
350 UInt guest_bytes_read = (UInt)guest_extents->len[0];
351 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, guest_bytes_read );
352 for (i = 0; i < guest_bytes_read; i++)
sewardjaa59f942004-10-09 09:34:36 +0000353 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000354 vex_printf("\n\n");
355 }
sewardjaa59f942004-10-09 09:34:36 +0000356 }
357
358 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000359 sanityCheckIRBB( irbb, "initial IR",
360 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000361
sewardjedf4d692004-08-17 13:52:58 +0000362 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000363 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
364 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000365 sanityCheckIRBB( irbb, "after initial iropt",
366 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000367
sewardjf48ac192004-10-29 00:41:29 +0000368 if (vex_traceflags & VEX_TRACE_OPT1) {
369 vex_printf("\n------------------------"
370 " After pre-instr IR optimisation "
371 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000372 ppIRBB ( irbb );
373 vex_printf("\n");
374 }
375
sewardjf13a16a2004-07-05 17:10:14 +0000376 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000377 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000378 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000379 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000380 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000381
sewardjf48ac192004-10-29 00:41:29 +0000382 if (vex_traceflags & VEX_TRACE_INST) {
383 vex_printf("\n------------------------"
384 " After instrumentation "
385 "------------------------\n\n");
386 ppIRBB ( irbb );
387 vex_printf("\n");
388 }
389
sewardj49651f42004-10-28 22:11:04 +0000390 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000391 sanityCheckIRBB( irbb, "after instrumentation",
392 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000393
sewardj9578a8b2004-11-04 19:44:48 +0000394 /* Do a post-instrumentation cleanup pass. */
395 if (cleanup_after_instrumentation) {
396 do_deadcode_BB( irbb );
397 irbb = cprop_BB( irbb );
398 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000399 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
400 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000401 }
402
403 if (vex_traceflags & VEX_TRACE_OPT2) {
404 vex_printf("\n------------------------"
405 " After post-instr IR optimisation "
406 "------------------------\n\n");
407 ppIRBB ( irbb );
408 vex_printf("\n");
409 }
410
sewardjf13a16a2004-07-05 17:10:14 +0000411 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000412 do_deadcode_BB( irbb );
413 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000414
415 if (vex_traceflags & VEX_TRACE_TREES) {
416 vex_printf("\n------------------------"
417 " After tree-building "
418 "------------------------\n\n");
419 ppIRBB ( irbb );
420 vex_printf("\n");
421 }
422
423 if (vex_traceflags & VEX_TRACE_VCODE)
424 vex_printf("\n------------------------"
425 " Instruction selection "
426 "------------------------\n");
427
sewardj9df271d2004-12-31 22:37:42 +0000428 vcode = iselBB ( irbb, subarch_host );
sewardjf13a16a2004-07-05 17:10:14 +0000429
sewardjf48ac192004-10-29 00:41:29 +0000430 if (vex_traceflags & VEX_TRACE_VCODE)
431 vex_printf("\n");
432
sewardjf48ac192004-10-29 00:41:29 +0000433 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000434 for (i = 0; i < vcode->arr_used; i++) {
435 vex_printf("%3d ", i);
436 ppInstr(vcode->arr[i]);
437 vex_printf("\n");
438 }
sewardjfbcaf332004-07-08 01:46:01 +0000439 vex_printf("\n");
440 }
sewardjfbcaf332004-07-08 01:46:01 +0000441
sewardjf13a16a2004-07-05 17:10:14 +0000442 /* Register allocate. */
443 rcode = doRegisterAllocation ( vcode, available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000444 n_available_real_regs,
445 isMove, getRegUsage, mapRegs,
446 genSpill, genReload, guest_sizeB,
447 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000448
sewardjf48ac192004-10-29 00:41:29 +0000449 if (vex_traceflags & VEX_TRACE_RCODE) {
450 vex_printf("\n------------------------"
451 " Register-allocated code "
452 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000453 for (i = 0; i < rcode->arr_used; i++) {
454 vex_printf("%3d ", i);
455 ppInstr(rcode->arr[i]);
456 vex_printf("\n");
457 }
sewardjfbcaf332004-07-08 01:46:01 +0000458 vex_printf("\n");
459 }
sewardjfbcaf332004-07-08 01:46:01 +0000460
sewardj81bd5502004-07-21 18:49:27 +0000461 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000462 if (vex_traceflags & VEX_TRACE_ASM) {
463 vex_printf("\n------------------------"
464 " Assembly "
465 "------------------------\n\n");
466 }
467
sewardj81bd5502004-07-21 18:49:27 +0000468 out_used = 0; /* tracks along the host_bytes array */
469 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000470 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000471 ppInstr(rcode->arr[i]);
472 vex_printf("\n");
473 }
sewardj81bd5502004-07-21 18:49:27 +0000474 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000475 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000476 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000477 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000478 vex_printf("0%x ", (UInt)insn_bytes[k]);
479 else
480 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000481 vex_printf("\n\n");
482 }
sewardj81bd5502004-07-21 18:49:27 +0000483 if (out_used + j > host_bytes_size) {
sewardjd887b862005-01-17 18:34:34 +0000484 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000485 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000486 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000487 }
488 for (k = 0; k < j; k++) {
489 host_bytes[out_used] = insn_bytes[k];
490 out_used++;
491 }
492 vassert(out_used <= host_bytes_size);
493 }
494 *host_bytes_used = out_used;
495
sewardjd887b862005-01-17 18:34:34 +0000496 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000497
sewardjf48ac192004-10-29 00:41:29 +0000498 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000499 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000500}
501
502
sewardj893aada2004-11-29 19:57:54 +0000503/* --------- Emulation warnings. --------- */
504
505HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
506{
507 switch (ew) {
508 case EmWarn_NONE:
509 return "none";
510 case EmWarn_X86_x87exns:
511 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000512 case EmWarn_X86_x87precision:
513 return "Selection of non-80-bit x87 FP precision";
514 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000515 return "Unmasking SSE FP exceptions";
516 case EmWarn_X86_fz:
517 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
518 case EmWarn_X86_daz:
519 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000520 default:
521 vpanic("LibVEX_EmWarn_string: unknown warning");
522 }
523}
sewardj35421a32004-07-05 13:12:34 +0000524
sewardjbef170b2004-12-21 01:23:00 +0000525/* --------- Arch/Subarch names. --------- */
526
527const HChar* LibVEX_ppVexArch ( VexArch arch )
528{
529 switch (arch) {
530 case VexArch_INVALID: return "INVALID";
531 case VexArchX86: return "X86";
532 case VexArchAMD64: return "AMD64";
533 case VexArchARM: return "ARM";
534 default: return "VexArch???";
535 }
536}
537
538const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
539{
540 switch (subarch) {
541 case VexSubArch_INVALID: return "INVALID";
542 case VexSubArch_NONE: return "NONE";
543 case VexSubArchX86_sse0: return "x86-sse0";
544 case VexSubArchX86_sse1: return "x86-sse1";
545 case VexSubArchX86_sse2: return "x86-sse2";
546 case VexSubArchARM_v4: return "arm-v4";
547 default: return "VexSubArch???";
548 }
549}
550
sewardj35421a32004-07-05 13:12:34 +0000551/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000552/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000553/*---------------------------------------------------------------*/