single_cpdo.c 2.8 KB

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