Revision e4b998d4
b/target-arm/translate-a64.c | ||
---|---|---|
7152 | 7152 |
} |
7153 | 7153 |
} |
7154 | 7154 |
|
7155 |
static void do_narrow_high_u32(TCGv_i32 res, TCGv_i64 in) |
|
7156 |
{ |
|
7157 |
tcg_gen_shri_i64(in, in, 32); |
|
7158 |
tcg_gen_trunc_i64_i32(res, in); |
|
7159 |
} |
|
7160 |
|
|
7161 |
static void do_narrow_round_high_u32(TCGv_i32 res, TCGv_i64 in) |
|
7162 |
{ |
|
7163 |
tcg_gen_addi_i64(in, in, 1U << 31); |
|
7164 |
do_narrow_high_u32(res, in); |
|
7165 |
} |
|
7166 |
|
|
7167 |
static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size, |
|
7168 |
int opcode, int rd, int rn, int rm) |
|
7169 |
{ |
|
7170 |
TCGv_i32 tcg_res[2]; |
|
7171 |
int part = is_q ? 2 : 0; |
|
7172 |
int pass; |
|
7173 |
|
|
7174 |
for (pass = 0; pass < 2; pass++) { |
|
7175 |
TCGv_i64 tcg_op1 = tcg_temp_new_i64(); |
|
7176 |
TCGv_i64 tcg_op2 = tcg_temp_new_i64(); |
|
7177 |
TCGv_i64 tcg_wideres = tcg_temp_new_i64(); |
|
7178 |
static NeonGenNarrowFn * const narrowfns[3][2] = { |
|
7179 |
{ gen_helper_neon_narrow_high_u8, |
|
7180 |
gen_helper_neon_narrow_round_high_u8 }, |
|
7181 |
{ gen_helper_neon_narrow_high_u16, |
|
7182 |
gen_helper_neon_narrow_round_high_u16 }, |
|
7183 |
{ do_narrow_high_u32, do_narrow_round_high_u32 }, |
|
7184 |
}; |
|
7185 |
NeonGenNarrowFn *gennarrow = narrowfns[size][is_u]; |
|
7186 |
|
|
7187 |
read_vec_element(s, tcg_op1, rn, pass, MO_64); |
|
7188 |
read_vec_element(s, tcg_op2, rm, pass, MO_64); |
|
7189 |
|
|
7190 |
gen_neon_addl(size, (opcode == 6), tcg_wideres, tcg_op1, tcg_op2); |
|
7191 |
|
|
7192 |
tcg_temp_free_i64(tcg_op1); |
|
7193 |
tcg_temp_free_i64(tcg_op2); |
|
7194 |
|
|
7195 |
tcg_res[pass] = tcg_temp_new_i32(); |
|
7196 |
gennarrow(tcg_res[pass], tcg_wideres); |
|
7197 |
tcg_temp_free_i64(tcg_wideres); |
|
7198 |
} |
|
7199 |
|
|
7200 |
for (pass = 0; pass < 2; pass++) { |
|
7201 |
write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32); |
|
7202 |
tcg_temp_free_i32(tcg_res[pass]); |
|
7203 |
} |
|
7204 |
if (!is_q) { |
|
7205 |
clear_vec_high(s, rd); |
|
7206 |
} |
|
7207 |
} |
|
7208 |
|
|
7155 | 7209 |
/* C3.6.15 AdvSIMD three different |
7156 | 7210 |
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0 |
7157 | 7211 |
* +---+---+---+-----------+------+---+------+--------+-----+------+------+ |
... | ... | |
7191 | 7245 |
case 4: /* ADDHN, ADDHN2, RADDHN, RADDHN2 */ |
7192 | 7246 |
case 6: /* SUBHN, SUBHN2, RSUBHN, RSUBHN2 */ |
7193 | 7247 |
/* 128 x 128 -> 64 */ |
7194 |
unsupported_encoding(s, insn); |
|
7248 |
if (size == 3) { |
|
7249 |
unallocated_encoding(s); |
|
7250 |
return; |
|
7251 |
} |
|
7252 |
handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm); |
|
7195 | 7253 |
break; |
7196 | 7254 |
case 14: /* PMULL, PMULL2 */ |
7197 | 7255 |
if (is_u || size == 1 || size == 2) { |
Also available in: Unified diff