Revision 19f329ad target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
91 | 91 |
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1)) |
92 | 92 |
|
93 | 93 |
#ifdef TARGET_SPARC64 |
94 |
#define FFPREG(r) (r) |
|
94 | 95 |
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e)) |
95 | 96 |
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c)) |
96 | 97 |
#else |
98 |
#define FFPREG(r) (r) |
|
97 | 99 |
#define DFPREG(r) (r & 0x1e) |
98 | 100 |
#define QFPREG(r) (r & 0x1c) |
99 | 101 |
#endif |
... | ... | |
331 | 333 |
} |
332 | 334 |
} |
333 | 335 |
|
336 |
// XXX suboptimal |
|
337 |
static inline void gen_mov_reg_N(TCGv reg, TCGv src) |
|
338 |
{ |
|
339 |
tcg_gen_shri_i32(reg, src, 23); |
|
340 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
341 |
} |
|
342 |
|
|
343 |
static inline void gen_mov_reg_Z(TCGv reg, TCGv src) |
|
344 |
{ |
|
345 |
tcg_gen_shri_i32(reg, src, 22); |
|
346 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
347 |
} |
|
348 |
|
|
349 |
static inline void gen_mov_reg_V(TCGv reg, TCGv src) |
|
350 |
{ |
|
351 |
tcg_gen_shri_i32(reg, src, 21); |
|
352 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
353 |
} |
|
354 |
|
|
355 |
static inline void gen_mov_reg_C(TCGv reg, TCGv src) |
|
356 |
{ |
|
357 |
tcg_gen_shri_i32(reg, src, 20); |
|
358 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
359 |
} |
|
360 |
|
|
361 |
// 1 |
|
362 |
static inline void gen_op_eval_ba(TCGv dst) |
|
363 |
{ |
|
364 |
tcg_gen_movi_tl(dst, 1); |
|
365 |
} |
|
366 |
|
|
367 |
// Z |
|
368 |
static inline void gen_op_eval_be(TCGv dst, TCGv src) |
|
369 |
{ |
|
370 |
gen_mov_reg_Z(dst, src); |
|
371 |
} |
|
372 |
|
|
373 |
// Z | (N ^ V) |
|
374 |
static inline void gen_op_eval_ble(TCGv dst, TCGv src) |
|
375 |
{ |
|
376 |
TCGv r_flag; |
|
377 |
|
|
378 |
r_flag = tcg_temp_new(TCG_TYPE_TL); |
|
379 |
gen_mov_reg_N(r_flag, src); |
|
380 |
gen_mov_reg_V(dst, src); |
|
381 |
tcg_gen_xor_tl(dst, dst, r_flag); |
|
382 |
gen_mov_reg_Z(r_flag, src); |
|
383 |
tcg_gen_or_tl(dst, dst, r_flag); |
|
384 |
} |
|
385 |
|
|
386 |
// N ^ V |
|
387 |
static inline void gen_op_eval_bl(TCGv dst, TCGv src) |
|
388 |
{ |
|
389 |
TCGv r_V; |
|
390 |
|
|
391 |
r_V = tcg_temp_new(TCG_TYPE_TL); |
|
392 |
gen_mov_reg_V(r_V, src); |
|
393 |
gen_mov_reg_N(dst, src); |
|
394 |
tcg_gen_xor_tl(dst, dst, r_V); |
|
395 |
} |
|
396 |
|
|
397 |
// C | Z |
|
398 |
static inline void gen_op_eval_bleu(TCGv dst, TCGv src) |
|
399 |
{ |
|
400 |
TCGv r_Z; |
|
401 |
|
|
402 |
r_Z = tcg_temp_new(TCG_TYPE_TL); |
|
403 |
gen_mov_reg_Z(r_Z, src); |
|
404 |
gen_mov_reg_C(dst, src); |
|
405 |
tcg_gen_or_tl(dst, dst, r_Z); |
|
406 |
} |
|
407 |
|
|
408 |
// C |
|
409 |
static inline void gen_op_eval_bcs(TCGv dst, TCGv src) |
|
410 |
{ |
|
411 |
gen_mov_reg_C(dst, src); |
|
412 |
} |
|
413 |
|
|
414 |
// V |
|
415 |
static inline void gen_op_eval_bvs(TCGv dst, TCGv src) |
|
416 |
{ |
|
417 |
gen_mov_reg_V(dst, src); |
|
418 |
} |
|
419 |
|
|
420 |
// 0 |
|
421 |
static inline void gen_op_eval_bn(TCGv dst) |
|
422 |
{ |
|
423 |
tcg_gen_movi_tl(dst, 0); |
|
424 |
} |
|
425 |
|
|
426 |
// N |
|
427 |
static inline void gen_op_eval_bneg(TCGv dst, TCGv src) |
|
428 |
{ |
|
429 |
gen_mov_reg_N(dst, src); |
|
430 |
} |
|
431 |
|
|
432 |
// !Z |
|
433 |
static inline void gen_op_eval_bne(TCGv dst, TCGv src) |
|
434 |
{ |
|
435 |
gen_mov_reg_Z(dst, src); |
|
436 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
437 |
} |
|
438 |
|
|
439 |
// !(Z | (N ^ V)) |
|
440 |
static inline void gen_op_eval_bg(TCGv dst, TCGv src) |
|
441 |
{ |
|
442 |
TCGv r_flag; |
|
443 |
|
|
444 |
r_flag = tcg_temp_new(TCG_TYPE_TL); |
|
445 |
gen_mov_reg_N(r_flag, src); |
|
446 |
gen_mov_reg_V(dst, src); |
|
447 |
tcg_gen_xor_tl(dst, dst, r_flag); |
|
448 |
gen_mov_reg_Z(r_flag, src); |
|
449 |
tcg_gen_or_tl(dst, dst, r_flag); |
|
450 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
451 |
} |
|
452 |
|
|
453 |
// !(N ^ V) |
|
454 |
static inline void gen_op_eval_bge(TCGv dst, TCGv src) |
|
455 |
{ |
|
456 |
TCGv r_V; |
|
457 |
|
|
458 |
r_V = tcg_temp_new(TCG_TYPE_TL); |
|
459 |
gen_mov_reg_V(r_V, src); |
|
460 |
gen_mov_reg_N(dst, src); |
|
461 |
tcg_gen_xor_tl(dst, dst, r_V); |
|
462 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
463 |
} |
|
464 |
|
|
465 |
// !(C | Z) |
|
466 |
static inline void gen_op_eval_bgu(TCGv dst, TCGv src) |
|
467 |
{ |
|
468 |
TCGv r_Z; |
|
469 |
|
|
470 |
r_Z = tcg_temp_new(TCG_TYPE_TL); |
|
471 |
gen_mov_reg_Z(r_Z, src); |
|
472 |
gen_mov_reg_C(dst, src); |
|
473 |
tcg_gen_or_tl(dst, dst, r_Z); |
|
474 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
475 |
} |
|
476 |
|
|
477 |
// !C |
|
478 |
static inline void gen_op_eval_bcc(TCGv dst, TCGv src) |
|
479 |
{ |
|
480 |
gen_mov_reg_C(dst, src); |
|
481 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
482 |
} |
|
483 |
|
|
484 |
// !N |
|
485 |
static inline void gen_op_eval_bpos(TCGv dst, TCGv src) |
|
486 |
{ |
|
487 |
gen_mov_reg_N(dst, src); |
|
488 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
489 |
} |
|
490 |
|
|
491 |
// !V |
|
492 |
static inline void gen_op_eval_bvc(TCGv dst, TCGv src) |
|
493 |
{ |
|
494 |
gen_mov_reg_V(dst, src); |
|
495 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
496 |
} |
|
497 |
|
|
498 |
/* |
|
499 |
FPSR bit field FCC1 | FCC0: |
|
500 |
0 = |
|
501 |
1 < |
|
502 |
2 > |
|
503 |
3 unordered |
|
504 |
*/ |
|
505 |
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src, |
|
506 |
unsigned int fcc_offset) |
|
507 |
{ |
|
508 |
tcg_gen_shri_i32(reg, src, 10 + fcc_offset); |
|
509 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
510 |
} |
|
511 |
|
|
512 |
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src, |
|
513 |
unsigned int fcc_offset) |
|
514 |
{ |
|
515 |
tcg_gen_shri_i32(reg, src, 11 + fcc_offset); |
|
516 |
tcg_gen_andi_tl(reg, reg, 0x1); |
|
517 |
} |
|
518 |
|
|
519 |
// !0: FCC0 | FCC1 |
|
520 |
static inline void gen_op_eval_fbne(TCGv dst, TCGv src, |
|
521 |
unsigned int fcc_offset) |
|
522 |
{ |
|
523 |
TCGv r_fcc1; |
|
524 |
|
|
525 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
526 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
527 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
528 |
tcg_gen_or_tl(dst, dst, r_fcc1); |
|
529 |
} |
|
530 |
|
|
531 |
// 1 or 2: FCC0 ^ FCC1 |
|
532 |
static inline void gen_op_eval_fblg(TCGv dst, TCGv src, |
|
533 |
unsigned int fcc_offset) |
|
534 |
{ |
|
535 |
TCGv r_fcc1; |
|
536 |
|
|
537 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
538 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
539 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
540 |
tcg_gen_xor_tl(dst, dst, r_fcc1); |
|
541 |
} |
|
542 |
|
|
543 |
// 1 or 3: FCC0 |
|
544 |
static inline void gen_op_eval_fbul(TCGv dst, TCGv src, |
|
545 |
unsigned int fcc_offset) |
|
546 |
{ |
|
547 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
548 |
} |
|
549 |
|
|
550 |
// 1: FCC0 & !FCC1 |
|
551 |
static inline void gen_op_eval_fbl(TCGv dst, TCGv src, |
|
552 |
unsigned int fcc_offset) |
|
553 |
{ |
|
554 |
TCGv r_fcc1; |
|
555 |
|
|
556 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
557 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
558 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
559 |
tcg_gen_xori_tl(r_fcc1, r_fcc1, 0x1); |
|
560 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
561 |
} |
|
562 |
|
|
563 |
// 2 or 3: FCC1 |
|
564 |
static inline void gen_op_eval_fbug(TCGv dst, TCGv src, |
|
565 |
unsigned int fcc_offset) |
|
566 |
{ |
|
567 |
gen_mov_reg_FCC1(dst, src, fcc_offset); |
|
568 |
} |
|
569 |
|
|
570 |
// 2: !FCC0 & FCC1 |
|
571 |
static inline void gen_op_eval_fbg(TCGv dst, TCGv src, |
|
572 |
unsigned int fcc_offset) |
|
573 |
{ |
|
574 |
TCGv r_fcc1; |
|
575 |
|
|
576 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
577 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
578 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
579 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
580 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
581 |
} |
|
582 |
|
|
583 |
// 3: FCC0 & FCC1 |
|
584 |
static inline void gen_op_eval_fbu(TCGv dst, TCGv src, |
|
585 |
unsigned int fcc_offset) |
|
586 |
{ |
|
587 |
TCGv r_fcc1; |
|
588 |
|
|
589 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
590 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
591 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
592 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
593 |
} |
|
594 |
|
|
595 |
// 0: !(FCC0 | FCC1) |
|
596 |
static inline void gen_op_eval_fbe(TCGv dst, TCGv src, |
|
597 |
unsigned int fcc_offset) |
|
598 |
{ |
|
599 |
TCGv r_fcc1; |
|
600 |
|
|
601 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
602 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
603 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
604 |
tcg_gen_or_tl(dst, dst, r_fcc1); |
|
605 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
606 |
} |
|
607 |
|
|
608 |
// 0 or 3: !(FCC0 ^ FCC1) |
|
609 |
static inline void gen_op_eval_fbue(TCGv dst, TCGv src, |
|
610 |
unsigned int fcc_offset) |
|
611 |
{ |
|
612 |
TCGv r_fcc1; |
|
613 |
|
|
614 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
615 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
616 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
617 |
tcg_gen_xor_tl(dst, dst, r_fcc1); |
|
618 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
619 |
} |
|
620 |
|
|
621 |
// 0 or 2: !FCC0 |
|
622 |
static inline void gen_op_eval_fbge(TCGv dst, TCGv src, |
|
623 |
unsigned int fcc_offset) |
|
624 |
{ |
|
625 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
626 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
627 |
} |
|
628 |
|
|
629 |
// !1: !(FCC0 & !FCC1) |
|
630 |
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src, |
|
631 |
unsigned int fcc_offset) |
|
632 |
{ |
|
633 |
TCGv r_fcc1; |
|
634 |
|
|
635 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
636 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
637 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
638 |
tcg_gen_xori_tl(r_fcc1, r_fcc1, 0x1); |
|
639 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
640 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
641 |
} |
|
642 |
|
|
643 |
// 0 or 1: !FCC1 |
|
644 |
static inline void gen_op_eval_fble(TCGv dst, TCGv src, |
|
645 |
unsigned int fcc_offset) |
|
646 |
{ |
|
647 |
gen_mov_reg_FCC1(dst, src, fcc_offset); |
|
648 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
649 |
} |
|
650 |
|
|
651 |
// !2: !(!FCC0 & FCC1) |
|
652 |
static inline void gen_op_eval_fbule(TCGv dst, TCGv src, |
|
653 |
unsigned int fcc_offset) |
|
654 |
{ |
|
655 |
TCGv r_fcc1; |
|
656 |
|
|
657 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
658 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
659 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
660 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
661 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
662 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
663 |
} |
|
664 |
|
|
665 |
// !3: !(FCC0 & FCC1) |
|
666 |
static inline void gen_op_eval_fbo(TCGv dst, TCGv src, |
|
667 |
unsigned int fcc_offset) |
|
668 |
{ |
|
669 |
TCGv r_fcc1; |
|
670 |
|
|
671 |
r_fcc1 = tcg_temp_new(TCG_TYPE_TL); |
|
672 |
gen_mov_reg_FCC0(dst, src, fcc_offset); |
|
673 |
gen_mov_reg_FCC1(r_fcc1, src, fcc_offset); |
|
674 |
tcg_gen_and_tl(dst, dst, r_fcc1); |
|
675 |
tcg_gen_xori_tl(dst, dst, 0x1); |
|
676 |
} |
|
677 |
|
|
334 | 678 |
static inline void gen_branch2(DisasContext *dc, target_ulong pc1, |
335 |
target_ulong pc2) |
|
679 |
target_ulong pc2, TCGv r_cond)
|
|
336 | 680 |
{ |
681 |
TCGv r_zero; |
|
337 | 682 |
int l1; |
338 | 683 |
|
339 | 684 |
l1 = gen_new_label(); |
685 |
r_zero = tcg_temp_new(TCG_TYPE_TL); |
|
686 |
tcg_gen_movi_tl(r_zero, 0); |
|
340 | 687 |
|
341 |
gen_op_jz_T2_label(l1);
|
|
688 |
tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1);
|
|
342 | 689 |
|
343 | 690 |
gen_goto_tb(dc, 0, pc1, pc1 + 4); |
344 | 691 |
|
... | ... | |
347 | 694 |
} |
348 | 695 |
|
349 | 696 |
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1, |
350 |
target_ulong pc2) |
|
697 |
target_ulong pc2, TCGv r_cond)
|
|
351 | 698 |
{ |
699 |
TCGv r_zero; |
|
352 | 700 |
int l1; |
353 | 701 |
|
354 | 702 |
l1 = gen_new_label(); |
703 |
r_zero = tcg_temp_new(TCG_TYPE_TL); |
|
704 |
tcg_gen_movi_tl(r_zero, 0); |
|
355 | 705 |
|
356 |
gen_op_jz_T2_label(l1);
|
|
706 |
tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1);
|
|
357 | 707 |
|
358 | 708 |
gen_goto_tb(dc, 0, pc2, pc1); |
359 | 709 |
|
... | ... | |
367 | 717 |
gen_goto_tb(dc, 0, pc, npc); |
368 | 718 |
} |
369 | 719 |
|
370 |
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2) |
|
720 |
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2, |
|
721 |
TCGv r_cond) |
|
371 | 722 |
{ |
723 |
TCGv r_zero; |
|
372 | 724 |
int l1, l2; |
373 | 725 |
|
374 | 726 |
l1 = gen_new_label(); |
375 | 727 |
l2 = gen_new_label(); |
376 |
gen_op_jz_T2_label(l1); |
|
728 |
r_zero = tcg_temp_new(TCG_TYPE_TL); |
|
729 |
tcg_gen_movi_tl(r_zero, 0); |
|
730 |
|
|
731 |
tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1); |
|
377 | 732 |
|
378 | 733 |
gen_movl_npc_im(npc1); |
379 | 734 |
gen_op_jmp_label(l2); |
... | ... | |
387 | 742 |
static inline void flush_T2(DisasContext * dc) |
388 | 743 |
{ |
389 | 744 |
if (dc->npc == JUMP_PC) { |
390 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); |
|
745 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
|
|
391 | 746 |
dc->npc = DYNAMIC_PC; |
392 | 747 |
} |
393 | 748 |
} |
... | ... | |
395 | 750 |
static inline void save_npc(DisasContext * dc) |
396 | 751 |
{ |
397 | 752 |
if (dc->npc == JUMP_PC) { |
398 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); |
|
753 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
|
|
399 | 754 |
dc->npc = DYNAMIC_PC; |
400 | 755 |
} else if (dc->npc != DYNAMIC_PC) { |
401 | 756 |
gen_movl_npc_im(dc->npc); |
... | ... | |
411 | 766 |
static inline void gen_mov_pc_npc(DisasContext * dc) |
412 | 767 |
{ |
413 | 768 |
if (dc->npc == JUMP_PC) { |
414 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); |
|
769 |
gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
|
|
415 | 770 |
tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc)); |
416 | 771 |
tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc)); |
417 | 772 |
dc->pc = DYNAMIC_PC; |
... | ... | |
432 | 787 |
tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc)); |
433 | 788 |
} |
434 | 789 |
|
435 |
static GenOpFunc * const gen_cond[2][16] = { |
|
436 |
{ |
|
437 |
gen_op_eval_bn, |
|
438 |
gen_op_eval_be, |
|
439 |
gen_op_eval_ble, |
|
440 |
gen_op_eval_bl, |
|
441 |
gen_op_eval_bleu, |
|
442 |
gen_op_eval_bcs, |
|
443 |
gen_op_eval_bneg, |
|
444 |
gen_op_eval_bvs, |
|
445 |
gen_op_eval_ba, |
|
446 |
gen_op_eval_bne, |
|
447 |
gen_op_eval_bg, |
|
448 |
gen_op_eval_bge, |
|
449 |
gen_op_eval_bgu, |
|
450 |
gen_op_eval_bcc, |
|
451 |
gen_op_eval_bpos, |
|
452 |
gen_op_eval_bvc, |
|
453 |
}, |
|
454 |
{ |
|
455 |
#ifdef TARGET_SPARC64 |
|
456 |
gen_op_eval_bn, |
|
457 |
gen_op_eval_xbe, |
|
458 |
gen_op_eval_xble, |
|
459 |
gen_op_eval_xbl, |
|
460 |
gen_op_eval_xbleu, |
|
461 |
gen_op_eval_xbcs, |
|
462 |
gen_op_eval_xbneg, |
|
463 |
gen_op_eval_xbvs, |
|
464 |
gen_op_eval_ba, |
|
465 |
gen_op_eval_xbne, |
|
466 |
gen_op_eval_xbg, |
|
467 |
gen_op_eval_xbge, |
|
468 |
gen_op_eval_xbgu, |
|
469 |
gen_op_eval_xbcc, |
|
470 |
gen_op_eval_xbpos, |
|
471 |
gen_op_eval_xbvc, |
|
472 |
#endif |
|
473 |
}, |
|
474 |
}; |
|
790 |
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond) |
|
791 |
{ |
|
792 |
TCGv r_src; |
|
475 | 793 |
|
476 |
static GenOpFunc * const gen_fcond[4][16] = { |
|
477 |
{ |
|
478 |
gen_op_eval_bn, |
|
479 |
gen_op_eval_fbne, |
|
480 |
gen_op_eval_fblg, |
|
481 |
gen_op_eval_fbul, |
|
482 |
gen_op_eval_fbl, |
|
483 |
gen_op_eval_fbug, |
|
484 |
gen_op_eval_fbg, |
|
485 |
gen_op_eval_fbu, |
|
486 |
gen_op_eval_ba, |
|
487 |
gen_op_eval_fbe, |
|
488 |
gen_op_eval_fbue, |
|
489 |
gen_op_eval_fbge, |
|
490 |
gen_op_eval_fbuge, |
|
491 |
gen_op_eval_fble, |
|
492 |
gen_op_eval_fbule, |
|
493 |
gen_op_eval_fbo, |
|
494 |
}, |
|
794 |
r_src = tcg_temp_new(TCG_TYPE_TL); |
|
495 | 795 |
#ifdef TARGET_SPARC64 |
496 |
{ |
|
497 |
gen_op_eval_bn, |
|
498 |
gen_op_eval_fbne_fcc1, |
|
499 |
gen_op_eval_fblg_fcc1, |
|
500 |
gen_op_eval_fbul_fcc1, |
|
501 |
gen_op_eval_fbl_fcc1, |
|
502 |
gen_op_eval_fbug_fcc1, |
|
503 |
gen_op_eval_fbg_fcc1, |
|
504 |
gen_op_eval_fbu_fcc1, |
|
505 |
gen_op_eval_ba, |
|
506 |
gen_op_eval_fbe_fcc1, |
|
507 |
gen_op_eval_fbue_fcc1, |
|
508 |
gen_op_eval_fbge_fcc1, |
|
509 |
gen_op_eval_fbuge_fcc1, |
|
510 |
gen_op_eval_fble_fcc1, |
|
511 |
gen_op_eval_fbule_fcc1, |
|
512 |
gen_op_eval_fbo_fcc1, |
|
513 |
}, |
|
514 |
{ |
|
515 |
gen_op_eval_bn, |
|
516 |
gen_op_eval_fbne_fcc2, |
|
517 |
gen_op_eval_fblg_fcc2, |
|
518 |
gen_op_eval_fbul_fcc2, |
|
519 |
gen_op_eval_fbl_fcc2, |
|
520 |
gen_op_eval_fbug_fcc2, |
|
521 |
gen_op_eval_fbg_fcc2, |
|
522 |
gen_op_eval_fbu_fcc2, |
|
523 |
gen_op_eval_ba, |
|
524 |
gen_op_eval_fbe_fcc2, |
|
525 |
gen_op_eval_fbue_fcc2, |
|
526 |
gen_op_eval_fbge_fcc2, |
|
527 |
gen_op_eval_fbuge_fcc2, |
|
528 |
gen_op_eval_fble_fcc2, |
|
529 |
gen_op_eval_fbule_fcc2, |
|
530 |
gen_op_eval_fbo_fcc2, |
|
531 |
}, |
|
532 |
{ |
|
533 |
gen_op_eval_bn, |
|
534 |
gen_op_eval_fbne_fcc3, |
|
535 |
gen_op_eval_fblg_fcc3, |
|
536 |
gen_op_eval_fbul_fcc3, |
|
537 |
gen_op_eval_fbl_fcc3, |
|
538 |
gen_op_eval_fbug_fcc3, |
|
539 |
gen_op_eval_fbg_fcc3, |
|
540 |
gen_op_eval_fbu_fcc3, |
|
541 |
gen_op_eval_ba, |
|
542 |
gen_op_eval_fbe_fcc3, |
|
543 |
gen_op_eval_fbue_fcc3, |
|
544 |
gen_op_eval_fbge_fcc3, |
|
545 |
gen_op_eval_fbuge_fcc3, |
|
546 |
gen_op_eval_fble_fcc3, |
|
547 |
gen_op_eval_fbule_fcc3, |
|
548 |
gen_op_eval_fbo_fcc3, |
|
549 |
}, |
|
796 |
if (cc) |
|
797 |
tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, xcc)); |
|
798 |
else |
|
799 |
tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, psr)); |
|
550 | 800 |
#else |
551 |
{}, {}, {},
|
|
801 |
tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, psr));
|
|
552 | 802 |
#endif |
553 |
}; |
|
803 |
switch (cond) { |
|
804 |
case 0x0: |
|
805 |
gen_op_eval_bn(r_dst); |
|
806 |
break; |
|
807 |
case 0x1: |
|
808 |
gen_op_eval_be(r_dst, r_src); |
|
809 |
break; |
|
810 |
case 0x2: |
|
811 |
gen_op_eval_ble(r_dst, r_src); |
|
812 |
break; |
|
813 |
case 0x3: |
|
814 |
gen_op_eval_bl(r_dst, r_src); |
|
815 |
break; |
|
816 |
case 0x4: |
|
817 |
gen_op_eval_bleu(r_dst, r_src); |
|
818 |
break; |
|
819 |
case 0x5: |
|
820 |
gen_op_eval_bcs(r_dst, r_src); |
|
821 |
break; |
|
822 |
case 0x6: |
|
823 |
gen_op_eval_bneg(r_dst, r_src); |
|
824 |
break; |
|
825 |
case 0x7: |
|
826 |
gen_op_eval_bvs(r_dst, r_src); |
|
827 |
break; |
|
828 |
case 0x8: |
|
829 |
gen_op_eval_ba(r_dst); |
|
830 |
break; |
|
831 |
case 0x9: |
|
832 |
gen_op_eval_bne(r_dst, r_src); |
|
833 |
break; |
|
834 |
case 0xa: |
|
835 |
gen_op_eval_bg(r_dst, r_src); |
|
836 |
break; |
|
837 |
case 0xb: |
|
838 |
gen_op_eval_bge(r_dst, r_src); |
|
839 |
break; |
|
840 |
case 0xc: |
|
841 |
gen_op_eval_bgu(r_dst, r_src); |
|
842 |
break; |
|
843 |
case 0xd: |
|
844 |
gen_op_eval_bcc(r_dst, r_src); |
|
845 |
break; |
|
846 |
case 0xe: |
|
847 |
gen_op_eval_bpos(r_dst, r_src); |
|
848 |
break; |
|
849 |
case 0xf: |
|
850 |
gen_op_eval_bvc(r_dst, r_src); |
|
851 |
break; |
|
852 |
} |
|
853 |
} |
|
554 | 854 |
|
555 |
#ifdef TARGET_SPARC64 |
|
556 |
static void gen_cond_reg(int cond) |
|
855 |
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond) |
|
557 | 856 |
{ |
558 |
switch (cond) { |
|
559 |
case 0x1: |
|
560 |
gen_op_eval_brz(); |
|
561 |
break; |
|
562 |
case 0x2: |
|
563 |
gen_op_eval_brlez(); |
|
564 |
break; |
|
565 |
case 0x3: |
|
566 |
gen_op_eval_brlz(); |
|
567 |
break; |
|
568 |
case 0x5: |
|
569 |
gen_op_eval_brnz(); |
|
570 |
break; |
|
571 |
case 0x6: |
|
572 |
gen_op_eval_brgz(); |
|
573 |
break; |
|
574 |
default: |
|
575 |
case 0x7: |
|
576 |
gen_op_eval_brgez(); |
|
577 |
break; |
|
578 |
} |
|
857 |
TCGv r_src; |
|
858 |
unsigned int offset; |
|
859 |
|
|
860 |
r_src = tcg_temp_new(TCG_TYPE_TL); |
|
861 |
tcg_gen_ld_tl(r_src, cpu_env, offsetof(CPUSPARCState, fsr)); |
|
862 |
|
|
863 |
switch (cc) { |
|
864 |
default: |
|
865 |
case 0x0: |
|
866 |
offset = 0; |
|
867 |
break; |
|
868 |
case 0x1: |
|
869 |
offset = 32 - 10; |
|
870 |
break; |
|
871 |
case 0x2: |
|
872 |
offset = 34 - 10; |
|
873 |
break; |
|
874 |
case 0x3: |
|
875 |
offset = 36 - 10; |
|
876 |
break; |
|
877 |
} |
|
878 |
|
|
879 |
switch (cond) { |
|
880 |
case 0x0: |
|
881 |
gen_op_eval_bn(r_dst); |
|
882 |
break; |
|
883 |
case 0x1: |
|
884 |
gen_op_eval_fbne(r_dst, r_src, offset); |
|
885 |
break; |
|
886 |
case 0x2: |
|
887 |
gen_op_eval_fblg(r_dst, r_src, offset); |
|
888 |
break; |
|
889 |
case 0x3: |
|
890 |
gen_op_eval_fbul(r_dst, r_src, offset); |
|
891 |
break; |
|
892 |
case 0x4: |
|
893 |
gen_op_eval_fbl(r_dst, r_src, offset); |
|
894 |
break; |
|
895 |
case 0x5: |
|
896 |
gen_op_eval_fbug(r_dst, r_src, offset); |
|
897 |
break; |
|
898 |
case 0x6: |
|
899 |
gen_op_eval_fbg(r_dst, r_src, offset); |
|
900 |
break; |
|
901 |
case 0x7: |
|
902 |
gen_op_eval_fbu(r_dst, r_src, offset); |
|
903 |
break; |
|
904 |
case 0x8: |
|
905 |
gen_op_eval_ba(r_dst); |
|
906 |
break; |
|
907 |
case 0x9: |
|
908 |
gen_op_eval_fbe(r_dst, r_src, offset); |
|
909 |
break; |
|
910 |
case 0xa: |
|
911 |
gen_op_eval_fbue(r_dst, r_src, offset); |
|
912 |
break; |
|
913 |
case 0xb: |
|
914 |
gen_op_eval_fbge(r_dst, r_src, offset); |
|
915 |
break; |
|
916 |
case 0xc: |
|
917 |
gen_op_eval_fbuge(r_dst, r_src, offset); |
|
918 |
break; |
|
919 |
case 0xd: |
|
920 |
gen_op_eval_fble(r_dst, r_src, offset); |
|
921 |
break; |
|
922 |
case 0xe: |
|
923 |
gen_op_eval_fbule(r_dst, r_src, offset); |
|
924 |
break; |
|
925 |
case 0xf: |
|
926 |
gen_op_eval_fbo(r_dst, r_src, offset); |
|
927 |
break; |
|
928 |
} |
|
579 | 929 |
} |
580 | 930 |
|
931 |
#ifdef TARGET_SPARC64 |
|
581 | 932 |
// Inverted logic |
582 | 933 |
static const int gen_tcg_cond_reg[8] = { |
583 | 934 |
-1, |
... | ... | |
589 | 940 |
TCG_COND_LE, |
590 | 941 |
TCG_COND_LT, |
591 | 942 |
}; |
943 |
|
|
944 |
static inline void gen_cond_reg(TCGv r_dst, int cond) |
|
945 |
{ |
|
946 |
TCGv r_zero; |
|
947 |
int l1; |
|
948 |
|
|
949 |
l1 = gen_new_label(); |
|
950 |
r_zero = tcg_temp_new(TCG_TYPE_TL); |
|
951 |
tcg_gen_movi_tl(r_zero, 0); |
|
952 |
tcg_gen_mov_tl(r_dst, r_zero); |
|
953 |
tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1); |
|
954 |
tcg_gen_movi_tl(r_dst, 1); |
|
955 |
gen_set_label(l1); |
|
956 |
} |
|
592 | 957 |
#endif |
593 | 958 |
|
594 | 959 |
/* XXX: potentially incorrect if dynamic npc */ |
... | ... | |
617 | 982 |
} |
618 | 983 |
} else { |
619 | 984 |
flush_T2(dc); |
620 |
gen_cond[cc][cond]();
|
|
985 |
gen_cond(cpu_T[2], cc, cond);
|
|
621 | 986 |
if (a) { |
622 |
gen_branch_a(dc, target, dc->npc); |
|
987 |
gen_branch_a(dc, target, dc->npc, cpu_T[2]);
|
|
623 | 988 |
dc->is_br = 1; |
624 | 989 |
} else { |
625 | 990 |
dc->pc = dc->npc; |
... | ... | |
656 | 1021 |
} |
657 | 1022 |
} else { |
658 | 1023 |
flush_T2(dc); |
659 |
gen_fcond[cc][cond]();
|
|
1024 |
gen_fcond(cpu_T[2], cc, cond);
|
|
660 | 1025 |
if (a) { |
661 |
gen_branch_a(dc, target, dc->npc); |
|
1026 |
gen_branch_a(dc, target, dc->npc, cpu_T[2]);
|
|
662 | 1027 |
dc->is_br = 1; |
663 | 1028 |
} else { |
664 | 1029 |
dc->pc = dc->npc; |
... | ... | |
677 | 1042 |
target_ulong target = dc->pc + offset; |
678 | 1043 |
|
679 | 1044 |
flush_T2(dc); |
680 |
gen_cond_reg(cond); |
|
1045 |
gen_cond_reg(cpu_T[2], cond);
|
|
681 | 1046 |
if (a) { |
682 |
gen_branch_a(dc, target, dc->npc); |
|
1047 |
gen_branch_a(dc, target, dc->npc, cpu_T[2]);
|
|
683 | 1048 |
dc->is_br = 1; |
684 | 1049 |
} else { |
685 | 1050 |
dc->pc = dc->npc; |
... | ... | |
1114 | 1479 |
} |
1115 | 1480 |
#endif |
1116 | 1481 |
|
1117 |
static inline void gen_mov_reg_C(TCGv reg) |
|
1118 |
{ |
|
1119 |
tcg_gen_ld_i32(reg, cpu_env, offsetof(CPUSPARCState, psr)); |
|
1120 |
tcg_gen_shri_i32(reg, reg, 20); |
|
1121 |
tcg_gen_andi_i32(reg, reg, 0x1); |
|
1122 |
} |
|
1123 |
|
|
1124 | 1482 |
/* before an instruction, dc->pc must be static */ |
1125 | 1483 |
static void disas_sparc_insn(DisasContext * dc) |
1126 | 1484 |
{ |
... | ... | |
1262 | 1620 |
flush_T2(dc); |
1263 | 1621 |
save_state(dc); |
1264 | 1622 |
if (cc == 0) |
1265 |
gen_cond[0][cond]();
|
|
1623 |
gen_cond(cpu_T[2], 0, cond);
|
|
1266 | 1624 |
else if (cc == 2) |
1267 |
gen_cond[1][cond]();
|
|
1625 |
gen_cond(cpu_T[2], 1, cond);
|
|
1268 | 1626 |
else |
1269 | 1627 |
goto illegal_insn; |
1270 | 1628 |
#else |
1271 | 1629 |
flush_T2(dc); |
1272 | 1630 |
save_state(dc); |
1273 |
gen_cond[0][cond]();
|
|
1631 |
gen_cond(cpu_T[2], 0, cond);
|
|
1274 | 1632 |
#endif |
1275 | 1633 |
tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]); |
1276 | 1634 |
} |
... | ... | |
1914 | 2272 |
gen_movl_reg_T0(rs1); |
1915 | 2273 |
tcg_gen_movi_tl(r_zero, 0); |
1916 | 2274 |
tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1); |
1917 |
gen_op_load_fpr_FT1(rs2);
|
|
2275 |
gen_op_load_fpr_FT0(rs2);
|
|
1918 | 2276 |
gen_op_store_FT0_fpr(rd); |
1919 | 2277 |
gen_set_label(l1); |
1920 | 2278 |
break; |
... | ... | |
1929 | 2287 |
gen_movl_reg_T0(rs1); |
1930 | 2288 |
tcg_gen_movi_tl(r_zero, 0); |
1931 | 2289 |
tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1); |
1932 |
gen_op_load_fpr_DT1(DFPREG(rs2));
|
|
2290 |
gen_op_load_fpr_DT0(DFPREG(rs2));
|
|
1933 | 2291 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
1934 | 2292 |
gen_set_label(l1); |
1935 | 2293 |
break; |
... | ... | |
1945 | 2303 |
gen_movl_reg_T0(rs1); |
1946 | 2304 |
tcg_gen_movi_tl(r_zero, 0); |
1947 | 2305 |
tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1); |
1948 |
gen_op_load_fpr_QT1(QFPREG(rs2));
|
|
2306 |
gen_op_load_fpr_QT0(QFPREG(rs2));
|
|
1949 | 2307 |
gen_op_store_QT0_fpr(QFPREG(rd)); |
1950 | 2308 |
gen_set_label(l1); |
1951 | 2309 |
break; |
... | ... | |
1956 | 2314 |
#endif |
1957 | 2315 |
switch (xop) { |
1958 | 2316 |
#ifdef TARGET_SPARC64 |
2317 |
#define FMOVCC(size_FDQ, fcc) \ |
|
2318 |
{ \ |
|
2319 |
TCGv r_zero, r_cond; \ |
|
2320 |
int l1; \ |
|
2321 |
\ |
|
2322 |
l1 = gen_new_label(); \ |
|
2323 |
r_zero = tcg_temp_new(TCG_TYPE_TL); \ |
|
2324 |
r_cond = tcg_temp_new(TCG_TYPE_TL); \ |
|
2325 |
tcg_gen_movi_tl(r_zero, 0); \ |
|
2326 |
cond = GET_FIELD_SP(insn, 14, 17); \ |
|
2327 |
gen_fcond(r_cond, fcc, cond); \ |
|
2328 |
tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1); \ |
|
2329 |
glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \ |
|
2330 |
glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \ |
|
2331 |
gen_set_label(l1); \ |
|
2332 |
} |
|
1959 | 2333 |
case 0x001: /* V9 fmovscc %fcc0 */ |
1960 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
1961 |
gen_op_load_fpr_FT0(rd); |
|
1962 |
gen_op_load_fpr_FT1(rs2); |
|
1963 |
flush_T2(dc); |
|
1964 |
gen_fcond[0][cond](); |
|
1965 |
gen_op_fmovs_cc(); |
|
1966 |
gen_op_store_FT0_fpr(rd); |
|
2334 |
FMOVCC(F, 0); |
|
1967 | 2335 |
break; |
1968 | 2336 |
case 0x002: /* V9 fmovdcc %fcc0 */ |
1969 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
1970 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
1971 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
1972 |
flush_T2(dc); |
|
1973 |
gen_fcond[0][cond](); |
|
1974 |
gen_op_fmovd_cc(); |
|
1975 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2337 |
FMOVCC(D, 0); |
|
1976 | 2338 |
break; |
1977 | 2339 |
case 0x003: /* V9 fmovqcc %fcc0 */ |
1978 | 2340 |
#if defined(CONFIG_USER_ONLY) |
1979 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
1980 |
gen_op_load_fpr_QT0(QFPREG(rd)); |
|
1981 |
gen_op_load_fpr_QT1(QFPREG(rs2)); |
|
1982 |
flush_T2(dc); |
|
1983 |
gen_fcond[0][cond](); |
|
1984 |
gen_op_fmovq_cc(); |
|
1985 |
gen_op_store_QT0_fpr(QFPREG(rd)); |
|
2341 |
FMOVCC(Q, 0); |
|
1986 | 2342 |
break; |
1987 | 2343 |
#else |
1988 | 2344 |
goto nfpu_insn; |
1989 | 2345 |
#endif |
1990 | 2346 |
case 0x041: /* V9 fmovscc %fcc1 */ |
1991 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
1992 |
gen_op_load_fpr_FT0(rd); |
|
1993 |
gen_op_load_fpr_FT1(rs2); |
|
1994 |
flush_T2(dc); |
|
1995 |
gen_fcond[1][cond](); |
|
1996 |
gen_op_fmovs_cc(); |
|
1997 |
gen_op_store_FT0_fpr(rd); |
|
2347 |
FMOVCC(F, 1); |
|
1998 | 2348 |
break; |
1999 | 2349 |
case 0x042: /* V9 fmovdcc %fcc1 */ |
2000 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2001 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
2002 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
2003 |
flush_T2(dc); |
|
2004 |
gen_fcond[1][cond](); |
|
2005 |
gen_op_fmovd_cc(); |
|
2006 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2350 |
FMOVCC(D, 1); |
|
2007 | 2351 |
break; |
2008 | 2352 |
case 0x043: /* V9 fmovqcc %fcc1 */ |
2009 | 2353 |
#if defined(CONFIG_USER_ONLY) |
2010 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2011 |
gen_op_load_fpr_QT0(QFPREG(rd)); |
|
2012 |
gen_op_load_fpr_QT1(QFPREG(rs2)); |
|
2013 |
flush_T2(dc); |
|
2014 |
gen_fcond[1][cond](); |
|
2015 |
gen_op_fmovq_cc(); |
|
2016 |
gen_op_store_QT0_fpr(QFPREG(rd)); |
|
2354 |
FMOVCC(Q, 1); |
|
2017 | 2355 |
break; |
2018 | 2356 |
#else |
2019 | 2357 |
goto nfpu_insn; |
2020 | 2358 |
#endif |
2021 | 2359 |
case 0x081: /* V9 fmovscc %fcc2 */ |
2022 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2023 |
gen_op_load_fpr_FT0(rd); |
|
2024 |
gen_op_load_fpr_FT1(rs2); |
|
2025 |
flush_T2(dc); |
|
2026 |
gen_fcond[2][cond](); |
|
2027 |
gen_op_fmovs_cc(); |
|
2028 |
gen_op_store_FT0_fpr(rd); |
|
2360 |
FMOVCC(F, 2); |
|
2029 | 2361 |
break; |
2030 | 2362 |
case 0x082: /* V9 fmovdcc %fcc2 */ |
2031 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2032 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
2033 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
2034 |
flush_T2(dc); |
|
2035 |
gen_fcond[2][cond](); |
|
2036 |
gen_op_fmovd_cc(); |
|
2037 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2363 |
FMOVCC(D, 2); |
|
2038 | 2364 |
break; |
2039 | 2365 |
case 0x083: /* V9 fmovqcc %fcc2 */ |
2040 | 2366 |
#if defined(CONFIG_USER_ONLY) |
2041 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2042 |
gen_op_load_fpr_QT0(rd); |
|
2043 |
gen_op_load_fpr_QT1(rs2); |
|
2044 |
flush_T2(dc); |
|
2045 |
gen_fcond[2][cond](); |
|
2046 |
gen_op_fmovq_cc(); |
|
2047 |
gen_op_store_QT0_fpr(rd); |
|
2367 |
FMOVCC(Q, 2); |
|
2048 | 2368 |
break; |
2049 | 2369 |
#else |
2050 | 2370 |
goto nfpu_insn; |
2051 | 2371 |
#endif |
2052 | 2372 |
case 0x0c1: /* V9 fmovscc %fcc3 */ |
2053 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2054 |
gen_op_load_fpr_FT0(rd); |
|
2055 |
gen_op_load_fpr_FT1(rs2); |
|
2056 |
flush_T2(dc); |
|
2057 |
gen_fcond[3][cond](); |
|
2058 |
gen_op_fmovs_cc(); |
|
2059 |
gen_op_store_FT0_fpr(rd); |
|
2373 |
FMOVCC(F, 3); |
|
2060 | 2374 |
break; |
2061 | 2375 |
case 0x0c2: /* V9 fmovdcc %fcc3 */ |
2062 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2063 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
2064 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
2065 |
flush_T2(dc); |
|
2066 |
gen_fcond[3][cond](); |
|
2067 |
gen_op_fmovd_cc(); |
|
2068 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2376 |
FMOVCC(D, 3); |
|
2069 | 2377 |
break; |
2070 | 2378 |
case 0x0c3: /* V9 fmovqcc %fcc3 */ |
2071 | 2379 |
#if defined(CONFIG_USER_ONLY) |
2072 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2073 |
gen_op_load_fpr_QT0(QFPREG(rd)); |
|
2074 |
gen_op_load_fpr_QT1(QFPREG(rs2)); |
|
2075 |
flush_T2(dc); |
|
2076 |
gen_fcond[3][cond](); |
|
2077 |
gen_op_fmovq_cc(); |
|
2078 |
gen_op_store_QT0_fpr(QFPREG(rd)); |
|
2380 |
FMOVCC(Q, 3); |
|
2079 | 2381 |
break; |
2080 | 2382 |
#else |
2081 | 2383 |
goto nfpu_insn; |
2082 | 2384 |
#endif |
2385 |
#undef FMOVCC |
|
2386 |
#define FMOVCC(size_FDQ, icc) \ |
|
2387 |
{ \ |
|
2388 |
TCGv r_zero, r_cond; \ |
|
2389 |
int l1; \ |
|
2390 |
\ |
|
2391 |
l1 = gen_new_label(); \ |
|
2392 |
r_zero = tcg_temp_new(TCG_TYPE_TL); \ |
|
2393 |
r_cond = tcg_temp_new(TCG_TYPE_TL); \ |
|
2394 |
tcg_gen_movi_tl(r_zero, 0); \ |
|
2395 |
cond = GET_FIELD_SP(insn, 14, 17); \ |
|
2396 |
gen_cond(r_cond, icc, cond); \ |
|
2397 |
tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1); \ |
|
2398 |
glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \ |
|
2399 |
glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \ |
|
2400 |
gen_set_label(l1); \ |
|
2401 |
} |
|
2402 |
|
|
2083 | 2403 |
case 0x101: /* V9 fmovscc %icc */ |
2084 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2085 |
gen_op_load_fpr_FT0(rd); |
|
2086 |
gen_op_load_fpr_FT1(rs2); |
|
2087 |
flush_T2(dc); |
|
2088 |
gen_cond[0][cond](); |
|
2089 |
gen_op_fmovs_cc(); |
|
2090 |
gen_op_store_FT0_fpr(rd); |
|
2404 |
FMOVCC(F, 0); |
|
2091 | 2405 |
break; |
2092 | 2406 |
case 0x102: /* V9 fmovdcc %icc */ |
2093 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2094 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
2095 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
2096 |
flush_T2(dc); |
|
2097 |
gen_cond[0][cond](); |
|
2098 |
gen_op_fmovd_cc(); |
|
2099 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2100 |
break; |
|
2407 |
FMOVCC(D, 0); |
|
2101 | 2408 |
case 0x103: /* V9 fmovqcc %icc */ |
2102 | 2409 |
#if defined(CONFIG_USER_ONLY) |
2103 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2104 |
gen_op_load_fpr_QT0(rd); |
|
2105 |
gen_op_load_fpr_QT1(rs2); |
|
2106 |
flush_T2(dc); |
|
2107 |
gen_cond[0][cond](); |
|
2108 |
gen_op_fmovq_cc(); |
|
2109 |
gen_op_store_QT0_fpr(rd); |
|
2410 |
FMOVCC(D, 0); |
|
2110 | 2411 |
break; |
2111 | 2412 |
#else |
2112 | 2413 |
goto nfpu_insn; |
2113 | 2414 |
#endif |
2114 | 2415 |
case 0x181: /* V9 fmovscc %xcc */ |
2115 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2116 |
gen_op_load_fpr_FT0(rd); |
|
2117 |
gen_op_load_fpr_FT1(rs2); |
|
2118 |
flush_T2(dc); |
|
2119 |
gen_cond[1][cond](); |
|
2120 |
gen_op_fmovs_cc(); |
|
2121 |
gen_op_store_FT0_fpr(rd); |
|
2416 |
FMOVCC(F, 1); |
|
2122 | 2417 |
break; |
2123 | 2418 |
case 0x182: /* V9 fmovdcc %xcc */ |
2124 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2125 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
|
2126 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
|
2127 |
flush_T2(dc); |
|
2128 |
gen_cond[1][cond](); |
|
2129 |
gen_op_fmovd_cc(); |
|
2130 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
|
2419 |
FMOVCC(D, 1); |
|
2131 | 2420 |
break; |
2132 | 2421 |
case 0x183: /* V9 fmovqcc %xcc */ |
2133 | 2422 |
#if defined(CONFIG_USER_ONLY) |
2134 |
cond = GET_FIELD_SP(insn, 14, 17); |
|
2135 |
gen_op_load_fpr_QT0(rd); |
|
2136 |
gen_op_load_fpr_QT1(rs2); |
|
2137 |
flush_T2(dc); |
|
2138 |
gen_cond[1][cond](); |
|
2139 |
gen_op_fmovq_cc(); |
|
2140 |
gen_op_store_QT0_fpr(rd); |
|
2423 |
FMOVCC(Q, 1); |
|
2141 | 2424 |
break; |
2142 | 2425 |
#else |
2143 | 2426 |
goto nfpu_insn; |
2144 | 2427 |
#endif |
2428 |
#undef FMOVCC |
|
2145 | 2429 |
#endif |
2146 | 2430 |
case 0x51: /* fcmps, V9 %fcc */ |
2147 | 2431 |
gen_op_load_fpr_FT0(rs1); |
... | ... | |
2347 | 2631 |
if (xop & 0x10) |
2348 | 2632 |
gen_op_addx_T1_T0_cc(); |
2349 | 2633 |
else { |
2350 |
gen_mov_reg_C(cpu_tmp0); |
|
2634 |
tcg_gen_ld_i32(cpu_tmp0, cpu_env, |
|
2635 |
offsetof(CPUSPARCState, psr)); |
|
2636 |
gen_mov_reg_C(cpu_tmp0, cpu_tmp0); |
|
2351 | 2637 |
tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0); |
2352 | 2638 |
tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
2353 | 2639 |
} |
... | ... | |
2371 | 2657 |
if (xop & 0x10) |
2372 | 2658 |
gen_op_subx_T1_T0_cc(); |
2373 | 2659 |
else { |
2374 |
gen_mov_reg_C(cpu_tmp0); |
|
2660 |
tcg_gen_ld_i32(cpu_tmp0, cpu_env, |
|
2661 |
offsetof(CPUSPARCState, psr)); |
|
2662 |
gen_mov_reg_C(cpu_tmp0, cpu_tmp0); |
|
2375 | 2663 |
tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0); |
2376 | 2664 |
tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
2377 | 2665 |
} |
... | ... | |
2751 | 3039 |
flush_T2(dc); |
2752 | 3040 |
if (insn & (1 << 18)) { |
2753 | 3041 |
if (cc == 0) |
2754 |
gen_cond[0][cond]();
|
|
3042 |
gen_cond(cpu_T[2], 0, cond);
|
|
2755 | 3043 |
else if (cc == 2) |
2756 |
gen_cond[1][cond]();
|
|
3044 |
gen_cond(cpu_T[2], 1, cond);
|
|
2757 | 3045 |
else |
2758 | 3046 |
goto illegal_insn; |
2759 | 3047 |
} else { |
2760 |
gen_fcond[cc][cond]();
|
|
3048 |
gen_fcond(cpu_T[2], cc, cond);
|
|
2761 | 3049 |
} |
2762 | 3050 |
|
2763 | 3051 |
l1 = gen_new_label(); |
... | ... | |
3817 | 4105 |
gen_op_next_insn(); |
3818 | 4106 |
} else if (dc->npc == JUMP_PC) { |
3819 | 4107 |
/* we can do a static jump */ |
3820 |
gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]); |
|
4108 |
gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
|
|
3821 | 4109 |
dc->is_br = 1; |
3822 | 4110 |
} else { |
3823 | 4111 |
dc->pc = dc->npc; |
Also available in: Unified diff