18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci NetWinder Floating Point Emulator 48c2ecf20Sopenharmony_ci (c) Rebel.COM, 1998,1999 58c2ecf20Sopenharmony_ci (c) Philip Blundell, 2001 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci*/ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "fpa11.h" 128c2ecf20Sopenharmony_ci#include "softfloat.h" 138c2ecf20Sopenharmony_ci#include "fpopcode.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cifloat32 float32_exp(float32 Fm); 168c2ecf20Sopenharmony_cifloat32 float32_ln(float32 Fm); 178c2ecf20Sopenharmony_cifloat32 float32_sin(float32 rFm); 188c2ecf20Sopenharmony_cifloat32 float32_cos(float32 rFm); 198c2ecf20Sopenharmony_cifloat32 float32_arcsin(float32 rFm); 208c2ecf20Sopenharmony_cifloat32 float32_arctan(float32 rFm); 218c2ecf20Sopenharmony_cifloat32 float32_log(float32 rFm); 228c2ecf20Sopenharmony_cifloat32 float32_tan(float32 rFm); 238c2ecf20Sopenharmony_cifloat32 float32_arccos(float32 rFm); 248c2ecf20Sopenharmony_cifloat32 float32_pow(float32 rFn, float32 rFm); 258c2ecf20Sopenharmony_cifloat32 float32_pol(float32 rFn, float32 rFm); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci return float32_sub(roundData, rFm, rFn); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci return float32_div(roundData, rFm, rFn); 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = { 388c2ecf20Sopenharmony_ci [ADF_CODE >> 20] = float32_add, 398c2ecf20Sopenharmony_ci [MUF_CODE >> 20] = float32_mul, 408c2ecf20Sopenharmony_ci [SUF_CODE >> 20] = float32_sub, 418c2ecf20Sopenharmony_ci [RSF_CODE >> 20] = float32_rsf, 428c2ecf20Sopenharmony_ci [DVF_CODE >> 20] = float32_div, 438c2ecf20Sopenharmony_ci [RDF_CODE >> 20] = float32_rdv, 448c2ecf20Sopenharmony_ci [RMF_CODE >> 20] = float32_rem, 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci [FML_CODE >> 20] = float32_mul, 478c2ecf20Sopenharmony_ci [FDV_CODE >> 20] = float32_div, 488c2ecf20Sopenharmony_ci [FRD_CODE >> 20] = float32_rdv, 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic float32 float32_mvf(struct roundingData *roundData, float32 rFm) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci return rFm; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic float32 float32_mnf(struct roundingData *roundData, float32 rFm) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci return rFm ^ 0x80000000; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic float32 float32_abs(struct roundingData *roundData, float32 rFm) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci return rFm & 0x7fffffff; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = { 678c2ecf20Sopenharmony_ci [MVF_CODE >> 20] = float32_mvf, 688c2ecf20Sopenharmony_ci [MNF_CODE >> 20] = float32_mnf, 698c2ecf20Sopenharmony_ci [ABS_CODE >> 20] = float32_abs, 708c2ecf20Sopenharmony_ci [RND_CODE >> 20] = float32_round_to_int, 718c2ecf20Sopenharmony_ci [URD_CODE >> 20] = float32_round_to_int, 728c2ecf20Sopenharmony_ci [SQT_CODE >> 20] = float32_sqrt, 738c2ecf20Sopenharmony_ci [NRM_CODE >> 20] = float32_mvf, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciunsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci FPA11 *fpa11 = GET_FPA11(); 798c2ecf20Sopenharmony_ci float32 rFm; 808c2ecf20Sopenharmony_ci unsigned int Fm, opc_mask_shift; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci Fm = getFm(opcode); 838c2ecf20Sopenharmony_ci if (CONSTANT_FM(opcode)) { 848c2ecf20Sopenharmony_ci rFm = getSingleConstant(Fm); 858c2ecf20Sopenharmony_ci } else if (fpa11->fType[Fm] == typeSingle) { 868c2ecf20Sopenharmony_ci rFm = fpa11->fpreg[Fm].fSingle; 878c2ecf20Sopenharmony_ci } else { 888c2ecf20Sopenharmony_ci return 0; 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; 928c2ecf20Sopenharmony_ci if (!MONADIC_INSTRUCTION(opcode)) { 938c2ecf20Sopenharmony_ci unsigned int Fn = getFn(opcode); 948c2ecf20Sopenharmony_ci float32 rFn; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if (fpa11->fType[Fn] == typeSingle && 978c2ecf20Sopenharmony_ci dyadic_single[opc_mask_shift]) { 988c2ecf20Sopenharmony_ci rFn = fpa11->fpreg[Fn].fSingle; 998c2ecf20Sopenharmony_ci rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm); 1008c2ecf20Sopenharmony_ci } else { 1018c2ecf20Sopenharmony_ci return 0; 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci } else { 1048c2ecf20Sopenharmony_ci if (monadic_single[opc_mask_shift]) { 1058c2ecf20Sopenharmony_ci rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm); 1068c2ecf20Sopenharmony_ci } else { 1078c2ecf20Sopenharmony_ci return 0; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci } 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci return 1; 1128c2ecf20Sopenharmony_ci} 113