Revision 2b71cd72

b/tcg/arm/tcg-target.c
157 157
# endif
158 158
#endif
159 159

  
160
    case '1':
161
        ct->ct |= TCG_CT_REG;
162
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
163
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
164
        break;
165

  
166
    case '2':
167
        ct->ct |= TCG_CT_REG;
168
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
169
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
170
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
171
        break;
172

  
173 160
    default:
174 161
        return -1;
175 162
    }
......
819 806
    }
820 807
}
821 808

  
822
static void tcg_out_div_helper(TCGContext *s, int cond, const TCGArg *args,
823
                void *helper_div, void *helper_rem, int shift)
824
{
825
    int div_reg = args[0];
826
    int rem_reg = args[1];
827

  
828
    /* stmdb sp!, { r0 - r3, ip, lr } */
829
    /* (Note that we need an even number of registers as per EABI) */
830
    tcg_out32(s, (cond << 28) | 0x092d500f);
831

  
832
    tcg_out_dat_reg(s, cond, ARITH_MOV, 0, 0, args[2], SHIFT_IMM_LSL(0));
833
    tcg_out_dat_reg(s, cond, ARITH_MOV, 1, 0, args[3], SHIFT_IMM_LSL(0));
834
    tcg_out_dat_reg(s, cond, ARITH_MOV, 2, 0, args[4], SHIFT_IMM_LSL(0));
835
    tcg_out_dat_reg(s, cond, ARITH_MOV, 3, 0, 2, shift);
836

  
837
    tcg_out_call(s, cond, (uint32_t) helper_div);
838
    tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 0, SHIFT_IMM_LSL(0));
839

  
840
    /* ldmia sp, { r0 - r3, fp, lr } */
841
    tcg_out32(s, (cond << 28) | 0x089d500f);
842

  
843
    tcg_out_dat_reg(s, cond, ARITH_MOV, 0, 0, args[2], SHIFT_IMM_LSL(0));
844
    tcg_out_dat_reg(s, cond, ARITH_MOV, 1, 0, args[3], SHIFT_IMM_LSL(0));
845
    tcg_out_dat_reg(s, cond, ARITH_MOV, 2, 0, args[4], SHIFT_IMM_LSL(0));
846
    tcg_out_dat_reg(s, cond, ARITH_MOV, 3, 0, 2, shift);
847

  
848
    tcg_out_call(s, cond, (uint32_t) helper_rem);
849

  
850
    tcg_out_dat_reg(s, cond, ARITH_MOV, rem_reg, 0, 0, SHIFT_IMM_LSL(0));
851
    tcg_out_dat_reg(s, cond, ARITH_MOV, div_reg, 0, 8, SHIFT_IMM_LSL(0));
852

  
853
    /* ldr r0, [sp], #4 */
854
    if (rem_reg != 0 && div_reg != 0) {
855
        tcg_out32(s, (cond << 28) | 0x04bd0004);
856
    } else {
857
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
858
    }
859
    /* ldr r1, [sp], #4 */
860
    if (rem_reg != 1 && div_reg != 1) {
861
        tcg_out32(s, (cond << 28) | 0x04bd1004);
862
    } else {
863
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
864
    }
865
    /* ldr r2, [sp], #4 */
866
    if (rem_reg != 2 && div_reg != 2) {
867
        tcg_out32(s, (cond << 28) | 0x04bd2004);
868
    } else {
869
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
870
    }
871
    /* ldr r3, [sp], #4 */
872
    if (rem_reg != 3 && div_reg != 3) {
873
        tcg_out32(s, (cond << 28) | 0x04bd3004);
874
    } else {
875
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
876
    }
877
    /* ldr ip, [sp], #4 */
878
    if (rem_reg != 12 && div_reg != 12) {
879
        tcg_out32(s, (cond << 28) | 0x04bdc004);
880
    } else {
881
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
882
    }
883
    /* ldr lr, [sp], #4 */
884
    if (rem_reg != 14 && div_reg != 14) {
885
        tcg_out32(s, (cond << 28) | 0x04bde004);
886
    } else {
887
        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 4);
888
    }
889
}
890

  
891 809
#ifdef CONFIG_SOFTMMU
892 810

  
893 811
#include "../../softmmu_defs.h"
......
1487 1405
    case INDEX_op_mulu2_i32:
1488 1406
        tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1489 1407
        break;
1490
    case INDEX_op_div2_i32:
1491
        tcg_out_div_helper(s, COND_AL, args,
1492
                        tcg_helper_div_i64, tcg_helper_rem_i64,
1493
                        SHIFT_IMM_ASR(31));
1494
        break;
1495
    case INDEX_op_divu2_i32:
1496
        tcg_out_div_helper(s, COND_AL, args,
1497
                        tcg_helper_divu_i64, tcg_helper_remu_i64,
1498
                        SHIFT_IMM_LSR(31));
1499
        break;
1500 1408
    /* XXX: Perhaps args[2] & 0x1f is wrong */
1501 1409
    case INDEX_op_shl_i32:
1502 1410
        c = const_args[2] ?
......
1652 1560
    { INDEX_op_sub_i32, { "r", "r", "rI" } },
1653 1561
    { INDEX_op_mul_i32, { "r", "r", "r" } },
1654 1562
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1655
    { INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } },
1656
    { INDEX_op_divu2_i32, { "r", "r", "r", "1", "2" } },
1657 1563
    { INDEX_op_and_i32, { "r", "r", "rI" } },
1658 1564
    { INDEX_op_andc_i32, { "r", "r", "rI" } },
1659 1565
    { INDEX_op_or_i32, { "r", "r", "rI" } },
b/tcg/arm/tcg-target.h
56 56
#define TCG_TARGET_CALL_STACK_OFFSET	0
57 57

  
58 58
/* optional instructions */
59
#define TCG_TARGET_HAS_div2_i32
60 59
#define TCG_TARGET_HAS_ext8s_i32
61 60
#define TCG_TARGET_HAS_ext16s_i32
62 61
// #define TCG_TARGET_HAS_ext8u_i32

Also available in: Unified diff