Commit 53c374879442751032608a488740686b794eb234

Authored by blueswir1
1 parent bc352085

Sparc code generator update

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5009 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/sparc/tcg-target.c
... ... @@ -137,8 +137,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
137 137 case 'L': /* qemu_ld/st constraint */
138 138 ct->ct |= TCG_CT_REG;
139 139 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
140   - tcg_regset_reset_reg(ct->u.regs, TCG_REG_I0);
141   - tcg_regset_reset_reg(ct->u.regs, TCG_REG_I1);
  140 + // Helper args
  141 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
  142 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
  143 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
  144 + // Internal use
  145 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
  146 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
142 147 break;
143 148 case 'I':
144 149 ct->ct |= TCG_CT_CONST_S11;
... ... @@ -290,7 +295,7 @@ static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
290 295  
291 296 static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
292 297 {
293   - if (check_fit_i32(arg, 13))
  298 + if (check_fit_i32(arg, 12))
294 299 tcg_out_movi_imm13(s, ret, arg);
295 300 else {
296 301 tcg_out_sethi(s, ret, arg);
... ... @@ -393,6 +398,18 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
393 398 }
394 399 }
395 400  
  401 +static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
  402 +{
  403 + if (val != 0) {
  404 + if (check_fit_tl(val, 13))
  405 + tcg_out_arithi(s, reg, reg, val, ARITH_AND);
  406 + else {
  407 + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
  408 + tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
  409 + }
  410 + }
  411 +}
  412 +
396 413 static inline void tcg_out_nop(TCGContext *s)
397 414 {
398 415 tcg_out_sethi(s, TCG_REG_G0, 0);
... ... @@ -480,9 +497,10 @@ static const void * const qemu_st_helpers[4] = {
480 497 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
481 498 int opc)
482 499 {
483   - int addr_reg, data_reg, r0, r1, mem_index, s_bits, ld_op;
  500 + int addr_reg, data_reg, r0, r1, arg0, arg1, mem_index, s_bits;
  501 + int target_ld_op, host_ld_op;
484 502 #if defined(CONFIG_SOFTMMU)
485   - uint8_t *label1_ptr, *label2_ptr;
  503 + uint32_t *label1_ptr, *label2_ptr;
486 504 #endif
487 505  
488 506 data_reg = *args++;
... ... @@ -490,15 +508,24 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
490 508 mem_index = *args;
491 509 s_bits = opc & 3;
492 510  
493   - r0 = TCG_REG_I0;
494   - r1 = TCG_REG_I1;
  511 + r0 = TCG_REG_L0;
  512 + r1 = TCG_REG_L1;
  513 + arg0 = TCG_REG_O0;
  514 + arg1 = TCG_REG_O1;
495 515  
496 516 #if TARGET_LONG_BITS == 32
497   - ld_op = LDUW;
  517 + target_ld_op = LDUW;
498 518 #else
499   - ld_op = LDX;
  519 + target_ld_op = LDX;
500 520 #endif
501 521  
  522 +#ifdef __arch64__
  523 + host_ld_op = LDX;
  524 +#else
  525 + host_ld_op = LDUW;
  526 +#endif
  527 +
  528 +
502 529 #if defined(CONFIG_SOFTMMU)
503 530 /* srl addr_reg, x, r1 */
504 531 tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
... ... @@ -508,56 +535,59 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
508 535 ARITH_AND);
509 536  
510 537 /* and r1, x, r1 */
511   - tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
512   - ARITH_AND);
  538 + tcg_out_andi(s, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
513 539  
514 540 /* add r1, x, r1 */
515   - tcg_out_arithi(s, r1, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_read),
516   - ARITH_ADD);
  541 + tcg_out_addi(s, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
517 542  
518   - /* ld [env + r1], r1 */
519   - tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op);
  543 + /* add env, r1, r1 */
  544 + tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
520 545  
521   - /* subcc r0, r1, %g0 */
522   - tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC);
  546 + /* ld [r1], arg1 */
  547 + tcg_out32(s, target_ld_op | INSN_RD(arg1) | INSN_RS1(r1) | INSN_RS2(TCG_REG_G0));
  548 +
  549 + /* subcc r0, arg1, %g0 */
  550 + tcg_out_arith(s, TCG_REG_G0, r0, arg1, ARITH_SUBCC);
523 551  
524 552 /* will become:
525 553 be label1 */
526   - label1_ptr = s->code_ptr;
  554 + label1_ptr = (uint32_t *)s->code_ptr;
527 555 tcg_out32(s, 0);
528 556  
529   - /* mov (delay slot)*/
530   - tcg_out_mov(s, r0, addr_reg);
  557 + /* mov (delay slot) */
  558 + tcg_out_mov(s, arg0, addr_reg);
531 559  
532 560 /* XXX: move that code at the end of the TB */
  561 + /* qemu_ld_helper[s_bits](arg0, arg1) */
533 562 tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
534 563 - (tcg_target_ulong)s->code_ptr) >> 2)
535 564 & 0x3fffffff));
536   - /* mov (delay slot)*/
537   - tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index);
  565 + /* mov (delay slot) */
  566 + tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
538 567  
  568 + /* data_reg = sign_extend(arg0) */
539 569 switch(opc) {
540 570 case 0 | 4:
541   - /* sll i0, 24/56, i0 */
542   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
543   - sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL);
544   - /* sra i0, 24/56, data_reg */
545   - tcg_out_arithi(s, data_reg, TCG_REG_I0,
546   - sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA);
  571 + /* sll arg0, 24/56, data_reg */
  572 + tcg_out_arithi(s, data_reg, arg0, sizeof(tcg_target_long) * 8 - 8,
  573 + SHIFT_SLL);
  574 + /* sra data_reg, 24/56, data_reg */
  575 + tcg_out_arithi(s, data_reg, data_reg, sizeof(tcg_target_long) * 8 - 8,
  576 + SHIFT_SRA);
547 577 break;
548 578 case 1 | 4:
549   - /* sll i0, 16/48, i0 */
550   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
551   - sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL);
552   - /* sra i0, 16/48, data_reg */
553   - tcg_out_arithi(s, data_reg, TCG_REG_I0,
554   - sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA);
  579 + /* sll arg0, 16/48, data_reg */
  580 + tcg_out_arithi(s, data_reg, arg0, sizeof(tcg_target_long) * 8 - 16,
  581 + SHIFT_SLL);
  582 + /* sra data_reg, 16/48, data_reg */
  583 + tcg_out_arithi(s, data_reg, data_reg, sizeof(tcg_target_long) * 8 - 16,
  584 + SHIFT_SRA);
555 585 break;
556 586 case 2 | 4:
557   - /* sll i0, 32, i0 */
558   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL);
559   - /* sra i0, 32, data_reg */
560   - tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA);
  587 + /* sll arg0, 32, data_reg */
  588 + tcg_out_arithi(s, data_reg, arg0, 32, SHIFT_SLL);
  589 + /* sra data_reg, 32, data_reg */
  590 + tcg_out_arithi(s, data_reg, data_reg, 32, SHIFT_SRA);
561 591 break;
562 592 case 0:
563 593 case 1:
... ... @@ -565,24 +595,27 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
565 595 case 3:
566 596 default:
567 597 /* mov */
568   - tcg_out_mov(s, data_reg, TCG_REG_I0);
  598 + tcg_out_mov(s, data_reg, arg0);
569 599 break;
570 600 }
571 601  
572 602 /* will become:
573 603 ba label2 */
574   - label2_ptr = s->code_ptr;
  604 + label2_ptr = (uint32_t *)s->code_ptr;
575 605 tcg_out32(s, 0);
576 606  
  607 + /* nop (delay slot */
  608 + tcg_out_nop(s);
  609 +
577 610 /* label1: */
578   - *label1_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
579   - INSN_OFF22((unsigned long)label1_ptr -
580   - (unsigned long)s->code_ptr));
  611 + *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
  612 + INSN_OFF22((unsigned long)s->code_ptr -
  613 + (unsigned long)label1_ptr));
581 614  
582 615 /* ld [r1 + x], r1 */
583 616 tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) -
584   - offsetof(CPUTLBEntry, addr_read), ld_op);
585   - /* add x(r1), r0 */
  617 + offsetof(CPUTLBEntry, addr_read), host_ld_op);
  618 + /* add r0, r1, r0 */
586 619 tcg_out_arith(s, r0, r1, r0, ARITH_ADD);
587 620 #else
588 621 r0 = addr_reg;
... ... @@ -649,17 +682,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
649 682 #if defined(CONFIG_SOFTMMU)
650 683 /* label2: */
651 684 *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
652   - INSN_OFF22((unsigned long)label2_ptr -
653   - (unsigned long)s->code_ptr));
  685 + INSN_OFF22((unsigned long)s->code_ptr -
  686 + (unsigned long)label2_ptr));
654 687 #endif
655 688 }
656 689  
657 690 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
658 691 int opc)
659 692 {
660   - int addr_reg, data_reg, r0, r1, mem_index, s_bits, ld_op;
  693 + int addr_reg, data_reg, r0, r1, arg0, arg1, arg2, mem_index, s_bits;
  694 + int target_ld_op, host_ld_op;
661 695 #if defined(CONFIG_SOFTMMU)
662   - uint8_t *label1_ptr, *label2_ptr;
  696 + uint32_t *label1_ptr, *label2_ptr;
663 697 #endif
664 698  
665 699 data_reg = *args++;
... ... @@ -668,67 +702,77 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
668 702  
669 703 s_bits = opc;
670 704  
671   - r0 = TCG_REG_I5;
672   - r1 = TCG_REG_I4;
  705 + r0 = TCG_REG_L0;
  706 + r1 = TCG_REG_L1;
  707 + arg0 = TCG_REG_O0;
  708 + arg1 = TCG_REG_O1;
  709 + arg2 = TCG_REG_O2;
673 710  
674 711 #if TARGET_LONG_BITS == 32
675   - ld_op = LDUW;
  712 + target_ld_op = LDUW;
  713 +#else
  714 + target_ld_op = LDX;
  715 +#endif
  716 +
  717 +#ifdef __arch64__
  718 + host_ld_op = LDX;
676 719 #else
677   - ld_op = LDX;
  720 + host_ld_op = LDUW;
678 721 #endif
679 722  
680 723 #if defined(CONFIG_SOFTMMU)
681 724 /* srl addr_reg, x, r1 */
682 725 tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
683 726 SHIFT_SRL);
  727 +
684 728 /* and addr_reg, x, r0 */
685 729 tcg_out_arithi(s, r0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
686 730 ARITH_AND);
687 731  
688 732 /* and r1, x, r1 */
689   - tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
690   - ARITH_AND);
  733 + tcg_out_andi(s, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
691 734  
692 735 /* add r1, x, r1 */
693   - tcg_out_arithi(s, r1, r1,
694   - offsetof(CPUState, tlb_table[mem_index][0].addr_write),
695   - ARITH_ADD);
  736 + tcg_out_addi(s, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
  737 +
  738 + /* add env, r1, r1 */
  739 + tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
696 740  
697   - /* ld [env + r1], r1 */
698   - tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op);
  741 + /* ld [r1], arg1 */
  742 + tcg_out32(s, target_ld_op | INSN_RD(arg1) | INSN_RS1(r1) | INSN_RS2(TCG_REG_G0));
699 743  
700   - /* subcc r0, r1, %g0 */
701   - tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC);
  744 + /* subcc r0, arg1, %g0 */
  745 + tcg_out_arith(s, TCG_REG_G0, r0, arg1, ARITH_SUBCC);
702 746  
703 747 /* will become:
704 748 be label1 */
705   - label1_ptr = s->code_ptr;
  749 + label1_ptr = (uint32_t *)s->code_ptr;
706 750 tcg_out32(s, 0);
707   - /* mov (delay slot)*/
708   - tcg_out_mov(s, r0, addr_reg);
709 751  
  752 + /* mov (delay slot) */
  753 + tcg_out_mov(s, arg0, addr_reg);
  754 +
  755 + /* arg1 = sign_extend(data_reg); */
710 756 switch(opc) {
711 757 case 0 | 4:
712   - /* sll i0, 24/56, i0 */
713   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
714   - sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL);
715   - /* sra i0, 24/56, data_reg */
716   - tcg_out_arithi(s, data_reg, TCG_REG_I0,
717   - sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA);
  758 + /* sll data_reg, 24/56, arg1 */
  759 + tcg_out_arithi(s, arg1, data_reg, sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL);
  760 + /* sra arg1, 24/56, arg1 */
  761 + tcg_out_arithi(s, arg1, arg1, sizeof(tcg_target_long) * 8 - 8,
  762 + SHIFT_SRA);
718 763 break;
719 764 case 1 | 4:
720   - /* sll i0, 16/48, i0 */
721   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
722   - sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL);
723   - /* sra i0, 16/48, data_reg */
724   - tcg_out_arithi(s, data_reg, TCG_REG_I0,
725   - sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA);
  765 + /* sll data_reg, 16/48, arg1 */
  766 + tcg_out_arithi(s, data_reg, arg1, sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL);
  767 + /* sra arg1, 16/48, arg1 */
  768 + tcg_out_arithi(s, arg1, arg1, sizeof(tcg_target_long) * 8 - 16,
  769 + SHIFT_SRA);
726 770 break;
727 771 case 2 | 4:
728   - /* sll i0, 32, i0 */
729   - tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL);
730   - /* sra i0, 32, data_reg */
731   - tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA);
  772 + /* sll data_reg, 32, arg1 */
  773 + tcg_out_arithi(s, data_reg, arg1, 32, SHIFT_SLL);
  774 + /* sra arg1, 32, arg1 */
  775 + tcg_out_arithi(s, arg1, arg1, 32, SHIFT_SRA);
732 776 break;
733 777 case 0:
734 778 case 1:
... ... @@ -736,31 +780,40 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
736 780 case 3:
737 781 default:
738 782 /* mov */
739   - tcg_out_mov(s, data_reg, TCG_REG_I0);
  783 + tcg_out_mov(s, arg1, data_reg);
740 784 break;
741 785 }
742 786  
  787 + /* mov */
  788 + tcg_out_mov(s, arg0, addr_reg);
  789 +
  790 + /* XXX: move that code at the end of the TB */
  791 + /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
743 792 tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
744 793 - (tcg_target_ulong)s->code_ptr) >> 2)
745 794 & 0x3fffffff));
746   - /* mov (delay slot)*/
747   - tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index);
  795 + /* mov (delay slot) */
  796 + tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
748 797  
749 798 /* will become:
750 799 ba label2 */
751   - label2_ptr = s->code_ptr;
  800 + label2_ptr = (uint32_t *)s->code_ptr;
752 801 tcg_out32(s, 0);
753 802  
  803 + /* nop (delay slot) */
  804 + tcg_out_nop(s);
  805 +
754 806 /* label1: */
755   - *label1_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
756   - INSN_OFF22((unsigned long)label1_ptr -
757   - (unsigned long)s->code_ptr));
  807 + *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
  808 + INSN_OFF22((unsigned long)s->code_ptr -
  809 + (unsigned long)label1_ptr));
758 810  
759 811 /* ld [r1 + x], r1 */
760   - tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) -
761   - offsetof(CPUTLBEntry, addr_write), ld_op);
762   - /* add x(r1), r0 */
763   - tcg_out_arith(s, r0, r1, r0, ARITH_ADD);
  812 + tcg_out_ldst(s, arg1, r1, offsetof(CPUTLBEntry, addend) -
  813 + offsetof(CPUTLBEntry, addr_write), host_ld_op);
  814 +
  815 + /* add r0, r1, r0 */
  816 + tcg_out_arith(s, r0, arg1, r0, ARITH_ADD);
764 817 #else
765 818 r0 = addr_reg;
766 819 #endif
... ... @@ -804,8 +857,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
804 857 #if defined(CONFIG_SOFTMMU)
805 858 /* label2: */
806 859 *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
807   - INSN_OFF22((unsigned long)label2_ptr -
808   - (unsigned long)s->code_ptr));
  860 + INSN_OFF22((unsigned long)s->code_ptr -
  861 + (unsigned long)label2_ptr));
809 862 #endif
810 863 }
811 864  
... ...
tcg/sparc/tcg-target.h
... ... @@ -75,11 +75,11 @@ enum {
75 75 #define TCG_REG_CALL_STACK TCG_REG_I6
76 76 #ifdef __arch64__
77 77 // Reserve space for AREG0
78   -#define TCG_TARGET_STACK_MINFRAME (176 + 2 * sizeof(long))
  78 +#define TCG_TARGET_STACK_MINFRAME (176 + 2 * (int)sizeof(long))
79 79 #define TCG_TARGET_CALL_STACK_OFFSET (2047 + TCG_TARGET_STACK_MINFRAME)
80 80 #define TCG_TARGET_STACK_ALIGN 16
81 81 #else
82   -#define TCG_TARGET_STACK_MINFRAME (92 + 2 * sizeof(long))
  82 +#define TCG_TARGET_STACK_MINFRAME (92 + 2 * (int)sizeof(long))
83 83 #define TCG_TARGET_CALL_STACK_OFFSET TCG_TARGET_STACK_MINFRAME
84 84 #define TCG_TARGET_STACK_ALIGN 8
85 85 #endif
... ...