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