blob: cbc4084e1450f38172a62e6ad88ba5b199b941e8 [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
sewardj80f5fce2004-12-20 04:37:50 +000058HChar* LibVEX_Version ( void )
59{
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;
149 LibVEX_SetAllocMode ( AllocModeTEMPORARY );
sewardj35421a32004-07-05 13:12:34 +0000150}
151
152
153/* --------- Make a translation. --------- */
154
155/* Exported to library client. */
156
sewardj887a11a2004-07-05 17:26:47 +0000157TranslateResult 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 ),
sewardj35421a32004-07-05 13:12:34 +0000167 /* OUT: the number of bytes actually read */
sewardjbef170b2004-12-21 01:23:00 +0000168 Int* guest_bytes_read,
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 );
sewardj8ea867b2004-10-30 19:03:02 +0000196 HInstrArray* (*iselBB) ( IRBB* );
sewardj443cd9d2004-07-18 23:06:45 +0000197 IRBB* (*bbToIR) ( UChar*, Addr64, Int*,
sewardj5bd4d162004-11-10 13:02:48 +0000198 Bool(*)(Addr64),
199 Bool(*)(Addr64), Bool );
sewardj81bd5502004-07-21 18:49:27 +0000200 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000201 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000202 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000203
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;
210 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000211 IRType guest_word_type;
212 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000213
sewardj49651f42004-10-28 22:11:04 +0000214 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000215 available_real_regs = NULL;
216 n_available_real_regs = 0;
217 isMove = NULL;
218 getRegUsage = NULL;
219 mapRegs = NULL;
220 genSpill = NULL;
221 genReload = NULL;
222 ppInstr = NULL;
223 ppReg = NULL;
224 iselBB = NULL;
225 bbToIR = NULL;
226 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000227 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000228 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000229 guest_word_type = Ity_INVALID;
230 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000231
sewardjf48ac192004-10-29 00:41:29 +0000232 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000233
sewardj35421a32004-07-05 13:12:34 +0000234 vassert(vex_initdone);
sewardj443cd9d2004-07-18 23:06:45 +0000235 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000236
sewardj2a9ad022004-11-25 02:46:58 +0000237
sewardjf13a16a2004-07-05 17:10:14 +0000238 /* First off, check that the guest and host insn sets
239 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000240
sewardjbef170b2004-12-21 01:23:00 +0000241 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000242
sewardjbef170b2004-12-21 01:23:00 +0000243 case VexArchX86:
sewardjf13a16a2004-07-05 17:10:14 +0000244 getAllocableRegs_X86 ( &n_available_real_regs,
245 &available_real_regs );
246 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
247 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
248 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
249 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
250 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000251 ppInstr = (void(*)(HInstr*)) ppX86Instr;
252 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000253 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000254 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardjc9a65702004-07-07 16:32:57 +0000255 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000256 host_word_type = Ity_I32;
sewardjf13a16a2004-07-05 17:10:14 +0000257 break;
sewardj2a9ad022004-11-25 02:46:58 +0000258
sewardjf13a16a2004-07-05 17:10:14 +0000259 default:
sewardj887a11a2004-07-05 17:26:47 +0000260 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000261 }
262
sewardj2a9ad022004-11-25 02:46:58 +0000263
sewardjbef170b2004-12-21 01:23:00 +0000264 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000265
sewardjbef170b2004-12-21 01:23:00 +0000266 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000267 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000268 bbToIR = bbToIR_X86;
269 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000270 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000271 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000272 guest_layout = &x86guest_layout;
sewardjf13a16a2004-07-05 17:10:14 +0000273 break;
sewardj2a9ad022004-11-25 02:46:58 +0000274
sewardjbef170b2004-12-21 01:23:00 +0000275 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000276 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000277 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000278 specHelper = guest_arm_spechelper;
279 guest_sizeB = sizeof(VexGuestARMState);
280 guest_word_type = Ity_I32;
281 guest_layout = &armGuest_layout;
282 break;
283
sewardjf13a16a2004-07-05 17:10:14 +0000284 default:
sewardj887a11a2004-07-05 17:26:47 +0000285 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000286 }
287
sewardj2a9ad022004-11-25 02:46:58 +0000288
sewardjf48ac192004-10-29 00:41:29 +0000289 if (vex_traceflags & VEX_TRACE_FE)
290 vex_printf("\n------------------------"
291 " Front end "
292 "------------------------\n\n");
293
sewardjf13a16a2004-07-05 17:10:14 +0000294 irbb = bbToIR ( guest_bytes,
295 guest_bytes_addr,
296 guest_bytes_read,
sewardjc9a65702004-07-07 16:32:57 +0000297 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000298 chase_into_ok,
sewardjc9a65702004-07-07 16:32:57 +0000299 host_is_bigendian );
sewardjf13a16a2004-07-05 17:10:14 +0000300
301 if (irbb == NULL) {
302 /* Access failure. */
sewardj443cd9d2004-07-18 23:06:45 +0000303 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000304 vex_traceflags = 0;
sewardjf13a16a2004-07-05 17:10:14 +0000305 return TransAccessFail;
306 }
sewardjaa59f942004-10-09 09:34:36 +0000307
308 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000309 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardjaa59f942004-10-09 09:34:36 +0000310 UChar* p = guest_bytes;
sewardjaa59f942004-10-09 09:34:36 +0000311 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, *guest_bytes_read );
312 for (i = 0; i < *guest_bytes_read; i++)
313 vex_printf(" %02x", (Int)p[i] );
sewardjf48ac192004-10-29 00:41:29 +0000314 vex_printf("\n\n");
sewardjaa59f942004-10-09 09:34:36 +0000315 }
316
317 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000318 sanityCheckIRBB( irbb, "initial IR",
319 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000320
sewardjedf4d692004-08-17 13:52:58 +0000321 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000322 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
323 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000324 sanityCheckIRBB( irbb, "after initial iropt",
325 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000326
sewardjf48ac192004-10-29 00:41:29 +0000327 if (vex_traceflags & VEX_TRACE_OPT1) {
328 vex_printf("\n------------------------"
329 " After pre-instr IR optimisation "
330 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000331 ppIRBB ( irbb );
332 vex_printf("\n");
333 }
334
sewardjf13a16a2004-07-05 17:10:14 +0000335 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000336 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000337 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000338 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000339 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000340
sewardjf48ac192004-10-29 00:41:29 +0000341 if (vex_traceflags & VEX_TRACE_INST) {
342 vex_printf("\n------------------------"
343 " After instrumentation "
344 "------------------------\n\n");
345 ppIRBB ( irbb );
346 vex_printf("\n");
347 }
348
sewardj49651f42004-10-28 22:11:04 +0000349 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000350 sanityCheckIRBB( irbb, "after instrumentation",
351 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000352
sewardj9578a8b2004-11-04 19:44:48 +0000353 /* Do a post-instrumentation cleanup pass. */
354 if (cleanup_after_instrumentation) {
355 do_deadcode_BB( irbb );
356 irbb = cprop_BB( irbb );
357 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000358 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
359 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000360 }
361
362 if (vex_traceflags & VEX_TRACE_OPT2) {
363 vex_printf("\n------------------------"
364 " After post-instr IR optimisation "
365 "------------------------\n\n");
366 ppIRBB ( irbb );
367 vex_printf("\n");
368 }
369
sewardjf13a16a2004-07-05 17:10:14 +0000370 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000371 do_deadcode_BB( irbb );
372 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000373
374 if (vex_traceflags & VEX_TRACE_TREES) {
375 vex_printf("\n------------------------"
376 " After tree-building "
377 "------------------------\n\n");
378 ppIRBB ( irbb );
379 vex_printf("\n");
380 }
381
382 if (vex_traceflags & VEX_TRACE_VCODE)
383 vex_printf("\n------------------------"
384 " Instruction selection "
385 "------------------------\n");
386
sewardj8ea867b2004-10-30 19:03:02 +0000387 vcode = iselBB ( irbb );
sewardjf13a16a2004-07-05 17:10:14 +0000388
sewardjf48ac192004-10-29 00:41:29 +0000389 if (vex_traceflags & VEX_TRACE_VCODE)
390 vex_printf("\n");
391
sewardjf48ac192004-10-29 00:41:29 +0000392 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000393 for (i = 0; i < vcode->arr_used; i++) {
394 vex_printf("%3d ", i);
395 ppInstr(vcode->arr[i]);
396 vex_printf("\n");
397 }
sewardjfbcaf332004-07-08 01:46:01 +0000398 vex_printf("\n");
399 }
sewardjfbcaf332004-07-08 01:46:01 +0000400
sewardjf13a16a2004-07-05 17:10:14 +0000401 /* Register allocate. */
402 rcode = doRegisterAllocation ( vcode, available_real_regs,
403 n_available_real_regs,
404 isMove, getRegUsage, mapRegs,
sewardj81ec4182004-10-25 23:15:52 +0000405 genSpill, genReload, guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000406 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000407
sewardjf48ac192004-10-29 00:41:29 +0000408 if (vex_traceflags & VEX_TRACE_RCODE) {
409 vex_printf("\n------------------------"
410 " Register-allocated code "
411 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000412 for (i = 0; i < rcode->arr_used; i++) {
413 vex_printf("%3d ", i);
414 ppInstr(rcode->arr[i]);
415 vex_printf("\n");
416 }
sewardjfbcaf332004-07-08 01:46:01 +0000417 vex_printf("\n");
418 }
sewardjfbcaf332004-07-08 01:46:01 +0000419
sewardj81bd5502004-07-21 18:49:27 +0000420 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000421 if (vex_traceflags & VEX_TRACE_ASM) {
422 vex_printf("\n------------------------"
423 " Assembly "
424 "------------------------\n\n");
425 }
426
sewardj81bd5502004-07-21 18:49:27 +0000427 out_used = 0; /* tracks along the host_bytes array */
428 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000429 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000430 ppInstr(rcode->arr[i]);
431 vex_printf("\n");
432 }
sewardj81bd5502004-07-21 18:49:27 +0000433 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000434 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000435 for (k = 0; k < j; k++)
sewardj86898e82004-07-22 17:26:12 +0000436 if (insn_bytes[k] < 16)
437 vex_printf("0%x ", (UInt)insn_bytes[k]);
438 else
439 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000440 vex_printf("\n\n");
441 }
sewardj81bd5502004-07-21 18:49:27 +0000442 if (out_used + j > host_bytes_size) {
443 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000444 vex_traceflags = 0;
sewardj81bd5502004-07-21 18:49:27 +0000445 return TransOutputFull;
446 }
447 for (k = 0; k < j; k++) {
448 host_bytes[out_used] = insn_bytes[k];
449 out_used++;
450 }
451 vassert(out_used <= host_bytes_size);
452 }
453 *host_bytes_used = out_used;
454
sewardj1f40a0a2004-07-21 12:28:07 +0000455 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000456
sewardjf48ac192004-10-29 00:41:29 +0000457 vex_traceflags = 0;
sewardj35421a32004-07-05 13:12:34 +0000458 return TransOK;
459}
460
461
sewardj893aada2004-11-29 19:57:54 +0000462/* --------- Emulation warnings. --------- */
463
464HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
465{
466 switch (ew) {
467 case EmWarn_NONE:
468 return "none";
469 case EmWarn_X86_x87exns:
470 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000471 case EmWarn_X86_x87precision:
472 return "Selection of non-80-bit x87 FP precision";
473 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000474 return "Unmasking SSE FP exceptions";
475 case EmWarn_X86_fz:
476 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
477 case EmWarn_X86_daz:
478 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000479 default:
480 vpanic("LibVEX_EmWarn_string: unknown warning");
481 }
482}
sewardj35421a32004-07-05 13:12:34 +0000483
sewardjbef170b2004-12-21 01:23:00 +0000484/* --------- Arch/Subarch names. --------- */
485
486const HChar* LibVEX_ppVexArch ( VexArch arch )
487{
488 switch (arch) {
489 case VexArch_INVALID: return "INVALID";
490 case VexArchX86: return "X86";
491 case VexArchAMD64: return "AMD64";
492 case VexArchARM: return "ARM";
493 default: return "VexArch???";
494 }
495}
496
497const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
498{
499 switch (subarch) {
500 case VexSubArch_INVALID: return "INVALID";
501 case VexSubArch_NONE: return "NONE";
502 case VexSubArchX86_sse0: return "x86-sse0";
503 case VexSubArchX86_sse1: return "x86-sse1";
504 case VexSubArchX86_sse2: return "x86-sse2";
505 case VexSubArchARM_v4: return "arm-v4";
506 default: return "VexSubArch???";
507 }
508}
509
sewardj35421a32004-07-05 13:12:34 +0000510/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000511/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000512/*---------------------------------------------------------------*/