From patchwork Mon Nov 16 19:40:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 545288 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 35D29141463 for ; Tue, 17 Nov 2015 10:53:08 +1100 (AEDT) Received: from localhost ([::1]:52334 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZyTa6-000107-7M for incoming@patchwork.ozlabs.org; Mon, 16 Nov 2015 18:53:06 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34071) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZyPdh-0007JA-Hc for qemu-devel@nongnu.org; Mon, 16 Nov 2015 14:40:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZyPdc-0002oj-Go for qemu-devel@nongnu.org; Mon, 16 Nov 2015 14:40:33 -0500 Received: from col004-omc2s13.hotmail.com ([65.55.34.87]:55432) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZyPdc-0002oc-4K for qemu-devel@nongnu.org; Mon, 16 Nov 2015 14:40:28 -0500 Received: from COL130-W12 ([65.55.34.72]) by COL004-OMC2S13.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Mon, 16 Nov 2015 11:40:27 -0800 X-TMN: [BMaPx2KeIxxWJ5krrqfvXTRQ8xvawPCn] X-Originating-Email: [xili_gchen_5257@hotmail.com] Message-ID: From: Chen Gang To: "rth@twiddle.net" , Peter Maydell , Chris Metcalf Date: Tue, 17 Nov 2015 03:40:27 +0800 Importance: Normal In-Reply-To: References: MIME-Version: 1.0 X-OriginalArrivalTime: 16 Nov 2015 19:40:27.0517 (UTC) FILETIME=[A4FD2AD0:01D120A6] X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 65.55.34.87 Cc: qemu-devel Subject: [Qemu-devel] [PATCH v2 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 1c4bb91e72995a1675d3aa0f911c534a3e8db749 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Tue, 17 Nov 2015 03:07:33 +0800 Subject: [PATCH v2 2/4] target-tilegx: Add single floating point implementation Signed-off-by: Chen Gang ---  target-tilegx/helper-fsingle.c | 212 +++++++++++++++++++++++++++++++++++++++++  1 file changed, 212 insertions(+)  create mode 100644 target-tilegx/helper-fsingle.c --  1.9.3 diff --git a/target-tilegx/helper-fsingle.c b/target-tilegx/helper-fsingle.c new file mode 100644 index 0000000..a33837e --- /dev/null +++ b/target-tilegx/helper-fsingle.c @@ -0,0 +1,212 @@ +/* + * 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.c" + +/* + * 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, float_status *fp_status) +{ +    float32 f; +    uint32_t sign = get_fsingle_sign(sfmt); +    uint32_t man = get_fsingle_man(sfmt); + +    if (get_fsingle_calc(sfmt) == TILEGX_F_CALC_CVT) { +        if (sign) { +            return int32_to_float32(0 - man, fp_status); +        } else { +            return uint32_to_float32(man, fp_status); +        } +    } else { +        f = float32_set_sign(float32_zero, sign); +        f |= create_f32_man(man>> 8); +        set_f32_exp(&f, get_fsingle_exp(sfmt)); +    } + +    return f; +} + +uint64_t helper_fsingle_pack2(CPUTLGState *env, uint64_t srca) +{ +    return float32_val(sfmt_to_float32(srca, &env->fp_status)); +} + +static void ana_bits(float_status *fp_status, +                     float32 fsrca, float32 fsrcb, uint64_t *sfmt) +{ +    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(); +    } +} + +static uint64_t main_calc(float_status *fp_status, +                          float32 fsrca, float32 fsrcb, +                          float32 (*calc)(float32, float32, float_status *)) +{ +    uint64_t sfmt = float32_to_sfmt(calc(fsrca, fsrcb, fp_status)); + +    ana_bits(fp_status, fsrca, fsrcb, &sfmt); + +    set_fsingle_calc(&sfmt, TILEGX_F_CALC_NCVT); +    return sfmt; +} + +uint64_t helper_fsingle_add1(CPUTLGState *env, uint64_t srca, uint64_t srcb) +{ +    return main_calc(&env->fp_status, +                     make_float32(srca), make_float32(srcb), float32_add); +} + +uint64_t helper_fsingle_sub1(CPUTLGState *env, uint64_t srca, uint64_t srcb) +{ +    return main_calc(&env->fp_status, +                     make_float32(srca), make_float32(srcb), float32_sub); +} + +uint64_t helper_fsingle_mul1(CPUTLGState *env, uint64_t srca, uint64_t srcb) +{ +    return main_calc(&env->fp_status, +                     make_float32(srca), make_float32(srcb), float32_mul); +}