Revision 750813cf target-arm/translate-a64.c

b/target-arm/translate-a64.c
2483 2483
    }
2484 2484
}
2485 2485

  
2486
/* Conditional compare (immediate) */
2487
static void disas_cc_imm(DisasContext *s, uint32_t insn)
2486
/* C3.5.4 - C3.5.5 Conditional compare (immediate / register)
2487
 *  31 30 29 28 27 26 25 24 23 22 21  20    16 15  12  11  10  9   5  4 3   0
2488
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
2489
 * |sf|op| S| 1  1  0  1  0  0  1  0 |imm5/rm | cond |i/r |o2|  Rn  |o3|nzcv |
2490
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
2491
 *        [1]                             y                [0]       [0]
2492
 */
2493
static void disas_cc(DisasContext *s, uint32_t insn)
2488 2494
{
2489
    unsupported_encoding(s, insn);
2490
}
2495
    unsigned int sf, op, y, cond, rn, nzcv, is_imm;
2496
    int label_continue = -1;
2497
    TCGv_i64 tcg_tmp, tcg_y, tcg_rn;
2491 2498

  
2492
/* Conditional compare (register) */
2493
static void disas_cc_reg(DisasContext *s, uint32_t insn)
2494
{
2495
    unsupported_encoding(s, insn);
2499
    if (!extract32(insn, 29, 1)) {
2500
        unallocated_encoding(s);
2501
        return;
2502
    }
2503
    if (insn & (1 << 10 | 1 << 4)) {
2504
        unallocated_encoding(s);
2505
        return;
2506
    }
2507
    sf = extract32(insn, 31, 1);
2508
    op = extract32(insn, 30, 1);
2509
    is_imm = extract32(insn, 11, 1);
2510
    y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */
2511
    cond = extract32(insn, 12, 4);
2512
    rn = extract32(insn, 5, 5);
2513
    nzcv = extract32(insn, 0, 4);
2514

  
2515
    if (cond < 0x0e) { /* not always */
2516
        int label_match = gen_new_label();
2517
        label_continue = gen_new_label();
2518
        arm_gen_test_cc(cond, label_match);
2519
        /* nomatch: */
2520
        tcg_tmp = tcg_temp_new_i64();
2521
        tcg_gen_movi_i64(tcg_tmp, nzcv << 28);
2522
        gen_set_nzcv(tcg_tmp);
2523
        tcg_temp_free_i64(tcg_tmp);
2524
        tcg_gen_br(label_continue);
2525
        gen_set_label(label_match);
2526
    }
2527
    /* match, or condition is always */
2528
    if (is_imm) {
2529
        tcg_y = new_tmp_a64(s);
2530
        tcg_gen_movi_i64(tcg_y, y);
2531
    } else {
2532
        tcg_y = cpu_reg(s, y);
2533
    }
2534
    tcg_rn = cpu_reg(s, rn);
2535

  
2536
    tcg_tmp = tcg_temp_new_i64();
2537
    if (op) {
2538
        gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y);
2539
    } else {
2540
        gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y);
2541
    }
2542
    tcg_temp_free_i64(tcg_tmp);
2543

  
2544
    if (cond < 0x0e) { /* continue */
2545
        gen_set_label(label_continue);
2546
    }
2496 2547
}
2497 2548

  
2498 2549
/* C3.5.6 Conditional select
......
2846 2897
            disas_adc_sbc(s, insn);
2847 2898
            break;
2848 2899
        case 0x2: /* Conditional compare */
2849
            if (insn & (1 << 11)) { /* (immediate) */
2850
                disas_cc_imm(s, insn);
2851
            } else {            /* (register) */
2852
                disas_cc_reg(s, insn);
2853
            }
2900
            disas_cc(s, insn); /* both imm and reg forms */
2854 2901
            break;
2855 2902
        case 0x4: /* Conditional select */
2856 2903
            disas_cond_select(s, insn);

Also available in: Unified diff