Revision 6ddbc6e4 target-arm/translate.c

b/target-arm/translate.c
226 226
{
227 227
    TCGv tmp1 = new_tmp();
228 228
    TCGv tmp2 = new_tmp();
229
    TCGv res;
230 229
    tcg_gen_ext8s_i32(tmp1, a);
231 230
    tcg_gen_ext8s_i32(tmp2, b);
232 231
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
......
495 494
    }
496 495
};
497 496

  
498
#define PAS_OP(pfx) {  \
499
    gen_op_ ## pfx ## add16_T0_T1, \
500
    gen_op_ ## pfx ## addsubx_T0_T1, \
501
    gen_op_ ## pfx ## subaddx_T0_T1, \
502
    gen_op_ ## pfx ## sub16_T0_T1, \
503
    gen_op_ ## pfx ## add8_T0_T1, \
504
    NULL, \
505
    NULL, \
506
    gen_op_ ## pfx ## sub8_T0_T1 }
507

  
508
static GenOpFunc *gen_arm_parallel_addsub[8][8] = {
509
    {},
510
    PAS_OP(s),
511
    PAS_OP(q),
512
    PAS_OP(sh),
513
    {},
514
    PAS_OP(u),
515
    PAS_OP(uq),
516
    PAS_OP(uh),
517
};
497
#define PAS_OP(pfx) \
498
    switch (op2) {  \
499
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
500
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
501
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
502
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
503
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
504
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
505
    }
506
void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
507
{
508
    TCGv tmp;
509

  
510
    switch (op1) {
511
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
512
    case 1:
513
        tmp = tcg_temp_new(TCG_TYPE_PTR);
514
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
515
        PAS_OP(s)
516
        break;
517
    case 5:
518
        tmp = tcg_temp_new(TCG_TYPE_PTR);
519
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
520
        PAS_OP(u)
521
        break;
522
#undef gen_pas_helper
523
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
524
    case 2:
525
        PAS_OP(q);
526
        break;
527
    case 3:
528
        PAS_OP(sh);
529
        break;
530
    case 6:
531
        PAS_OP(uq);
532
        break;
533
    case 7:
534
        PAS_OP(uh);
535
        break;
536
#undef gen_pas_helper
537
    }
538
}
518 539
#undef PAS_OP
519 540

  
520
/* For unknown reasons Arm and Thumb-2 use arbitrarily diffenet encodings.  */
521
#define PAS_OP(pfx) {  \
522
    gen_op_ ## pfx ## add8_T0_T1, \
523
    gen_op_ ## pfx ## add16_T0_T1, \
524
    gen_op_ ## pfx ## addsubx_T0_T1, \
525
    NULL, \
526
    gen_op_ ## pfx ## sub8_T0_T1, \
527
    gen_op_ ## pfx ## sub16_T0_T1, \
528
    gen_op_ ## pfx ## subaddx_T0_T1, \
529
    NULL }
530

  
531
static GenOpFunc *gen_thumb2_parallel_addsub[8][8] = {
532
    PAS_OP(s),
533
    PAS_OP(q),
534
    PAS_OP(sh),
535
    {},
536
    PAS_OP(u),
537
    PAS_OP(uq),
538
    PAS_OP(uh),
539
    {}
540
};
541
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
542
#define PAS_OP(pfx) \
543
    switch (op2) {  \
544
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
545
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
546
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
547
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
548
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
549
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
550
    }
551
void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
552
{
553
    TCGv tmp;
554

  
555
    switch (op1) {
556
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
557
    case 0:
558
        tmp = tcg_temp_new(TCG_TYPE_PTR);
559
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
560
        PAS_OP(s)
561
        break;
562
    case 4:
563
        tmp = tcg_temp_new(TCG_TYPE_PTR);
564
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
565
        PAS_OP(u)
566
        break;
567
#undef gen_pas_helper
568
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
569
    case 1:
570
        PAS_OP(q);
571
        break;
572
    case 2:
573
        PAS_OP(sh);
574
        break;
575
    case 5:
576
        PAS_OP(uq);
577
        break;
578
    case 6:
579
        PAS_OP(uh);
580
        break;
581
#undef gen_pas_helper
582
    }
583
}
541 584
#undef PAS_OP
542 585

  
543 586
static GenOpFunc1 *gen_test_cc[14] = {
......
4906 4949
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
4907 4950
    TCGv tmp;
4908 4951
    TCGv tmp2;
4952
    TCGv tmp3;
4909 4953

  
4910 4954
    insn = ldl_code(s->pc);
4911 4955
    s->pc += 4;
......
5591 5635
                switch ((insn >> 23) & 3) {
5592 5636
                case 0: /* Parallel add/subtract.  */
5593 5637
                    op1 = (insn >> 20) & 7;
5594
                    gen_movl_T0_reg(s, rn);
5595
                    gen_movl_T1_reg(s, rm);
5638
                    tmp = load_reg(s, rn);
5639
                    tmp2 = load_reg(s, rm);
5596 5640
                    sh = (insn >> 5) & 7;
5597 5641
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
5598 5642
                        goto illegal_op;
5599
                    gen_arm_parallel_addsub[op1][sh]();
5600
                    gen_movl_reg_T0(s, rd);
5643
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
5644
                    dead_tmp(tmp2);
5645
                    store_reg(s, rd, tmp);
5601 5646
                    break;
5602 5647
                case 1:
5603 5648
                    if ((insn & 0x00700020) == 0) {
......
5620 5665
                        store_reg(s, rd, tmp);
5621 5666
                    } else if ((insn & 0x00200020) == 0x00200000) {
5622 5667
                        /* [us]sat */
5623
                        gen_movl_T1_reg(s, rm);
5668
                        tmp = load_reg(s, rm);
5624 5669
                        shift = (insn >> 7) & 0x1f;
5625 5670
                        if (insn & (1 << 6)) {
5626 5671
                            if (shift == 0)
5627 5672
                                shift = 31;
5628
                            gen_op_sarl_T1_im(shift);
5673
                            tcg_gen_sari_i32(tmp, tmp, shift);
5629 5674
                        } else {
5630
                            gen_op_shll_T1_im(shift);
5675
                            tcg_gen_shli_i32(tmp, tmp, shift);
5631 5676
                        }
5632 5677
                        sh = (insn >> 16) & 0x1f;
5633 5678
                        if (sh != 0) {
5634 5679
                            if (insn & (1 << 22))
5635
                                gen_op_usat_T1(sh);
5680
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
5636 5681
                            else
5637
                                gen_op_ssat_T1(sh);
5682
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
5638 5683
                        }
5639
                        gen_movl_T1_reg(s, rd);
5684
                        store_reg(s, rd, tmp);
5640 5685
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
5641 5686
                        /* [us]sat16 */
5642
                        gen_movl_T1_reg(s, rm);
5687
                        tmp = load_reg(s, rm);
5643 5688
                        sh = (insn >> 16) & 0x1f;
5644 5689
                        if (sh != 0) {
5645 5690
                            if (insn & (1 << 22))
5646
                                gen_op_usat16_T1(sh);
5691
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
5647 5692
                            else
5648
                                gen_op_ssat16_T1(sh);
5693
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
5649 5694
                        }
5650
                        gen_movl_T1_reg(s, rd);
5695
                        store_reg(s, rd, tmp);
5651 5696
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
5652 5697
                        /* Select bytes.  */
5653
                        gen_movl_T0_reg(s, rn);
5654
                        gen_movl_T1_reg(s, rm);
5655
                        gen_op_sel_T0_T1();
5656
                        gen_movl_reg_T0(s, rd);
5698
                        tmp = load_reg(s, rn);
5699
                        tmp2 = load_reg(s, rm);
5700
                        tmp3 = new_tmp();
5701
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
5702
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
5703
                        dead_tmp(tmp3);
5704
                        dead_tmp(tmp2);
5705
                        store_reg(s, rd, tmp);
5657 5706
                    } else if ((insn & 0x000003e0) == 0x00000060) {
5658 5707
                        gen_movl_T1_reg(s, rm);
5659 5708
                        shift = (insn >> 10) & 3;
......
5755 5804
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
5756 5805
                    switch (op1) {
5757 5806
                    case 0: /* Unsigned sum of absolute differences.  */
5758
                            goto illegal_op;
5759
                        gen_movl_T0_reg(s, rm);
5760
                        gen_movl_T1_reg(s, rs);
5761
                        gen_op_usad8_T0_T1();
5807
                        ARCH(6);
5808
                        tmp = load_reg(s, rm);
5809
                        tmp2 = load_reg(s, rs);
5810
                        gen_helper_usad8(tmp, tmp, tmp2);
5811
                        dead_tmp(tmp2);
5762 5812
                        if (rn != 15) {
5763
                            gen_movl_T1_reg(s, rn);
5764
                            gen_op_addl_T0_T1();
5813
                            tmp2 = load_reg(s, rn);
5814
                            tcg_gen_add_i32(tmp, tmp, tmp2);
5815
                            dead_tmp(tmp2);
5765 5816
                        }
5766
                        gen_movl_reg_T0(s, rd);
5817
                        store_reg(s, rd, tmp);
5767 5818
                        break;
5768 5819
                    case 0x20: case 0x24: case 0x28: case 0x2c:
5769 5820
                        /* Bitfield insert/clear.  */
......
6120 6171
    uint32_t insn, imm, shift, offset, addr;
6121 6172
    uint32_t rd, rn, rm, rs;
6122 6173
    TCGv tmp;
6174
    TCGv tmp2;
6175
    TCGv tmp3;
6123 6176
    int op;
6124 6177
    int shiftop;
6125 6178
    int conds;
......
6464 6517
            shift = (insn >> 4) & 7;
6465 6518
            if ((op & 3) == 3 || (shift & 3) == 3)
6466 6519
                goto illegal_op;
6467
            gen_movl_T0_reg(s, rn);
6468
            gen_movl_T1_reg(s, rm);
6469
            gen_thumb2_parallel_addsub[op][shift]();
6470
            gen_movl_reg_T0(s, rd);
6520
            tmp = load_reg(s, rn);
6521
            tmp2 = load_reg(s, rm);
6522
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
6523
            dead_tmp(tmp2);
6524
            store_reg(s, rd, tmp);
6471 6525
            break;
6472 6526
        case 3: /* Other data processing.  */
6473 6527
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
......
6498 6552
                    break;
6499 6553
                case 0x10: /* sel */
6500 6554
                    gen_movl_T1_reg(s, rm);
6501
                    gen_op_sel_T0_T1();
6555
                    tmp3 = new_tmp();
6556
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6557
                    gen_helper_sel_flags(cpu_T[0], tmp3, cpu_T[0], cpu_T[1]);
6558
                    dead_tmp(tmp3);
6502 6559
                    break;
6503 6560
                case 0x18: /* clz */
6504 6561
                    gen_helper_clz(cpu_T[0], cpu_T[0]);
......
6581 6638
                gen_movl_reg_T0(s, rd);
6582 6639
                break;
6583 6640
            case 7: /* Unsigned sum of absolute differences.  */
6584
                gen_op_usad8_T0_T1();
6641
                gen_helper_usad8(cpu_T[0], cpu_T[0], cpu_T[1]);
6585 6642
                if (rs != 15) {
6586 6643
                    gen_movl_T1_reg(s, rs);
6587 6644
                    gen_op_addl_T0_T1();
......
6821 6878
                    op = (insn >> 21) & 7;
6822 6879
                    imm = insn & 0x1f;
6823 6880
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
6824
                    if (rn == 15)
6825
                        gen_op_movl_T1_im(0);
6826
                    else
6827
                        gen_movl_T1_reg(s, rn);
6881
                    if (rn == 15) {
6882
                        tmp = new_tmp();
6883
                        tcg_gen_movi_i32(tmp, 0);
6884
                    } else {
6885
                        tmp = load_reg(s, rn);
6886
                    }
6828 6887
                    switch (op) {
6829 6888
                    case 2: /* Signed bitfield extract.  */
6830 6889
                        imm++;
6831 6890
                        if (shift + imm > 32)
6832 6891
                            goto illegal_op;
6833 6892
                        if (imm < 32)
6834
                            gen_sbfx(cpu_T[1], shift, imm);
6893
                            gen_sbfx(tmp, shift, imm);
6835 6894
                        break;
6836 6895
                    case 6: /* Unsigned bitfield extract.  */
6837 6896
                        imm++;
6838 6897
                        if (shift + imm > 32)
6839 6898
                            goto illegal_op;
6840 6899
                        if (imm < 32)
6841
                            gen_ubfx(cpu_T[1], shift, (1u << imm) - 1);
6900
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
6842 6901
                        break;
6843 6902
                    case 3: /* Bitfield insert/clear.  */
6844 6903
                        if (imm < shift)
6845 6904
                            goto illegal_op;
6846 6905
                        imm = imm + 1 - shift;
6847 6906
                        if (imm != 32) {
6848
                            gen_movl_T0_reg(s, rd);
6849
                            gen_bfi(cpu_T[1], cpu_T[0], cpu_T[1],
6907
                            tmp2 = load_reg(s, rd);
6908
                            gen_bfi(tmp, tmp2, tmp,
6850 6909
                                    shift, ((1u << imm) - 1) << shift);
6910
                            dead_tmp(tmp2);
6851 6911
                        }
6852 6912
                        break;
6853 6913
                    case 7:
6854 6914
                        goto illegal_op;
6855 6915
                    default: /* Saturate.  */
6856
                        gen_movl_T1_reg(s, rn);
6857 6916
                        if (shift) {
6858 6917
                            if (op & 1)
6859
                                gen_op_sarl_T1_im(shift);
6918
                                tcg_gen_sari_i32(tmp, tmp, shift);
6860 6919
                            else
6861
                                gen_op_shll_T1_im(shift);
6920
                                tcg_gen_shli_i32(tmp, tmp, shift);
6862 6921
                        }
6922
                        tmp2 = tcg_const_i32(imm);
6863 6923
                        if (op & 4) {
6864 6924
                            /* Unsigned.  */
6865
                            gen_op_ssat_T1(imm);
6866 6925
                            if ((op & 1) && shift == 0)
6867
                                gen_op_usat16_T1(imm);
6926
                                gen_helper_usat16(tmp, tmp, tmp2);
6868 6927
                            else
6869
                                gen_op_usat_T1(imm);
6928
                                gen_helper_usat(tmp, tmp, tmp2);
6870 6929
                        } else {
6871 6930
                            /* Signed.  */
6872
                            gen_op_ssat_T1(imm);
6873 6931
                            if ((op & 1) && shift == 0)
6874
                                gen_op_ssat16_T1(imm);
6932
                                gen_helper_ssat16(tmp, tmp, tmp2);
6875 6933
                            else
6876
                                gen_op_ssat_T1(imm);
6934
                                gen_helper_ssat(tmp, tmp, tmp2);
6877 6935
                        }
6878 6936
                        break;
6879 6937
                    }
6880
                    gen_movl_reg_T1(s, rd);
6938
                    store_reg(s, rd, tmp);
6881 6939
                } else {
6882 6940
                    imm = ((insn & 0x04000000) >> 15)
6883 6941
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);

Also available in: Unified diff