blob: dadd89778b00720f6279c2ea38b8bd448142ee2c [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. */
sewardjcf787902004-11-03 09:08:33 +0000318 sanityCheckIRBB(irbb, guest_word_type);
sewardje8e9d732004-07-16 21:03:45 +0000319
sewardjedf4d692004-08-17 13:52:58 +0000320 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000321 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
322 guest_bytes_addr );
sewardjcf787902004-11-03 09:08:33 +0000323 sanityCheckIRBB(irbb, guest_word_type);
sewardjedf4d692004-08-17 13:52:58 +0000324
sewardjf48ac192004-10-29 00:41:29 +0000325 if (vex_traceflags & VEX_TRACE_OPT1) {
326 vex_printf("\n------------------------"
327 " After pre-instr IR optimisation "
328 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000329 ppIRBB ( irbb );
330 vex_printf("\n");
331 }
332
sewardjf13a16a2004-07-05 17:10:14 +0000333 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000334 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000335 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000336 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000337 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000338
sewardjf48ac192004-10-29 00:41:29 +0000339 if (vex_traceflags & VEX_TRACE_INST) {
340 vex_printf("\n------------------------"
341 " After instrumentation "
342 "------------------------\n\n");
343 ppIRBB ( irbb );
344 vex_printf("\n");
345 }
346
sewardj49651f42004-10-28 22:11:04 +0000347 if (instrument1 || instrument2)
sewardjcf787902004-11-03 09:08:33 +0000348 sanityCheckIRBB(irbb, guest_word_type);
sewardjf13a16a2004-07-05 17:10:14 +0000349
sewardj9578a8b2004-11-04 19:44:48 +0000350 /* Do a post-instrumentation cleanup pass. */
351 if (cleanup_after_instrumentation) {
352 do_deadcode_BB( irbb );
353 irbb = cprop_BB( irbb );
354 do_deadcode_BB( irbb );
355 sanityCheckIRBB(irbb, guest_word_type);
356 }
357
358 if (vex_traceflags & VEX_TRACE_OPT2) {
359 vex_printf("\n------------------------"
360 " After post-instr IR optimisation "
361 "------------------------\n\n");
362 ppIRBB ( irbb );
363 vex_printf("\n");
364 }
365
sewardjf13a16a2004-07-05 17:10:14 +0000366 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000367 do_deadcode_BB( irbb );
368 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000369
370 if (vex_traceflags & VEX_TRACE_TREES) {
371 vex_printf("\n------------------------"
372 " After tree-building "
373 "------------------------\n\n");
374 ppIRBB ( irbb );
375 vex_printf("\n");
376 }
377
378 if (vex_traceflags & VEX_TRACE_VCODE)
379 vex_printf("\n------------------------"
380 " Instruction selection "
381 "------------------------\n");
382
sewardj8ea867b2004-10-30 19:03:02 +0000383 vcode = iselBB ( irbb );
sewardjf13a16a2004-07-05 17:10:14 +0000384
sewardjf48ac192004-10-29 00:41:29 +0000385 if (vex_traceflags & VEX_TRACE_VCODE)
386 vex_printf("\n");
387
sewardjf48ac192004-10-29 00:41:29 +0000388 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000389 for (i = 0; i < vcode->arr_used; i++) {
390 vex_printf("%3d ", i);
391 ppInstr(vcode->arr[i]);
392 vex_printf("\n");
393 }
sewardjfbcaf332004-07-08 01:46:01 +0000394 vex_printf("\n");
395 }
sewardjfbcaf332004-07-08 01:46:01 +0000396
sewardjf13a16a2004-07-05 17:10:14 +0000397 /* Register allocate. */
398 rcode = doRegisterAllocation ( vcode, available_real_regs,
399 n_available_real_regs,
400 isMove, getRegUsage, mapRegs,
sewardj81ec4182004-10-25 23:15:52 +0000401 genSpill, genReload, guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000402 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000403
sewardjf48ac192004-10-29 00:41:29 +0000404 if (vex_traceflags & VEX_TRACE_RCODE) {
405 vex_printf("\n------------------------"
406 " Register-allocated code "
407 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000408 for (i = 0; i < rcode->arr_used; i++) {
409 vex_printf("%3d ", i);
410 ppInstr(rcode->arr[i]);
411 vex_printf("\n");
412 }
sewardjfbcaf332004-07-08 01:46:01 +0000413 vex_printf("\n");
414 }
sewardjfbcaf332004-07-08 01:46:01 +0000415
sewardj81bd5502004-07-21 18:49:27 +0000416 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000417 if (vex_traceflags & VEX_TRACE_ASM) {
418 vex_printf("\n------------------------"
419 " Assembly "
420 "------------------------\n\n");
421 }
422
sewardj81bd5502004-07-21 18:49:27 +0000423 out_used = 0; /* tracks along the host_bytes array */
424 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000425 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000426 ppInstr(rcode->arr[i]);
427 vex_printf("\n");
428 }
sewardj81bd5502004-07-21 18:49:27 +0000429 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000430 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000431 for (k = 0; k < j; k++)
sewardj86898e82004-07-22 17:26:12 +0000432 if (insn_bytes[k] < 16)
433 vex_printf("0%x ", (UInt)insn_bytes[k]);
434 else
435 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000436 vex_printf("\n\n");
437 }
sewardj81bd5502004-07-21 18:49:27 +0000438 if (out_used + j > host_bytes_size) {
439 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000440 vex_traceflags = 0;
sewardj81bd5502004-07-21 18:49:27 +0000441 return TransOutputFull;
442 }
443 for (k = 0; k < j; k++) {
444 host_bytes[out_used] = insn_bytes[k];
445 out_used++;
446 }
447 vassert(out_used <= host_bytes_size);
448 }
449 *host_bytes_used = out_used;
450
sewardj1f40a0a2004-07-21 12:28:07 +0000451 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000452
sewardjf48ac192004-10-29 00:41:29 +0000453 vex_traceflags = 0;
sewardj35421a32004-07-05 13:12:34 +0000454 return TransOK;
455}
456
457
sewardj893aada2004-11-29 19:57:54 +0000458/* --------- Emulation warnings. --------- */
459
460HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
461{
462 switch (ew) {
463 case EmWarn_NONE:
464 return "none";
465 case EmWarn_X86_x87exns:
466 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000467 case EmWarn_X86_x87precision:
468 return "Selection of non-80-bit x87 FP precision";
469 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000470 return "Unmasking SSE FP exceptions";
471 case EmWarn_X86_fz:
472 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
473 case EmWarn_X86_daz:
474 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000475 default:
476 vpanic("LibVEX_EmWarn_string: unknown warning");
477 }
478}
sewardj35421a32004-07-05 13:12:34 +0000479
sewardjbef170b2004-12-21 01:23:00 +0000480/* --------- Arch/Subarch names. --------- */
481
482const HChar* LibVEX_ppVexArch ( VexArch arch )
483{
484 switch (arch) {
485 case VexArch_INVALID: return "INVALID";
486 case VexArchX86: return "X86";
487 case VexArchAMD64: return "AMD64";
488 case VexArchARM: return "ARM";
489 default: return "VexArch???";
490 }
491}
492
493const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
494{
495 switch (subarch) {
496 case VexSubArch_INVALID: return "INVALID";
497 case VexSubArch_NONE: return "NONE";
498 case VexSubArchX86_sse0: return "x86-sse0";
499 case VexSubArchX86_sse1: return "x86-sse1";
500 case VexSubArchX86_sse2: return "x86-sse2";
501 case VexSubArchARM_v4: return "arm-v4";
502 default: return "VexSubArch???";
503 }
504}
505
sewardj35421a32004-07-05 13:12:34 +0000506/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000507/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000508/*---------------------------------------------------------------*/