15b569507SJia Liu /* 25b569507SJia Liu * OpenRISC float helper routines 35b569507SJia Liu * 45b569507SJia Liu * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> 55b569507SJia Liu * Feng Gao <gf91597@gmail.com> 65b569507SJia Liu * 75b569507SJia Liu * This library is free software; you can redistribute it and/or 85b569507SJia Liu * modify it under the terms of the GNU Lesser General Public 95b569507SJia Liu * License as published by the Free Software Foundation; either 10198a2d21SThomas Huth * version 2.1 of the License, or (at your option) any later version. 115b569507SJia Liu * 125b569507SJia Liu * This library is distributed in the hope that it will be useful, 135b569507SJia Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of 145b569507SJia Liu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 155b569507SJia Liu * Lesser General Public License for more details. 165b569507SJia Liu * 175b569507SJia Liu * You should have received a copy of the GNU Lesser General Public 185b569507SJia Liu * License along with this library; if not, see <http://www.gnu.org/licenses/>. 195b569507SJia Liu */ 205b569507SJia Liu 21ed2decc6SPeter Maydell #include "qemu/osdep.h" 225b569507SJia Liu #include "cpu.h" 232ef6175aSRichard Henderson #include "exec/helper-proto.h" 245b569507SJia Liu #include "exception.h" 2524f91e81SAlex Bennée #include "fpu/softfloat.h" 265b569507SJia Liu 274e2d3007SRichard Henderson static int ieee_ex_to_openrisc(int fexcp) 285b569507SJia Liu { 295b569507SJia Liu int ret = 0; 305b569507SJia Liu if (fexcp & float_flag_invalid) { 314e2d3007SRichard Henderson ret |= FPCSR_IVF; 325b569507SJia Liu } 335b569507SJia Liu if (fexcp & float_flag_overflow) { 344e2d3007SRichard Henderson ret |= FPCSR_OVF; 355b569507SJia Liu } 365b569507SJia Liu if (fexcp & float_flag_underflow) { 374e2d3007SRichard Henderson ret |= FPCSR_UNF; 385b569507SJia Liu } 395b569507SJia Liu if (fexcp & float_flag_divbyzero) { 404e2d3007SRichard Henderson ret |= FPCSR_DZF; 415b569507SJia Liu } 425b569507SJia Liu if (fexcp & float_flag_inexact) { 434e2d3007SRichard Henderson ret |= FPCSR_IXF; 445b569507SJia Liu } 455b569507SJia Liu return ret; 465b569507SJia Liu } 475b569507SJia Liu 484e2d3007SRichard Henderson void HELPER(update_fpcsr)(CPUOpenRISCState *env) 495b569507SJia Liu { 504e2d3007SRichard Henderson int tmp = get_float_exception_flags(&env->fp_status); 515b569507SJia Liu 524e2d3007SRichard Henderson if (tmp) { 534e2d3007SRichard Henderson set_float_exception_flags(0, &env->fp_status); 544e2d3007SRichard Henderson tmp = ieee_ex_to_openrisc(tmp); 554e2d3007SRichard Henderson if (tmp) { 564e2d3007SRichard Henderson env->fpcsr |= tmp; 574e2d3007SRichard Henderson if (env->fpcsr & FPCSR_FPEE) { 584e2d3007SRichard Henderson helper_exception(env, EXCP_FPE); 594e2d3007SRichard Henderson } 604e2d3007SRichard Henderson } 615b569507SJia Liu } 625b569507SJia Liu } 635b569507SJia Liu 645b569507SJia Liu uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val) 655b569507SJia Liu { 66*62f2b038SRichard Henderson return int64_to_float64(val, &env->fp_status); 675b569507SJia Liu } 685b569507SJia Liu 695b569507SJia Liu uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val) 705b569507SJia Liu { 714e2d3007SRichard Henderson return int32_to_float32(val, &env->fp_status); 725b569507SJia Liu } 735b569507SJia Liu 745b569507SJia Liu uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val) 755b569507SJia Liu { 76*62f2b038SRichard Henderson return float64_to_int64_round_to_zero(val, &env->fp_status); 775b569507SJia Liu } 785b569507SJia Liu 795b569507SJia Liu uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val) 805b569507SJia Liu { 81091a3516SRichard Henderson return float32_to_int32_round_to_zero(val, &env->fp_status); 825b569507SJia Liu } 835b569507SJia Liu 84*62f2b038SRichard Henderson uint64_t HELPER(stod)(CPUOpenRISCState *env, uint32_t val) 85*62f2b038SRichard Henderson { 86*62f2b038SRichard Henderson return float32_to_float64(val, &env->fp_status); 87*62f2b038SRichard Henderson } 88*62f2b038SRichard Henderson 89*62f2b038SRichard Henderson uint32_t HELPER(dtos)(CPUOpenRISCState *env, uint64_t val) 90*62f2b038SRichard Henderson { 91*62f2b038SRichard Henderson return float64_to_float32(val, &env->fp_status); 92*62f2b038SRichard Henderson } 93*62f2b038SRichard Henderson 945b569507SJia Liu #define FLOAT_CALC(name) \ 955b569507SJia Liu uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \ 965b569507SJia Liu uint64_t fdt0, uint64_t fdt1) \ 974e2d3007SRichard Henderson { return float64_ ## name(fdt0, fdt1, &env->fp_status); } \ 985b569507SJia Liu uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \ 995b569507SJia Liu uint32_t fdt0, uint32_t fdt1) \ 1004e2d3007SRichard Henderson { return float32_ ## name(fdt0, fdt1, &env->fp_status); } 1015b569507SJia Liu 1025b569507SJia Liu FLOAT_CALC(add) 1035b569507SJia Liu FLOAT_CALC(sub) 1045b569507SJia Liu FLOAT_CALC(mul) 1055b569507SJia Liu FLOAT_CALC(div) 1065b569507SJia Liu FLOAT_CALC(rem) 1075b569507SJia Liu #undef FLOAT_CALC 1085b569507SJia Liu 109762e22edSRichard Henderson 110762e22edSRichard Henderson uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a, 111762e22edSRichard Henderson uint64_t b, uint64_t c) 112762e22edSRichard Henderson { 1134e2d3007SRichard Henderson /* Note that or1ksim doesn't use fused operation. */ 1144e2d3007SRichard Henderson b = float64_mul(b, c, &env->fp_status); 1154e2d3007SRichard Henderson return float64_add(a, b, &env->fp_status); 1165b569507SJia Liu } 1175b569507SJia Liu 118762e22edSRichard Henderson uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a, 119762e22edSRichard Henderson uint32_t b, uint32_t c) 120762e22edSRichard Henderson { 1214e2d3007SRichard Henderson /* Note that or1ksim doesn't use fused operation. */ 1224e2d3007SRichard Henderson b = float32_mul(b, c, &env->fp_status); 1234e2d3007SRichard Henderson return float32_add(a, b, &env->fp_status); 124762e22edSRichard Henderson } 1255b569507SJia Liu 1265b569507SJia Liu 1274e2d3007SRichard Henderson #define FLOAT_CMP(name, impl) \ 1284e2d3007SRichard Henderson target_ulong helper_float_ ## name ## _d(CPUOpenRISCState *env, \ 1295b569507SJia Liu uint64_t fdt0, uint64_t fdt1) \ 1304e2d3007SRichard Henderson { return float64_ ## impl(fdt0, fdt1, &env->fp_status); } \ 1314e2d3007SRichard Henderson target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env, \ 1325b569507SJia Liu uint32_t fdt0, uint32_t fdt1) \ 1334e2d3007SRichard Henderson { return float32_ ## impl(fdt0, fdt1, &env->fp_status); } 1345b569507SJia Liu 1354e2d3007SRichard Henderson FLOAT_CMP(le, le) 1364e2d3007SRichard Henderson FLOAT_CMP(lt, lt) 1374e2d3007SRichard Henderson FLOAT_CMP(eq, eq_quiet) 1385b569507SJia Liu #undef FLOAT_CMP 139