blob: 43ac46d11bc0fefe3522ee31a09ff45a673bc5b0 [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"
cerionaabdfbf2005-01-29 12:56:15 +000041#include "libvex_guest_ppc32.h"
sewardjf13a16a2004-07-05 17:10:14 +000042
sewardjc0ee2ed2004-07-27 10:29:41 +000043#include "main/vex_globals.h"
44#include "main/vex_util.h"
45#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000046#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000047
sewardj2a9ad022004-11-25 02:46:58 +000048#include "host-x86/hdefs.h"
49
50#include "guest-x86/gdefs.h"
sewardj44d494d2005-01-20 20:26:33 +000051#include "guest-amd64/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000052#include "guest-arm/gdefs.h"
cerionaabdfbf2005-01-29 12:56:15 +000053#include "guest-ppc32/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000054
sewardj35421a32004-07-05 13:12:34 +000055
56/* This file contains the top level interface to the library. */
57
58/* --------- Initialise the library. --------- */
59
60/* Exported to library client. */
61
sewardjd887b862005-01-17 18:34:34 +000062const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000063{
64return
65#include "main/vex_svnversion.h"
66 ;
67}
68
69
70/* Exported to library client. */
71
sewardj08613742004-10-25 13:01:45 +000072void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
73{
74 vcon->iropt_verbosity = 0;
75 vcon->iropt_level = 2;
76 vcon->iropt_precise_memory_exns = False;
77 vcon->iropt_unroll_thresh = 120;
78 vcon->guest_max_insns = 50;
79 vcon->guest_chase_thresh = 10;
80}
81
82
83/* Exported to library client. */
84
sewardj887a11a2004-07-05 17:26:47 +000085void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000086 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000087 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000088 void (*failure_exit) ( void ),
89 /* logging output function */
90 void (*log_bytes) ( Char*, Int nbytes ),
91 /* debug paranoia level */
92 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +000093 /* Are we supporting valgrind checking? */
94 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +000095 /* Control ... */
96 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +000097)
98{
sewardj08613742004-10-25 13:01:45 +000099 /* First off, do enough minimal setup so that the following
100 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000101 vex_failure_exit = failure_exit;
102 vex_log_bytes = log_bytes;
103
104 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000105 vassert(!vex_initdone);
106 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000107 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000108 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000109
110 vassert(vcon->iropt_verbosity >= 0);
111 vassert(vcon->iropt_level >= 0);
112 vassert(vcon->iropt_level <= 2);
113 vassert(vcon->iropt_unroll_thresh >= 0);
114 vassert(vcon->iropt_unroll_thresh <= 400);
115 vassert(vcon->guest_max_insns >= 1);
116 vassert(vcon->guest_max_insns <= 100);
117 vassert(vcon->guest_chase_thresh >= 0);
118 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000119
sewardj81ec4182004-10-25 23:15:52 +0000120 /* All the guest state structs must have an 8-aligned size. */
121 vassert(0 == sizeof(VexGuestX86State) % 8);
122
sewardjea602bc2004-10-14 21:40:12 +0000123 /* Check that Vex has been built with sizes of basic types as
124 stated in priv/libvex_basictypes.h. Failure of any of these is
125 a serious configuration error and should be corrected
126 immediately. If any of these assertions fail you can fully
127 expect Vex not to work properly, if at all. */
128
129 vassert(1 == sizeof(UChar));
130 vassert(1 == sizeof(Char));
131 vassert(2 == sizeof(UShort));
132 vassert(2 == sizeof(Short));
133 vassert(4 == sizeof(UInt));
134 vassert(4 == sizeof(Int));
135 vassert(8 == sizeof(ULong));
136 vassert(8 == sizeof(Long));
137 vassert(4 == sizeof(Float));
138 vassert(8 == sizeof(Double));
139 vassert(1 == sizeof(Bool));
140 vassert(4 == sizeof(Addr32));
141 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000142 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000143
144 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
145 vassert(sizeof(void*) == sizeof(int*));
146 vassert(sizeof(void*) == sizeof(HWord));
147
148 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000149 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000150 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000151 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000152 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000153 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000154}
155
156
157/* --------- Make a translation. --------- */
158
159/* Exported to library client. */
160
sewardjd887b862005-01-17 18:34:34 +0000161VexTranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000162 /* The instruction sets we are translating from and to. */
sewardjbef170b2004-12-21 01:23:00 +0000163 VexArch arch_guest,
164 VexSubArch subarch_guest,
165 VexArch arch_host,
166 VexSubArch subarch_host,
sewardj35421a32004-07-05 13:12:34 +0000167 /* IN: the block to translate, and its guest address. */
sewardjbef170b2004-12-21 01:23:00 +0000168 UChar* guest_bytes,
169 Addr64 guest_bytes_addr,
170 Bool (*chase_into_ok) ( Addr64 ),
sewardj72c72812005-01-19 11:49:45 +0000171 /* OUT: which bits of guest code actually got translated */
172 VexGuestExtents* guest_extents,
sewardj35421a32004-07-05 13:12:34 +0000173 /* IN: a place to put the resulting code, and its size */
sewardjbef170b2004-12-21 01:23:00 +0000174 UChar* host_bytes,
175 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000176 /* OUT: how much of the output area is used. */
sewardjbef170b2004-12-21 01:23:00 +0000177 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000178 /* IN: optionally, two instrumentation functions. */
sewardjbef170b2004-12-21 01:23:00 +0000179 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
180 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
181 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000182 /* IN: optionally, an access check function for guest code. */
sewardjbef170b2004-12-21 01:23:00 +0000183 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000184 /* IN: debug: trace vex activity at various points */
sewardjbef170b2004-12-21 01:23:00 +0000185 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000186)
187{
sewardj81bd5502004-07-21 18:49:27 +0000188 /* This the bundle of functions we need to do the back-end stuff
189 (insn selection, reg-alloc, assembly) whilst being insulated
190 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000191 HReg* available_real_regs;
192 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000193 Bool (*isMove) (HInstr*, HReg*, HReg*);
194 void (*getRegUsage) (HRegUsage*, HInstr*);
195 void (*mapRegs) (HRegRemap*, HInstr*);
196 HInstr* (*genSpill) ( HReg, Int );
197 HInstr* (*genReload) ( HReg, Int );
198 void (*ppInstr) ( HInstr* );
199 void (*ppReg) ( HReg );
sewardj9df271d2004-12-31 22:37:42 +0000200 HInstrArray* (*iselBB) ( IRBB*, VexSubArch );
sewardj72c72812005-01-19 11:49:45 +0000201 IRBB* (*bbToIR) ( UChar*, Addr64,
202 VexGuestExtents*,
sewardj5bd4d162004-11-10 13:02:48 +0000203 Bool(*)(Addr64),
sewardj72c72812005-01-19 11:49:45 +0000204 Bool(*)(Addr64),
205 Bool, VexSubArch );
sewardj81bd5502004-07-21 18:49:27 +0000206 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000207 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000208 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000209
sewardjeeac8412004-11-02 00:26:55 +0000210 VexGuestLayout* guest_layout;
211 Bool host_is_bigendian = False;
212 IRBB* irbb;
213 HInstrArray* vcode;
214 HInstrArray* rcode;
215 Int i, j, k, out_used, guest_sizeB;
216 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000217 IRType guest_word_type;
218 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000219
sewardj49651f42004-10-28 22:11:04 +0000220 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000221 available_real_regs = NULL;
222 n_available_real_regs = 0;
223 isMove = NULL;
224 getRegUsage = NULL;
225 mapRegs = NULL;
226 genSpill = NULL;
227 genReload = NULL;
228 ppInstr = NULL;
229 ppReg = NULL;
230 iselBB = NULL;
231 bbToIR = NULL;
232 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000233 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000234 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000235 guest_word_type = Ity_INVALID;
236 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000237
sewardjf48ac192004-10-29 00:41:29 +0000238 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000239
sewardj35421a32004-07-05 13:12:34 +0000240 vassert(vex_initdone);
sewardjd887b862005-01-17 18:34:34 +0000241 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000242
sewardj2a9ad022004-11-25 02:46:58 +0000243
sewardjf13a16a2004-07-05 17:10:14 +0000244 /* First off, check that the guest and host insn sets
245 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000246
sewardjbef170b2004-12-21 01:23:00 +0000247 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000248
sewardjbef170b2004-12-21 01:23:00 +0000249 case VexArchX86:
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;
253 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
254 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
255 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
256 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000257 ppInstr = (void(*)(HInstr*)) ppX86Instr;
258 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000259 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000260 emit = (Int(*)(UChar*,Int,HInstr*)) 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;
sewardj9df271d2004-12-31 22:37:42 +0000263 vassert(subarch_host == VexSubArchX86_sse0
264 || subarch_host == VexSubArchX86_sse1
265 || subarch_host == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000266 break;
sewardj2a9ad022004-11-25 02:46:58 +0000267
sewardjf13a16a2004-07-05 17:10:14 +0000268 default:
sewardj887a11a2004-07-05 17:26:47 +0000269 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000270 }
271
sewardj2a9ad022004-11-25 02:46:58 +0000272
sewardjbef170b2004-12-21 01:23:00 +0000273 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000274
sewardjbef170b2004-12-21 01:23:00 +0000275 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000276 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000277 bbToIR = bbToIR_X86;
278 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000279 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000280 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000281 guest_layout = &x86guest_layout;
sewardj9df271d2004-12-31 22:37:42 +0000282 vassert(subarch_guest == VexSubArchX86_sse0
283 || subarch_guest == VexSubArchX86_sse1
284 || subarch_guest == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000285 break;
sewardj2a9ad022004-11-25 02:46:58 +0000286
sewardj44d494d2005-01-20 20:26:33 +0000287 case VexArchAMD64:
288 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
289 bbToIR = bbToIR_AMD64;
290 specHelper = guest_amd64_spechelper;
291 guest_sizeB = sizeof(VexGuestAMD64State);
292 guest_word_type = Ity_I64;
293 guest_layout = &amd64guest_layout;
294 vassert(subarch_guest == VexSubArch_NONE);
295 break;
296
sewardjbef170b2004-12-21 01:23:00 +0000297 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000298 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000299 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000300 specHelper = guest_arm_spechelper;
301 guest_sizeB = sizeof(VexGuestARMState);
302 guest_word_type = Ity_I32;
303 guest_layout = &armGuest_layout;
sewardj44d494d2005-01-20 20:26:33 +0000304 vassert(subarch_guest == VexSubArchARM_v4);
sewardj2a9ad022004-11-25 02:46:58 +0000305 break;
306
cerionaabdfbf2005-01-29 12:56:15 +0000307 case VexArchPPC32:
308 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
309 bbToIR = bbToIR_PPC32;
310 specHelper = guest_ppc32_spechelper;
311 guest_sizeB = sizeof(VexGuestPPC32State);
312 guest_word_type = Ity_I32;
313 guest_layout = &ppc32Guest_layout;
314 vassert(subarch_guest == VexSubArchPPC32);
315 break;
316
sewardjf13a16a2004-07-05 17:10:14 +0000317 default:
sewardj887a11a2004-07-05 17:26:47 +0000318 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000319 }
320
sewardj9df271d2004-12-31 22:37:42 +0000321 /* yet more sanity checks ... */
322 if (arch_guest == VexArchX86 && arch_host == VexArchX86) {
323 /* doesn't necessarily have to be true, but if it isn't it means
324 we are simulating one flavour of x86 on a different one, which
325 is pretty strange. */
326 vassert(subarch_guest == subarch_host);
327 }
sewardj2a9ad022004-11-25 02:46:58 +0000328
sewardjf48ac192004-10-29 00:41:29 +0000329 if (vex_traceflags & VEX_TRACE_FE)
330 vex_printf("\n------------------------"
331 " Front end "
332 "------------------------\n\n");
333
sewardjf13a16a2004-07-05 17:10:14 +0000334 irbb = bbToIR ( guest_bytes,
sewardj72c72812005-01-19 11:49:45 +0000335 guest_bytes_addr,
336 guest_extents,
337 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000338 chase_into_ok,
sewardj72c72812005-01-19 11:49:45 +0000339 host_is_bigendian,
sewardj9df271d2004-12-31 22:37:42 +0000340 subarch_guest );
sewardjf13a16a2004-07-05 17:10:14 +0000341
342 if (irbb == NULL) {
343 /* Access failure. */
sewardjd887b862005-01-17 18:34:34 +0000344 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000345 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000346 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000347 }
sewardjaa59f942004-10-09 09:34:36 +0000348
sewardj72c72812005-01-19 11:49:45 +0000349 vassert(guest_extents->n_used >= 1 && guest_extents->n_used <= 3);
350 vassert(guest_extents->base[0] == guest_bytes_addr);
351 for (i = 0; i < guest_extents->n_used; i++) {
352 vassert(guest_extents->len[i] < 10000); /* sanity */
353 }
354
sewardjaa59f942004-10-09 09:34:36 +0000355 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000356 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj72c72812005-01-19 11:49:45 +0000357 if (guest_extents->n_used > 1) {
358 vex_printf("can't show code due to extents > 1\n");
359 } else {
360 /* HACK */
361 UChar* p = (UChar*)guest_bytes;
362 UInt guest_bytes_read = (UInt)guest_extents->len[0];
363 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, guest_bytes_read );
364 for (i = 0; i < guest_bytes_read; i++)
sewardjaa59f942004-10-09 09:34:36 +0000365 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000366 vex_printf("\n\n");
367 }
sewardjaa59f942004-10-09 09:34:36 +0000368 }
369
370 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000371 sanityCheckIRBB( irbb, "initial IR",
372 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000373
sewardjedf4d692004-08-17 13:52:58 +0000374 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000375 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
376 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000377 sanityCheckIRBB( irbb, "after initial iropt",
378 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000379
sewardjf48ac192004-10-29 00:41:29 +0000380 if (vex_traceflags & VEX_TRACE_OPT1) {
381 vex_printf("\n------------------------"
382 " After pre-instr IR optimisation "
383 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000384 ppIRBB ( irbb );
385 vex_printf("\n");
386 }
387
sewardjf13a16a2004-07-05 17:10:14 +0000388 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000389 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000390 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000391 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000392 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000393
sewardjf48ac192004-10-29 00:41:29 +0000394 if (vex_traceflags & VEX_TRACE_INST) {
395 vex_printf("\n------------------------"
396 " After instrumentation "
397 "------------------------\n\n");
398 ppIRBB ( irbb );
399 vex_printf("\n");
400 }
401
sewardj49651f42004-10-28 22:11:04 +0000402 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000403 sanityCheckIRBB( irbb, "after instrumentation",
404 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000405
sewardj9578a8b2004-11-04 19:44:48 +0000406 /* Do a post-instrumentation cleanup pass. */
407 if (cleanup_after_instrumentation) {
408 do_deadcode_BB( irbb );
409 irbb = cprop_BB( irbb );
410 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000411 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
412 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000413 }
414
415 if (vex_traceflags & VEX_TRACE_OPT2) {
416 vex_printf("\n------------------------"
417 " After post-instr IR optimisation "
418 "------------------------\n\n");
419 ppIRBB ( irbb );
420 vex_printf("\n");
421 }
422
sewardjf13a16a2004-07-05 17:10:14 +0000423 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000424 do_deadcode_BB( irbb );
425 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000426
427 if (vex_traceflags & VEX_TRACE_TREES) {
428 vex_printf("\n------------------------"
429 " After tree-building "
430 "------------------------\n\n");
431 ppIRBB ( irbb );
432 vex_printf("\n");
433 }
434
435 if (vex_traceflags & VEX_TRACE_VCODE)
436 vex_printf("\n------------------------"
437 " Instruction selection "
438 "------------------------\n");
439
sewardj9df271d2004-12-31 22:37:42 +0000440 vcode = iselBB ( irbb, subarch_host );
sewardjf13a16a2004-07-05 17:10:14 +0000441
sewardjf48ac192004-10-29 00:41:29 +0000442 if (vex_traceflags & VEX_TRACE_VCODE)
443 vex_printf("\n");
444
sewardjf48ac192004-10-29 00:41:29 +0000445 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000446 for (i = 0; i < vcode->arr_used; i++) {
447 vex_printf("%3d ", i);
448 ppInstr(vcode->arr[i]);
449 vex_printf("\n");
450 }
sewardjfbcaf332004-07-08 01:46:01 +0000451 vex_printf("\n");
452 }
sewardjfbcaf332004-07-08 01:46:01 +0000453
sewardjf13a16a2004-07-05 17:10:14 +0000454 /* Register allocate. */
455 rcode = doRegisterAllocation ( vcode, available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000456 n_available_real_regs,
457 isMove, getRegUsage, mapRegs,
458 genSpill, genReload, guest_sizeB,
459 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000460
sewardjf48ac192004-10-29 00:41:29 +0000461 if (vex_traceflags & VEX_TRACE_RCODE) {
462 vex_printf("\n------------------------"
463 " Register-allocated code "
464 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000465 for (i = 0; i < rcode->arr_used; i++) {
466 vex_printf("%3d ", i);
467 ppInstr(rcode->arr[i]);
468 vex_printf("\n");
469 }
sewardjfbcaf332004-07-08 01:46:01 +0000470 vex_printf("\n");
471 }
sewardjfbcaf332004-07-08 01:46:01 +0000472
sewardj81bd5502004-07-21 18:49:27 +0000473 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000474 if (vex_traceflags & VEX_TRACE_ASM) {
475 vex_printf("\n------------------------"
476 " Assembly "
477 "------------------------\n\n");
478 }
479
sewardj81bd5502004-07-21 18:49:27 +0000480 out_used = 0; /* tracks along the host_bytes array */
481 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000482 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000483 ppInstr(rcode->arr[i]);
484 vex_printf("\n");
485 }
sewardj81bd5502004-07-21 18:49:27 +0000486 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000487 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000488 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000489 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000490 vex_printf("0%x ", (UInt)insn_bytes[k]);
491 else
492 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000493 vex_printf("\n\n");
494 }
sewardj81bd5502004-07-21 18:49:27 +0000495 if (out_used + j > host_bytes_size) {
sewardjd887b862005-01-17 18:34:34 +0000496 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000497 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000498 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000499 }
500 for (k = 0; k < j; k++) {
501 host_bytes[out_used] = insn_bytes[k];
502 out_used++;
503 }
504 vassert(out_used <= host_bytes_size);
505 }
506 *host_bytes_used = out_used;
507
sewardjd887b862005-01-17 18:34:34 +0000508 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000509
sewardjf48ac192004-10-29 00:41:29 +0000510 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000511 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000512}
513
514
sewardj893aada2004-11-29 19:57:54 +0000515/* --------- Emulation warnings. --------- */
516
517HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
518{
519 switch (ew) {
520 case EmWarn_NONE:
521 return "none";
522 case EmWarn_X86_x87exns:
523 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000524 case EmWarn_X86_x87precision:
525 return "Selection of non-80-bit x87 FP precision";
526 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000527 return "Unmasking SSE FP exceptions";
528 case EmWarn_X86_fz:
529 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
530 case EmWarn_X86_daz:
531 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000532 default:
533 vpanic("LibVEX_EmWarn_string: unknown warning");
534 }
535}
sewardj35421a32004-07-05 13:12:34 +0000536
sewardjbef170b2004-12-21 01:23:00 +0000537/* --------- Arch/Subarch names. --------- */
538
539const HChar* LibVEX_ppVexArch ( VexArch arch )
540{
541 switch (arch) {
542 case VexArch_INVALID: return "INVALID";
543 case VexArchX86: return "X86";
544 case VexArchAMD64: return "AMD64";
545 case VexArchARM: return "ARM";
546 default: return "VexArch???";
547 }
548}
549
550const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
551{
552 switch (subarch) {
553 case VexSubArch_INVALID: return "INVALID";
554 case VexSubArch_NONE: return "NONE";
555 case VexSubArchX86_sse0: return "x86-sse0";
556 case VexSubArchX86_sse1: return "x86-sse1";
557 case VexSubArchX86_sse2: return "x86-sse2";
558 case VexSubArchARM_v4: return "arm-v4";
559 default: return "VexSubArch???";
560 }
561}
562
sewardj35421a32004-07-05 13:12:34 +0000563/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000564/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000565/*---------------------------------------------------------------*/