arm/translate-a64: initial decode for simd_three_reg_same_fp16

This is the initial decode skeleton for the Advanced SIMD three same
instruction group.

The fprintf is purely to aid debugging as the additional instructions
are added. It will be removed once the group is complete.

Backports commit 376e8d6cda985df31c8561db4b7ea365b6fe6f87 from qemu
This commit is contained in:
Alex Bennée 2018-03-08 12:52:55 -05:00 committed by Lioncash
parent fe74abd307
commit 2f850606e9
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -10379,6 +10379,79 @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
}
}
/*
* Advanced SIMD three same (ARMv8.2 FP16 variants)
*
* 31 30 29 28 24 23 22 21 20 16 15 14 13 11 10 9 5 4 0
* +---+---+---+-----------+---------+------+-----+--------+---+------+------+
* | 0 | Q | U | 0 1 1 1 0 | a | 1 0 | Rm | 0 0 | opcode | 1 | Rn | Rd |
* +---+---+---+-----------+---------+------+-----+--------+---+------+------+
*
* This includes FMULX, FCMEQ (register), FRECPS, FRSQRTS, FCMGE
* (register), FACGE, FABD, FCMGT (register) and FACGT.
*
*/
static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
int opcode, fpopcode;
int is_q, u, a, rm, rn, rd;
int datasize, elements;
int pass;
TCGv_ptr fpst;
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
unallocated_encoding(s);
return;
}
if (!fp_access_check(s)) {
return;
}
/* For these floating point ops, the U, a and opcode bits
* together indicate the operation.
*/
opcode = extract32(insn, 11, 3);
u = extract32(insn, 29, 1);
a = extract32(insn, 23, 1);
is_q = extract32(insn, 30, 1);
rm = extract32(insn, 16, 5);
rn = extract32(insn, 5, 5);
rd = extract32(insn, 0, 5);
fpopcode = opcode | (a << 3) | (u << 4);
datasize = is_q ? 128 : 64;
elements = datasize / 16;
fpst = get_fpstatus_ptr(tcg_ctx, true);
for (pass = 0; pass < elements; pass++) {
TCGv_i32 tcg_op1 = tcg_temp_new_i32(tcg_ctx);
TCGv_i32 tcg_op2 = tcg_temp_new_i32(tcg_ctx);
TCGv_i32 tcg_res = tcg_temp_new_i32(tcg_ctx);
read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
switch (fpopcode) {
default:
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
__func__, insn, fpopcode, s->pc);
g_assert_not_reached();
}
write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
tcg_temp_free_i32(tcg_ctx, tcg_res);
tcg_temp_free_i32(tcg_ctx, tcg_op1);
tcg_temp_free_i32(tcg_ctx, tcg_op2);
}
tcg_temp_free_ptr(tcg_ctx, fpst);
clear_vec_high(s, is_q, rd);
}
static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
int size, int rn, int rd)
{
@ -12140,6 +12213,7 @@ static const AArch64DecodeTable data_proc_simd[] = {
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
{ 0xce800000, 0xffe00000, disas_crypto_xar },
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
{ 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
{ 0x00000000, 0x00000000, NULL }
};