blob: b93ee57182220ccaddc0dfa9045df8fb5e22bedf [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
sewardj08613742004-10-25 13:01:45 +000058void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
59{
60 vcon->iropt_verbosity = 0;
61 vcon->iropt_level = 2;
62 vcon->iropt_precise_memory_exns = False;
63 vcon->iropt_unroll_thresh = 120;
64 vcon->guest_max_insns = 50;
65 vcon->guest_chase_thresh = 10;
66}
67
68
69/* Exported to library client. */
70
sewardj887a11a2004-07-05 17:26:47 +000071void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000072 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000073 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000074 void (*failure_exit) ( void ),
75 /* logging output function */
76 void (*log_bytes) ( Char*, Int nbytes ),
77 /* debug paranoia level */
78 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +000079 /* Are we supporting valgrind checking? */
80 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +000081 /* Control ... */
82 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +000083)
84{
sewardj08613742004-10-25 13:01:45 +000085 /* First off, do enough minimal setup so that the following
86 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +000087 vex_failure_exit = failure_exit;
88 vex_log_bytes = log_bytes;
89
90 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +000091 vassert(!vex_initdone);
92 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +000093 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +000094 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +000095
96 vassert(vcon->iropt_verbosity >= 0);
97 vassert(vcon->iropt_level >= 0);
98 vassert(vcon->iropt_level <= 2);
99 vassert(vcon->iropt_unroll_thresh >= 0);
100 vassert(vcon->iropt_unroll_thresh <= 400);
101 vassert(vcon->guest_max_insns >= 1);
102 vassert(vcon->guest_max_insns <= 100);
103 vassert(vcon->guest_chase_thresh >= 0);
104 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000105
sewardj81ec4182004-10-25 23:15:52 +0000106 /* All the guest state structs must have an 8-aligned size. */
107 vassert(0 == sizeof(VexGuestX86State) % 8);
108
sewardjea602bc2004-10-14 21:40:12 +0000109 /* Check that Vex has been built with sizes of basic types as
110 stated in priv/libvex_basictypes.h. Failure of any of these is
111 a serious configuration error and should be corrected
112 immediately. If any of these assertions fail you can fully
113 expect Vex not to work properly, if at all. */
114
115 vassert(1 == sizeof(UChar));
116 vassert(1 == sizeof(Char));
117 vassert(2 == sizeof(UShort));
118 vassert(2 == sizeof(Short));
119 vassert(4 == sizeof(UInt));
120 vassert(4 == sizeof(Int));
121 vassert(8 == sizeof(ULong));
122 vassert(8 == sizeof(Long));
123 vassert(4 == sizeof(Float));
124 vassert(8 == sizeof(Double));
125 vassert(1 == sizeof(Bool));
126 vassert(4 == sizeof(Addr32));
127 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000128 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000129
130 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
131 vassert(sizeof(void*) == sizeof(int*));
132 vassert(sizeof(void*) == sizeof(HWord));
133
134 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000135 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000136 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000137 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000138 vex_initdone = True;
139 LibVEX_SetAllocMode ( AllocModeTEMPORARY );
sewardj35421a32004-07-05 13:12:34 +0000140}
141
142
143/* --------- Make a translation. --------- */
144
145/* Exported to library client. */
146
sewardj887a11a2004-07-05 17:26:47 +0000147TranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000148 /* The instruction sets we are translating from and to. */
149 InsnSet iset_guest,
150 InsnSet iset_host,
151 /* IN: the block to translate, and its guest address. */
sewardj81bd5502004-07-21 18:49:27 +0000152 UChar* guest_bytes,
sewardj35421a32004-07-05 13:12:34 +0000153 Addr64 guest_bytes_addr,
sewardj5bd4d162004-11-10 13:02:48 +0000154 Bool (*chase_into_ok) ( Addr64 ),
sewardj35421a32004-07-05 13:12:34 +0000155 /* OUT: the number of bytes actually read */
156 Int* guest_bytes_read,
157 /* IN: a place to put the resulting code, and its size */
sewardj81bd5502004-07-21 18:49:27 +0000158 UChar* host_bytes,
159 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000160 /* OUT: how much of the output area is used. */
161 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000162 /* IN: optionally, two instrumentation functions. */
sewardjcf787902004-11-03 09:08:33 +0000163 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
164 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
sewardj9578a8b2004-11-04 19:44:48 +0000165 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000166 /* IN: optionally, an access check function for guest code. */
sewardj58800ff2004-07-28 01:51:10 +0000167 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000168 /* IN: debug: trace vex activity at various points */
169 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000170)
171{
sewardj81bd5502004-07-21 18:49:27 +0000172 /* This the bundle of functions we need to do the back-end stuff
173 (insn selection, reg-alloc, assembly) whilst being insulated
174 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000175 HReg* available_real_regs;
176 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000177 Bool (*isMove) (HInstr*, HReg*, HReg*);
178 void (*getRegUsage) (HRegUsage*, HInstr*);
179 void (*mapRegs) (HRegRemap*, HInstr*);
180 HInstr* (*genSpill) ( HReg, Int );
181 HInstr* (*genReload) ( HReg, Int );
182 void (*ppInstr) ( HInstr* );
183 void (*ppReg) ( HReg );
sewardj8ea867b2004-10-30 19:03:02 +0000184 HInstrArray* (*iselBB) ( IRBB* );
sewardj443cd9d2004-07-18 23:06:45 +0000185 IRBB* (*bbToIR) ( UChar*, Addr64, Int*,
sewardj5bd4d162004-11-10 13:02:48 +0000186 Bool(*)(Addr64),
187 Bool(*)(Addr64), Bool );
sewardj81bd5502004-07-21 18:49:27 +0000188 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000189 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000190 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000191
sewardjeeac8412004-11-02 00:26:55 +0000192 VexGuestLayout* guest_layout;
193 Bool host_is_bigendian = False;
194 IRBB* irbb;
195 HInstrArray* vcode;
196 HInstrArray* rcode;
197 Int i, j, k, out_used, guest_sizeB;
198 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000199 IRType guest_word_type;
200 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000201
sewardj49651f42004-10-28 22:11:04 +0000202 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000203 available_real_regs = NULL;
204 n_available_real_regs = 0;
205 isMove = NULL;
206 getRegUsage = NULL;
207 mapRegs = NULL;
208 genSpill = NULL;
209 genReload = NULL;
210 ppInstr = NULL;
211 ppReg = NULL;
212 iselBB = NULL;
213 bbToIR = NULL;
214 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000215 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000216 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000217 guest_word_type = Ity_INVALID;
218 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000219
sewardjf48ac192004-10-29 00:41:29 +0000220 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000221
sewardj35421a32004-07-05 13:12:34 +0000222 vassert(vex_initdone);
sewardj443cd9d2004-07-18 23:06:45 +0000223 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000224
sewardj2a9ad022004-11-25 02:46:58 +0000225
sewardjf13a16a2004-07-05 17:10:14 +0000226 /* First off, check that the guest and host insn sets
227 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000228
sewardjf13a16a2004-07-05 17:10:14 +0000229 switch (iset_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000230
sewardjf13a16a2004-07-05 17:10:14 +0000231 case InsnSetX86:
232 getAllocableRegs_X86 ( &n_available_real_regs,
233 &available_real_regs );
234 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
235 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
236 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
237 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
238 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000239 ppInstr = (void(*)(HInstr*)) ppX86Instr;
240 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000241 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000242 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardjc9a65702004-07-07 16:32:57 +0000243 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000244 host_word_type = Ity_I32;
sewardjf13a16a2004-07-05 17:10:14 +0000245 break;
sewardj2a9ad022004-11-25 02:46:58 +0000246
sewardjf13a16a2004-07-05 17:10:14 +0000247 default:
sewardj887a11a2004-07-05 17:26:47 +0000248 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000249 }
250
sewardj2a9ad022004-11-25 02:46:58 +0000251
sewardjf13a16a2004-07-05 17:10:14 +0000252 switch (iset_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000253
sewardjf13a16a2004-07-05 17:10:14 +0000254 case InsnSetX86:
sewardj8d2291c2004-10-25 14:50:21 +0000255 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000256 bbToIR = bbToIR_X86;
257 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000258 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000259 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000260 guest_layout = &x86guest_layout;
sewardjf13a16a2004-07-05 17:10:14 +0000261 break;
sewardj2a9ad022004-11-25 02:46:58 +0000262
263 case InsnSetARM:
264 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000265 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000266 specHelper = guest_arm_spechelper;
267 guest_sizeB = sizeof(VexGuestARMState);
268 guest_word_type = Ity_I32;
269 guest_layout = &armGuest_layout;
270 break;
271
sewardjf13a16a2004-07-05 17:10:14 +0000272 default:
sewardj887a11a2004-07-05 17:26:47 +0000273 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000274 }
275
sewardj2a9ad022004-11-25 02:46:58 +0000276
sewardjf48ac192004-10-29 00:41:29 +0000277 if (vex_traceflags & VEX_TRACE_FE)
278 vex_printf("\n------------------------"
279 " Front end "
280 "------------------------\n\n");
281
sewardjf13a16a2004-07-05 17:10:14 +0000282 irbb = bbToIR ( guest_bytes,
283 guest_bytes_addr,
284 guest_bytes_read,
sewardjc9a65702004-07-07 16:32:57 +0000285 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000286 chase_into_ok,
sewardjc9a65702004-07-07 16:32:57 +0000287 host_is_bigendian );
sewardjf13a16a2004-07-05 17:10:14 +0000288
289 if (irbb == NULL) {
290 /* Access failure. */
sewardj443cd9d2004-07-18 23:06:45 +0000291 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000292 vex_traceflags = 0;
sewardjf13a16a2004-07-05 17:10:14 +0000293 return TransAccessFail;
294 }
sewardjaa59f942004-10-09 09:34:36 +0000295
296 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000297 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardjaa59f942004-10-09 09:34:36 +0000298 UChar* p = guest_bytes;
sewardjaa59f942004-10-09 09:34:36 +0000299 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, *guest_bytes_read );
300 for (i = 0; i < *guest_bytes_read; i++)
301 vex_printf(" %02x", (Int)p[i] );
sewardjf48ac192004-10-29 00:41:29 +0000302 vex_printf("\n\n");
sewardjaa59f942004-10-09 09:34:36 +0000303 }
304
305 /* Sanity check the initial IR. */
sewardjcf787902004-11-03 09:08:33 +0000306 sanityCheckIRBB(irbb, guest_word_type);
sewardje8e9d732004-07-16 21:03:45 +0000307
sewardjedf4d692004-08-17 13:52:58 +0000308 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000309 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
310 guest_bytes_addr );
sewardjcf787902004-11-03 09:08:33 +0000311 sanityCheckIRBB(irbb, guest_word_type);
sewardjedf4d692004-08-17 13:52:58 +0000312
sewardjf48ac192004-10-29 00:41:29 +0000313 if (vex_traceflags & VEX_TRACE_OPT1) {
314 vex_printf("\n------------------------"
315 " After pre-instr IR optimisation "
316 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000317 ppIRBB ( irbb );
318 vex_printf("\n");
319 }
320
sewardjf13a16a2004-07-05 17:10:14 +0000321 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000322 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000323 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000324 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000325 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000326
sewardjf48ac192004-10-29 00:41:29 +0000327 if (vex_traceflags & VEX_TRACE_INST) {
328 vex_printf("\n------------------------"
329 " After instrumentation "
330 "------------------------\n\n");
331 ppIRBB ( irbb );
332 vex_printf("\n");
333 }
334
sewardj49651f42004-10-28 22:11:04 +0000335 if (instrument1 || instrument2)
sewardjcf787902004-11-03 09:08:33 +0000336 sanityCheckIRBB(irbb, guest_word_type);
sewardjf13a16a2004-07-05 17:10:14 +0000337
sewardj9578a8b2004-11-04 19:44:48 +0000338 /* Do a post-instrumentation cleanup pass. */
339 if (cleanup_after_instrumentation) {
340 do_deadcode_BB( irbb );
341 irbb = cprop_BB( irbb );
342 do_deadcode_BB( irbb );
343 sanityCheckIRBB(irbb, guest_word_type);
344 }
345
346 if (vex_traceflags & VEX_TRACE_OPT2) {
347 vex_printf("\n------------------------"
348 " After post-instr IR optimisation "
349 "------------------------\n\n");
350 ppIRBB ( irbb );
351 vex_printf("\n");
352 }
353
sewardjf13a16a2004-07-05 17:10:14 +0000354 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000355 do_deadcode_BB( irbb );
356 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000357
358 if (vex_traceflags & VEX_TRACE_TREES) {
359 vex_printf("\n------------------------"
360 " After tree-building "
361 "------------------------\n\n");
362 ppIRBB ( irbb );
363 vex_printf("\n");
364 }
365
366 if (vex_traceflags & VEX_TRACE_VCODE)
367 vex_printf("\n------------------------"
368 " Instruction selection "
369 "------------------------\n");
370
sewardj8ea867b2004-10-30 19:03:02 +0000371 vcode = iselBB ( irbb );
sewardjf13a16a2004-07-05 17:10:14 +0000372
sewardjf48ac192004-10-29 00:41:29 +0000373 if (vex_traceflags & VEX_TRACE_VCODE)
374 vex_printf("\n");
375
sewardjf48ac192004-10-29 00:41:29 +0000376 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000377 for (i = 0; i < vcode->arr_used; i++) {
378 vex_printf("%3d ", i);
379 ppInstr(vcode->arr[i]);
380 vex_printf("\n");
381 }
sewardjfbcaf332004-07-08 01:46:01 +0000382 vex_printf("\n");
383 }
sewardjfbcaf332004-07-08 01:46:01 +0000384
sewardjf13a16a2004-07-05 17:10:14 +0000385 /* Register allocate. */
386 rcode = doRegisterAllocation ( vcode, available_real_regs,
387 n_available_real_regs,
388 isMove, getRegUsage, mapRegs,
sewardj81ec4182004-10-25 23:15:52 +0000389 genSpill, genReload, guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000390 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000391
sewardjf48ac192004-10-29 00:41:29 +0000392 if (vex_traceflags & VEX_TRACE_RCODE) {
393 vex_printf("\n------------------------"
394 " Register-allocated code "
395 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000396 for (i = 0; i < rcode->arr_used; i++) {
397 vex_printf("%3d ", i);
398 ppInstr(rcode->arr[i]);
399 vex_printf("\n");
400 }
sewardjfbcaf332004-07-08 01:46:01 +0000401 vex_printf("\n");
402 }
sewardjfbcaf332004-07-08 01:46:01 +0000403
sewardj81bd5502004-07-21 18:49:27 +0000404 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000405 if (vex_traceflags & VEX_TRACE_ASM) {
406 vex_printf("\n------------------------"
407 " Assembly "
408 "------------------------\n\n");
409 }
410
sewardj81bd5502004-07-21 18:49:27 +0000411 out_used = 0; /* tracks along the host_bytes array */
412 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000413 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000414 ppInstr(rcode->arr[i]);
415 vex_printf("\n");
416 }
sewardj81bd5502004-07-21 18:49:27 +0000417 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000418 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000419 for (k = 0; k < j; k++)
sewardj86898e82004-07-22 17:26:12 +0000420 if (insn_bytes[k] < 16)
421 vex_printf("0%x ", (UInt)insn_bytes[k]);
422 else
423 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000424 vex_printf("\n\n");
425 }
sewardj81bd5502004-07-21 18:49:27 +0000426 if (out_used + j > host_bytes_size) {
427 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000428 vex_traceflags = 0;
sewardj81bd5502004-07-21 18:49:27 +0000429 return TransOutputFull;
430 }
431 for (k = 0; k < j; k++) {
432 host_bytes[out_used] = insn_bytes[k];
433 out_used++;
434 }
435 vassert(out_used <= host_bytes_size);
436 }
437 *host_bytes_used = out_used;
438
sewardj1f40a0a2004-07-21 12:28:07 +0000439 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000440
sewardjf48ac192004-10-29 00:41:29 +0000441 vex_traceflags = 0;
sewardj35421a32004-07-05 13:12:34 +0000442 return TransOK;
443}
444
445
sewardj893aada2004-11-29 19:57:54 +0000446/* --------- Emulation warnings. --------- */
447
448HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
449{
450 switch (ew) {
451 case EmWarn_NONE:
452 return "none";
453 case EmWarn_X86_x87exns:
454 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000455 case EmWarn_X86_x87precision:
456 return "Selection of non-80-bit x87 FP precision";
457 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000458 return "Unmasking SSE FP exceptions";
459 case EmWarn_X86_fz:
460 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
461 case EmWarn_X86_daz:
462 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000463 default:
464 vpanic("LibVEX_EmWarn_string: unknown warning");
465 }
466}
sewardj35421a32004-07-05 13:12:34 +0000467
468/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000469/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000470/*---------------------------------------------------------------*/