VirtualBox

source: vbox/trunk/src/recompiler/translate-all.c@ 24345

Last change on this file since 24345 was 17265, checked in by vboxsync, 16 years ago

REM: cleanup

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1/*
2 * Host code generation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29#include <stdarg.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33
34#include "config.h"
35
36#define NO_CPU_IO_DEFS
37#include "cpu.h"
38#include "exec-all.h"
39#include "disas.h"
40#include "tcg.h"
41
42/* code generation context */
43TCGContext tcg_ctx;
44
45uint16_t gen_opc_buf[OPC_BUF_SIZE];
46TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
47
48target_ulong gen_opc_pc[OPC_BUF_SIZE];
49uint16_t gen_opc_icount[OPC_BUF_SIZE];
50uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
51#if defined(TARGET_I386)
52uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
53#elif defined(TARGET_SPARC)
54target_ulong gen_opc_npc[OPC_BUF_SIZE];
55target_ulong gen_opc_jump_pc[2];
56#elif defined(TARGET_MIPS)
57uint32_t gen_opc_hflags[OPC_BUF_SIZE];
58#endif
59
60/* XXX: suppress that */
61unsigned long code_gen_max_block_size(void)
62{
63#ifdef VBOX
64 /* Just to suppress a lot of dummy warnings */
65 static long max;
66#else
67 static unsigned long max;
68#endif
69
70 if (max == 0) {
71 max = TCG_MAX_OP_SIZE;
72#define DEF(s, n, copy_size) max = (copy_size > max) ? copy_size : max;
73#include "tcg-opc.h"
74#undef DEF
75 max *= OPC_MAX_SIZE;
76 }
77
78 return max;
79}
80
81void cpu_gen_init()
82{
83 tcg_context_init(&tcg_ctx);
84 tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
85 CPU_TEMP_BUF_NLONGS * sizeof(long));
86}
87
88/* return non zero if the very first instruction is invalid so that
89 the virtual CPU can trigger an exception.
90
91 '*gen_code_size_ptr' contains the size of the generated code (host
92 code).
93*/
94int cpu_gen_code(CPUState *env, TranslationBlock *tb,
95 int *gen_code_size_ptr)
96{
97 TCGContext *s = &tcg_ctx;
98 uint8_t *gen_code_buf;
99 int gen_code_size;
100#ifdef CONFIG_PROFILER
101 int64_t ti;
102#endif
103
104#ifdef CONFIG_PROFILER
105 s->tb_count1++; /* includes aborted translations because of
106 exceptions */
107 ti = profile_getclock();
108#endif
109
110#ifdef VBOX
111 RAWEx_ProfileStart(env, STATS_QEMU_COMPILATION);
112 tcg_func_start(s);
113
114 gen_intermediate_code(env, tb);
115#else /* !VBOX */
116 tcg_func_start(s);
117
118 gen_intermediate_code(env, tb);
119#endif /* !VBOX */
120
121 /* generate machine code */
122 gen_code_buf = tb->tc_ptr;
123 tb->tb_next_offset[0] = 0xffff;
124 tb->tb_next_offset[1] = 0xffff;
125 s->tb_next_offset = tb->tb_next_offset;
126#ifdef USE_DIRECT_JUMP
127 s->tb_jmp_offset = tb->tb_jmp_offset;
128 s->tb_next = NULL;
129 /* the following two entries are optional (only used for string ops) */
130 tb->tb_jmp_offset[2] = 0xffff;
131 tb->tb_jmp_offset[3] = 0xffff;
132#else
133 s->tb_jmp_offset = NULL;
134 s->tb_next = tb->tb_next;
135#endif
136
137#ifdef CONFIG_PROFILER
138 s->tb_count++;
139 s->interm_time += profile_getclock() - ti;
140 s->code_time -= profile_getclock();
141#endif
142
143 gen_code_size = dyngen_code(s, gen_code_buf);
144 *gen_code_size_ptr = gen_code_size;
145#ifdef CONFIG_PROFILER
146 s->code_time += profile_getclock();
147 s->code_in_len += tb->size;
148 s->code_out_len += gen_code_size;
149#endif
150
151#ifdef VBOX
152 RAWEx_ProfileStop(env, STATS_QEMU_COMPILATION);
153#endif
154
155#ifdef DEBUG_DISAS
156 if (loglevel & CPU_LOG_TB_OUT_ASM) {
157 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
158 disas(logfile, tb->tc_ptr, *gen_code_size_ptr);
159 fprintf(logfile, "\n");
160 fflush(logfile);
161 }
162#endif
163 return 0;
164}
165
166/* The cpu state corresponding to 'searched_pc' is restored.
167 */
168int cpu_restore_state(TranslationBlock *tb,
169 CPUState *env, unsigned long searched_pc,
170 void *puc)
171{
172 TCGContext *s = &tcg_ctx;
173 int j;
174 unsigned long tc_ptr;
175#ifdef CONFIG_PROFILER
176 int64_t ti;
177#endif
178
179#ifdef CONFIG_PROFILER
180 ti = profile_getclock();
181#endif
182 tcg_func_start(s);
183
184 gen_intermediate_code_pc(env, tb);
185
186 if (use_icount) {
187 /* Reset the cycle counter to the start of the block. */
188 env->icount_decr.u16.low += tb->icount;
189 /* Clear the IO flag. */
190 env->can_do_io = 0;
191 }
192
193 /* find opc index corresponding to search_pc */
194 tc_ptr = (unsigned long)tb->tc_ptr;
195 if (searched_pc < tc_ptr)
196 return -1;
197
198 s->tb_next_offset = tb->tb_next_offset;
199#ifdef USE_DIRECT_JUMP
200 s->tb_jmp_offset = tb->tb_jmp_offset;
201 s->tb_next = NULL;
202#else
203 s->tb_jmp_offset = NULL;
204 s->tb_next = tb->tb_next;
205#endif
206 j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
207 if (j < 0)
208 return -1;
209 /* now find start of instruction before */
210 while (gen_opc_instr_start[j] == 0)
211 j--;
212 env->icount_decr.u16.low -= gen_opc_icount[j];
213
214 gen_pc_load(env, tb, searched_pc, j, puc);
215
216#ifdef CONFIG_PROFILER
217 s->restore_time += profile_getclock() - ti;
218 s->restore_count++;
219#endif
220 return 0;
221}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette