Commit cf495bcf9ffe0f1450a5de7497612dd1be23ff2a

Authored by bellard
1 parent fb0eaffc

SPARC fixes: corrected PC/NPC logic (now slower but can be optimized a lot) - fi…

…xed flags computations - added register window exceptions support - fixed mul and div - added mulscc - fixed immediate field decoding


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@484 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/sparc/syscall_nr.h
... ... @@ -182,7 +182,7 @@
182 182 #define TARGET_NR_sysinfo 214 /* Linux Specific */
183 183 #define TARGET_NR_ipc 215 /* Linux Specific */
184 184 #define TARGET_NR_sigreturn 216 /* Linux Specific */
185   -#define TARGET_NR_clone 217 /* Linux Specific */
  185 +#define TARGET_NR_clone 2170 /* Linux Specific */
186 186 #define TARGET_NR_adjtimex 219 /* Linux Specific */
187 187 #define TARGET_NR_sigprocmask 220 /* Linux Specific */
188 188 #define TARGET_NR_create_module 221 /* Linux Specific */
... ...
target-sparc/cpu.h
... ... @@ -7,29 +7,42 @@
7 7  
8 8 /*#define EXCP_INTERRUPT 0x100*/
9 9  
  10 +/* trap definitions */
  11 +#define TT_ILL_INSN 0x02
  12 +#define TT_WIN_OVF 0x05
  13 +#define TT_WIN_UNF 0x06
  14 +#define TT_DIV_ZERO 0x2a
  15 +#define TT_TRAP 0x80
10 16  
11 17 #define PSR_NEG (1<<23)
12 18 #define PSR_ZERO (1<<22)
13 19 #define PSR_OVF (1<<21)
14 20 #define PSR_CARRY (1<<20)
15 21  
  22 +#define NWINDOWS 32
  23 +
16 24 typedef struct CPUSPARCState {
17   - uint32_t gregs[8]; /* general registers */
18   - uint32_t *regwptr; /* pointer to current register window */
19   - double *regfptr; /* floating point registers */
20   - uint32_t pc; /* program counter */
21   - uint32_t npc; /* next program counter */
22   - uint32_t sp; /* stack pointer */
23   - uint32_t y; /* multiply/divide register */
24   - uint32_t psr; /* processor state register */
25   - uint32_t T2;
26   - jmp_buf jmp_env;
27   - int user_mode_only;
28   - int exception_index;
29   - int interrupt_index;
30   - int interrupt_request;
31   - struct TranslationBlock *current_tb;
32   - void *opaque;
  25 + uint32_t gregs[8]; /* general registers */
  26 + uint32_t *regwptr; /* pointer to current register window */
  27 + double *regfptr; /* floating point registers */
  28 + uint32_t pc; /* program counter */
  29 + uint32_t npc; /* next program counter */
  30 + uint32_t sp; /* stack pointer */
  31 + uint32_t y; /* multiply/divide register */
  32 + uint32_t psr; /* processor state register */
  33 + uint32_t T2;
  34 + uint32_t cwp; /* index of current register window (extracted
  35 + from PSR) */
  36 + uint32_t wim; /* window invalid mask */
  37 + jmp_buf jmp_env;
  38 + int user_mode_only;
  39 + int exception_index;
  40 + int interrupt_index;
  41 + int interrupt_request;
  42 + struct TranslationBlock *current_tb;
  43 + void *opaque;
  44 + /* NOTE: we allow 8 more registers to handle wrapping */
  45 + uint32_t regbase[NWINDOWS * 16 + 8];
33 46 } CPUSPARCState;
34 47  
35 48 CPUSPARCState *cpu_sparc_init(void);
... ...
target-sparc/op.c
... ... @@ -20,7 +20,7 @@
20 20  
21 21 #include "exec.h"
22 22  
23   -/*XXX*/
  23 + /*XXX*/
24 24 #define REGNAME g0
25 25 #define REG (env->gregs[0])
26 26 #include "op_template.h"
... ... @@ -117,380 +117,545 @@
117 117 #define REGNAME o7
118 118 #define REG (env->regwptr[7])
119 119 #include "op_template.h"
120   -
121 120 #define EIP (env->pc)
122 121  
  122 +#define FLAG_SET(x) (env->psr&x)?1:0
  123 +#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
  124 +
123 125 void OPPROTO op_movl_T0_0(void)
124 126 {
125   - T0 = 0;
  127 + T0 = 0;
126 128 }
127 129  
128 130 void OPPROTO op_movl_T0_1(void)
129 131 {
130   - T0 = 1;
  132 + T0 = 1;
131 133 }
132 134  
133 135 void OPPROTO op_movl_T0_im(void)
134 136 {
135   - T0 = PARAM1;
  137 + T0 = PARAM1;
136 138 }
137 139  
138 140 void OPPROTO op_movl_T1_im(void)
139 141 {
140   - T1 = PARAM1;
  142 + T1 = PARAM1;
141 143 }
142 144  
143 145 void OPPROTO op_movl_T2_im(void)
144 146 {
145   - T2 = PARAM1;
  147 + T2 = PARAM1;
146 148 }
147 149  
148 150 void OPPROTO op_addl_T1_im(void)
149 151 {
150   - T1 += PARAM1;
  152 + T1 += PARAM1;
151 153 }
152 154  
153 155 void OPPROTO op_addl_T1_T2(void)
154 156 {
155   - T1 += T2;
  157 + T1 += T2;
156 158 }
157 159  
158 160 void OPPROTO op_subl_T1_T2(void)
159 161 {
160   - T1 -= T2;
  162 + T1 -= T2;
161 163 }
162 164  
163   -void OPPROTO op_add_T1_T0 (void)
  165 +void OPPROTO op_add_T1_T0(void)
164 166 {
165   - T0 += T1;
  167 + T0 += T1;
166 168 }
167 169  
168   -void OPPROTO op_and_T1_T0 (void)
  170 +void OPPROTO op_add_T1_T0_cc(void)
169 171 {
170   - T0 &= T1;
  172 + unsigned int src1;
  173 + src1 = T0;
  174 + T0 += T1;
  175 + env->psr = 0;
  176 + if (!T0)
  177 + env->psr |= PSR_ZERO;
  178 + if ((int) T0 < 0)
  179 + env->psr |= PSR_NEG;
  180 + if (T0 < src1)
  181 + env->psr |= PSR_CARRY;
  182 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
  183 + env->psr |= PSR_OVF;
  184 + FORCE_RET();
171 185 }
172 186  
173   -void OPPROTO op_or_T1_T0 (void)
  187 +void OPPROTO op_sub_T1_T0(void)
174 188 {
175   - T0 |= T1;
  189 + T0 -= T1;
176 190 }
177 191  
178   -void OPPROTO op_xor_T1_T0 (void)
  192 +void OPPROTO op_sub_T1_T0_cc(void)
179 193 {
180   - T0 ^= T1;
  194 + unsigned int src1;
  195 +
  196 + src1 = T0;
  197 + T0 -= T1;
  198 + env->psr = 0;
  199 + if (!T0)
  200 + env->psr |= PSR_ZERO;
  201 + if ((int) T0 < 0)
  202 + env->psr |= PSR_NEG;
  203 + if (src1 < T1)
  204 + env->psr |= PSR_CARRY;
  205 + if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
  206 + env->psr |= PSR_OVF;
  207 + FORCE_RET();
181 208 }
182 209  
183   -void OPPROTO op_sub_T1_T0 (void)
  210 +void OPPROTO op_and_T1_T0(void)
184 211 {
185   - T0 -= T1;
  212 + T0 &= T1;
186 213 }
187 214  
188   -void OPPROTO op_andn_T1_T0 (void)
  215 +void OPPROTO op_or_T1_T0(void)
189 216 {
190   - T0 &= ~T1;
  217 + T0 |= T1;
191 218 }
192 219  
193   -void OPPROTO op_orn_T1_T0 (void)
  220 +void OPPROTO op_xor_T1_T0(void)
194 221 {
195   - T0 |= ~T1;
  222 + T0 ^= T1;
196 223 }
197 224  
198   -void OPPROTO op_xnor_T1_T0 (void)
  225 +void OPPROTO op_andn_T1_T0(void)
199 226 {
200   - T0 ^= ~T1;
  227 + T0 &= ~T1;
201 228 }
202 229  
203   -void OPPROTO op_addx_T1_T0 (void)
  230 +void OPPROTO op_orn_T1_T0(void)
204 231 {
205   - T0 += T1+((env->psr & PSR_CARRY)?1:0);
  232 + T0 |= ~T1;
206 233 }
207 234  
208   -void OPPROTO op_umul_T1_T0 (void)
  235 +void OPPROTO op_xnor_T1_T0(void)
209 236 {
210   - unsigned long long res = T0*T1;
211   - T0 = res & 0xffffffff;
212   - env->y = res >> 32;
  237 + T0 ^= ~T1;
213 238 }
214 239  
215   -void OPPROTO op_smul_T1_T0 (void)
  240 +void OPPROTO op_addx_T1_T0(void)
216 241 {
217   - long long res = T0*T1;
218   - T0 = res & 0xffffffff;
219   - env->y = res >> 32;
  242 + T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
220 243 }
221 244  
222   -void OPPROTO op_udiv_T1_T0 (void)
  245 +void OPPROTO op_umul_T1_T0(void)
223 246 {
224   - unsigned long long x0 = T0 * env->y;
225   - unsigned int x1 = T1;
226   - T0 = x0 / x1;
  247 + uint64_t res;
  248 + res = (uint64_t) T0 *(uint64_t) T1;
  249 + T0 = res & 0xffffffff;
  250 + env->y = res >> 32;
227 251 }
228 252  
229   -void OPPROTO op_sdiv_T1_T0 (void)
  253 +void OPPROTO op_smul_T1_T0(void)
230 254 {
231   - long long x0 = T0 * env->y;
232   - int x1 = T1;
233   - T0 = x0 / x1;
  255 + uint64_t res;
  256 + res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
  257 + T0 = res & 0xffffffff;
  258 + env->y = res >> 32;
234 259 }
235 260  
236   -void OPPROTO op_subx_T1_T0 (void)
  261 +void OPPROTO op_mulscc_T1_T0(void)
237 262 {
238   - T0 -= T1+((env->psr & PSR_CARRY)?1:0);
  263 + unsigned int b1, C, V, b2, src1;
  264 + C = FLAG_SET(PSR_CARRY);
  265 + V = FLAG_SET(PSR_OVF);
  266 + b1 = C ^ V;
  267 + b2 = T0 & 1;
  268 + T0 = (b1 << 31) | (T0 >> 1);
  269 + if (!(env->y & 1))
  270 + T1 = 0;
  271 + /* do addition and update flags */
  272 + src1 = T0;
  273 + T0 += T1;
  274 + env->psr = 0;
  275 + if (!T0)
  276 + env->psr |= PSR_ZERO;
  277 + if ((int) T0 < 0)
  278 + env->psr |= PSR_NEG;
  279 + if (T0 < src1)
  280 + env->psr |= PSR_CARRY;
  281 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
  282 + env->psr |= PSR_OVF;
  283 + env->y = (b2 << 31) | (env->y >> 1);
  284 + FORCE_RET();
  285 +}
  286 +
  287 +void OPPROTO op_udiv_T1_T0(void)
  288 +{
  289 + uint64_t x0;
  290 + uint32_t x1;
  291 +
  292 + x0 = T0 | ((uint64_t) (env->y) << 32);
  293 + x1 = T1;
  294 + x0 = x0 / x1;
  295 + if (x0 > 0xffffffff) {
  296 + T0 = 0xffffffff;
  297 + T1 = 1;
  298 + } else {
  299 + T0 = x0;
  300 + T1 = 0;
  301 + }
  302 + FORCE_RET();
239 303 }
240 304  
241   -void OPPROTO op_set_flags (void)
  305 +void OPPROTO op_sdiv_T1_T0(void)
242 306 {
243   - env->psr = 0;
244   - if (!T0) env->psr |= PSR_ZERO;
245   - if ((unsigned int) T0 < (unsigned int) T1) env->psr |= PSR_CARRY;
246   - if ((int) T0 < (int) T1) env->psr |= PSR_OVF;
247   - if ((int) T0 < 0) env->psr |= PSR_NEG;
  307 + int64_t x0;
  308 + int32_t x1;
  309 +
  310 + x0 = T0 | ((uint64_t) (env->y) << 32);
  311 + x1 = T1;
  312 + x0 = x0 / x1;
  313 + if ((int32_t) x0 != x0) {
  314 + T0 = x0 >> 63;
  315 + T1 = 1;
  316 + } else {
  317 + T0 = x0;
  318 + T1 = 0;
  319 + }
  320 + FORCE_RET();
248 321 }
249 322  
250   -void OPPROTO op_sll (void)
  323 +void OPPROTO op_div_cc(void)
251 324 {
252   - T0 <<= T1;
  325 + env->psr = 0;
  326 + if (!T0)
  327 + env->psr |= PSR_ZERO;
  328 + if ((int) T0 < 0)
  329 + env->psr |= PSR_NEG;
  330 + if (T1)
  331 + env->psr |= PSR_OVF;
  332 + FORCE_RET();
253 333 }
254 334  
255   -void OPPROTO op_srl (void)
  335 +void OPPROTO op_subx_T1_T0(void)
256 336 {
257   - T0 >>= T1;
  337 + T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
258 338 }
259 339  
260   -void OPPROTO op_sra (void)
  340 +void OPPROTO op_logic_T0_cc(void)
261 341 {
262   - int x = T0 >> T1;
263   - T0 = x;
  342 + env->psr = 0;
  343 + if (!T0)
  344 + env->psr |= PSR_ZERO;
  345 + if ((int) T0 < 0)
  346 + env->psr |= PSR_NEG;
  347 + FORCE_RET();
264 348 }
265 349  
266   -void OPPROTO op_st (void)
  350 +void OPPROTO op_set_flags(void)
267 351 {
268   - stl ((void *) T0, T1);
  352 + env->psr = 0;
  353 + if (!T0)
  354 + env->psr |= PSR_ZERO;
  355 + if ((unsigned int) T0 < (unsigned int) T1)
  356 + env->psr |= PSR_CARRY;
  357 + if ((int) T0 < (int) T1)
  358 + env->psr |= PSR_OVF;
  359 + if ((int) T0 < 0)
  360 + env->psr |= PSR_NEG;
  361 + FORCE_RET();
269 362 }
270 363  
271   -void OPPROTO op_stb (void)
  364 +void OPPROTO op_sll(void)
272 365 {
273   - stb ((void *) T0, T1);
  366 + T0 <<= T1;
274 367 }
275 368  
276   -void OPPROTO op_sth (void)
  369 +void OPPROTO op_srl(void)
277 370 {
278   - stw ((void *) T0, T1);
  371 + T0 >>= T1;
279 372 }
280 373  
281   -void OPPROTO op_ld (void)
  374 +void OPPROTO op_sra(void)
282 375 {
283   - T1 = ldl ((void *) T0);
  376 + T0 = ((int32_t) T0) >> T1;
284 377 }
285 378  
286   -void OPPROTO op_ldub (void)
  379 +void OPPROTO op_st(void)
287 380 {
288   - T1 = ldub ((void *) T0);
  381 + stl((void *) T0, T1);
289 382 }
290 383  
291   -void OPPROTO op_lduh (void)
  384 +void OPPROTO op_stb(void)
292 385 {
293   - T1 = lduw ((void *) T0);
  386 + stb((void *) T0, T1);
294 387 }
295 388  
296   -void OPPROTO op_ldsb (void)
  389 +void OPPROTO op_sth(void)
297 390 {
298   - T1 = ldsb ((void *) T0);
  391 + stw((void *) T0, T1);
299 392 }
300 393  
301   -void OPPROTO op_ldsh (void)
  394 +void OPPROTO op_std(void)
302 395 {
303   - T1 = ldsw ((void *) T0);
  396 + stl((void *) T0, T1);
  397 + stl((void *) (T0 + 4), T2);
304 398 }
305 399  
306   -void OPPROTO op_ldstub (void)
  400 +void OPPROTO op_ld(void)
307 401 {
308   - T1 = ldub ((void *) T0);
309   - stb ((void *) T0, 0xff); /* XXX: Should be Atomically */
  402 + T1 = ldl((void *) T0);
310 403 }
311 404  
312   -void OPPROTO op_swap (void)
  405 +void OPPROTO op_ldub(void)
313 406 {
314   - unsigned int tmp = ldl ((void *) T0);
315   - stl ((void *) T0, T1); /* XXX: Should be Atomically */
316   - T1 = tmp;
  407 + T1 = ldub((void *) T0);
317 408 }
318 409  
319   -void OPPROTO op_ldd (void)
  410 +void OPPROTO op_lduh(void)
320 411 {
321   - T1 = ldl ((void *) T0);
322   - T0 = ldl ((void *) T0+4);
  412 + T1 = lduw((void *) T0);
323 413 }
324 414  
325   -void OPPROTO op_wry (void)
  415 +void OPPROTO op_ldsb(void)
326 416 {
327   - env->y = T0^T1;
  417 + T1 = ldsb((void *) T0);
328 418 }
329 419  
330   -void OPPROTO op_rdy (void)
  420 +void OPPROTO op_ldsh(void)
331 421 {
332   - T0 = env->y;
  422 + T1 = ldsw((void *) T0);
333 423 }
334 424  
335   -#define regwptr (env->regwptr)
  425 +void OPPROTO op_ldstub(void)
  426 +{
  427 + T1 = ldub((void *) T0);
  428 + stb((void *) T0, 0xff); /* XXX: Should be Atomically */
  429 +}
336 430  
337   -void OPPROTO op_save (void)
  431 +void OPPROTO op_swap(void)
338 432 {
339   - regwptr -= 16;
  433 + unsigned int tmp = ldl((void *) T0);
  434 + stl((void *) T0, T1); /* XXX: Should be Atomically */
  435 + T1 = tmp;
340 436 }
341 437  
342   -void OPPROTO op_restore (void)
  438 +void OPPROTO op_ldd(void)
343 439 {
344   - regwptr += 16;
  440 + T1 = ldl((void *) T0);
  441 + T0 = ldl((void *) (T0 + 4));
345 442 }
346 443  
347   -void OPPROTO op_trap (void)
  444 +void OPPROTO op_wry(void)
348 445 {
349   - env->exception_index = PARAM1;
350   - cpu_loop_exit ();
  446 + env->y = T0;
351 447 }
352 448  
353   -void OPPROTO op_exit_tb (void)
  449 +void OPPROTO op_rdy(void)
354 450 {
355   - EXIT_TB ();
  451 + T0 = env->y;
356 452 }
357 453  
358   -void OPPROTO op_eval_be (void)
  454 +void raise_exception(int tt)
  455 +{
  456 + env->exception_index = tt;
  457 + cpu_loop_exit();
  458 +}
  459 +
  460 +void memcpy32(uint32_t *dst, const uint32_t *src)
359 461 {
360   - T0 = (env->psr & PSR_ZERO);
  462 + dst[0] = src[0];
  463 + dst[1] = src[1];
  464 + dst[2] = src[2];
  465 + dst[3] = src[3];
  466 + dst[4] = src[4];
  467 + dst[5] = src[5];
  468 + dst[6] = src[6];
  469 + dst[7] = src[7];
361 470 }
362 471  
363   -#define FLAG_SET(x) (env->psr&x)?1:0
364   -#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
  472 +static inline void set_cwp(int new_cwp)
  473 +{
  474 + /* put the modified wrap registers at their proper location */
  475 + if (env->cwp == (NWINDOWS - 1))
  476 + memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
  477 + env->cwp = new_cwp;
  478 + /* put the wrap registers at their temporary location */
  479 + if (new_cwp == (NWINDOWS - 1))
  480 + memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
  481 + env->regwptr = env->regbase + (new_cwp * 16);
  482 +}
365 483  
366   -void OPPROTO op_eval_ble (void)
  484 +/* XXX: use another pointer for %iN registers to avoid slow wrapping
  485 + handling ? */
  486 +void OPPROTO op_save(void)
367 487 {
368   - GET_FLAGS;
369   - T0 = Z | (N^V);
  488 + int cwp;
  489 + cwp = (env->cwp - 1) & (NWINDOWS - 1);
  490 + if (env->wim & (1 << cwp)) {
  491 + raise_exception(TT_WIN_OVF);
  492 + }
  493 + set_cwp(cwp);
  494 + FORCE_RET();
370 495 }
371 496  
372   -void OPPROTO op_eval_bl (void)
  497 +void OPPROTO op_restore(void)
373 498 {
374   - GET_FLAGS;
375   - T0 = N^V;
  499 + int cwp;
  500 + cwp = (env->cwp + 1) & (NWINDOWS - 1);
  501 + if (env->wim & (1 << cwp)) {
  502 + raise_exception(TT_WIN_UNF);
  503 + }
  504 + set_cwp(cwp);
  505 + FORCE_RET();
376 506 }
377 507  
378   -void OPPROTO op_eval_bleu (void)
  508 +void OPPROTO op_exception(void)
379 509 {
380   - GET_FLAGS;
381   - T0 = C|Z;
  510 + env->exception_index = PARAM1;
  511 + cpu_loop_exit();
382 512 }
383 513  
384   -void OPPROTO op_eval_bcs (void)
  514 +void OPPROTO op_trap_T0(void)
385 515 {
386   - T0 = (env->psr & PSR_CARRY);
  516 + env->exception_index = TT_TRAP + (T0 & 0x7f);
  517 + cpu_loop_exit();
387 518 }
388 519  
389   -void OPPROTO op_eval_bvs (void)
  520 +void OPPROTO op_trapcc_T0(void)
390 521 {
391   - T0 = (env->psr & PSR_OVF);
  522 + if (T2) {
  523 + env->exception_index = TT_TRAP + (T0 & 0x7f);
  524 + cpu_loop_exit();
  525 + }
  526 + FORCE_RET();
392 527 }
393 528  
394   -void OPPROTO op_eval_bneg (void)
  529 +void OPPROTO op_exit_tb(void)
395 530 {
396   - T0 = (env->psr & PSR_NEG);
  531 + EXIT_TB();
397 532 }
398 533  
399   -void OPPROTO op_eval_bne (void)
  534 +void OPPROTO op_eval_be(void)
400 535 {
401   - T0 = !(env->psr & PSR_ZERO);
  536 + T2 = (env->psr & PSR_ZERO);
402 537 }
403 538  
404   -void OPPROTO op_eval_bg (void)
  539 +void OPPROTO op_eval_ble(void)
405 540 {
406   - GET_FLAGS;
407   - T0 = !(Z | (N^V));
  541 + GET_FLAGS;
  542 + T2 = Z | (N ^ V);
408 543 }
409 544  
410   -/*XXX: This seems to be documented wrong in the SPARC V8 Manual
411   - The manual states: !(N^V)
412   - but I assume Z | !(N^V) to be correct */
413   -void OPPROTO op_eval_bge (void)
  545 +void OPPROTO op_eval_bl(void)
414 546 {
415   - GET_FLAGS;
416   - T0 = Z | !(N^V);
  547 + GET_FLAGS;
  548 + T2 = N ^ V;
417 549 }
418 550  
419   -void OPPROTO op_eval_bgu (void)
  551 +void OPPROTO op_eval_bleu(void)
420 552 {
421   - GET_FLAGS;
422   - T0 = !(C | Z);
  553 + GET_FLAGS;
  554 + T2 = C | Z;
423 555 }
424 556  
425   -void OPPROTO op_eval_bcc (void)
  557 +void OPPROTO op_eval_bcs(void)
426 558 {
427   - T0 = !(env->psr & PSR_CARRY);
  559 + T2 = (env->psr & PSR_CARRY);
428 560 }
429 561  
430   -void OPPROTO op_eval_bpos (void)
  562 +void OPPROTO op_eval_bvs(void)
431 563 {
432   - T0 = !(env->psr & PSR_NEG);
  564 + T2 = (env->psr & PSR_OVF);
433 565 }
434 566  
435   -void OPPROTO op_eval_bvc (void)
  567 +void OPPROTO op_eval_bneg(void)
436 568 {
437   - T0 = !(env->psr & PSR_OVF);
  569 + T2 = (env->psr & PSR_NEG);
438 570 }
439 571  
440   -void OPPROTO op_jmp_im (void)
  572 +void OPPROTO op_eval_bne(void)
441 573 {
442   - env->pc = PARAM1;
  574 + T2 = !(env->psr & PSR_ZERO);
443 575 }
444 576  
445   -void OPPROTO op_call (void)
  577 +void OPPROTO op_eval_bg(void)
446 578 {
447   - regwptr[7] = PARAM1-4;
448   - env->pc = PARAM1+PARAM2;
  579 + GET_FLAGS;
  580 + T2 = !(Z | (N ^ V));
449 581 }
450 582  
451   -void OPPROTO op_jmpl (void)
  583 +void OPPROTO op_eval_bge(void)
452 584 {
453   - env->npc = T0;
  585 + GET_FLAGS;
  586 + T2 = !(N ^ V);
454 587 }
455 588  
456   -void OPPROTO op_generic_jmp_1 (void)
  589 +void OPPROTO op_eval_bgu(void)
457 590 {
458   - T1 = PARAM1;
459   - env->pc = PARAM1+PARAM2;
  591 + GET_FLAGS;
  592 + T2 = !(C | Z);
460 593 }
461 594  
462   -void OPPROTO op_generic_jmp_2 (void)
  595 +void OPPROTO op_eval_bcc(void)
463 596 {
464   - T1 = PARAM1;
465   - env->pc = env->npc;
  597 + T2 = !(env->psr & PSR_CARRY);
466 598 }
467 599  
468   -unsigned long old_T0;
  600 +void OPPROTO op_eval_bpos(void)
  601 +{
  602 + T2 = !(env->psr & PSR_NEG);
  603 +}
  604 +
  605 +void OPPROTO op_eval_bvc(void)
  606 +{
  607 + T2 = !(env->psr & PSR_OVF);
  608 +}
  609 +
  610 +void OPPROTO op_movl_T2_0(void)
  611 +{
  612 + T2 = 0;
  613 +}
  614 +
  615 +void OPPROTO op_movl_T2_1(void)
  616 +{
  617 + T2 = 1;
  618 +}
  619 +
  620 +void OPPROTO op_jmp_im(void)
  621 +{
  622 + env->pc = PARAM1;
  623 +}
  624 +
  625 +void OPPROTO op_movl_npc_im(void)
  626 +{
  627 + env->npc = PARAM1;
  628 +}
469 629  
470   -void OPPROTO op_save_T0 (void)
  630 +void OPPROTO op_movl_npc_T0(void)
471 631 {
472   - old_T0 = T0;
  632 + env->npc = T0;
473 633 }
474 634  
475   -void OPPROTO op_restore_T0 (void)
  635 +void OPPROTO op_next_insn(void)
476 636 {
477   - T0 = old_T0;
  637 + env->pc = env->npc;
  638 + env->npc = env->npc + 4;
478 639 }
479 640  
480   -void OPPROTO op_generic_branch (void)
  641 +void OPPROTO op_generic_branch(void)
481 642 {
482   - if (T0)
483   - JUMP_TB (op_generic_branch, PARAM1, 0, PARAM2);
484   - else
485   - JUMP_TB (op_generic_branch, PARAM1, 1, PARAM3);
486   - FORCE_RET ();
  643 + if (T2) {
  644 + env->npc = PARAM1;
  645 + } else {
  646 + env->npc = PARAM2;
  647 + }
  648 + FORCE_RET();
487 649 }
488 650  
489   -void OPPROTO op_generic_branch_a (void)
  651 +void OPPROTO op_generic_branch_a(void)
490 652 {
491   - if (T0)
492   - env->npc = PARAM3;
493   - else
494   - JUMP_TB (op_generic_branch_a, PARAM1, 0, PARAM2);
495   - FORCE_RET ();
  653 + if (T2) {
  654 + env->pc = PARAM2;
  655 + env->npc = PARAM1;
  656 + } else {
  657 + env->pc = PARAM2 + 4;
  658 + env->npc = PARAM2 + 8;
  659 + }
  660 + FORCE_RET();
496 661 }
... ...
target-sparc/translate.c
... ... @@ -34,18 +34,13 @@
34 34 and the 'anull' bit in the branch instruction opcode is set. This is
35 35 currently solved by doing a jump after the delay slot instruction.
36 36  
37   - There is also one big (currently unsolved) bug in the branch code:
38   - If a delay slot modifies the condition codes then the new condition
39   - codes, instead of the old ones will be used.
40   -
41 37 TODO-list:
42 38  
  39 + Register window overflow/underflow check
43 40 FPU-Instructions
44 41 Coprocessor-Instructions
45   - Fix above bug
46 42 Check signedness issues
47 43 Privileged instructions
48   - Register window overflow/underflow check
49 44 Optimize synthetic instructions
50 45 Optional alignment and privileged instruction check
51 46  
... ... @@ -65,14 +60,10 @@
65 60 #define DEBUG_DISAS
66 61  
67 62 typedef struct DisasContext {
68   - uint8_t *pc;
69   - uint8_t *npc;
70   - void (*branch) (struct DisasContext *, uint32_t, uint32_t);
71   - unsigned int delay_slot:2;
72   - uint32_t insn;
73   - uint32_t target;
74   - int is_br;
75   - struct TranslationBlock *tb;
  63 + uint8_t *pc; /* NULL means dynamic value */
  64 + uint8_t *npc; /* NULL means dynamic value */
  65 + int is_br;
  66 + struct TranslationBlock *tb;
76 67 } DisasContext;
77 68  
78 69 static uint16_t *gen_opc_ptr;
... ... @@ -84,7 +75,7 @@ enum {
84 75 #define DEF(s,n,copy_size) INDEX_op_ ## s,
85 76 #include "opc.h"
86 77 #undef DEF
87   - NB_OPS
  78 + NB_OPS
88 79 };
89 80  
90 81 #include "gen-op.h"
... ... @@ -94,651 +85,781 @@ enum {
94 85  
95 86 #define IS_IMM (insn & (1<<13))
96 87  
97   -static void disas_sparc_insn (DisasContext *dc);
  88 +static void disas_sparc_insn(DisasContext * dc);
98 89  
99   -typedef void (GenOpFunc)(void);
100   -typedef void (GenOpFunc1)(long);
101   -typedef void (GenOpFunc2)(long, long);
102   -typedef void (GenOpFunc3)(long, long, long);
  90 +typedef void (GenOpFunc) (void);
  91 +typedef void (GenOpFunc1) (long);
  92 +typedef void (GenOpFunc2) (long, long);
  93 +typedef void (GenOpFunc3) (long, long, long);
103 94  
104 95 static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
105   - {
106   - gen_op_movl_g0_T0,
107   - gen_op_movl_g1_T0,
108   - gen_op_movl_g2_T0,
109   - gen_op_movl_g3_T0,
110   - gen_op_movl_g4_T0,
111   - gen_op_movl_g5_T0,
112   - gen_op_movl_g6_T0,
113   - gen_op_movl_g7_T0,
114   - gen_op_movl_o0_T0,
115   - gen_op_movl_o1_T0,
116   - gen_op_movl_o2_T0,
117   - gen_op_movl_o3_T0,
118   - gen_op_movl_o4_T0,
119   - gen_op_movl_o5_T0,
120   - gen_op_movl_o6_T0,
121   - gen_op_movl_o7_T0,
122   - gen_op_movl_l0_T0,
123   - gen_op_movl_l1_T0,
124   - gen_op_movl_l2_T0,
125   - gen_op_movl_l3_T0,
126   - gen_op_movl_l4_T0,
127   - gen_op_movl_l5_T0,
128   - gen_op_movl_l6_T0,
129   - gen_op_movl_l7_T0,
130   - gen_op_movl_i0_T0,
131   - gen_op_movl_i1_T0,
132   - gen_op_movl_i2_T0,
133   - gen_op_movl_i3_T0,
134   - gen_op_movl_i4_T0,
135   - gen_op_movl_i5_T0,
136   - gen_op_movl_i6_T0,
137   - gen_op_movl_i7_T0,
138   - },
139   - {
140   - gen_op_movl_g0_T1,
141   - gen_op_movl_g1_T1,
142   - gen_op_movl_g2_T1,
143   - gen_op_movl_g3_T1,
144   - gen_op_movl_g4_T1,
145   - gen_op_movl_g5_T1,
146   - gen_op_movl_g6_T1,
147   - gen_op_movl_g7_T1,
148   - gen_op_movl_o0_T1,
149   - gen_op_movl_o1_T1,
150   - gen_op_movl_o2_T1,
151   - gen_op_movl_o3_T1,
152   - gen_op_movl_o4_T1,
153   - gen_op_movl_o5_T1,
154   - gen_op_movl_o6_T1,
155   - gen_op_movl_o7_T1,
156   - gen_op_movl_l0_T1,
157   - gen_op_movl_l1_T1,
158   - gen_op_movl_l2_T1,
159   - gen_op_movl_l3_T1,
160   - gen_op_movl_l4_T1,
161   - gen_op_movl_l5_T1,
162   - gen_op_movl_l6_T1,
163   - gen_op_movl_l7_T1,
164   - gen_op_movl_i0_T1,
165   - gen_op_movl_i1_T1,
166   - gen_op_movl_i2_T1,
167   - gen_op_movl_i3_T1,
168   - gen_op_movl_i4_T1,
169   - gen_op_movl_i5_T1,
170   - gen_op_movl_i6_T1,
171   - gen_op_movl_i7_T1,
172   - }
  96 + {
  97 + gen_op_movl_g0_T0,
  98 + gen_op_movl_g1_T0,
  99 + gen_op_movl_g2_T0,
  100 + gen_op_movl_g3_T0,
  101 + gen_op_movl_g4_T0,
  102 + gen_op_movl_g5_T0,
  103 + gen_op_movl_g6_T0,
  104 + gen_op_movl_g7_T0,
  105 + gen_op_movl_o0_T0,
  106 + gen_op_movl_o1_T0,
  107 + gen_op_movl_o2_T0,
  108 + gen_op_movl_o3_T0,
  109 + gen_op_movl_o4_T0,
  110 + gen_op_movl_o5_T0,
  111 + gen_op_movl_o6_T0,
  112 + gen_op_movl_o7_T0,
  113 + gen_op_movl_l0_T0,
  114 + gen_op_movl_l1_T0,
  115 + gen_op_movl_l2_T0,
  116 + gen_op_movl_l3_T0,
  117 + gen_op_movl_l4_T0,
  118 + gen_op_movl_l5_T0,
  119 + gen_op_movl_l6_T0,
  120 + gen_op_movl_l7_T0,
  121 + gen_op_movl_i0_T0,
  122 + gen_op_movl_i1_T0,
  123 + gen_op_movl_i2_T0,
  124 + gen_op_movl_i3_T0,
  125 + gen_op_movl_i4_T0,
  126 + gen_op_movl_i5_T0,
  127 + gen_op_movl_i6_T0,
  128 + gen_op_movl_i7_T0,
  129 + },
  130 + {
  131 + gen_op_movl_g0_T1,
  132 + gen_op_movl_g1_T1,
  133 + gen_op_movl_g2_T1,
  134 + gen_op_movl_g3_T1,
  135 + gen_op_movl_g4_T1,
  136 + gen_op_movl_g5_T1,
  137 + gen_op_movl_g6_T1,
  138 + gen_op_movl_g7_T1,
  139 + gen_op_movl_o0_T1,
  140 + gen_op_movl_o1_T1,
  141 + gen_op_movl_o2_T1,
  142 + gen_op_movl_o3_T1,
  143 + gen_op_movl_o4_T1,
  144 + gen_op_movl_o5_T1,
  145 + gen_op_movl_o6_T1,
  146 + gen_op_movl_o7_T1,
  147 + gen_op_movl_l0_T1,
  148 + gen_op_movl_l1_T1,
  149 + gen_op_movl_l2_T1,
  150 + gen_op_movl_l3_T1,
  151 + gen_op_movl_l4_T1,
  152 + gen_op_movl_l5_T1,
  153 + gen_op_movl_l6_T1,
  154 + gen_op_movl_l7_T1,
  155 + gen_op_movl_i0_T1,
  156 + gen_op_movl_i1_T1,
  157 + gen_op_movl_i2_T1,
  158 + gen_op_movl_i3_T1,
  159 + gen_op_movl_i4_T1,
  160 + gen_op_movl_i5_T1,
  161 + gen_op_movl_i6_T1,
  162 + gen_op_movl_i7_T1,
  163 + }
173 164 };
174 165  
175 166 static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
176   - {
177   - gen_op_movl_T0_g0,
178   - gen_op_movl_T0_g1,
179   - gen_op_movl_T0_g2,
180   - gen_op_movl_T0_g3,
181   - gen_op_movl_T0_g4,
182   - gen_op_movl_T0_g5,
183   - gen_op_movl_T0_g6,
184   - gen_op_movl_T0_g7,
185   - gen_op_movl_T0_o0,
186   - gen_op_movl_T0_o1,
187   - gen_op_movl_T0_o2,
188   - gen_op_movl_T0_o3,
189   - gen_op_movl_T0_o4,
190   - gen_op_movl_T0_o5,
191   - gen_op_movl_T0_o6,
192   - gen_op_movl_T0_o7,
193   - gen_op_movl_T0_l0,
194   - gen_op_movl_T0_l1,
195   - gen_op_movl_T0_l2,
196   - gen_op_movl_T0_l3,
197   - gen_op_movl_T0_l4,
198   - gen_op_movl_T0_l5,
199   - gen_op_movl_T0_l6,
200   - gen_op_movl_T0_l7,
201   - gen_op_movl_T0_i0,
202   - gen_op_movl_T0_i1,
203   - gen_op_movl_T0_i2,
204   - gen_op_movl_T0_i3,
205   - gen_op_movl_T0_i4,
206   - gen_op_movl_T0_i5,
207   - gen_op_movl_T0_i6,
208   - gen_op_movl_T0_i7,
209   - },
210   - {
211   - gen_op_movl_T1_g0,
212   - gen_op_movl_T1_g1,
213   - gen_op_movl_T1_g2,
214   - gen_op_movl_T1_g3,
215   - gen_op_movl_T1_g4,
216   - gen_op_movl_T1_g5,
217   - gen_op_movl_T1_g6,
218   - gen_op_movl_T1_g7,
219   - gen_op_movl_T1_o0,
220   - gen_op_movl_T1_o1,
221   - gen_op_movl_T1_o2,
222   - gen_op_movl_T1_o3,
223   - gen_op_movl_T1_o4,
224   - gen_op_movl_T1_o5,
225   - gen_op_movl_T1_o6,
226   - gen_op_movl_T1_o7,
227   - gen_op_movl_T1_l0,
228   - gen_op_movl_T1_l1,
229   - gen_op_movl_T1_l2,
230   - gen_op_movl_T1_l3,
231   - gen_op_movl_T1_l4,
232   - gen_op_movl_T1_l5,
233   - gen_op_movl_T1_l6,
234   - gen_op_movl_T1_l7,
235   - gen_op_movl_T1_i0,
236   - gen_op_movl_T1_i1,
237   - gen_op_movl_T1_i2,
238   - gen_op_movl_T1_i3,
239   - gen_op_movl_T1_i4,
240   - gen_op_movl_T1_i5,
241   - gen_op_movl_T1_i6,
242   - gen_op_movl_T1_i7,
243   - },
244   - {
245   - gen_op_movl_T2_g0,
246   - gen_op_movl_T2_g1,
247   - gen_op_movl_T2_g2,
248   - gen_op_movl_T2_g3,
249   - gen_op_movl_T2_g4,
250   - gen_op_movl_T2_g5,
251   - gen_op_movl_T2_g6,
252   - gen_op_movl_T2_g7,
253   - gen_op_movl_T2_o0,
254   - gen_op_movl_T2_o1,
255   - gen_op_movl_T2_o2,
256   - gen_op_movl_T2_o3,
257   - gen_op_movl_T2_o4,
258   - gen_op_movl_T2_o5,
259   - gen_op_movl_T2_o6,
260   - gen_op_movl_T2_o7,
261   - gen_op_movl_T2_l0,
262   - gen_op_movl_T2_l1,
263   - gen_op_movl_T2_l2,
264   - gen_op_movl_T2_l3,
265   - gen_op_movl_T2_l4,
266   - gen_op_movl_T2_l5,
267   - gen_op_movl_T2_l6,
268   - gen_op_movl_T2_l7,
269   - gen_op_movl_T2_i0,
270   - gen_op_movl_T2_i1,
271   - gen_op_movl_T2_i2,
272   - gen_op_movl_T2_i3,
273   - gen_op_movl_T2_i4,
274   - gen_op_movl_T2_i5,
275   - gen_op_movl_T2_i6,
276   - gen_op_movl_T2_i7,
277   - }
  167 + {
  168 + gen_op_movl_T0_g0,
  169 + gen_op_movl_T0_g1,
  170 + gen_op_movl_T0_g2,
  171 + gen_op_movl_T0_g3,
  172 + gen_op_movl_T0_g4,
  173 + gen_op_movl_T0_g5,
  174 + gen_op_movl_T0_g6,
  175 + gen_op_movl_T0_g7,
  176 + gen_op_movl_T0_o0,
  177 + gen_op_movl_T0_o1,
  178 + gen_op_movl_T0_o2,
  179 + gen_op_movl_T0_o3,
  180 + gen_op_movl_T0_o4,
  181 + gen_op_movl_T0_o5,
  182 + gen_op_movl_T0_o6,
  183 + gen_op_movl_T0_o7,
  184 + gen_op_movl_T0_l0,
  185 + gen_op_movl_T0_l1,
  186 + gen_op_movl_T0_l2,
  187 + gen_op_movl_T0_l3,
  188 + gen_op_movl_T0_l4,
  189 + gen_op_movl_T0_l5,
  190 + gen_op_movl_T0_l6,
  191 + gen_op_movl_T0_l7,
  192 + gen_op_movl_T0_i0,
  193 + gen_op_movl_T0_i1,
  194 + gen_op_movl_T0_i2,
  195 + gen_op_movl_T0_i3,
  196 + gen_op_movl_T0_i4,
  197 + gen_op_movl_T0_i5,
  198 + gen_op_movl_T0_i6,
  199 + gen_op_movl_T0_i7,
  200 + },
  201 + {
  202 + gen_op_movl_T1_g0,
  203 + gen_op_movl_T1_g1,
  204 + gen_op_movl_T1_g2,
  205 + gen_op_movl_T1_g3,
  206 + gen_op_movl_T1_g4,
  207 + gen_op_movl_T1_g5,
  208 + gen_op_movl_T1_g6,
  209 + gen_op_movl_T1_g7,
  210 + gen_op_movl_T1_o0,
  211 + gen_op_movl_T1_o1,
  212 + gen_op_movl_T1_o2,
  213 + gen_op_movl_T1_o3,
  214 + gen_op_movl_T1_o4,
  215 + gen_op_movl_T1_o5,
  216 + gen_op_movl_T1_o6,
  217 + gen_op_movl_T1_o7,
  218 + gen_op_movl_T1_l0,
  219 + gen_op_movl_T1_l1,
  220 + gen_op_movl_T1_l2,
  221 + gen_op_movl_T1_l3,
  222 + gen_op_movl_T1_l4,
  223 + gen_op_movl_T1_l5,
  224 + gen_op_movl_T1_l6,
  225 + gen_op_movl_T1_l7,
  226 + gen_op_movl_T1_i0,
  227 + gen_op_movl_T1_i1,
  228 + gen_op_movl_T1_i2,
  229 + gen_op_movl_T1_i3,
  230 + gen_op_movl_T1_i4,
  231 + gen_op_movl_T1_i5,
  232 + gen_op_movl_T1_i6,
  233 + gen_op_movl_T1_i7,
  234 + },
  235 + {
  236 + gen_op_movl_T2_g0,
  237 + gen_op_movl_T2_g1,
  238 + gen_op_movl_T2_g2,
  239 + gen_op_movl_T2_g3,
  240 + gen_op_movl_T2_g4,
  241 + gen_op_movl_T2_g5,
  242 + gen_op_movl_T2_g6,
  243 + gen_op_movl_T2_g7,
  244 + gen_op_movl_T2_o0,
  245 + gen_op_movl_T2_o1,
  246 + gen_op_movl_T2_o2,
  247 + gen_op_movl_T2_o3,
  248 + gen_op_movl_T2_o4,
  249 + gen_op_movl_T2_o5,
  250 + gen_op_movl_T2_o6,
  251 + gen_op_movl_T2_o7,
  252 + gen_op_movl_T2_l0,
  253 + gen_op_movl_T2_l1,
  254 + gen_op_movl_T2_l2,
  255 + gen_op_movl_T2_l3,
  256 + gen_op_movl_T2_l4,
  257 + gen_op_movl_T2_l5,
  258 + gen_op_movl_T2_l6,
  259 + gen_op_movl_T2_l7,
  260 + gen_op_movl_T2_i0,
  261 + gen_op_movl_T2_i1,
  262 + gen_op_movl_T2_i2,
  263 + gen_op_movl_T2_i3,
  264 + gen_op_movl_T2_i4,
  265 + gen_op_movl_T2_i5,
  266 + gen_op_movl_T2_i6,
  267 + gen_op_movl_T2_i7,
  268 + }
278 269 };
279 270  
280 271 static GenOpFunc1 *gen_op_movl_TN_im[3] = {
281   - gen_op_movl_T0_im,
282   - gen_op_movl_T1_im,
283   - gen_op_movl_T2_im
  272 + gen_op_movl_T0_im,
  273 + gen_op_movl_T1_im,
  274 + gen_op_movl_T2_im
284 275 };
285 276  
286   -static inline void gen_movl_imm_TN (int reg, int imm)
  277 +static inline void gen_movl_imm_TN(int reg, int imm)
287 278 {
288   - gen_op_movl_TN_im[reg](imm);
  279 + gen_op_movl_TN_im[reg] (imm);
289 280 }
290 281  
291   -static inline void gen_movl_imm_T1 (int val)
  282 +static inline void gen_movl_imm_T1(int val)
292 283 {
293   - gen_movl_imm_TN (1, val);
  284 + gen_movl_imm_TN(1, val);
294 285 }
295 286  
296   -static inline void gen_movl_imm_T0 (int val)
  287 +static inline void gen_movl_imm_T0(int val)
297 288 {
298   - gen_movl_imm_TN (0, val);
  289 + gen_movl_imm_TN(0, val);
299 290 }
300 291  
301   -static inline void gen_movl_reg_TN (int reg, int t)
  292 +static inline void gen_movl_reg_TN(int reg, int t)
302 293 {
303   - if (reg) gen_op_movl_reg_TN[t][reg]();
304   - else gen_movl_imm_TN (t, 0);
  294 + if (reg)
  295 + gen_op_movl_reg_TN[t][reg] ();
  296 + else
  297 + gen_movl_imm_TN(t, 0);
305 298 }
306 299  
307   -static inline void gen_movl_reg_T0 (int reg)
  300 +static inline void gen_movl_reg_T0(int reg)
308 301 {
309   - gen_movl_reg_TN (reg, 0);
  302 + gen_movl_reg_TN(reg, 0);
310 303 }
311 304  
312   -static inline void gen_movl_reg_T1 (int reg)
  305 +static inline void gen_movl_reg_T1(int reg)
313 306 {
314   - gen_movl_reg_TN (reg, 1);
  307 + gen_movl_reg_TN(reg, 1);
315 308 }
316 309  
317   -static inline void gen_movl_reg_T2 (int reg)
  310 +static inline void gen_movl_reg_T2(int reg)
318 311 {
319   - gen_movl_reg_TN (reg, 2);
  312 + gen_movl_reg_TN(reg, 2);
320 313 }
321 314  
322   -static inline void gen_movl_TN_reg (int reg, int t)
  315 +static inline void gen_movl_TN_reg(int reg, int t)
323 316 {
324   - if (reg) gen_op_movl_TN_reg[t][reg]();
  317 + if (reg)
  318 + gen_op_movl_TN_reg[t][reg] ();
325 319 }
326 320  
327   -static inline void gen_movl_T0_reg (int reg)
  321 +static inline void gen_movl_T0_reg(int reg)
328 322 {
329   - gen_movl_TN_reg (reg, 0);
  323 + gen_movl_TN_reg(reg, 0);
330 324 }
331 325  
332   -static inline void gen_movl_T1_reg (int reg)
  326 +static inline void gen_movl_T1_reg(int reg)
333 327 {
334   - gen_movl_TN_reg (reg, 1);
  328 + gen_movl_TN_reg(reg, 1);
335 329 }
336 330  
337   -static void do_branch (DisasContext *dc, uint32_t target, uint32_t insn)
  331 +static void gen_cond(int cond)
338 332 {
339   - unsigned int cond = GET_FIELD (insn, 3, 6), a = (insn & (1<<29)), ib = 0;
340   - target += (uint32_t) dc->pc-4;
341   - if (!a) disas_sparc_insn (dc);
342 333 switch (cond) {
343   - case 0x0: gen_op_movl_T0_0 (); break;
344   - case 0x1: gen_op_eval_be (); break;
345   - case 0x2: gen_op_eval_ble (); break;
346   - case 0x3: gen_op_eval_bl (); break;
347   - case 0x4: gen_op_eval_bleu (); break;
348   - case 0x5: gen_op_eval_bcs (); break;
349   - case 0x6: gen_op_eval_bneg (); break;
350   - case 0x7: gen_op_eval_bvs (); break;
351   - case 0x8: gen_op_movl_T0_1 (); break;
352   - case 0x9: gen_op_eval_bne (); break;
353   - case 0xa: gen_op_eval_bg (); break;
354   - case 0xb: gen_op_eval_bge (); break;
355   - case 0xc: gen_op_eval_bgu (); break;
356   - case 0xd: gen_op_eval_bcc (); break;
357   - case 0xe: gen_op_eval_bpos (); break;
358   - case 0xf: gen_op_eval_bvc (); break;
359   - }
360   - if (a && ((cond|0x8) != 0x8)) {
361   - gen_op_generic_branch_a ((uint32_t) dc->tb,
362   - (uint32_t) dc->pc+4, target);
363   - disas_sparc_insn (dc);
364   - ib = 1;
  334 + case 0x0:
  335 + gen_op_movl_T2_0();
  336 + break;
  337 + case 0x1:
  338 + gen_op_eval_be();
  339 + break;
  340 + case 0x2:
  341 + gen_op_eval_ble();
  342 + break;
  343 + case 0x3:
  344 + gen_op_eval_bl();
  345 + break;
  346 + case 0x4:
  347 + gen_op_eval_bleu();
  348 + break;
  349 + case 0x5:
  350 + gen_op_eval_bcs();
  351 + break;
  352 + case 0x6:
  353 + gen_op_eval_bneg();
  354 + break;
  355 + case 0x7:
  356 + gen_op_eval_bvs();
  357 + break;
  358 + case 0x8:
  359 + gen_op_movl_T2_1();
  360 + break;
  361 + case 0x9:
  362 + gen_op_eval_bne();
  363 + break;
  364 + case 0xa:
  365 + gen_op_eval_bg();
  366 + break;
  367 + case 0xb:
  368 + gen_op_eval_bge();
  369 + break;
  370 + case 0xc:
  371 + gen_op_eval_bgu();
  372 + break;
  373 + case 0xd:
  374 + gen_op_eval_bcc();
  375 + break;
  376 + case 0xe:
  377 + gen_op_eval_bpos();
  378 + break;
  379 + default:
  380 + case 0xf:
  381 + gen_op_eval_bvc();
  382 + break;
365 383 }
366   - else
367   - if (cond && !a) {
368   - gen_op_generic_branch ((uint32_t) dc->tb, (uint32_t) target,
369   - (uint32_t) dc->pc);
370   - ib = 1;
371   - }
372   - if (ib) dc->is_br = DISAS_JUMP;
373 384 }
374 385  
375   -/* target == 0x1 means CALL- else JMPL-instruction */
376   -static void do_jump (DisasContext *dc, uint32_t target, uint32_t rd)
  386 +
  387 +static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
377 388 {
378   - uint32_t orig_pc = (uint32_t) dc->pc-8;
379   - if (target != 0x1)
380   - gen_op_generic_jmp_1 (orig_pc, target);
381   - else
382   - gen_op_generic_jmp_2 (orig_pc);
383   - gen_movl_T1_reg (rd);
384   - dc->is_br = DISAS_JUMP;
385   - gen_op_movl_T0_0 ();
  389 + unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
  390 + target += (uint32_t) dc->pc;
  391 + if (cond == 0x0) {
  392 + /* unconditional not taken */
  393 + if (a) {
  394 + dc->pc = dc->npc + 4;
  395 + dc->npc = dc->pc + 4;
  396 + } else {
  397 + dc->pc = dc->npc;
  398 + dc->npc = dc->pc + 4;
  399 + }
  400 + } else if (cond == 0x8) {
  401 + /* unconditional taken */
  402 + if (a) {
  403 + dc->pc = (uint8_t *) target;
  404 + dc->npc = dc->pc + 4;
  405 + } else {
  406 + dc->pc = dc->npc;
  407 + dc->npc = (uint8_t *) target;
  408 + }
  409 + } else {
  410 + gen_cond(cond);
  411 + if (a) {
  412 + gen_op_generic_branch_a((uint32_t) target,
  413 + (uint32_t) (dc->npc));
  414 + dc->is_br = 1;
  415 + dc->pc = NULL;
  416 + dc->npc = NULL;
  417 + } else {
  418 + dc->pc = dc->npc;
  419 + gen_op_generic_branch((uint32_t) target,
  420 + (uint32_t) (dc->npc + 4));
  421 + dc->npc = NULL;
  422 + }
  423 + }
386 424 }
387 425  
388   -#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), b-a)
  426 +#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
389 427  
390   -static int
391   -sign_extend (x, len)
392   - int x, len;
  428 +static int sign_extend(int x, int len)
393 429 {
394   - int signbit = (1 << (len - 1));
395   - int mask = (signbit << 1) - 1;
396   - return ((x & mask) ^ signbit) - signbit;
  430 + len = 32 - len;
  431 + return (x << len) >> len;
397 432 }
398 433  
399   -static void disas_sparc_insn (DisasContext *dc)
  434 +static inline void save_state(DisasContext * dc)
400 435 {
401   - unsigned int insn, opc, rs1, rs2, rd;
  436 + gen_op_jmp_im((uint32_t)dc->pc);
  437 + if (dc->npc != NULL)
  438 + gen_op_movl_npc_im((long) dc->npc);
  439 +}
402 440  
403   - if (dc->delay_slot == 1) {
404   - insn = dc->insn;
405   - } else {
406   - if (dc->delay_slot) dc->delay_slot--;
407   - insn = htonl (*(unsigned int *) (dc->pc));
408   - dc->pc += 4;
409   - }
  441 +static void disas_sparc_insn(DisasContext * dc)
  442 +{
  443 + unsigned int insn, opc, rs1, rs2, rd;
410 444  
411   - opc = GET_FIELD (insn, 0, 1);
  445 + insn = ldl_code(dc->pc);
  446 + opc = GET_FIELD(insn, 0, 1);
412 447  
413   - rd = GET_FIELD (insn, 2, 6);
414   - switch (opc) {
415   - case 0: /* branches/sethi */
416   - {
417   - unsigned int xop = GET_FIELD (insn, 7, 9);
418   - int target;
419   - target = GET_FIELD (insn, 10, 31);
420   - switch (xop) {
421   - case 0x0: case 0x1: /* UNIMPL */
422   - printf ("UNIMPLEMENTED: %p\n", dc->pc-4);
423   - exit (23);
424   - break;
425   - case 0x2: /* BN+x */
426   - {
427   - target <<= 2;
428   - target = sign_extend (target, 22);
429   - do_branch (dc, target, insn);
430   - break;
431   - }
432   - case 0x3: /* FBN+x */
433   - break;
434   - case 0x4: /* SETHI */
435   - gen_movl_imm_T0 (target<<10);
436   - gen_movl_T0_reg (rd);
437   - break;
438   - case 0x5: /*CBN+x*/
439   - break;
440   - }
441   - break;
442   - }
443   - case 1: /*CALL*/
  448 + rd = GET_FIELD(insn, 2, 6);
  449 + switch (opc) {
  450 + case 0: /* branches/sethi */
  451 + {
  452 + unsigned int xop = GET_FIELD(insn, 7, 9);
  453 + int target;
  454 + target = GET_FIELD(insn, 10, 31);
  455 + switch (xop) {
  456 + case 0x0:
  457 + case 0x1: /* UNIMPL */
  458 + goto illegal_insn;
  459 + case 0x2: /* BN+x */
444 460 {
445   - unsigned int target = GET_FIELDs (insn, 2, 31) << 2;
446   - if (dc->delay_slot) {
447   - do_jump (dc, target, 15);
448   - dc->delay_slot = 0;
449   - } else {
450   - dc->insn = insn;
451   - dc->delay_slot = 2;
452   - }
453   - break;
  461 + target <<= 2;
  462 + target = sign_extend(target, 22);
  463 + do_branch(dc, target, insn);
  464 + goto jmp_insn;
454 465 }
455   - case 2: /* FPU & Logical Operations */
456   - {
457   - unsigned int xop = GET_FIELD (insn, 7, 12);
458   - if (xop == 58) { /* generate trap */
459   - dc->is_br = DISAS_JUMP;
460   - gen_op_jmp_im ((uint32_t) dc->pc);
461   - if (IS_IMM) gen_op_trap (GET_FIELD (insn, 25, 31));
462   - /* else XXX*/
463   - gen_op_movl_T0_0 ();
464   - break;
465   - }
466   - if (xop == 0x34 || xop == 0x35) { /* FPU Operations */
467   - exit (33);
468   - }
469   - rs1 = GET_FIELD (insn, 13, 17);
470   - gen_movl_reg_T0 (rs1);
471   - if (IS_IMM) { /* immediate */
472   - rs2 = GET_FIELDs (insn, 20, 31);
473   - gen_movl_imm_T1 (rs2);
474   - } else { /* register */
475   - rs2 = GET_FIELD (insn, 27, 31);
476   - gen_movl_reg_T1 (rs2);
477   - }
478   - if (xop < 0x20) {
479   - switch (xop &~ 0x10) {
480   - case 0x0:
481   - gen_op_add_T1_T0 ();
482   - break;
483   - case 0x1:
484   - gen_op_and_T1_T0 ();
485   - break;
486   - case 0x2:
487   - gen_op_or_T1_T0 ();
488   - break;
489   - case 0x3:
490   - gen_op_xor_T1_T0 ();
491   - break;
492   - case 0x4:
493   - gen_op_sub_T1_T0 ();
494   - break;
495   - case 0x5:
496   - gen_op_andn_T1_T0 ();
497   - break;
498   - case 0x6:
499   - gen_op_orn_T1_T0 ();
500   - break;
501   - case 0x7:
502   - gen_op_xnor_T1_T0 ();
503   - break;
504   - case 0x8:
505   - gen_op_addx_T1_T0 ();
506   - break;
507   - case 0xa:
508   - gen_op_umul_T1_T0 ();
509   - break;
510   - case 0xb:
511   - gen_op_smul_T1_T0 ();
512   - break;
513   - case 0xc:
514   - gen_op_subx_T1_T0 ();
515   - break;
516   - case 0xe:
517   - gen_op_udiv_T1_T0 ();
518   - break;
519   - case 0xf:
520   - gen_op_sdiv_T1_T0 ();
521   - break;
522   - default:
523   - exit (17);
524   - break;
525   - }
526   - gen_movl_T0_reg (rd);
527   - if (xop & 0x10) {
528   - gen_op_set_flags ();
529   - }
530   - } else {
531   - switch (xop) {
532   - case 0x25: /* SLL */
533   - gen_op_sll ();
534   - break;
535   - case 0x26:
536   - gen_op_srl ();
537   - break;
538   - case 0x27:
539   - gen_op_sra ();
540   - break;
541   - case 0x28: case 0x30:
542   - {
543   - unsigned int rdi = GET_FIELD (insn, 13, 17);
544   - if (!rdi) (xop==0x28?gen_op_rdy ():gen_op_wry());
545   - /* else gen_op_su_trap (); */
546   - break;
547   - }
548   - /* Problem with jmpl: if restore is executed in the delay
549   - slot, then the wrong registers are beeing used */
550   - case 0x38: /* jmpl */
551   - {
552   - if (dc->delay_slot) {
553   - gen_op_add_T1_T0 ();
554   - do_jump (dc, 1, rd);
555   - dc->delay_slot = 0;
556   - } else {
557   - gen_op_add_T1_T0 ();
558   - gen_op_jmpl ();
559   - dc->insn = insn;
560   - dc->delay_slot = 2;
561   - }
562   - break;
563   - }
564   - case 0x3c: /* save */
565   - gen_op_add_T1_T0 ();
566   - gen_op_save ();
567   - gen_movl_T0_reg (rd);
568   - break;
569   - case 0x3d: /* restore */
570   - gen_op_add_T1_T0 ();
571   - gen_op_restore ();
572   - gen_movl_T0_reg (rd);
573   - break;
574   - }
575   - }
576   - break;
  466 + case 0x3: /* FBN+x */
  467 + break;
  468 + case 0x4: /* SETHI */
  469 + gen_movl_imm_T0(target << 10);
  470 + gen_movl_T0_reg(rd);
  471 + break;
  472 + case 0x5: /*CBN+x */
  473 + break;
  474 + }
  475 + break;
  476 + }
  477 + case 1:
  478 + /*CALL*/ {
  479 + unsigned int target = GET_FIELDs(insn, 2, 31) << 2;
  480 +
  481 + gen_op_movl_T0_im((long) (dc->pc));
  482 + gen_movl_T0_reg(15);
  483 + target = (long) dc->pc + target;
  484 + dc->pc = dc->npc;
  485 + dc->npc = (uint8_t *) target;
  486 + }
  487 + goto jmp_insn;
  488 + case 2: /* FPU & Logical Operations */
  489 + {
  490 + unsigned int xop = GET_FIELD(insn, 7, 12);
  491 + if (xop == 0x3a) { /* generate trap */
  492 + int cond;
  493 + rs1 = GET_FIELD(insn, 13, 17);
  494 + gen_movl_reg_T0(rs1);
  495 + if (IS_IMM) {
  496 + gen_movl_imm_T1(GET_FIELD(insn, 25, 31));
  497 + } else {
  498 + rs2 = GET_FIELD(insn, 27, 31);
  499 + gen_movl_reg_T1(rs2);
  500 + }
  501 + gen_op_add_T1_T0();
  502 + save_state(dc);
  503 + cond = GET_FIELD(insn, 3, 6);
  504 + if (cond == 0x8) {
  505 + gen_op_trap_T0();
  506 + dc->is_br = 1;
  507 + goto jmp_insn;
  508 + } else {
  509 + gen_op_trapcc_T0();
  510 + }
  511 + } else if (xop == 0x28) {
  512 + rs1 = GET_FIELD(insn, 13, 17);
  513 + switch(rs1) {
  514 + case 0: /* rdy */
  515 + gen_op_rdy();
  516 + gen_movl_T0_reg(rd);
  517 + break;
  518 + default:
  519 + goto illegal_insn;
  520 + }
  521 + } else if (xop == 0x34 || xop == 0x35) { /* FPU Operations */
  522 + goto illegal_insn;
  523 + } else {
  524 + rs1 = GET_FIELD(insn, 13, 17);
  525 + gen_movl_reg_T0(rs1);
  526 + if (IS_IMM) { /* immediate */
  527 + rs2 = GET_FIELDs(insn, 19, 31);
  528 + gen_movl_imm_T1(rs2);
  529 + } else { /* register */
  530 + rs2 = GET_FIELD(insn, 27, 31);
  531 + gen_movl_reg_T1(rs2);
  532 + }
  533 + if (xop < 0x20) {
  534 + switch (xop & ~0x10) {
  535 + case 0x0:
  536 + if (xop & 0x10)
  537 + gen_op_add_T1_T0_cc();
  538 + else
  539 + gen_op_add_T1_T0();
  540 + break;
  541 + case 0x1:
  542 + gen_op_and_T1_T0();
  543 + if (xop & 0x10)
  544 + gen_op_logic_T0_cc();
  545 + break;
  546 + case 0x2:
  547 + gen_op_or_T1_T0();
  548 + if (xop & 0x10)
  549 + gen_op_logic_T0_cc();
  550 + break;
  551 + case 0x3:
  552 + gen_op_xor_T1_T0();
  553 + if (xop & 0x10)
  554 + gen_op_logic_T0_cc();
  555 + break;
  556 + case 0x4:
  557 + if (xop & 0x10)
  558 + gen_op_sub_T1_T0_cc();
  559 + else
  560 + gen_op_sub_T1_T0();
  561 + break;
  562 + case 0x5:
  563 + gen_op_andn_T1_T0();
  564 + if (xop & 0x10)
  565 + gen_op_logic_T0_cc();
  566 + break;
  567 + case 0x6:
  568 + gen_op_orn_T1_T0();
  569 + if (xop & 0x10)
  570 + gen_op_logic_T0_cc();
  571 + break;
  572 + case 0x7:
  573 + gen_op_xnor_T1_T0();
  574 + if (xop & 0x10)
  575 + gen_op_logic_T0_cc();
  576 + break;
  577 + case 0x8:
  578 + gen_op_addx_T1_T0();
  579 + if (xop & 0x10)
  580 + gen_op_set_flags();
  581 + break;
  582 + case 0xa:
  583 + gen_op_umul_T1_T0();
  584 + if (xop & 0x10)
  585 + gen_op_logic_T0_cc();
  586 + break;
  587 + case 0xb:
  588 + gen_op_smul_T1_T0();
  589 + if (xop & 0x10)
  590 + gen_op_logic_T0_cc();
  591 + break;
  592 + case 0xc:
  593 + gen_op_subx_T1_T0();
  594 + if (xop & 0x10)
  595 + gen_op_set_flags();
  596 + break;
  597 + case 0xe:
  598 + gen_op_udiv_T1_T0();
  599 + if (xop & 0x10)
  600 + gen_op_div_cc();
  601 + break;
  602 + case 0xf:
  603 + gen_op_sdiv_T1_T0();
  604 + if (xop & 0x10)
  605 + gen_op_div_cc();
  606 + break;
  607 + default:
  608 + goto illegal_insn;
  609 + }
  610 + gen_movl_T0_reg(rd);
  611 + } else {
  612 + switch (xop) {
  613 + case 0x24: /* mulscc */
  614 + gen_op_mulscc_T1_T0();
  615 + gen_movl_T0_reg(rd);
  616 + break;
  617 + case 0x25: /* SLL */
  618 + gen_op_sll();
  619 + gen_movl_T0_reg(rd);
  620 + break;
  621 + case 0x26:
  622 + gen_op_srl();
  623 + gen_movl_T0_reg(rd);
  624 + break;
  625 + case 0x27:
  626 + gen_op_sra();
  627 + gen_movl_T0_reg(rd);
  628 + break;
  629 + case 0x30:
  630 + {
  631 + gen_op_xor_T1_T0();
  632 + switch(rd) {
  633 + case 0:
  634 + gen_op_wry();
  635 + break;
  636 + default:
  637 + goto illegal_insn;
  638 + }
  639 + }
  640 + break;
  641 + case 0x38: /* jmpl */
  642 + {
  643 + gen_op_add_T1_T0();
  644 + gen_op_movl_npc_T0();
  645 + if (rd != 0) {
  646 + gen_op_movl_T0_im((long) (dc->pc));
  647 + gen_movl_T0_reg(rd);
  648 + }
  649 + dc->pc = dc->npc;
  650 + dc->npc = NULL;
  651 + }
  652 + goto jmp_insn;
  653 + case 0x3b: /* flush */
  654 + /* nothing to do */
  655 + break;
  656 + case 0x3c: /* save */
  657 + save_state(dc);
  658 + gen_op_add_T1_T0();
  659 + gen_op_save();
  660 + gen_movl_T0_reg(rd);
  661 + break;
  662 + case 0x3d: /* restore */
  663 + save_state(dc);
  664 + gen_op_add_T1_T0();
  665 + gen_op_restore();
  666 + gen_movl_T0_reg(rd);
  667 + break;
  668 + default:
  669 + goto illegal_insn;
  670 + }
  671 + }
  672 + }
  673 + break;
  674 + }
  675 + case 3: /* load/store instructions */
  676 + {
  677 + unsigned int xop = GET_FIELD(insn, 7, 12);
  678 + rs1 = GET_FIELD(insn, 13, 17);
  679 + gen_movl_reg_T0(rs1);
  680 + if (IS_IMM) { /* immediate */
  681 + rs2 = GET_FIELDs(insn, 19, 31);
  682 + gen_movl_imm_T1(rs2);
  683 + } else { /* register */
  684 + rs2 = GET_FIELD(insn, 27, 31);
  685 + gen_movl_reg_T1(rs2);
  686 + }
  687 + gen_op_add_T1_T0();
  688 + if (xop < 4 || xop > 7) {
  689 + switch (xop) {
  690 + case 0x0: /* load word */
  691 + gen_op_ld();
  692 + break;
  693 + case 0x1: /* load unsigned byte */
  694 + gen_op_ldub();
  695 + break;
  696 + case 0x2: /* load unsigned halfword */
  697 + gen_op_lduh();
  698 + break;
  699 + case 0x3: /* load double word */
  700 + gen_op_ldd();
  701 + gen_movl_T0_reg(rd + 1);
  702 + break;
  703 + case 0x9: /* load signed byte */
  704 + gen_op_ldsb();
  705 + break;
  706 + case 0xa: /* load signed halfword */
  707 + gen_op_ldsh();
  708 + break;
  709 + case 0xd: /* ldstub -- XXX: should be atomically */
  710 + gen_op_ldstub();
  711 + break;
  712 + case 0x0f: /* swap register with memory. Also atomically */
  713 + gen_op_swap();
  714 + break;
577 715 }
578   - case 3: /* load/store instructions */
579   - {
580   - unsigned int xop = GET_FIELD (insn, 7, 12);
581   - rs1 = GET_FIELD (insn, 13, 17);
582   - gen_movl_reg_T0 (rs1);
583   - if (IS_IMM) { /* immediate */
584   - rs2 = GET_FIELDs (insn, 20, 31);
585   - gen_movl_imm_T1 (rs2);
586   - } else { /* register */
587   - rs2 = GET_FIELD (insn, 27, 31);
588   - gen_movl_reg_T1 (rs2);
589   - }
590   - gen_op_add_T1_T0 ();
591   - if (xop < 4 || xop > 7) {
592   - switch (xop) {
593   - case 0x0: /* load word */
594   - gen_op_ld ();
595   - break;
596   - case 0x1: /* load unsigned byte */
597   - gen_op_ldub ();
598   - break;
599   - case 0x2: /* load unsigned halfword */
600   - gen_op_lduh ();
601   - break;
602   - case 0x3: /* load double word */
603   - gen_op_ldd ();
604   - gen_movl_T0_reg (rd+1);
605   - break;
606   - case 0x9: /* load signed byte */
607   - gen_op_ldsb ();
608   - break;
609   - case 0xa: /* load signed halfword */
610   - gen_op_ldsh ();
611   - break;
612   - case 0xd: /* ldstub -- XXX: should be atomically */
613   - gen_op_ldstub ();
614   - break;
615   - case 0x0f: /* swap register with memory. Also atomically */
616   - gen_op_swap ();
617   - break;
618   - }
619   - gen_movl_T1_reg (rd);
620   - } else if (xop < 8) {
621   - gen_movl_reg_T1 (rd);
622   - switch (xop) {
623   - case 0x4:
624   - gen_op_st ();
625   - break;
626   - case 0x5:
627   - gen_op_stb ();
628   - break;
629   - case 0x6:
630   - gen_op_sth ();
631   - break;
632   - case 0x7:
633   - gen_op_st ();
634   - gen_movl_reg_T1 (rd+1);
635   - gen_op_st ();
636   - break;
637   - }
638   - }
  716 + gen_movl_T1_reg(rd);
  717 + } else if (xop < 8) {
  718 + gen_movl_reg_T1(rd);
  719 + switch (xop) {
  720 + case 0x4:
  721 + gen_op_st();
  722 + break;
  723 + case 0x5:
  724 + gen_op_stb();
  725 + break;
  726 + case 0x6:
  727 + gen_op_sth();
  728 + break;
  729 + case 0x7:
  730 + gen_movl_reg_T2(rd + 1);
  731 + gen_op_std();
  732 + break;
639 733 }
  734 + }
640 735 }
  736 + }
  737 + /* default case for non jump instructions */
  738 + if (dc->npc != NULL) {
  739 + dc->pc = dc->npc;
  740 + dc->npc = dc->npc + 4;
  741 + } else {
  742 + dc->pc = NULL;
  743 + gen_op_next_insn();
  744 + }
  745 + jmp_insn:;
  746 + return;
  747 + illegal_insn:
  748 + gen_op_jmp_im((uint32_t)dc->pc);
  749 + if (dc->npc != NULL)
  750 + gen_op_movl_npc_im((long) dc->npc);
  751 + gen_op_exception(TT_ILL_INSN);
  752 + dc->is_br = 1;
641 753 }
642 754  
643   -static inline int gen_intermediate_code_internal (TranslationBlock *tb, int spc)
  755 +static inline int gen_intermediate_code_internal(TranslationBlock * tb,
  756 + int spc)
644 757 {
645   - uint8_t *pc_start = (uint8_t *) tb->pc;
646   - uint16_t *gen_opc_end;
647   - DisasContext dc;
648   -
649   - memset (&dc, 0, sizeof (dc));
650   - if (spc) {
651   - printf ("SearchPC not yet supported\n");
652   - exit (0);
653   - }
654   - dc.tb = tb;
655   - dc.pc = pc_start;
656   -
657   - gen_opc_ptr = gen_opc_buf;
658   - gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
659   - gen_opparam_ptr = gen_opparam_buf;
660   -
661   - do {
662   - disas_sparc_insn (&dc);
663   - } while (!dc.is_br && (gen_opc_ptr < gen_opc_end) &&
664   - (dc.pc - pc_start) < (TARGET_PAGE_SIZE - 32));
665   -
666   - switch (dc.is_br) {
667   - case DISAS_JUMP:
668   - case DISAS_TB_JUMP:
669   - gen_op_exit_tb ();
670   - break;
671   - }
672   -
673   - *gen_opc_ptr = INDEX_op_end;
  758 + uint8_t *pc_start, *last_pc;
  759 + uint16_t *gen_opc_end;
  760 + DisasContext dc1, *dc = &dc1;
  761 +
  762 + memset(dc, 0, sizeof(DisasContext));
  763 + if (spc) {
  764 + printf("SearchPC not yet supported\n");
  765 + exit(0);
  766 + }
  767 + dc->tb = tb;
  768 + pc_start = (uint8_t *) tb->pc;
  769 + dc->pc = pc_start;
  770 + dc->npc = (uint8_t *) tb->cs_base;
  771 +
  772 + gen_opc_ptr = gen_opc_buf;
  773 + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
  774 + gen_opparam_ptr = gen_opparam_buf;
  775 +
  776 + do {
  777 + last_pc = dc->pc;
  778 + disas_sparc_insn(dc);
  779 + if (dc->is_br)
  780 + break;
  781 + /* if the next PC is different, we abort now */
  782 + if (dc->pc != (last_pc + 4))
  783 + break;
  784 + } while ((gen_opc_ptr < gen_opc_end) &&
  785 + (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
  786 + if (dc->pc != NULL)
  787 + gen_op_jmp_im((long) dc->pc);
  788 + if (dc->npc != NULL)
  789 + gen_op_movl_npc_im((long) dc->npc);
  790 + gen_op_movl_T0_0();
  791 + gen_op_exit_tb();
  792 +
  793 + *gen_opc_ptr = INDEX_op_end;
674 794 #ifdef DEBUG_DISAS
675   - if (loglevel) {
676   - fprintf (logfile, "--------------\n");
677   - fprintf (logfile, "IN: %s\n", lookup_symbol (pc_start));
678   - disas(logfile, pc_start, dc.pc - pc_start, 0, 0);
679   - fprintf(logfile, "\n");
680   - fprintf(logfile, "OP:\n");
681   - dump_ops(gen_opc_buf, gen_opparam_buf);
682   - fprintf(logfile, "\n");
683   - }
  795 + if (loglevel) {
  796 + fprintf(logfile, "--------------\n");
  797 + fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
  798 + disas(logfile, pc_start, last_pc + 4 - pc_start, 0, 0);
  799 + fprintf(logfile, "\n");
  800 + fprintf(logfile, "OP:\n");
  801 + dump_ops(gen_opc_buf, gen_opparam_buf);
  802 + fprintf(logfile, "\n");
  803 + }
684 804 #endif
685 805  
686   - return 0;
  806 + return 0;
687 807 }
688 808  
689   -int gen_intermediate_code (CPUSPARCState *env, TranslationBlock *tb)
  809 +int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
690 810 {
691   - return gen_intermediate_code_internal(tb, 0);
  811 + return gen_intermediate_code_internal(tb, 0);
692 812 }
693 813  
694   -int gen_intermediate_code_pc (CPUSPARCState *env, TranslationBlock *tb)
  814 +int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
695 815 {
696   - return gen_intermediate_code_internal(tb, 1);
  816 + return gen_intermediate_code_internal(tb, 1);
697 817 }
698 818  
699   -void *mycpu;
700   -
701   -CPUSPARCState *cpu_sparc_init (void)
  819 +CPUSPARCState *cpu_sparc_init(void)
702 820 {
703   - CPUSPARCState *env;
704   -
705   - cpu_exec_init ();
706   -
707   - if (!(env = malloc (sizeof(CPUSPARCState))))
708   - return (NULL);
709   - memset (env, 0, sizeof (*env));
710   - if (!(env->regwptr = malloc (0x2000)))
711   - return (NULL);
712   - memset (env->regwptr, 0, 0x2000);
713   - env->regwptr += 127;
714   - env->user_mode_only = 1;
715   - mycpu = env;
716   - return (env);
  821 + CPUSPARCState *env;
  822 +
  823 + cpu_exec_init();
  824 +
  825 + if (!(env = malloc(sizeof(CPUSPARCState))))
  826 + return (NULL);
  827 + memset(env, 0, sizeof(*env));
  828 + env->cwp = 0;
  829 + env->wim = 1;
  830 + env->regwptr = env->regbase + (env->cwp * 16);
  831 + env->user_mode_only = 1;
  832 + return (env);
717 833 }
718 834  
719 835 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
720 836  
721   -void cpu_sparc_dump_state (CPUSPARCState *env, FILE *f, int flags)
  837 +void cpu_sparc_dump_state(CPUSPARCState * env, FILE * f, int flags)
722 838 {
723   - int i, x;
724   -
725   - fprintf (f, "@PC: %p\n", (void *) env->pc);
726   - fprintf (f, "General Registers:\n");
727   - for (i=0;i<4;i++)
728   - fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
729   - fprintf (f, "\n");
730   - for (;i<8;i++)
731   - fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
732   - fprintf (f, "\nCurrent Register Window:\n");
733   - for (x=0;x<3;x++) {
734   - for (i=0;i<4;i++)
735   - fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':(x==1?'l':'i')), i, env->regwptr[i+x*8]);
736   - fprintf (f, "\n");
737   - for (;i<8;i++)
738   - fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':x==1?'l':'i'), i, env->regwptr[i+x*8]);
739   - fprintf (f, "\n");
740   - }
741   - fprintf (f, "PSR: %x -> %c%c%c%c\n", env->psr,
742   - GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
743   - GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'));
  839 + int i, x;
  840 +
  841 + fprintf(f, "pc: 0x%08x npc: 0x%08x\n", (int) env->pc, (int) env->npc);
  842 + fprintf(f, "General Registers:\n");
  843 + for (i = 0; i < 4; i++)
  844 + fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
  845 + fprintf(f, "\n");
  846 + for (; i < 8; i++)
  847 + fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
  848 + fprintf(f, "\nCurrent Register Window:\n");
  849 + for (x = 0; x < 3; x++) {
  850 + for (i = 0; i < 4; i++)
  851 + fprintf(f, "%%%c%d: 0x%08x\t",
  852 + (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
  853 + env->regwptr[i + x * 8]);
  854 + fprintf(f, "\n");
  855 + for (; i < 8; i++)
  856 + fprintf(f, "%%%c%d: 0x%08x\t",
  857 + (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
  858 + env->regwptr[i + x * 8]);
  859 + fprintf(f, "\n");
  860 + }
  861 + fprintf(f, "psr: 0x%08x -> %c%c%c%c wim: 0x%08x\n", env->psr | env->cwp,
  862 + GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
  863 + GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
  864 + env->wim);
744 865 }
... ...