double_cpdo.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. float64 float64_exp(float64 Fm);
  21. float64 float64_ln(float64 Fm);
  22. float64 float64_sin(float64 rFm);
  23. float64 float64_cos(float64 rFm);
  24. float64 float64_arcsin(float64 rFm);
  25. float64 float64_arctan(float64 rFm);
  26. float64 float64_log(float64 rFm);
  27. float64 float64_tan(float64 rFm);
  28. float64 float64_arccos(float64 rFm);
  29. float64 float64_pow(float64 rFn,float64 rFm);
  30. float64 float64_pol(float64 rFn,float64 rFm);
  31. unsigned int DoubleCPDO(const unsigned int opcode)
  32. {
  33. FPA11 *fpa11 = GET_FPA11();
  34. float64 rFm, rFn = 0; //FIXME - should be zero?
  35. unsigned int Fd, Fm, Fn, nRc = 1;
  36. //printk("DoubleCPDO(0x%08x)\n",opcode);
  37. Fm = getFm(opcode);
  38. if (CONSTANT_FM(opcode))
  39. {
  40. rFm = getDoubleConstant(Fm);
  41. }
  42. else
  43. {
  44. switch (fpa11->fType[Fm])
  45. {
  46. case typeSingle:
  47. rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
  48. break;
  49. case typeDouble:
  50. rFm = fpa11->fpreg[Fm].fDouble;
  51. break;
  52. case typeExtended:
  53. // !! patb
  54. //printk("not implemented! why not?\n");
  55. //!! ScottB
  56. // should never get here, if extended involved
  57. // then other operand should be promoted then
  58. // ExtendedCPDO called.
  59. break;
  60. default: return 0;
  61. }
  62. }
  63. if (!MONADIC_INSTRUCTION(opcode))
  64. {
  65. Fn = getFn(opcode);
  66. switch (fpa11->fType[Fn])
  67. {
  68. case typeSingle:
  69. rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
  70. break;
  71. case typeDouble:
  72. rFn = fpa11->fpreg[Fn].fDouble;
  73. break;
  74. default: return 0;
  75. }
  76. }
  77. Fd = getFd(opcode);
  78. /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
  79. switch (opcode & MASK_ARITHMETIC_OPCODE)
  80. {
  81. /* dyadic opcodes */
  82. case ADF_CODE:
  83. fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
  84. break;
  85. case MUF_CODE:
  86. case FML_CODE:
  87. fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
  88. break;
  89. case SUF_CODE:
  90. fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
  91. break;
  92. case RSF_CODE:
  93. fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
  94. break;
  95. case DVF_CODE:
  96. case FDV_CODE:
  97. fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
  98. break;
  99. case RDF_CODE:
  100. case FRD_CODE:
  101. fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
  102. break;
  103. #if 0
  104. case POW_CODE:
  105. fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
  106. break;
  107. case RPW_CODE:
  108. fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
  109. break;
  110. #endif
  111. case RMF_CODE:
  112. fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
  113. break;
  114. #if 0
  115. case POL_CODE:
  116. fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
  117. break;
  118. #endif
  119. /* monadic opcodes */
  120. case MVF_CODE:
  121. fpa11->fpreg[Fd].fDouble = rFm;
  122. break;
  123. case MNF_CODE:
  124. {
  125. unsigned int *p = (unsigned int*)&rFm;
  126. p[1] ^= 0x80000000;
  127. fpa11->fpreg[Fd].fDouble = rFm;
  128. }
  129. break;
  130. case ABS_CODE:
  131. {
  132. unsigned int *p = (unsigned int*)&rFm;
  133. p[1] &= 0x7fffffff;
  134. fpa11->fpreg[Fd].fDouble = rFm;
  135. }
  136. break;
  137. case RND_CODE:
  138. case URD_CODE:
  139. fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm);
  140. break;
  141. case SQT_CODE:
  142. fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
  143. break;
  144. #if 0
  145. case LOG_CODE:
  146. fpa11->fpreg[Fd].fDouble = float64_log(rFm);
  147. break;
  148. case LGN_CODE:
  149. fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
  150. break;
  151. case EXP_CODE:
  152. fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
  153. break;
  154. case SIN_CODE:
  155. fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
  156. break;
  157. case COS_CODE:
  158. fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
  159. break;
  160. case TAN_CODE:
  161. fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
  162. break;
  163. case ASN_CODE:
  164. fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
  165. break;
  166. case ACS_CODE:
  167. fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
  168. break;
  169. case ATN_CODE:
  170. fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
  171. break;
  172. #endif
  173. case NRM_CODE:
  174. break;
  175. default:
  176. {
  177. nRc = 0;
  178. }
  179. }
  180. if (0 != nRc) fpa11->fType[Fd] = typeDouble;
  181. return nRc;
  182. }
  183. #if 0
  184. float64 float64_exp(float64 rFm)
  185. {
  186. return rFm;
  187. //series
  188. }
  189. float64 float64_ln(float64 rFm)
  190. {
  191. return rFm;
  192. //series
  193. }
  194. float64 float64_sin(float64 rFm)
  195. {
  196. return rFm;
  197. //series
  198. }
  199. float64 float64_cos(float64 rFm)
  200. {
  201. return rFm;
  202. //series
  203. }
  204. #if 0
  205. float64 float64_arcsin(float64 rFm)
  206. {
  207. //series
  208. }
  209. float64 float64_arctan(float64 rFm)
  210. {
  211. //series
  212. }
  213. #endif
  214. float64 float64_log(float64 rFm)
  215. {
  216. return float64_div(float64_ln(rFm),getDoubleConstant(7));
  217. }
  218. float64 float64_tan(float64 rFm)
  219. {
  220. return float64_div(float64_sin(rFm),float64_cos(rFm));
  221. }
  222. float64 float64_arccos(float64 rFm)
  223. {
  224. return rFm;
  225. //return float64_sub(halfPi,float64_arcsin(rFm));
  226. }
  227. float64 float64_pow(float64 rFn,float64 rFm)
  228. {
  229. return float64_exp(float64_mul(rFm,float64_ln(rFn)));
  230. }
  231. float64 float64_pol(float64 rFn,float64 rFm)
  232. {
  233. return float64_arctan(float64_div(rFn,rFm));
  234. }
  235. #endif