blob: c41b87b5a530efb2252f22d86a2c0e8a656db7ac [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 );
sewardj9df271d2004-12-31 22:37:42 +0000196 HInstrArray* (*iselBB) ( IRBB*, VexSubArch );
sewardj443cd9d2004-07-18 23:06:45 +0000197 IRBB* (*bbToIR) ( UChar*, Addr64, Int*,
sewardj5bd4d162004-11-10 13:02:48 +0000198 Bool(*)(Addr64),
sewardj9df271d2004-12-31 22:37:42 +0000199 Bool(*)(Addr64), Bool, VexSubArch );
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;
sewardj9df271d2004-12-31 22:37:42 +0000257 vassert(subarch_host == VexSubArchX86_sse0
258 || subarch_host == VexSubArchX86_sse1
259 || subarch_host == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000260 break;
sewardj2a9ad022004-11-25 02:46:58 +0000261
sewardjf13a16a2004-07-05 17:10:14 +0000262 default:
sewardj887a11a2004-07-05 17:26:47 +0000263 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000264 }
265
sewardj2a9ad022004-11-25 02:46:58 +0000266
sewardjbef170b2004-12-21 01:23:00 +0000267 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000268
sewardjbef170b2004-12-21 01:23:00 +0000269 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000270 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000271 bbToIR = bbToIR_X86;
272 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000273 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000274 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000275 guest_layout = &x86guest_layout;
sewardj9df271d2004-12-31 22:37:42 +0000276 vassert(subarch_guest == VexSubArchX86_sse0
277 || subarch_guest == VexSubArchX86_sse1
278 || subarch_guest == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000279 break;
sewardj2a9ad022004-11-25 02:46:58 +0000280
sewardjbef170b2004-12-21 01:23:00 +0000281 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000282 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000283 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000284 specHelper = guest_arm_spechelper;
285 guest_sizeB = sizeof(VexGuestARMState);
286 guest_word_type = Ity_I32;
287 guest_layout = &armGuest_layout;
288 break;
289
sewardjf13a16a2004-07-05 17:10:14 +0000290 default:
sewardj887a11a2004-07-05 17:26:47 +0000291 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000292 }
293
sewardj9df271d2004-12-31 22:37:42 +0000294 /* yet more sanity checks ... */
295 if (arch_guest == VexArchX86 && arch_host == VexArchX86) {
296 /* doesn't necessarily have to be true, but if it isn't it means
297 we are simulating one flavour of x86 on a different one, which
298 is pretty strange. */
299 vassert(subarch_guest == subarch_host);
300 }
sewardj2a9ad022004-11-25 02:46:58 +0000301
sewardjf48ac192004-10-29 00:41:29 +0000302 if (vex_traceflags & VEX_TRACE_FE)
303 vex_printf("\n------------------------"
304 " Front end "
305 "------------------------\n\n");
306
sewardjf13a16a2004-07-05 17:10:14 +0000307 irbb = bbToIR ( guest_bytes,
308 guest_bytes_addr,
309 guest_bytes_read,
sewardjc9a65702004-07-07 16:32:57 +0000310 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000311 chase_into_ok,
sewardj9df271d2004-12-31 22:37:42 +0000312 host_is_bigendian,
313 subarch_guest );
sewardjf13a16a2004-07-05 17:10:14 +0000314
315 if (irbb == NULL) {
316 /* Access failure. */
sewardj443cd9d2004-07-18 23:06:45 +0000317 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000318 vex_traceflags = 0;
sewardjf13a16a2004-07-05 17:10:14 +0000319 return TransAccessFail;
320 }
sewardjaa59f942004-10-09 09:34:36 +0000321
322 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000323 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardjaa59f942004-10-09 09:34:36 +0000324 UChar* p = guest_bytes;
sewardjaa59f942004-10-09 09:34:36 +0000325 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, *guest_bytes_read );
326 for (i = 0; i < *guest_bytes_read; i++)
327 vex_printf(" %02x", (Int)p[i] );
sewardjf48ac192004-10-29 00:41:29 +0000328 vex_printf("\n\n");
sewardjaa59f942004-10-09 09:34:36 +0000329 }
330
331 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000332 sanityCheckIRBB( irbb, "initial IR",
333 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000334
sewardjedf4d692004-08-17 13:52:58 +0000335 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000336 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
337 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000338 sanityCheckIRBB( irbb, "after initial iropt",
339 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000340
sewardjf48ac192004-10-29 00:41:29 +0000341 if (vex_traceflags & VEX_TRACE_OPT1) {
342 vex_printf("\n------------------------"
343 " After pre-instr IR optimisation "
344 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000345 ppIRBB ( irbb );
346 vex_printf("\n");
347 }
348
sewardjf13a16a2004-07-05 17:10:14 +0000349 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000350 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000351 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000352 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000353 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000354
sewardjf48ac192004-10-29 00:41:29 +0000355 if (vex_traceflags & VEX_TRACE_INST) {
356 vex_printf("\n------------------------"
357 " After instrumentation "
358 "------------------------\n\n");
359 ppIRBB ( irbb );
360 vex_printf("\n");
361 }
362
sewardj49651f42004-10-28 22:11:04 +0000363 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000364 sanityCheckIRBB( irbb, "after instrumentation",
365 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000366
sewardj9578a8b2004-11-04 19:44:48 +0000367 /* Do a post-instrumentation cleanup pass. */
368 if (cleanup_after_instrumentation) {
369 do_deadcode_BB( irbb );
370 irbb = cprop_BB( irbb );
371 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000372 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
373 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000374 }
375
376 if (vex_traceflags & VEX_TRACE_OPT2) {
377 vex_printf("\n------------------------"
378 " After post-instr IR optimisation "
379 "------------------------\n\n");
380 ppIRBB ( irbb );
381 vex_printf("\n");
382 }
383
sewardjf13a16a2004-07-05 17:10:14 +0000384 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000385 do_deadcode_BB( irbb );
386 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000387
388 if (vex_traceflags & VEX_TRACE_TREES) {
389 vex_printf("\n------------------------"
390 " After tree-building "
391 "------------------------\n\n");
392 ppIRBB ( irbb );
393 vex_printf("\n");
394 }
395
396 if (vex_traceflags & VEX_TRACE_VCODE)
397 vex_printf("\n------------------------"
398 " Instruction selection "
399 "------------------------\n");
400
sewardj9df271d2004-12-31 22:37:42 +0000401 vcode = iselBB ( irbb, subarch_host );
sewardjf13a16a2004-07-05 17:10:14 +0000402
sewardjf48ac192004-10-29 00:41:29 +0000403 if (vex_traceflags & VEX_TRACE_VCODE)
404 vex_printf("\n");
405
sewardjf48ac192004-10-29 00:41:29 +0000406 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000407 for (i = 0; i < vcode->arr_used; i++) {
408 vex_printf("%3d ", i);
409 ppInstr(vcode->arr[i]);
410 vex_printf("\n");
411 }
sewardjfbcaf332004-07-08 01:46:01 +0000412 vex_printf("\n");
413 }
sewardjfbcaf332004-07-08 01:46:01 +0000414
sewardjf13a16a2004-07-05 17:10:14 +0000415 /* Register allocate. */
416 rcode = doRegisterAllocation ( vcode, available_real_regs,
417 n_available_real_regs,
418 isMove, getRegUsage, mapRegs,
sewardj81ec4182004-10-25 23:15:52 +0000419 genSpill, genReload, guest_sizeB,
sewardj2b515872004-07-05 20:50:45 +0000420 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000421
sewardjf48ac192004-10-29 00:41:29 +0000422 if (vex_traceflags & VEX_TRACE_RCODE) {
423 vex_printf("\n------------------------"
424 " Register-allocated code "
425 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000426 for (i = 0; i < rcode->arr_used; i++) {
427 vex_printf("%3d ", i);
428 ppInstr(rcode->arr[i]);
429 vex_printf("\n");
430 }
sewardjfbcaf332004-07-08 01:46:01 +0000431 vex_printf("\n");
432 }
sewardjfbcaf332004-07-08 01:46:01 +0000433
sewardj81bd5502004-07-21 18:49:27 +0000434 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000435 if (vex_traceflags & VEX_TRACE_ASM) {
436 vex_printf("\n------------------------"
437 " Assembly "
438 "------------------------\n\n");
439 }
440
sewardj81bd5502004-07-21 18:49:27 +0000441 out_used = 0; /* tracks along the host_bytes array */
442 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000443 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000444 ppInstr(rcode->arr[i]);
445 vex_printf("\n");
446 }
sewardj81bd5502004-07-21 18:49:27 +0000447 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000448 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000449 for (k = 0; k < j; k++)
sewardj86898e82004-07-22 17:26:12 +0000450 if (insn_bytes[k] < 16)
451 vex_printf("0%x ", (UInt)insn_bytes[k]);
452 else
453 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000454 vex_printf("\n\n");
455 }
sewardj81bd5502004-07-21 18:49:27 +0000456 if (out_used + j > host_bytes_size) {
457 LibVEX_ClearTemporary(False);
sewardjf48ac192004-10-29 00:41:29 +0000458 vex_traceflags = 0;
sewardj81bd5502004-07-21 18:49:27 +0000459 return TransOutputFull;
460 }
461 for (k = 0; k < j; k++) {
462 host_bytes[out_used] = insn_bytes[k];
463 out_used++;
464 }
465 vassert(out_used <= host_bytes_size);
466 }
467 *host_bytes_used = out_used;
468
sewardj1f40a0a2004-07-21 12:28:07 +0000469 LibVEX_ClearTemporary(False);
sewardjf13a16a2004-07-05 17:10:14 +0000470
sewardjf48ac192004-10-29 00:41:29 +0000471 vex_traceflags = 0;
sewardj35421a32004-07-05 13:12:34 +0000472 return TransOK;
473}
474
475
sewardj893aada2004-11-29 19:57:54 +0000476/* --------- Emulation warnings. --------- */
477
478HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
479{
480 switch (ew) {
481 case EmWarn_NONE:
482 return "none";
483 case EmWarn_X86_x87exns:
484 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000485 case EmWarn_X86_x87precision:
486 return "Selection of non-80-bit x87 FP precision";
487 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000488 return "Unmasking SSE FP exceptions";
489 case EmWarn_X86_fz:
490 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
491 case EmWarn_X86_daz:
492 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000493 default:
494 vpanic("LibVEX_EmWarn_string: unknown warning");
495 }
496}
sewardj35421a32004-07-05 13:12:34 +0000497
sewardjbef170b2004-12-21 01:23:00 +0000498/* --------- Arch/Subarch names. --------- */
499
500const HChar* LibVEX_ppVexArch ( VexArch arch )
501{
502 switch (arch) {
503 case VexArch_INVALID: return "INVALID";
504 case VexArchX86: return "X86";
505 case VexArchAMD64: return "AMD64";
506 case VexArchARM: return "ARM";
507 default: return "VexArch???";
508 }
509}
510
511const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
512{
513 switch (subarch) {
514 case VexSubArch_INVALID: return "INVALID";
515 case VexSubArch_NONE: return "NONE";
516 case VexSubArchX86_sse0: return "x86-sse0";
517 case VexSubArchX86_sse1: return "x86-sse1";
518 case VexSubArchX86_sse2: return "x86-sse2";
519 case VexSubArchARM_v4: return "arm-v4";
520 default: return "VexSubArch???";
521 }
522}
523
sewardj35421a32004-07-05 13:12:34 +0000524/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000525/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000526/*---------------------------------------------------------------*/