From patchwork Fri Sep 27 00:48:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 278381 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ED1AC2C033E for ; Fri, 27 Sep 2013 11:18:53 +1000 (EST) Received: from localhost ([::1]:60661 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPMho-0007J4-0n for incoming@patchwork.ozlabs.org; Thu, 26 Sep 2013 21:18:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39159) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPMFF-0001OE-Po for qemu-devel@nongnu.org; Thu, 26 Sep 2013 20:49:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VPMEw-0004oP-Hv for qemu-devel@nongnu.org; Thu, 26 Sep 2013 20:49:21 -0400 Received: from cantor2.suse.de ([195.135.220.15]:52756 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPMEw-0004mU-44 for qemu-devel@nongnu.org; Thu, 26 Sep 2013 20:49:02 -0400 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E690AA562F; Fri, 27 Sep 2013 02:48:58 +0200 (CEST) From: Alexander Graf To: qemu-devel@nongnu.org Date: Fri, 27 Sep 2013 02:48:47 +0200 Message-Id: <1380242934-20953-54-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1380242934-20953-1-git-send-email-agraf@suse.de> References: <1380242934-20953-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: Peter Maydell , Michael Matz , C Fontana , Dirk Mueller , Laurent Desnogues , Christoffer Dall , Richard Henderson Subject: [Qemu-devel] [PATCH 53/60] AArch64: Add "Floating-point compare" instruction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch adds support for instructions that belong to the "Floating-point compare" group of instructions. Signed-off-by: Alexander Graf --- target-arm/translate-a64.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index cc35c4e..948e5c4 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1975,6 +1975,69 @@ static void handle_fpintconv(DisasContext *s, uint32_t insn) } } +/* Floating-point compare */ +static void handle_fcmp(DisasContext *s, uint32_t insn) +{ + int opc = get_bits(insn, 3, 2); + int rn = get_bits(insn, 5, 5); + int rm = get_bits(insn, 16, 5); + bool is_32bit = !get_bits(insn, 22, 1); + bool is_cmp_with_zero = get_bits(opc, 0, 1); + int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]); + int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]); + TCGv_i32 tcg_op1_32 = tcg_temp_new_i32(); + TCGv_i32 tcg_op1_64 = tcg_temp_new_i64(); + TCGv_i32 tcg_op2_32; + TCGv_i32 tcg_op2_64; + + if (get_bits(insn, 23, 1)) { + unallocated_encoding(s); + } + + tcg_gen_ld_i64(tcg_op1_64, cpu_env, freg_offs_n); + + if (is_32bit) { + tcg_gen_trunc_i64_i32(tcg_op1_32, tcg_op1_64); + } + + if (is_cmp_with_zero) { + tcg_op2_32 = tcg_const_i32(0); + tcg_op2_64 = tcg_const_i64(0); + } else { + tcg_op2_32 = tcg_temp_new_i32(); + tcg_op2_64 = tcg_temp_new_i64(); + + tcg_gen_ld_i64(tcg_op2_64, cpu_env, freg_offs_m); + if (is_32bit) { + tcg_gen_trunc_i64_i32(tcg_op2_32, tcg_op2_64); + } + } + + switch (opc | (is_32bit ? 0x0 : 0x4)) { + case 0x0: /* FCMP single, 32bit */ + case 0x1: /* FCMPZ single, 32bit */ + gen_helper_vfp_cmps(pstate, tcg_op1_32, tcg_op2_32, cpu_env); + break; + case 0x2: /* FCMPE single, 32bit */ + case 0x3: /* FCMPEZ single, 32bit */ + gen_helper_vfp_cmpes(pstate, tcg_op1_32, tcg_op2_32, cpu_env); + break; + case 0x4: /* FCMP double, 64bit */ + case 0x5: /* FCMPZ double, 64bit */ + gen_helper_vfp_cmpd(pstate, tcg_op1_64, tcg_op2_64, cpu_env); + break; + case 0x6: /* FCMPE double, 64bit */ + case 0x7: /* FCMPEZ double, 64bit */ + gen_helper_vfp_cmped(pstate, tcg_op1_64, tcg_op2_64, cpu_env); + break; + } + + tcg_temp_free_i64(tcg_op1_64); + tcg_temp_free_i64(tcg_op2_64); + tcg_temp_free_i32(tcg_op1_32); + tcg_temp_free_i32(tcg_op2_32); +} + /* SIMD ORR */ static void handle_simdorr(DisasContext *s, uint32_t insn) { @@ -2563,6 +2626,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s) } else if (get_bits(insn, 21, 1) && !get_bits(insn, 30, 1) && !get_bits(insn, 10, 6)) { handle_fpintconv(s, insn); + } else if (!get_bits(insn, 29, 3) && get_bits(insn, 21, 1) && + (get_bits(insn, 10, 6) == 0x8) && !get_bits(insn, 0, 3)) { + handle_fcmp(s, insn); } else { unallocated_encoding(s); }