From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Peter Crosthwaite" <peter.crosthwaite@xilinx.com>,
patches@linaro.org, "Michael Matz" <matz@suse.de>,
"Alexander Graf" <agraf@suse.de>,
"Will Newton" <will.newton@linaro.org>,
"Dirk Mueller" <dmueller@suse.de>,
"Laurent Desnogues" <laurent.desnogues@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
kvmarm@lists.cs.columbia.edu,
"Christoffer Dall" <christoffer.dall@linaro.org>,
"Richard Henderson" <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH 09/16] target-arm: A64: Implement FCVT[NMAPZ][SU] SIMD instructions
Date: Sun, 9 Mar 2014 15:11:00 +0000 [thread overview]
Message-ID: <1394377867-7115-10-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1394377867-7115-1-git-send-email-peter.maydell@linaro.org>
Implement the floating-point-to-integer conversion instructions
FCVT[NMAPZ][SU] in the 2-reg-misc and scalar-2-reg-misc
categories.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/translate-a64.c | 188 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 169 insertions(+), 19 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index ccc449e..d0df8d2 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -6683,11 +6683,14 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
}
static void handle_2misc_64(DisasContext *s, int opcode, bool u,
- TCGv_i64 tcg_rd, TCGv_i64 tcg_rn)
+ TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
+ TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
{
/* Handle 64->64 opcodes which are shared between the scalar and
* vector 2-reg-misc groups. We cover every integer opcode where size == 3
* is valid in either group and also the double-precision fp ops.
+ * The caller only need provide tcg_rmode and tcg_fpstatus if the op
+ * requires them.
*/
TCGCond cond;
@@ -6741,6 +6744,28 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
case 0x7f: /* FSQRT */
gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, cpu_env);
break;
+ case 0x1a: /* FCVTNS */
+ case 0x1b: /* FCVTMS */
+ case 0x1c: /* FCVTAS */
+ case 0x3a: /* FCVTPS */
+ case 0x3b: /* FCVTZS */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_tosqd(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
+ case 0x5a: /* FCVTNU */
+ case 0x5b: /* FCVTMU */
+ case 0x5c: /* FCVTAU */
+ case 0x7a: /* FCVTPU */
+ case 0x7b: /* FCVTZU */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
default:
g_assert_not_reached();
}
@@ -6868,6 +6893,10 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
int opcode = extract32(insn, 12, 5);
int size = extract32(insn, 22, 2);
bool u = extract32(insn, 29, 1);
+ bool is_fcvt = false;
+ int rmode;
+ TCGv_i32 tcg_rmode;
+ TCGv_ptr tcg_fpstatus;
switch (opcode) {
case 0xa: /* CMLT */
@@ -6909,17 +6938,24 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
}
case 0x1a: /* FCVTNS */
case 0x1b: /* FCVTMS */
- case 0x1c: /* FCVTAS */
case 0x3a: /* FCVTPS */
case 0x3b: /* FCVTZS */
- case 0x3d: /* FRECPE */
- case 0x3f: /* FRECPX */
- case 0x56: /* FCVTXN, FCVTXN2 */
case 0x5a: /* FCVTNU */
case 0x5b: /* FCVTMU */
- case 0x5c: /* FCVTAU */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
+ is_fcvt = true;
+ rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
+ break;
+ case 0x1c: /* FCVTAS */
+ case 0x5c: /* FCVTAU */
+ /* TIEAWAY doesn't fit in the usual rounding mode encoding */
+ is_fcvt = true;
+ rmode = FPROUNDING_TIEAWAY;
+ break;
+ case 0x3d: /* FRECPE */
+ case 0x3f: /* FRECPX */
+ case 0x56: /* FCVTXN, FCVTXN2 */
case 0x7d: /* FRSQRTE */
unsupported_encoding(s, insn);
return;
@@ -6938,18 +6974,66 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
return;
}
+ if (is_fcvt) {
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_fpstatus = get_fpstatus_ptr();
+ } else {
+ TCGV_UNUSED_I32(tcg_rmode);
+ TCGV_UNUSED_PTR(tcg_fpstatus);
+ }
+
if (size == 3) {
TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
TCGv_i64 tcg_rd = tcg_temp_new_i64();
- handle_2misc_64(s, opcode, u, tcg_rd, tcg_rn);
+ handle_2misc_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rmode, tcg_fpstatus);
write_fp_dreg(s, rd, tcg_rd);
tcg_temp_free_i64(tcg_rd);
tcg_temp_free_i64(tcg_rn);
+ } else if (size == 2) {
+ TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
+
+ switch (opcode) {
+ case 0x1a: /* FCVTNS */
+ case 0x1b: /* FCVTMS */
+ case 0x1c: /* FCVTAS */
+ case 0x3a: /* FCVTPS */
+ case 0x3b: /* FCVTZS */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_tosls(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
+ case 0x5a: /* FCVTNU */
+ case 0x5b: /* FCVTMU */
+ case 0x5c: /* FCVTAU */
+ case 0x7a: /* FCVTPU */
+ case 0x7b: /* FCVTZU */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_touls(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
+ default:
+ g_assert_not_reached();
+ }
+
+ write_fp_sreg(s, rd, tcg_rd);
+ tcg_temp_free_i32(tcg_rd);
+ tcg_temp_free_i32(tcg_rn);
} else {
- /* the 'size might not be 64' ops aren't implemented yet */
g_assert_not_reached();
}
+
+ if (is_fcvt) {
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_temp_free_i32(tcg_rmode);
+ tcg_temp_free_ptr(tcg_fpstatus);
+ }
}
/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
@@ -8573,6 +8657,11 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
bool is_q = extract32(insn, 30, 1);
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
+ bool need_fpstatus = false;
+ bool need_rmode = false;
+ int rmode;
+ TCGv_i32 tcg_rmode;
+ TCGv_ptr tcg_fpstatus;
switch (opcode) {
case 0x0: /* REV64, REV32 */
@@ -8691,28 +8780,44 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
return;
}
break;
+ case 0x1a: /* FCVTNS */
+ case 0x1b: /* FCVTMS */
+ case 0x3a: /* FCVTPS */
+ case 0x3b: /* FCVTZS */
+ case 0x5a: /* FCVTNU */
+ case 0x5b: /* FCVTMU */
+ case 0x7a: /* FCVTPU */
+ case 0x7b: /* FCVTZU */
+ need_fpstatus = true;
+ need_rmode = true;
+ rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
+ if (size == 3 && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ case 0x5c: /* FCVTAU */
+ case 0x1c: /* FCVTAS */
+ need_fpstatus = true;
+ need_rmode = true;
+ rmode = FPROUNDING_TIEAWAY;
+ if (size == 3 && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
case 0x16: /* FCVTN, FCVTN2 */
case 0x17: /* FCVTL, FCVTL2 */
case 0x18: /* FRINTN */
case 0x19: /* FRINTM */
- case 0x1a: /* FCVTNS */
- case 0x1b: /* FCVTMS */
- case 0x1c: /* FCVTAS */
case 0x38: /* FRINTP */
case 0x39: /* FRINTZ */
- case 0x3a: /* FCVTPS */
- case 0x3b: /* FCVTZS */
case 0x3c: /* URECPE */
case 0x3d: /* FRECPE */
case 0x56: /* FCVTXN, FCVTXN2 */
case 0x58: /* FRINTA */
case 0x59: /* FRINTX */
- case 0x5a: /* FCVTNU */
- case 0x5b: /* FCVTMU */
- case 0x5c: /* FCVTAU */
case 0x79: /* FRINTI */
- case 0x7a: /* FCVTPU */
- case 0x7b: /* FCVTZU */
case 0x7c: /* URSQRTE */
case 0x7d: /* FRSQRTE */
unsupported_encoding(s, insn);
@@ -8728,6 +8833,18 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
return;
}
+ if (need_fpstatus) {
+ tcg_fpstatus = get_fpstatus_ptr();
+ } else {
+ TCGV_UNUSED_PTR(tcg_fpstatus);
+ }
+ if (need_rmode) {
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ } else {
+ TCGV_UNUSED_I32(tcg_rmode);
+ }
+
if (size == 3) {
/* All 64-bit element operations can be shared with scalar 2misc */
int pass;
@@ -8738,7 +8855,8 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
read_vec_element(s, tcg_op, rn, pass, MO_64);
- handle_2misc_64(s, opcode, u, tcg_res, tcg_op);
+ handle_2misc_64(s, opcode, u, tcg_res, tcg_op,
+ tcg_rmode, tcg_fpstatus);
write_vec_element(s, tcg_res, rd, pass, MO_64);
@@ -8801,6 +8919,30 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
case 0x7f: /* FSQRT */
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
break;
+ case 0x1a: /* FCVTNS */
+ case 0x1b: /* FCVTMS */
+ case 0x1c: /* FCVTAS */
+ case 0x3a: /* FCVTPS */
+ case 0x3b: /* FCVTZS */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_tosls(tcg_res, tcg_op,
+ tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
+ case 0x5a: /* FCVTNU */
+ case 0x5b: /* FCVTMU */
+ case 0x5c: /* FCVTAU */
+ case 0x7a: /* FCVTPU */
+ case 0x7b: /* FCVTZU */
+ {
+ TCGv_i32 tcg_shift = tcg_const_i32(0);
+ gen_helper_vfp_touls(tcg_res, tcg_op,
+ tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ break;
+ }
default:
g_assert_not_reached();
}
@@ -8893,6 +9035,14 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
if (!is_q) {
clear_vec_high(s, rd);
}
+
+ if (need_rmode) {
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_temp_free_i32(tcg_rmode);
+ }
+ if (need_fpstatus) {
+ tcg_temp_free_ptr(tcg_fpstatus);
+ }
}
/* C3.6.13 AdvSIMD scalar x indexed element
--
1.9.0
next prev parent reply other threads:[~2014-03-09 15:11 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-09 15:10 [Qemu-devel] [PATCH 00/16] A64 Neon patches: sixth set Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 01/16] target-arm: A64: Implement PMULL instruction Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 02/16] target-arm: A64: Fix bug in add_sub_ext handling of rn Peter Maydell
2014-03-13 8:04 ` Laurent Desnogues
2014-03-09 15:10 ` [Qemu-devel] [PATCH 03/16] target-arm: A64: Add last AdvSIMD Integer to FP ops Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 04/16] target-arm: A64: Add FSQRT to C3.6.17 (two misc) Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 05/16] target-arm: A64: Add remaining CLS/Z vector ops Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 06/16] target-arm: A64: Saturating and narrowing shift ops Peter Maydell
2014-03-10 15:34 ` Janne Grunau
2014-03-09 15:10 ` [Qemu-devel] [PATCH 07/16] target-arm: A64: Implement SADDLP, UADDLP, SADALP, UADALP Peter Maydell
2014-03-09 15:10 ` [Qemu-devel] [PATCH 08/16] target-arm: A64: Implement SHLL, SHLL2 Peter Maydell
2014-03-09 15:11 ` Peter Maydell [this message]
2014-03-11 13:53 ` [Qemu-devel] [PATCH 09/16] target-arm: A64: Implement FCVT[NMAPZ][SU] SIMD instructions Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 10/16] target-arm: A64: Implement FCVTN Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 11/16] target-arm: A64: Implement FCVTL Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 12/16] target-arm: A64: List unsupported shift-imm opcodes Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 13/16] target-arm: A64: Add FRECPX (reciprocal exponent) Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 14/16] target-arm: A64: Implement SRI Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 15/16] target-arm: A64: Implement FRINT* Peter Maydell
2014-03-09 15:11 ` [Qemu-devel] [PATCH 16/16] exec-all.h: Increase MAX_OP_PER_INSTR for ARM A64 decoder Peter Maydell
2014-03-10 13:24 ` Michael Matz
2014-03-10 13:27 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1394377867-7115-10-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=agraf@suse.de \
--cc=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=dmueller@suse.de \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=laurent.desnogues@gmail.com \
--cc=matz@suse.de \
--cc=patches@linaro.org \
--cc=peter.crosthwaite@xilinx.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=will.newton@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).