>From 3270485ebd56429f6f62f0a4f967009d8a1b14d6 Mon Sep 17 00:00:00 2001 From: Chen Gang <gang.chen.5...@gmail.com> Date: Sun, 8 Nov 2015 09:08:40 +0800 Subject: [PATCH 2/4] target-tilegx: Implement fpu single floating point instructions
Signed-off-by: Chen Gang <gang.chen.5...@gmail.com> --- target-tilegx/fsingle_helper.c | 168 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 target-tilegx/fsingle_helper.c diff --git a/target-tilegx/fsingle_helper.c b/target-tilegx/fsingle_helper.c new file mode 100644 index 0000000..f8f6b69 --- /dev/null +++ b/target-tilegx/fsingle_helper.c @@ -0,0 +1,168 @@ +/* + * 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 + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +#include "cpu.h" +#include "qemu-common.h" +#include "exec/helper-proto.h" +#include "fpu/softfloat.h" + +#include "fpu.h" + +#pragma pack(push, 1) +typedef union F32Fmt { + uint32_t f; + struct { +#if defined(HOST_WORDS_BIGENDIAN) + uint32_t sign : 1; + uint32_t exp : 8; + uint32_t frac : 23; +#else + uint32_t frac : 23; + uint32_t exp : 8; + uint32_t sign : 1; +#endif + } bits; +} F32Fmt; +#pragma pack(pop) + +static uint64_t sfmt_to_uint64(TileGXFPSFmt a) +{ + union { + TileGXFPSFmt a; + uint64_t v; + } t; + t.a = a; + return t.v; +} + +static TileGXFPSFmt uint64_to_sfmt(uint64 v) +{ + union { + TileGXFPSFmt a; + uint64_t v; + } t; + t.v = v; + return t.a; +} + +static TileGXFPSFmt float32_to_sfmt(float32 f) +{ + F32Fmt tmp = {f}; + union { + TileGXFPSFmt fmt; + uint64_t v; + } sfmt; + + sfmt.v = 0; + sfmt.fmt.sign = tmp.bits.sign; + sfmt.fmt.exp = tmp.bits.exp; + sfmt.fmt.mantissa = (tmp.bits.frac << 8) | (1 << 31); + + return sfmt.fmt; +} + +static float32 sfmt_to_float32(TileGXFPSFmt sfmt, float_status *fp_status) +{ + F32Fmt f; + + if (sfmt.calc == TILEGX_F_CALC_CVT) { + if (sfmt.sign) + f.f = int32_to_float32(0 - sfmt.mantissa, fp_status); + else + f.f = uint32_to_float32(sfmt.mantissa, fp_status); + } else { + f.bits.sign = sfmt.sign; + f.bits.exp = sfmt.exp; + f.bits.frac = sfmt.mantissa>> 8; + } + + return f.f; +} + +uint64_t helper_fsingle_pack2(CPUTLGState *env, uint64_t srca) +{ + return float32_val(sfmt_to_float32(uint64_to_sfmt(srca), &env->fp_status)); +} + +static void ana_bits(float_status *fp_status, + float32 fsrca, float32 fsrcb, TileGXFPSFmt *sfmt) +{ + if (float32_eq(fsrca, fsrcb, fp_status)) { + sfmt->eq = 1; + } else { + sfmt->neq = 1; + } + + if (float32_lt(fsrca, fsrcb, fp_status)) { + sfmt->lt = 1; + } + if (float32_le(fsrca, fsrcb, fp_status)) { + sfmt->le = 1; + } + + if (float32_lt(fsrcb, fsrca, fp_status)) { + sfmt->gt = 1; + } + if (float32_le(fsrcb, fsrca, fp_status)) { + sfmt->ge = 1; + } + + if (float32_unordered(fsrca, fsrcb, fp_status)) { + sfmt->unordered = 1; + } +} + +static uint64_t main_calc(float_status *fp_status, + float32 fsrca, float32 fsrcb, + float32 (*calc)(float32, float32, float_status *)) +{ + TileGXFPSFmt sfmt = float32_to_sfmt(calc(fsrca, fsrcb, fp_status)); + + ana_bits(fp_status, fsrca, fsrcb, &sfmt); + + if (calc == float32_add) + sfmt.calc = TILEGX_F_CALC_ADD; + else if (calc == float32_sub) + sfmt.calc = TILEGX_F_CALC_SUB; + else + sfmt.calc = TILEGX_F_CALC_MUL; + + sfmt_to_float32(sfmt, fp_status); + + return sfmt_to_uint64(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); +} -- 1.9.3
0002-target-tilegx-Implement-fpu-single-floating-point-in.patch
Description: Binary data