target/arm: Implement FCSEL for fp16

These were missed out from the rest of the half-precision work.

Backports commit ace97feef3613194900d4eb9ffc6819b840fbaeb from qemu
This commit is contained in:
Alex Bennée 2018-05-15 22:26:50 -04:00 committed by Lioncash
parent 80074e4745
commit cd76e7aaaa
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -4995,15 +4995,34 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
unsigned int mos, type, rm, cond, rn, rd; unsigned int mos, type, rm, cond, rn, rd;
TCGv_i64 t_true, t_false, t_zero; TCGv_i64 t_true, t_false, t_zero;
DisasCompare64 c; DisasCompare64 c;
TCGMemOp sz;
mos = extract32(insn, 29, 3); mos = extract32(insn, 29, 3);
type = extract32(insn, 22, 2); /* 0 = single, 1 = double */ type = extract32(insn, 22, 2);
rm = extract32(insn, 16, 5); rm = extract32(insn, 16, 5);
cond = extract32(insn, 12, 4); cond = extract32(insn, 12, 4);
rn = extract32(insn, 5, 5); rn = extract32(insn, 5, 5);
rd = extract32(insn, 0, 5); rd = extract32(insn, 0, 5);
if (mos || type > 1) { if (mos) {
unallocated_encoding(s);
return;
}
switch (type) {
case 0:
sz = MO_32;
break;
case 1:
sz = MO_64;
break;
case 3:
sz = MO_16;
if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
break;
}
/* fallthru */
default:
unallocated_encoding(s); unallocated_encoding(s);
return; return;
} }
@ -5012,11 +5031,11 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
return; return;
} }
/* Zero extend sreg inputs to 64 bits now. */ /* Zero extend sreg & hreg inputs to 64 bits now. */
t_true = tcg_temp_new_i64(tcg_ctx); t_true = tcg_temp_new_i64(tcg_ctx);
t_false = tcg_temp_new_i64(tcg_ctx); t_false = tcg_temp_new_i64(tcg_ctx);
read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32); read_vec_element(s, t_true, rn, 0, sz);
read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32); read_vec_element(s, t_false, rm, 0, sz);
a64_test_cc(tcg_ctx, &c, cond); a64_test_cc(tcg_ctx, &c, cond);
t_zero = tcg_const_i64(tcg_ctx, 0); t_zero = tcg_const_i64(tcg_ctx, 0);
@ -5025,7 +5044,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_ctx, t_false); tcg_temp_free_i64(tcg_ctx, t_false);
a64_free_cc(tcg_ctx, &c); a64_free_cc(tcg_ctx, &c);
/* Note that sregs write back zeros to the high bits, /* Note that sregs & hregs write back zeros to the high bits,
and we've already done the zero-extension. */ and we've already done the zero-extension. */
write_fp_dreg(s, rd, t_true); write_fp_dreg(s, rd, t_true);
tcg_temp_free_i64(tcg_ctx, t_true); tcg_temp_free_i64(tcg_ctx, t_true);