0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "fpa11.h"
0011 #include "softfloat.h"
0012 #include "fpopcode.h"
0013
0014 union float64_components {
0015 float64 f64;
0016 unsigned int i[2];
0017 };
0018
0019 float64 float64_exp(float64 Fm);
0020 float64 float64_ln(float64 Fm);
0021 float64 float64_sin(float64 rFm);
0022 float64 float64_cos(float64 rFm);
0023 float64 float64_arcsin(float64 rFm);
0024 float64 float64_arctan(float64 rFm);
0025 float64 float64_log(float64 rFm);
0026 float64 float64_tan(float64 rFm);
0027 float64 float64_arccos(float64 rFm);
0028 float64 float64_pow(float64 rFn, float64 rFm);
0029 float64 float64_pol(float64 rFn, float64 rFm);
0030
0031 static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm)
0032 {
0033 return float64_sub(roundData, rFm, rFn);
0034 }
0035
0036 static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm)
0037 {
0038 return float64_div(roundData, rFm, rFn);
0039 }
0040
0041 static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = {
0042 [ADF_CODE >> 20] = float64_add,
0043 [MUF_CODE >> 20] = float64_mul,
0044 [SUF_CODE >> 20] = float64_sub,
0045 [RSF_CODE >> 20] = float64_rsf,
0046 [DVF_CODE >> 20] = float64_div,
0047 [RDF_CODE >> 20] = float64_rdv,
0048 [RMF_CODE >> 20] = float64_rem,
0049
0050
0051 [FML_CODE >> 20] = float64_mul,
0052 [FDV_CODE >> 20] = float64_div,
0053 [FRD_CODE >> 20] = float64_rdv,
0054 };
0055
0056 static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
0057 {
0058 return rFm;
0059 }
0060
0061 static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
0062 {
0063 union float64_components u;
0064
0065 u.f64 = rFm;
0066 #ifdef __ARMEB__
0067 u.i[0] ^= 0x80000000;
0068 #else
0069 u.i[1] ^= 0x80000000;
0070 #endif
0071
0072 return u.f64;
0073 }
0074
0075 static float64 float64_abs(struct roundingData *roundData,float64 rFm)
0076 {
0077 union float64_components u;
0078
0079 u.f64 = rFm;
0080 #ifdef __ARMEB__
0081 u.i[0] &= 0x7fffffff;
0082 #else
0083 u.i[1] &= 0x7fffffff;
0084 #endif
0085
0086 return u.f64;
0087 }
0088
0089 static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = {
0090 [MVF_CODE >> 20] = float64_mvf,
0091 [MNF_CODE >> 20] = float64_mnf,
0092 [ABS_CODE >> 20] = float64_abs,
0093 [RND_CODE >> 20] = float64_round_to_int,
0094 [URD_CODE >> 20] = float64_round_to_int,
0095 [SQT_CODE >> 20] = float64_sqrt,
0096 [NRM_CODE >> 20] = float64_mvf,
0097 };
0098
0099 unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
0100 {
0101 FPA11 *fpa11 = GET_FPA11();
0102 float64 rFm;
0103 unsigned int Fm, opc_mask_shift;
0104
0105 Fm = getFm(opcode);
0106 if (CONSTANT_FM(opcode)) {
0107 rFm = getDoubleConstant(Fm);
0108 } else {
0109 switch (fpa11->fType[Fm]) {
0110 case typeSingle:
0111 rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
0112 break;
0113
0114 case typeDouble:
0115 rFm = fpa11->fpreg[Fm].fDouble;
0116 break;
0117
0118 default:
0119 return 0;
0120 }
0121 }
0122
0123 opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
0124 if (!MONADIC_INSTRUCTION(opcode)) {
0125 unsigned int Fn = getFn(opcode);
0126 float64 rFn;
0127
0128 switch (fpa11->fType[Fn]) {
0129 case typeSingle:
0130 rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
0131 break;
0132
0133 case typeDouble:
0134 rFn = fpa11->fpreg[Fn].fDouble;
0135 break;
0136
0137 default:
0138 return 0;
0139 }
0140
0141 if (dyadic_double[opc_mask_shift]) {
0142 rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm);
0143 } else {
0144 return 0;
0145 }
0146 } else {
0147 if (monadic_double[opc_mask_shift]) {
0148 rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm);
0149 } else {
0150 return 0;
0151 }
0152 }
0153
0154 return 1;
0155 }