extended_cpdo.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. NetWinder Floating Point Emulator
  3. (c) Rebel.COM, 1998,1999
  4. Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #include "fpa11.h"
  18. #include "softfloat.h"
  19. #include "fpopcode.h"
  20. floatx80 floatx80_exp(floatx80 Fm);
  21. floatx80 floatx80_ln(floatx80 Fm);
  22. floatx80 floatx80_sin(floatx80 rFm);
  23. floatx80 floatx80_cos(floatx80 rFm);
  24. floatx80 floatx80_arcsin(floatx80 rFm);
  25. floatx80 floatx80_arctan(floatx80 rFm);
  26. floatx80 floatx80_log(floatx80 rFm);
  27. floatx80 floatx80_tan(floatx80 rFm);
  28. floatx80 floatx80_arccos(floatx80 rFm);
  29. floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
  30. floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
  31. unsigned int ExtendedCPDO(const unsigned int opcode)
  32. {
  33. FPA11 *fpa11 = GET_FPA11();
  34. floatx80 rFm, rFn;
  35. unsigned int Fd, Fm, Fn, nRc = 1;
  36. //printk("ExtendedCPDO(0x%08x)\n",opcode);
  37. Fm = getFm(opcode);
  38. if (CONSTANT_FM(opcode))
  39. {
  40. rFm = getExtendedConstant(Fm);
  41. }
  42. else
  43. {
  44. switch (fpa11->fType[Fm])
  45. {
  46. case typeSingle:
  47. rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
  48. break;
  49. case typeDouble:
  50. rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
  51. break;
  52. case typeExtended:
  53. rFm = fpa11->fpreg[Fm].fExtended;
  54. break;
  55. default: return 0;
  56. }
  57. }
  58. if (!MONADIC_INSTRUCTION(opcode))
  59. {
  60. Fn = getFn(opcode);
  61. switch (fpa11->fType[Fn])
  62. {
  63. case typeSingle:
  64. rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
  65. break;
  66. case typeDouble:
  67. rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
  68. break;
  69. case typeExtended:
  70. rFn = fpa11->fpreg[Fn].fExtended;
  71. break;
  72. default: return 0;
  73. }
  74. }
  75. Fd = getFd(opcode);
  76. switch (opcode & MASK_ARITHMETIC_OPCODE)
  77. {
  78. /* dyadic opcodes */
  79. case ADF_CODE:
  80. fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
  81. break;
  82. case MUF_CODE:
  83. case FML_CODE:
  84. fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
  85. break;
  86. case SUF_CODE:
  87. fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
  88. break;
  89. case RSF_CODE:
  90. fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
  91. break;
  92. case DVF_CODE:
  93. case FDV_CODE:
  94. fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
  95. break;
  96. case RDF_CODE:
  97. case FRD_CODE:
  98. fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
  99. break;
  100. #if 0
  101. case POW_CODE:
  102. fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
  103. break;
  104. case RPW_CODE:
  105. fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
  106. break;
  107. #endif
  108. case RMF_CODE:
  109. fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
  110. break;
  111. #if 0
  112. case POL_CODE:
  113. fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
  114. break;
  115. #endif
  116. /* monadic opcodes */
  117. case MVF_CODE:
  118. fpa11->fpreg[Fd].fExtended = rFm;
  119. break;
  120. case MNF_CODE:
  121. rFm.high ^= 0x8000;
  122. fpa11->fpreg[Fd].fExtended = rFm;
  123. break;
  124. case ABS_CODE:
  125. rFm.high &= 0x7fff;
  126. fpa11->fpreg[Fd].fExtended = rFm;
  127. break;
  128. case RND_CODE:
  129. case URD_CODE:
  130. fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm);
  131. break;
  132. case SQT_CODE:
  133. fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
  134. break;
  135. #if 0
  136. case LOG_CODE:
  137. fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
  138. break;
  139. case LGN_CODE:
  140. fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
  141. break;
  142. case EXP_CODE:
  143. fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
  144. break;
  145. case SIN_CODE:
  146. fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
  147. break;
  148. case COS_CODE:
  149. fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
  150. break;
  151. case TAN_CODE:
  152. fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
  153. break;
  154. case ASN_CODE:
  155. fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
  156. break;
  157. case ACS_CODE:
  158. fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
  159. break;
  160. case ATN_CODE:
  161. fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
  162. break;
  163. #endif
  164. case NRM_CODE:
  165. break;
  166. default:
  167. {
  168. nRc = 0;
  169. }
  170. }
  171. if (0 != nRc) fpa11->fType[Fd] = typeExtended;
  172. return nRc;
  173. }
  174. #if 0
  175. floatx80 floatx80_exp(floatx80 Fm)
  176. {
  177. //series
  178. }
  179. floatx80 floatx80_ln(floatx80 Fm)
  180. {
  181. //series
  182. }
  183. floatx80 floatx80_sin(floatx80 rFm)
  184. {
  185. //series
  186. }
  187. floatx80 floatx80_cos(floatx80 rFm)
  188. {
  189. //series
  190. }
  191. floatx80 floatx80_arcsin(floatx80 rFm)
  192. {
  193. //series
  194. }
  195. floatx80 floatx80_arctan(floatx80 rFm)
  196. {
  197. //series
  198. }
  199. floatx80 floatx80_log(floatx80 rFm)
  200. {
  201. return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
  202. }
  203. floatx80 floatx80_tan(floatx80 rFm)
  204. {
  205. return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
  206. }
  207. floatx80 floatx80_arccos(floatx80 rFm)
  208. {
  209. //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
  210. }
  211. floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
  212. {
  213. return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
  214. }
  215. floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
  216. {
  217. return floatx80_arctan(floatx80_div(rFn,rFm));
  218. }
  219. #endif