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;
TCGv_i64 t_true, t_false, t_zero;
DisasCompare64 c;
TCGMemOp sz;
mos = extract32(insn, 29, 3);
type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
type = extract32(insn, 22, 2);
rm = extract32(insn, 16, 5);
cond = extract32(insn, 12, 4);
rn = extract32(insn, 5, 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);
return;
}
@ -5012,11 +5031,11 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
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_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_false, rm, 0, type ? MO_64 : MO_32);
read_vec_element(s, t_true, rn, 0, sz);
read_vec_element(s, t_false, rm, 0, sz);
a64_test_cc(tcg_ctx, &c, cond);
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);
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. */
write_fp_dreg(s, rd, t_true);
tcg_temp_free_i64(tcg_ctx, t_true);