1c88f8107SLaurent Vivier /* 2c88f8107SLaurent Vivier * m68k FPU helpers 3c88f8107SLaurent Vivier * 4c88f8107SLaurent Vivier * Copyright (c) 2006-2007 CodeSourcery 5c88f8107SLaurent Vivier * Written by Paul Brook 6c88f8107SLaurent Vivier * 7c88f8107SLaurent Vivier * This library is free software; you can redistribute it and/or 8c88f8107SLaurent Vivier * modify it under the terms of the GNU Lesser General Public 9c88f8107SLaurent Vivier * License as published by the Free Software Foundation; either 10c88f8107SLaurent Vivier * version 2 of the License, or (at your option) any later version. 11c88f8107SLaurent Vivier * 12c88f8107SLaurent Vivier * This library is distributed in the hope that it will be useful, 13c88f8107SLaurent Vivier * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c88f8107SLaurent Vivier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15c88f8107SLaurent Vivier * General Public License for more details. 16c88f8107SLaurent Vivier * 17c88f8107SLaurent Vivier * You should have received a copy of the GNU Lesser General Public 18c88f8107SLaurent Vivier * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19c88f8107SLaurent Vivier */ 20c88f8107SLaurent Vivier 21c88f8107SLaurent Vivier #include "qemu/osdep.h" 22c88f8107SLaurent Vivier #include "cpu.h" 23c88f8107SLaurent Vivier #include "exec/helper-proto.h" 24*f83311e4SLaurent Vivier #include "exec/exec-all.h" 25c88f8107SLaurent Vivier 26*f83311e4SLaurent Vivier int32_t HELPER(reds32)(CPUM68KState *env, FPReg *val) 27c88f8107SLaurent Vivier { 28*f83311e4SLaurent Vivier return floatx80_to_int32(val->d, &env->fp_status); 29c88f8107SLaurent Vivier } 30c88f8107SLaurent Vivier 31*f83311e4SLaurent Vivier float32 HELPER(redf32)(CPUM68KState *env, FPReg *val) 32c88f8107SLaurent Vivier { 33*f83311e4SLaurent Vivier return floatx80_to_float32(val->d, &env->fp_status); 34c88f8107SLaurent Vivier } 35c88f8107SLaurent Vivier 36*f83311e4SLaurent Vivier void HELPER(exts32)(CPUM68KState *env, FPReg *res, int32_t val) 37c88f8107SLaurent Vivier { 38*f83311e4SLaurent Vivier res->d = int32_to_floatx80(val, &env->fp_status); 39c88f8107SLaurent Vivier } 40c88f8107SLaurent Vivier 41*f83311e4SLaurent Vivier void HELPER(extf32)(CPUM68KState *env, FPReg *res, float32 val) 42c88f8107SLaurent Vivier { 43*f83311e4SLaurent Vivier res->d = float32_to_floatx80(val, &env->fp_status); 44c88f8107SLaurent Vivier } 45c88f8107SLaurent Vivier 46*f83311e4SLaurent Vivier void HELPER(extf64)(CPUM68KState *env, FPReg *res, float64 val) 47c88f8107SLaurent Vivier { 48*f83311e4SLaurent Vivier res->d = float64_to_floatx80(val, &env->fp_status); 49c88f8107SLaurent Vivier } 50c88f8107SLaurent Vivier 51*f83311e4SLaurent Vivier float64 HELPER(redf64)(CPUM68KState *env, FPReg *val) 52c88f8107SLaurent Vivier { 53*f83311e4SLaurent Vivier return floatx80_to_float64(val->d, &env->fp_status); 54c88f8107SLaurent Vivier } 55c88f8107SLaurent Vivier 56*f83311e4SLaurent Vivier void HELPER(firound)(CPUM68KState *env, FPReg *res, FPReg *val) 57c88f8107SLaurent Vivier { 58*f83311e4SLaurent Vivier res->d = floatx80_round_to_int(val->d, &env->fp_status); 59c88f8107SLaurent Vivier } 60c88f8107SLaurent Vivier 61*f83311e4SLaurent Vivier void HELPER(fitrunc)(CPUM68KState *env, FPReg *res, FPReg *val) 62c88f8107SLaurent Vivier { 63*f83311e4SLaurent Vivier res->d = floatx80_round_to_int(val->d, &env->fp_status); 64c88f8107SLaurent Vivier } 65c88f8107SLaurent Vivier 66*f83311e4SLaurent Vivier void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val) 67c88f8107SLaurent Vivier { 68*f83311e4SLaurent Vivier res->d = floatx80_sqrt(val->d, &env->fp_status); 69c88f8107SLaurent Vivier } 70c88f8107SLaurent Vivier 71*f83311e4SLaurent Vivier void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val) 72c88f8107SLaurent Vivier { 73*f83311e4SLaurent Vivier res->d = floatx80_abs(val->d); 74c88f8107SLaurent Vivier } 75c88f8107SLaurent Vivier 76*f83311e4SLaurent Vivier void HELPER(fchs)(CPUM68KState *env, FPReg *res, FPReg *val) 77c88f8107SLaurent Vivier { 78*f83311e4SLaurent Vivier res->d = floatx80_chs(val->d); 79c88f8107SLaurent Vivier } 80c88f8107SLaurent Vivier 81*f83311e4SLaurent Vivier void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) 82c88f8107SLaurent Vivier { 83*f83311e4SLaurent Vivier res->d = floatx80_add(val0->d, val1->d, &env->fp_status); 84c88f8107SLaurent Vivier } 85c88f8107SLaurent Vivier 86*f83311e4SLaurent Vivier void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) 87c88f8107SLaurent Vivier { 88*f83311e4SLaurent Vivier res->d = floatx80_sub(val1->d, val0->d, &env->fp_status); 89c88f8107SLaurent Vivier } 90c88f8107SLaurent Vivier 91*f83311e4SLaurent Vivier void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) 92*f83311e4SLaurent Vivier { 93*f83311e4SLaurent Vivier res->d = floatx80_mul(val0->d, val1->d, &env->fp_status); 94*f83311e4SLaurent Vivier } 95*f83311e4SLaurent Vivier 96*f83311e4SLaurent Vivier void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) 97*f83311e4SLaurent Vivier { 98*f83311e4SLaurent Vivier res->d = floatx80_div(val1->d, val0->d, &env->fp_status); 99*f83311e4SLaurent Vivier } 100*f83311e4SLaurent Vivier 101*f83311e4SLaurent Vivier void HELPER(fsub_cmp)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) 102c88f8107SLaurent Vivier { 103c88f8107SLaurent Vivier /* ??? This may incorrectly raise exceptions. */ 104c88f8107SLaurent Vivier /* ??? Should flush denormals to zero. */ 105*f83311e4SLaurent Vivier res->d = floatx80_sub(val0->d, val1->d, &env->fp_status); 106*f83311e4SLaurent Vivier if (floatx80_is_quiet_nan(res->d, &env->fp_status)) { 107c88f8107SLaurent Vivier /* +/-inf compares equal against itself, but sub returns nan. */ 108*f83311e4SLaurent Vivier if (!floatx80_is_quiet_nan(val0->d, &env->fp_status) 109*f83311e4SLaurent Vivier && !floatx80_is_quiet_nan(val1->d, &env->fp_status)) { 110*f83311e4SLaurent Vivier res->d = floatx80_zero; 111*f83311e4SLaurent Vivier if (floatx80_lt_quiet(val0->d, res->d, &env->fp_status)) { 112*f83311e4SLaurent Vivier res->d = floatx80_chs(res->d); 113c88f8107SLaurent Vivier } 114c88f8107SLaurent Vivier } 115c88f8107SLaurent Vivier } 116c88f8107SLaurent Vivier } 117c88f8107SLaurent Vivier 118*f83311e4SLaurent Vivier uint32_t HELPER(fcompare)(CPUM68KState *env, FPReg *val) 119c88f8107SLaurent Vivier { 120*f83311e4SLaurent Vivier return floatx80_compare_quiet(val->d, floatx80_zero, &env->fp_status); 121c88f8107SLaurent Vivier } 122