single_cpdo.c (2904B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 NetWinder Floating Point Emulator 4 (c) Rebel.COM, 1998,1999 5 (c) Philip Blundell, 2001 6 7 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 8 9*/ 10 11#include "fpa11.h" 12#include "softfloat.h" 13#include "fpopcode.h" 14 15float32 float32_exp(float32 Fm); 16float32 float32_ln(float32 Fm); 17float32 float32_sin(float32 rFm); 18float32 float32_cos(float32 rFm); 19float32 float32_arcsin(float32 rFm); 20float32 float32_arctan(float32 rFm); 21float32 float32_log(float32 rFm); 22float32 float32_tan(float32 rFm); 23float32 float32_arccos(float32 rFm); 24float32 float32_pow(float32 rFn, float32 rFm); 25float32 float32_pol(float32 rFn, float32 rFm); 26 27static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) 28{ 29 return float32_sub(roundData, rFm, rFn); 30} 31 32static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) 33{ 34 return float32_div(roundData, rFm, rFn); 35} 36 37static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = { 38 [ADF_CODE >> 20] = float32_add, 39 [MUF_CODE >> 20] = float32_mul, 40 [SUF_CODE >> 20] = float32_sub, 41 [RSF_CODE >> 20] = float32_rsf, 42 [DVF_CODE >> 20] = float32_div, 43 [RDF_CODE >> 20] = float32_rdv, 44 [RMF_CODE >> 20] = float32_rem, 45 46 [FML_CODE >> 20] = float32_mul, 47 [FDV_CODE >> 20] = float32_div, 48 [FRD_CODE >> 20] = float32_rdv, 49}; 50 51static float32 float32_mvf(struct roundingData *roundData, float32 rFm) 52{ 53 return rFm; 54} 55 56static float32 float32_mnf(struct roundingData *roundData, float32 rFm) 57{ 58 return rFm ^ 0x80000000; 59} 60 61static float32 float32_abs(struct roundingData *roundData, float32 rFm) 62{ 63 return rFm & 0x7fffffff; 64} 65 66static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = { 67 [MVF_CODE >> 20] = float32_mvf, 68 [MNF_CODE >> 20] = float32_mnf, 69 [ABS_CODE >> 20] = float32_abs, 70 [RND_CODE >> 20] = float32_round_to_int, 71 [URD_CODE >> 20] = float32_round_to_int, 72 [SQT_CODE >> 20] = float32_sqrt, 73 [NRM_CODE >> 20] = float32_mvf, 74}; 75 76unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) 77{ 78 FPA11 *fpa11 = GET_FPA11(); 79 float32 rFm; 80 unsigned int Fm, opc_mask_shift; 81 82 Fm = getFm(opcode); 83 if (CONSTANT_FM(opcode)) { 84 rFm = getSingleConstant(Fm); 85 } else if (fpa11->fType[Fm] == typeSingle) { 86 rFm = fpa11->fpreg[Fm].fSingle; 87 } else { 88 return 0; 89 } 90 91 opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; 92 if (!MONADIC_INSTRUCTION(opcode)) { 93 unsigned int Fn = getFn(opcode); 94 float32 rFn; 95 96 if (fpa11->fType[Fn] == typeSingle && 97 dyadic_single[opc_mask_shift]) { 98 rFn = fpa11->fpreg[Fn].fSingle; 99 rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm); 100 } else { 101 return 0; 102 } 103 } else { 104 if (monadic_single[opc_mask_shift]) { 105 rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm); 106 } else { 107 return 0; 108 } 109 } 110 111 return 1; 112}