blob: c8feac46d33784d8f338bfdec56d7dfb17bdeb39 [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"
sewardj2a9ad022004-11-25 02:46:58 +000039#include "libvex_guest_arm.h"
sewardjf13a16a2004-07-05 17:10:14 +000040
sewardjc0ee2ed2004-07-27 10:29:41 +000041#include "main/vex_globals.h"
42#include "main/vex_util.h"
43#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000044#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000045
sewardj2a9ad022004-11-25 02:46:58 +000046#include "host-x86/hdefs.h"
47
48#include "guest-x86/gdefs.h"
49#include "guest-arm/gdefs.h"
50
sewardj35421a32004-07-05 13:12:34 +000051
52/* This file contains the top level interface to the library. */
53
54/* --------- Initialise the library. --------- */
55
56/* Exported to library client. */
57
sewardjd887b862005-01-17 18:34:34 +000058const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000059{
60return
61#include "main/vex_svnversion.h"
62 ;
63}
64
65
66/* Exported to library client. */
67
sewardj08613742004-10-25 13:01:45 +000068void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
69{
70 vcon->iropt_verbosity = 0;
71 vcon->iropt_level = 2;
72 vcon->iropt_precise_memory_exns = False;
73 vcon->iropt_unroll_thresh = 120;
74 vcon->guest_max_insns = 50;
75 vcon->guest_chase_thresh = 10;
76}
77
78
79/* Exported to library client. */
80
sewardj887a11a2004-07-05 17:26:47 +000081void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000082 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000083 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000084 void (*failure_exit) ( void ),
85 /* logging output function */
86 void (*log_bytes) ( Char*, Int nbytes ),
87 /* debug paranoia level */
88 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +000089 /* Are we supporting valgrind checking? */
90 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +000091 /* Control ... */
92 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +000093)
94{
sewardj08613742004-10-25 13:01:45 +000095 /* First off, do enough minimal setup so that the following
96 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +000097 vex_failure_exit = failure_exit;
98 vex_log_bytes = log_bytes;
99
100 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000101 vassert(!vex_initdone);
102 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000103 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000104 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000105
106 vassert(vcon->iropt_verbosity >= 0);
107 vassert(vcon->iropt_level >= 0);
108 vassert(vcon->iropt_level <= 2);
109 vassert(vcon->iropt_unroll_thresh >= 0);
110 vassert(vcon->iropt_unroll_thresh <= 400);
111 vassert(vcon->guest_max_insns >= 1);
112 vassert(vcon->guest_max_insns <= 100);
113 vassert(vcon->guest_chase_thresh >= 0);
114 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000115
sewardj81ec4182004-10-25 23:15:52 +0000116 /* All the guest state structs must have an 8-aligned size. */
117 vassert(0 == sizeof(VexGuestX86State) % 8);
118
sewardjea602bc2004-10-14 21:40:12 +0000119 /* Check that Vex has been built with sizes of basic types as
120 stated in priv/libvex_basictypes.h. Failure of any of these is
121 a serious configuration error and should be corrected
122 immediately. If any of these assertions fail you can fully
123 expect Vex not to work properly, if at all. */
124
125 vassert(1 == sizeof(UChar));
126 vassert(1 == sizeof(Char));
127 vassert(2 == sizeof(UShort));
128 vassert(2 == sizeof(Short));
129 vassert(4 == sizeof(UInt));
130 vassert(4 == sizeof(Int));
131 vassert(8 == sizeof(ULong));
132 vassert(8 == sizeof(Long));
133 vassert(4 == sizeof(Float));
134 vassert(8 == sizeof(Double));
135 vassert(1 == sizeof(Bool));
136 vassert(4 == sizeof(Addr32));
137 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000138 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000139
140 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
141 vassert(sizeof(void*) == sizeof(int*));
142 vassert(sizeof(void*) == sizeof(HWord));
143
144 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000145 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000146 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000147 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000148 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000149 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000150}
151
152
153/* --------- Make a translation. --------- */
154
155/* Exported to library client. */
156
sewardjd887b862005-01-17 18:34:34 +0000157VexTranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000158 /* The instruction sets we are translating from and to. */
sewardjbef170b2004-12-21 01:23:00 +0000159 VexArch arch_guest,
160 VexSubArch subarch_guest,
161 VexArch arch_host,
162 VexSubArch subarch_host,
sewardj35421a32004-07-05 13:12:34 +0000163 /* IN: the block to translate, and its guest address. */
sewardjbef170b2004-12-21 01:23:00 +0000164 UChar* guest_bytes,
165 Addr64 guest_bytes_addr,
166 Bool (*chase_into_ok) ( Addr64 ),
sewardj72c72812005-01-19 11:49:45 +0000167 /* OUT: which bits of guest code actually got translated */
168 VexGuestExtents* guest_extents,
sewardj35421a32004-07-05 13:12:34 +0000169 /* IN: a place to put the resulting code, and its size */
sewardjbef170b2004-12-21 01:23:00 +0000170 UChar* host_bytes,
171 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000172 /* OUT: how much of the output area is used. */
sewardjbef170b2004-12-21 01:23:00 +0000173 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000174 /* IN: optionally, two instrumentation functions. */
sewardjbef170b2004-12-21 01:23:00 +0000175 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
176 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
177 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000178 /* IN: optionally, an access check function for guest code. */
sewardjbef170b2004-12-21 01:23:00 +0000179 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000180 /* IN: debug: trace vex activity at various points */
sewardjbef170b2004-12-21 01:23:00 +0000181 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000182)
183{
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;
sewardj443cd9d2004-07-18 23:06:45 +0000189 Bool (*isMove) (HInstr*, HReg*, HReg*);
190 void (*getRegUsage) (HRegUsage*, HInstr*);
191 void (*mapRegs) (HRegRemap*, HInstr*);
192 HInstr* (*genSpill) ( HReg, Int );
193 HInstr* (*genReload) ( HReg, Int );
194 void (*ppInstr) ( HInstr* );
195 void (*ppReg) ( HReg );
sewardj9df271d2004-12-31 22:37:42 +0000196 HInstrArray* (*iselBB) ( IRBB*, VexSubArch );
sewardj72c72812005-01-19 11:49:45 +0000197 IRBB* (*bbToIR) ( UChar*, Addr64,
198 VexGuestExtents*,
sewardj5bd4d162004-11-10 13:02:48 +0000199 Bool(*)(Addr64),
sewardj72c72812005-01-19 11:49:45 +0000200 Bool(*)(Addr64),
201 Bool, VexSubArch );
sewardj81bd5502004-07-21 18:49:27 +0000202 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000203 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000204 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000205
sewardjeeac8412004-11-02 00:26:55 +0000206 VexGuestLayout* guest_layout;
207 Bool host_is_bigendian = False;
208 IRBB* irbb;
209 HInstrArray* vcode;
210 HInstrArray* rcode;
211 Int i, j, k, out_used, guest_sizeB;
212 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000213 IRType guest_word_type;
214 IRType host_word_type;
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;
227 bbToIR = NULL;
228 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000229 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000230 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000231 guest_word_type = Ity_INVALID;
232 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000233
sewardjf48ac192004-10-29 00:41:29 +0000234 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000235
sewardj35421a32004-07-05 13:12:34 +0000236 vassert(vex_initdone);
sewardjd887b862005-01-17 18:34:34 +0000237 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000238
sewardj2a9ad022004-11-25 02:46:58 +0000239
sewardjf13a16a2004-07-05 17:10:14 +0000240 /* First off, check that the guest and host insn sets
241 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000242
sewardjbef170b2004-12-21 01:23:00 +0000243 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000244
sewardjbef170b2004-12-21 01:23:00 +0000245 case VexArchX86:
sewardjf13a16a2004-07-05 17:10:14 +0000246 getAllocableRegs_X86 ( &n_available_real_regs,
247 &available_real_regs );
248 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
249 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
250 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
251 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
252 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000253 ppInstr = (void(*)(HInstr*)) ppX86Instr;
254 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000255 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000256 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000257 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000258 host_word_type = Ity_I32;
sewardj9df271d2004-12-31 22:37:42 +0000259 vassert(subarch_host == VexSubArchX86_sse0
260 || subarch_host == VexSubArchX86_sse1
261 || subarch_host == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000262 break;
sewardj2a9ad022004-11-25 02:46:58 +0000263
sewardjf13a16a2004-07-05 17:10:14 +0000264 default:
sewardj887a11a2004-07-05 17:26:47 +0000265 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000266 }
267
sewardj2a9ad022004-11-25 02:46:58 +0000268
sewardjbef170b2004-12-21 01:23:00 +0000269 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000270
sewardjbef170b2004-12-21 01:23:00 +0000271 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000272 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000273 bbToIR = bbToIR_X86;
274 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000275 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000276 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000277 guest_layout = &x86guest_layout;
sewardj9df271d2004-12-31 22:37:42 +0000278 vassert(subarch_guest == VexSubArchX86_sse0
279 || subarch_guest == VexSubArchX86_sse1
280 || subarch_guest == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000281 break;
sewardj2a9ad022004-11-25 02:46:58 +0000282
sewardjbef170b2004-12-21 01:23:00 +0000283 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000284 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000285 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000286 specHelper = guest_arm_spechelper;
287 guest_sizeB = sizeof(VexGuestARMState);
288 guest_word_type = Ity_I32;
289 guest_layout = &armGuest_layout;
290 break;
291
sewardjf13a16a2004-07-05 17:10:14 +0000292 default:
sewardj887a11a2004-07-05 17:26:47 +0000293 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000294 }
295
sewardj9df271d2004-12-31 22:37:42 +0000296 /* yet more sanity checks ... */
297 if (arch_guest == VexArchX86 && arch_host == VexArchX86) {
298 /* doesn't necessarily have to be true, but if it isn't it means
299 we are simulating one flavour of x86 on a different one, which
300 is pretty strange. */
301 vassert(subarch_guest == subarch_host);
302 }
sewardj2a9ad022004-11-25 02:46:58 +0000303
sewardjf48ac192004-10-29 00:41:29 +0000304 if (vex_traceflags & VEX_TRACE_FE)
305 vex_printf("\n------------------------"
306 " Front end "
307 "------------------------\n\n");
308
sewardjf13a16a2004-07-05 17:10:14 +0000309 irbb = bbToIR ( guest_bytes,
sewardj72c72812005-01-19 11:49:45 +0000310 guest_bytes_addr,
311 guest_extents,
312 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000313 chase_into_ok,
sewardj72c72812005-01-19 11:49:45 +0000314 host_is_bigendian,
sewardj9df271d2004-12-31 22:37:42 +0000315 subarch_guest );
sewardjf13a16a2004-07-05 17:10:14 +0000316
317 if (irbb == NULL) {
318 /* Access failure. */
sewardjd887b862005-01-17 18:34:34 +0000319 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000320 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000321 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000322 }
sewardjaa59f942004-10-09 09:34:36 +0000323
sewardj72c72812005-01-19 11:49:45 +0000324 vassert(guest_extents->n_used >= 1 && guest_extents->n_used <= 3);
325 vassert(guest_extents->base[0] == guest_bytes_addr);
326 for (i = 0; i < guest_extents->n_used; i++) {
327 vassert(guest_extents->len[i] < 10000); /* sanity */
328 }
329
sewardjaa59f942004-10-09 09:34:36 +0000330 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000331 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj72c72812005-01-19 11:49:45 +0000332 if (guest_extents->n_used > 1) {
333 vex_printf("can't show code due to extents > 1\n");
334 } else {
335 /* HACK */
336 UChar* p = (UChar*)guest_bytes;
337 UInt guest_bytes_read = (UInt)guest_extents->len[0];
338 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, guest_bytes_read );
339 for (i = 0; i < guest_bytes_read; i++)
sewardjaa59f942004-10-09 09:34:36 +0000340 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000341 vex_printf("\n\n");
342 }
sewardjaa59f942004-10-09 09:34:36 +0000343 }
344
345 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000346 sanityCheckIRBB( irbb, "initial IR",
347 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000348
sewardjedf4d692004-08-17 13:52:58 +0000349 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000350 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
351 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000352 sanityCheckIRBB( irbb, "after initial iropt",
353 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000354
sewardjf48ac192004-10-29 00:41:29 +0000355 if (vex_traceflags & VEX_TRACE_OPT1) {
356 vex_printf("\n------------------------"
357 " After pre-instr IR optimisation "
358 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000359 ppIRBB ( irbb );
360 vex_printf("\n");
361 }
362
sewardjf13a16a2004-07-05 17:10:14 +0000363 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000364 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000365 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000366 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000367 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000368
sewardjf48ac192004-10-29 00:41:29 +0000369 if (vex_traceflags & VEX_TRACE_INST) {
370 vex_printf("\n------------------------"
371 " After instrumentation "
372 "------------------------\n\n");
373 ppIRBB ( irbb );
374 vex_printf("\n");
375 }
376
sewardj49651f42004-10-28 22:11:04 +0000377 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000378 sanityCheckIRBB( irbb, "after instrumentation",
379 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000380
sewardj9578a8b2004-11-04 19:44:48 +0000381 /* Do a post-instrumentation cleanup pass. */
382 if (cleanup_after_instrumentation) {
383 do_deadcode_BB( irbb );
384 irbb = cprop_BB( irbb );
385 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000386 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
387 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000388 }
389
390 if (vex_traceflags & VEX_TRACE_OPT2) {
391 vex_printf("\n------------------------"
392 " After post-instr IR optimisation "
393 "------------------------\n\n");
394 ppIRBB ( irbb );
395 vex_printf("\n");
396 }
397
sewardjf13a16a2004-07-05 17:10:14 +0000398 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000399 do_deadcode_BB( irbb );
400 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000401
402 if (vex_traceflags & VEX_TRACE_TREES) {
403 vex_printf("\n------------------------"
404 " After tree-building "
405 "------------------------\n\n");
406 ppIRBB ( irbb );
407 vex_printf("\n");
408 }
409
410 if (vex_traceflags & VEX_TRACE_VCODE)
411 vex_printf("\n------------------------"
412 " Instruction selection "
413 "------------------------\n");
414
sewardj9df271d2004-12-31 22:37:42 +0000415 vcode = iselBB ( irbb, subarch_host );
sewardjf13a16a2004-07-05 17:10:14 +0000416
sewardjf48ac192004-10-29 00:41:29 +0000417 if (vex_traceflags & VEX_TRACE_VCODE)
418 vex_printf("\n");
419
sewardjf48ac192004-10-29 00:41:29 +0000420 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000421 for (i = 0; i < vcode->arr_used; i++) {
422 vex_printf("%3d ", i);
423 ppInstr(vcode->arr[i]);
424 vex_printf("\n");
425 }
sewardjfbcaf332004-07-08 01:46:01 +0000426 vex_printf("\n");
427 }
sewardjfbcaf332004-07-08 01:46:01 +0000428
sewardjf13a16a2004-07-05 17:10:14 +0000429 /* Register allocate. */
430 rcode = doRegisterAllocation ( vcode, available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000431 n_available_real_regs,
432 isMove, getRegUsage, mapRegs,
433 genSpill, genReload, guest_sizeB,
434 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000435
sewardjf48ac192004-10-29 00:41:29 +0000436 if (vex_traceflags & VEX_TRACE_RCODE) {
437 vex_printf("\n------------------------"
438 " Register-allocated code "
439 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000440 for (i = 0; i < rcode->arr_used; i++) {
441 vex_printf("%3d ", i);
442 ppInstr(rcode->arr[i]);
443 vex_printf("\n");
444 }
sewardjfbcaf332004-07-08 01:46:01 +0000445 vex_printf("\n");
446 }
sewardjfbcaf332004-07-08 01:46:01 +0000447
sewardj81bd5502004-07-21 18:49:27 +0000448 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000449 if (vex_traceflags & VEX_TRACE_ASM) {
450 vex_printf("\n------------------------"
451 " Assembly "
452 "------------------------\n\n");
453 }
454
sewardj81bd5502004-07-21 18:49:27 +0000455 out_used = 0; /* tracks along the host_bytes array */
456 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000457 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000458 ppInstr(rcode->arr[i]);
459 vex_printf("\n");
460 }
sewardj81bd5502004-07-21 18:49:27 +0000461 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000462 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000463 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000464 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000465 vex_printf("0%x ", (UInt)insn_bytes[k]);
466 else
467 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000468 vex_printf("\n\n");
469 }
sewardj81bd5502004-07-21 18:49:27 +0000470 if (out_used + j > host_bytes_size) {
sewardjd887b862005-01-17 18:34:34 +0000471 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000472 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000473 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000474 }
475 for (k = 0; k < j; k++) {
476 host_bytes[out_used] = insn_bytes[k];
477 out_used++;
478 }
479 vassert(out_used <= host_bytes_size);
480 }
481 *host_bytes_used = out_used;
482
sewardjd887b862005-01-17 18:34:34 +0000483 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000484
sewardjf48ac192004-10-29 00:41:29 +0000485 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000486 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000487}
488
489
sewardj893aada2004-11-29 19:57:54 +0000490/* --------- Emulation warnings. --------- */
491
492HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
493{
494 switch (ew) {
495 case EmWarn_NONE:
496 return "none";
497 case EmWarn_X86_x87exns:
498 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000499 case EmWarn_X86_x87precision:
500 return "Selection of non-80-bit x87 FP precision";
501 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000502 return "Unmasking SSE FP exceptions";
503 case EmWarn_X86_fz:
504 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
505 case EmWarn_X86_daz:
506 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000507 default:
508 vpanic("LibVEX_EmWarn_string: unknown warning");
509 }
510}
sewardj35421a32004-07-05 13:12:34 +0000511
sewardjbef170b2004-12-21 01:23:00 +0000512/* --------- Arch/Subarch names. --------- */
513
514const HChar* LibVEX_ppVexArch ( VexArch arch )
515{
516 switch (arch) {
517 case VexArch_INVALID: return "INVALID";
518 case VexArchX86: return "X86";
519 case VexArchAMD64: return "AMD64";
520 case VexArchARM: return "ARM";
521 default: return "VexArch???";
522 }
523}
524
525const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
526{
527 switch (subarch) {
528 case VexSubArch_INVALID: return "INVALID";
529 case VexSubArch_NONE: return "NONE";
530 case VexSubArchX86_sse0: return "x86-sse0";
531 case VexSubArchX86_sse1: return "x86-sse1";
532 case VexSubArchX86_sse2: return "x86-sse2";
533 case VexSubArchARM_v4: return "arm-v4";
534 default: return "VexSubArch???";
535 }
536}
537
sewardj35421a32004-07-05 13:12:34 +0000538/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000539/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000540/*---------------------------------------------------------------*/