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 15 float32 float32_exp(float32 Fm); 16 float32 float32_ln(float32 Fm); 17 float32 float32_sin(float32 rFm); 18 float32 float32_cos(float32 rFm); 19 float32 float32_arcsin(float32 rFm); 20 float32 float32_arctan(float32 rFm); 21 float32 float32_log(float32 rFm); 22 float32 float32_tan(float32 rFm); 23 float32 float32_arccos(float32 rFm); 24 float32 float32_pow(float32 rFn, float32 rFm); 25 float32 float32_pol(float32 rFn, float32 rFm); 26 27 static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) 28 { 29 return float32_sub(roundData, rFm, rFn); 30 } 31 32 static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) 33 { 34 return float32_div(roundData, rFm, rFn); 35 } 36 37 static 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 51 static float32 float32_mvf(struct roundingData *roundData, float32 rFm) 52 { 53 return rFm; 54 } 55 56 static float32 float32_mnf(struct roundingData *roundData, float32 rFm) 57 { 58 return rFm ^ 0x80000000; 59 } 60 61 static float32 float32_abs(struct roundingData *roundData, float32 rFm) 62 { 63 return rFm & 0x7fffffff; 64 } 65 66 static 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 76 unsigned 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 } 113