blob: 8bf93c9991a59e62f3d45fac27c38b60ae0c773e [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));
128
129 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
130 vassert(sizeof(void*) == sizeof(int*));
131 vassert(sizeof(void*) == sizeof(HWord));
132
133 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000134 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000135 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000136 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000137 vex_initdone = True;
138 LibVEX_SetAllocMode ( AllocModeTEMPORARY );
sewardj35421a32004-07-05 13:12:34 +0000139}
140
141
142/* --------- Make a translation. --------- */
143
144/* Exported to library client. */
145
sewardj887a11a2004-07-05 17:26:47 +0000146TranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000147 /* The instruction sets we are translating from and to. */
148 InsnSet iset_guest,
149 InsnSet iset_host,
150 /* IN: the block to translate, and its guest address. */
sewardj81bd5502004-07-21 18:49:27 +0000151 UChar* guest_bytes,
sewardj35421a32004-07-05 13:12:34 +0000152 Addr64 guest_bytes_addr,
sewardj5bd4d162004-11-10 13:02:48 +0000153 Bool (*chase_into_ok) ( Addr64 ),
sewardj35421a32004-07-05 13:12:34 +0000154 /* OUT: the number of bytes actually read */
155 Int* guest_bytes_read,
156 /* IN: a place to put the resulting code, and its size */
sewardj81bd5502004-07-21 18:49:27 +0000157 UChar* host_bytes,
158 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000159 /* OUT: how much of the output area is used. */
160 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000161 /* IN: optionally, two instrumentation functions. */
sewardjcf787902004-11-03 09:08:33 +0000162 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
163 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
sewardj9578a8b2004-11-04 19:44:48 +0000164 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000165 /* IN: optionally, an access check function for guest code. */
sewardj58800ff2004-07-28 01:51:10 +0000166 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000167 /* IN: debug: trace vex activity at various points */
168 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000169)
170{
sewardj81bd5502004-07-21 18:49:27 +0000171 /* This the bundle of functions we need to do the back-end stuff
172 (insn selection, reg-alloc, assembly) whilst being insulated
173 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000174 HReg* available_real_regs;
175 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000176 Bool (*isMove) (HInstr*, HReg*, HReg*);
177 void (*getRegUsage) (HRegUsage*, HInstr*);
178 void (*mapRegs) (HRegRemap*, HInstr*);
179 HInstr* (*genSpill) ( HReg, Int );
180 HInstr* (*genReload) ( HReg, Int );
181 void (*ppInstr) ( HInstr* );
182 void (*ppReg) ( HReg );
sewardj8ea867b2004-10-30 19:03:02 +0000183 HInstrArray* (*iselBB) ( IRBB* );
sewardj443cd9d2004-07-18 23:06:45 +0000184 IRBB* (*bbToIR) ( UChar*, Addr64, Int*,
sewardj5bd4d162004-11-10 13:02:48 +0000185 Bool(*)(Addr64),
186 Bool(*)(Addr64), Bool );
sewardj81bd5502004-07-21 18:49:27 +0000187 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000188 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000189 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000190
sewardjeeac8412004-11-02 00:26:55 +0000191 VexGuestLayout* guest_layout;
192 Bool host_is_bigendian = False;
193 IRBB* irbb;
194 HInstrArray* vcode;
195 HInstrArray* rcode;
196 Int i, j, k, out_used, guest_sizeB;
197 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000198 IRType guest_word_type;
199 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000200
sewardj49651f42004-10-28 22:11:04 +0000201 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000202 available_real_regs = NULL;
203 n_available_real_regs = 0;
204 isMove = NULL;
205 getRegUsage = NULL;
206 mapRegs = NULL;
207 genSpill = NULL;
208 genReload = NULL;
209 ppInstr = NULL;
210 ppReg = NULL;
211 iselBB = NULL;
212 bbToIR = NULL;
213 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000214 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000215 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000216 guest_word_type = Ity_INVALID;
217 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000218
sewardjf48ac192004-10-29 00:41:29 +0000219 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000220
sewardj35421a32004-07-05 13:12:34 +0000221 vassert(vex_initdone);
sewardj443cd9d2004-07-18 23:06:45 +0000222 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000223
sewardj2a9ad022004-11-25 02:46:58 +0000224
sewardjf13a16a2004-07-05 17:10:14 +0000225 /* First off, check that the guest and host insn sets
226 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000227
sewardjf13a16a2004-07-05 17:10:14 +0000228 switch (iset_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000229
sewardjf13a16a2004-07-05 17:10:14 +0000230 case InsnSetX86:
231 getAllocableRegs_X86 ( &n_available_real_regs,
232 &available_real_regs );
233 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
234 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
235 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
236 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
237 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000238 ppInstr = (void(*)(HInstr*)) ppX86Instr;
239 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000240 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000241 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardjc9a65702004-07-07 16:32:57 +0000242 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000243 host_word_type = Ity_I32;
sewardjf13a16a2004-07-05 17:10:14 +0000244 break;
sewardj2a9ad022004-11-25 02:46:58 +0000245
sewardjf13a16a2004-07-05 17:10:14 +0000246 default:
sewardj887a11a2004-07-05 17:26:47 +0000247 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000248 }
249
sewardj2a9ad022004-11-25 02:46:58 +0000250
sewardjf13a16a2004-07-05 17:10:14 +0000251 switch (iset_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000252
sewardjf13a16a2004-07-05 17:10:14 +0000253 case InsnSetX86:
sewardj8d2291c2004-10-25 14:50:21 +0000254 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000255 bbToIR = bbToIR_X86;
256 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000257 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000258 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000259 guest_layout = &x86guest_layout;
sewardjf13a16a2004-07-05 17:10:14 +0000260 break;
sewardj2a9ad022004-11-25 02:46:58 +0000261
262 case InsnSetARM:
263 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000264 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000265 specHelper = guest_arm_spechelper;
266 guest_sizeB = sizeof(VexGuestARMState);
267 guest_word_type = Ity_I32;
268 guest_layout = &armGuest_layout;
269 break;
270
sewardjf13a16a2004-07-05 17:10:14 +0000271 default:
sewardj887a11a2004-07-05 17:26:47 +0000272 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000273 }
274
sewardj2a9ad022004-11-25 02:46:58 +0000275
sewardjf48ac192004-10-29 00:41:29 +0000276 if (vex_traceflags & VEX_TRACE_FE)
277 vex_printf("\n------------------------"
278 " Front end "
279 "------------------------\n\n");
280
sewardjf13a16a2004-07-05 17:10:14 +0000281 irbb = bbToIR ( guest_bytes,
282 guest_bytes_addr,
283 guest_bytes_read,
sewardjc9a65702004-07-07 16:32:57 +0000284 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000285 chase_into_ok,
sewardjc9a65702004-07-07 16:32:57 +0000286 host_is_bigendian );
sewardjf13a16a2004-07-05 17:10:14 +0000287
288 if (irbb == NULL) {
289 /* Access failure. */
sewardj443cd9d2004-07-18 23:06:45 +0000290 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000291 vex_traceflags = 0;
sewardjf13a16a2004-07-05 17:10:14 +0000292 return TransAccessFail;
293 }
sewardjaa59f942004-10-09 09:34:36 +0000294
295 /* If debugging, show the raw guest bytes for this bb. */
sewardjf48ac192004-10-29 00:41:29 +0000296 if (vex_traceflags & VEX_TRACE_FE) {
sewardjaa59f942004-10-09 09:34:36 +0000297 UChar* p = guest_bytes;
sewardjaa59f942004-10-09 09:34:36 +0000298 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, *guest_bytes_read );
299 for (i = 0; i < *guest_bytes_read; i++)
300 vex_printf(" %02x", (Int)p[i] );
sewardjf48ac192004-10-29 00:41:29 +0000301 vex_printf("\n\n");
sewardjaa59f942004-10-09 09:34:36 +0000302 }
303
304 /* Sanity check the initial IR. */
sewardjcf787902004-11-03 09:08:33 +0000305 sanityCheckIRBB(irbb, guest_word_type);
sewardje8e9d732004-07-16 21:03:45 +0000306
sewardjedf4d692004-08-17 13:52:58 +0000307 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000308 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
309 guest_bytes_addr );
sewardjcf787902004-11-03 09:08:33 +0000310 sanityCheckIRBB(irbb, guest_word_type);
sewardjedf4d692004-08-17 13:52:58 +0000311
sewardjf48ac192004-10-29 00:41:29 +0000312 if (vex_traceflags & VEX_TRACE_OPT1) {
313 vex_printf("\n------------------------"
314 " After pre-instr IR optimisation "
315 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000316 ppIRBB ( irbb );
317 vex_printf("\n");
318 }
319
sewardjf13a16a2004-07-05 17:10:14 +0000320 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000321 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000322 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000323 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000324 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000325
sewardjf48ac192004-10-29 00:41:29 +0000326 if (vex_traceflags & VEX_TRACE_INST) {
327 vex_printf("\n------------------------"
328 " After instrumentation "
329 "------------------------\n\n");
330 ppIRBB ( irbb );
331 vex_printf("\n");
332 }
333
sewardj49651f42004-10-28 22:11:04 +0000334 if (instrument1 || instrument2)
sewardjcf787902004-11-03 09:08:33 +0000335 sanityCheckIRBB(irbb, guest_word_type);
sewardjf13a16a2004-07-05 17:10:14 +0000336
sewardj9578a8b2004-11-04 19:44:48 +0000337 /* Do a post-instrumentation cleanup pass. */
338 if (cleanup_after_instrumentation) {
339 do_deadcode_BB( irbb );
340 irbb = cprop_BB( irbb );
341 do_deadcode_BB( irbb );
342 sanityCheckIRBB(irbb, guest_word_type);
343 }
344
345 if (vex_traceflags & VEX_TRACE_OPT2) {
346 vex_printf("\n------------------------"
347 " After post-instr IR optimisation "
348 "------------------------\n\n");
349 ppIRBB ( irbb );
350 vex_printf("\n");
351 }
352
sewardjf13a16a2004-07-05 17:10:14 +0000353 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000354 do_deadcode_BB( irbb );
355 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000356
357 if (vex_traceflags & VEX_TRACE_TREES) {
358 vex_printf("\n------------------------"
359 " After tree-building "
360 "------------------------\n\n");
361 ppIRBB ( irbb );
362 vex_printf("\n");
363 }
364
365 if (vex_traceflags & VEX_TRACE_VCODE)
366 vex_printf("\n------------------------"
367 " Instruction selection "
368 "------------------------\n");
369
sewardj8ea867b2004-10-30 19:03:02 +0000370 vcode = iselBB ( irbb );
sewardjf13a16a2004-07-05 17:10:14 +0000371
sewardjf48ac192004-10-29 00:41:29 +0000372 if (vex_traceflags & VEX_TRACE_VCODE)
373 vex_printf("\n");
374
sewardjf48ac192004-10-29 00:41:29 +0000375 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000376 for (i = 0; i < vcode->arr_used; i++) {
377 vex_printf("%3d ", i);
378 ppInstr(vcode->arr[i]);
379 vex_printf("\n");
380 }
sewardjfbcaf332004-07-08 01:46:01 +0000381 vex_printf("\n");
382 }
sewardjfbcaf332004-07-08 01:46:01 +0000383
sewardjf13a16a2004-07-05 17:10:14 +0000384 /* Register allocate. */
385 rcode = doRegisterAllocation ( vcode, available_real_regs,
386 n_available_real_regs,
387 isMove, getRegUsage, mapRegs,
sewardj81ec4182004-10-25 23:15:52 +0000388 genSpill, genReload, guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000389 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000390
sewardjf48ac192004-10-29 00:41:29 +0000391 if (vex_traceflags & VEX_TRACE_RCODE) {
392 vex_printf("\n------------------------"
393 " Register-allocated code "
394 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000395 for (i = 0; i < rcode->arr_used; i++) {
396 vex_printf("%3d ", i);
397 ppInstr(rcode->arr[i]);
398 vex_printf("\n");
399 }
sewardjfbcaf332004-07-08 01:46:01 +0000400 vex_printf("\n");
401 }
sewardjfbcaf332004-07-08 01:46:01 +0000402
sewardj81bd5502004-07-21 18:49:27 +0000403 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000404 if (vex_traceflags & VEX_TRACE_ASM) {
405 vex_printf("\n------------------------"
406 " Assembly "
407 "------------------------\n\n");
408 }
409
sewardj81bd5502004-07-21 18:49:27 +0000410 out_used = 0; /* tracks along the host_bytes array */
411 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000412 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000413 ppInstr(rcode->arr[i]);
414 vex_printf("\n");
415 }
sewardj81bd5502004-07-21 18:49:27 +0000416 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000417 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000418 for (k = 0; k < j; k++)
sewardj86898e82004-07-22 17:26:12 +0000419 if (insn_bytes[k] < 16)
420 vex_printf("0%x ", (UInt)insn_bytes[k]);
421 else
422 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000423 vex_printf("\n\n");
424 }
sewardj81bd5502004-07-21 18:49:27 +0000425 if (out_used + j > host_bytes_size) {
426 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000427 vex_traceflags = 0;
sewardj81bd5502004-07-21 18:49:27 +0000428 return TransOutputFull;
429 }
430 for (k = 0; k < j; k++) {
431 host_bytes[out_used] = insn_bytes[k];
432 out_used++;
433 }
434 vassert(out_used <= host_bytes_size);
435 }
436 *host_bytes_used = out_used;
437
sewardj1f40a0a2004-07-21 12:28:07 +0000438 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000439
sewardjf48ac192004-10-29 00:41:29 +0000440 vex_traceflags = 0;
sewardj35421a32004-07-05 13:12:34 +0000441 return TransOK;
442}
443
444
sewardj893aada2004-11-29 19:57:54 +0000445/* --------- Emulation warnings. --------- */
446
447HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
448{
449 switch (ew) {
450 case EmWarn_NONE:
451 return "none";
452 case EmWarn_X86_x87exns:
453 return "Unmasking x87 FP exceptions";
454 case EmWarn_X86_x87rounding:
455 return "Selection of unsupported x87 FP rounding mode (+inf/-inf)";
456 case EmWarn_X86_x87precision:
457 return "Selection of non-80-bit x87 FP precision";
458 case EmWarn_X86_sseExns:
459 return "Unmasking SSE FP exceptionss";
460 case EmWarn_X86_sseRounding:
461 return "Selection of unsupported SSE FP rounding mode";
462 default:
463 vpanic("LibVEX_EmWarn_string: unknown warning");
464 }
465}
sewardj35421a32004-07-05 13:12:34 +0000466
467/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000468/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000469/*---------------------------------------------------------------*/