From patchwork Wed Dec 23 21:48:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 560747 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3C574140BAD for ; Thu, 24 Dec 2015 08:50:39 +1100 (AEDT) Received: from localhost ([::1]:58027 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBrIr-0003uf-6S for incoming@patchwork.ozlabs.org; Wed, 23 Dec 2015 16:50:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45892) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBrIO-00035p-TX for qemu-devel@nongnu.org; Wed, 23 Dec 2015 16:50:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aBrIL-0004fs-Lq for qemu-devel@nongnu.org; Wed, 23 Dec 2015 16:50:08 -0500 Received: from out114-135.biz.mail.alibaba.com ([205.204.114.135]:35572 helo=out11.biz.mail.alibaba.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBrIK-0004cb-O7 for qemu-devel@nongnu.org; Wed, 23 Dec 2015 16:50:05 -0500 X-Alimail-AntiSpam: AC=CONTINUE; BC=0.07444138|-1; FP=11435866858648330232|1|1|2|0|-1|-1|-1; HT=e01l04446; MF=chengang@emindsoft.com.cn; NM=1; PH=DS; RN=7; RT=6; SR=0; TI=SMTPD_----4Nunx6t_1450907391; Received: from localhost.localdomain.localdomain(mailfrom:chengang@emindsoft.com.cn ip:223.72.67.117) by smtp.aliyun-inc.com(10.147.40.44); Thu, 24 Dec 2015 05:49:52 +0800 From: chengang@emindsoft.com.cn To: rth@twiddle.net, peter.maydell@linaro.org, cmetcalf@ezchip.com Date: Thu, 24 Dec 2015 05:48:33 +0800 Message-Id: <1450907315-10135-3-git-send-email-chengang@emindsoft.com.cn> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1450907315-10135-1-git-send-email-chengang@emindsoft.com.cn> References: <1450907315-10135-1-git-send-email-chengang@emindsoft.com.cn> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 205.204.114.135 Cc: Chen Gang , qemu-devel@nongnu.org, Chen Gang Subject: [Qemu-devel] [PATCH v4 2/4] target-tilegx: Add single floating point implementation 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 From: Chen Gang Signed-off-by: Chen Gang --- target-tilegx/helper-fsingle.c | 211 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 target-tilegx/helper-fsingle.c diff --git a/target-tilegx/helper-fsingle.c b/target-tilegx/helper-fsingle.c new file mode 100644 index 0000000..b6c3b0e --- /dev/null +++ b/target-tilegx/helper-fsingle.c @@ -0,0 +1,211 @@ +/* + * QEMU TILE-Gx helpers + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * + */ + +#include "cpu.h" +#include "qemu-common.h" +#include "exec/helper-proto.h" +#include "fpu/softfloat.h" + +#include "helper-fshared.h" + +/* + * FSingle instructions implemenation: + * + * fsingle_add1 ; calc srca and srcb, + * ; convert float_32 to TileGXFPSFmt result. + * ; move TileGXFPSFmt result to dest. + * + * fsingle_sub1 ; calc srca and srcb. + * ; convert float_32 to TileGXFPSFmt result. + * ; move TileGXFPSFmt result to dest. + * + * fsingle_addsub2 ; nop. + * + * fsingle_mul1 ; calc srca and srcb. + * ; convert float_32 value to TileGXFPSFmt result. + * ; move TileGXFPSFmt result to dest. + * + * fsingle_mul2 ; move srca to dest. + * + * fsingle_pack1 ; nop + * + * fsingle_pack2 ; treate srca as TileGXFPSFmt result. + * ; convert TileGXFPSFmt result to float_32 value. + * ; move float_32 value to dest. + */ + +#define TILEGX_F_CALC_CVT 0 /* convert int to fsingle */ +#define TILEGX_F_CALC_NCVT 1 /* Not convertion */ + +static uint32_t get_f32_exp(float32 f) +{ + return extract32(float32_val(f), 23, 8); +} + +static void set_f32_exp(float32 *f, uint32_t exp) +{ + *f = make_float32(deposit32(float32_val(*f), 23, 8, exp)); +} + +static uint32_t get_f32_man(float32 f) +{ + return float32_val(f) & 0x7fffff; +} + +static float32 create_f32_man(uint32_t man) +{ + return make_float32(man & 0x7fffff); +} + +static inline uint32_t get_fsingle_exp(uint64_t n) +{ + return n & 0xff; +} + +static inline uint64_t create_fsingle_exp(uint32_t exp) +{ + return exp & 0xff; +} + +static inline uint32_t get_fsingle_sign(uint64_t n) +{ + return test_bit(10, &n); +} + +static inline void set_fsingle_sign(uint64_t *n) +{ + set_bit(10, n); +} + +static inline unsigned int get_fsingle_calc(uint64_t n) +{ + return test_bit(11, &n); +} + +static inline void set_fsingle_calc(uint64_t *n, uint32_t calc) +{ + set_bit(11, n); +} + +static inline unsigned int get_fsingle_man(uint64_t n) +{ + return n >> 32; +} + +static inline uint64_t create_fsingle_man(uint32_t man) +{ + return (uint64_t)man << 32; +} + +static uint64_t float32_to_sfmt(float32 f) +{ + uint64_t sfmt = 0; + + if (float32_is_neg(f)) { + set_fsingle_sign(&sfmt); + } + sfmt |= create_fsingle_exp(get_f32_exp(f)); + sfmt |= create_fsingle_man((get_f32_man(f) << 8) | (1 << 31)); + + return sfmt; +} + +static float32 sfmt_to_float32(uint64_t sfmt) +{ + uint32_t sign = get_fsingle_sign(sfmt); + uint32_t man = get_fsingle_man(sfmt); + uint32_t exp = get_fsingle_exp(sfmt); + float32 f; + + if (get_fsingle_calc(sfmt) == TILEGX_F_CALC_CVT) { + if (sign) { + f = int32_to_float32(0 - man, &fp_status); + } else { + f = uint32_to_float32(man, &fp_status); + } + exp += get_f32_exp(f) - 0x9e; + if ((int32_t) exp < 0) { + return float32_infinity | float32_set_sign(float32_zero, sign); + } else if (exp >= 0xff) { + return float32_zero | float32_set_sign(float32_zero, sign); + } else { + set_f32_exp(&f, exp); + } + } else { + f = create_f32_man(man >> 8); + set_f32_exp(&f, exp); + } + + f = float32_set_sign(f, sign); + return f; +} + +uint64_t helper_fsingle_pack2(uint64_t srca) +{ + return float32_val(sfmt_to_float32(srca)); +} + +static uint64_t main_calc(float32 fsrca, float32 fsrcb, + float32 (*calc)(float32, float32, float_status *)) +{ + uint64_t sfmt = float32_to_sfmt(calc(fsrca, fsrcb, &fp_status)); + + if (float32_eq(fsrca, fsrcb, &fp_status)) { + sfmt |= create_fsfd_flag_eq(); + } else { + sfmt |= create_fsfd_flag_ne(); + } + + if (float32_lt(fsrca, fsrcb, &fp_status)) { + sfmt |= create_fsfd_flag_lt(); + } + if (float32_le(fsrca, fsrcb, &fp_status)) { + sfmt |= create_fsfd_flag_le(); + } + + if (float32_lt(fsrcb, fsrca, &fp_status)) { + sfmt |= create_fsfd_flag_gt(); + } + if (float32_le(fsrcb, fsrca, &fp_status)) { + sfmt |= create_fsfd_flag_ge(); + } + + if (float32_unordered(fsrca, fsrcb, &fp_status)) { + sfmt |= create_fsfd_flag_un(); + } + + set_fsingle_calc(&sfmt, TILEGX_F_CALC_NCVT); + return sfmt; +} + +uint64_t helper_fsingle_add1(uint64_t srca, uint64_t srcb) +{ + return main_calc(make_float32(srca), make_float32(srcb), float32_add); +} + +uint64_t helper_fsingle_sub1(uint64_t srca, uint64_t srcb) +{ + return main_calc(make_float32(srca), make_float32(srcb), float32_sub); +} + +uint64_t helper_fsingle_mul1(uint64_t srca, uint64_t srcb) +{ + return main_calc(make_float32(srca), make_float32(srcb), float32_mul); +}