fpopcode.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #include "fpsr.h"
  21. #include "fpmodule.h"
  22. #include "fpmodule.inl"
  23. const floatx80 floatx80Constant[] = {
  24. { 0x0000, 0x0000000000000000ULL}, /* extended 0.0 */
  25. { 0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */
  26. { 0x4000, 0x8000000000000000ULL}, /* extended 2.0 */
  27. { 0x4000, 0xc000000000000000ULL}, /* extended 3.0 */
  28. { 0x4001, 0x8000000000000000ULL}, /* extended 4.0 */
  29. { 0x4001, 0xa000000000000000ULL}, /* extended 5.0 */
  30. { 0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */
  31. { 0x4002, 0xa000000000000000ULL} /* extended 10.0 */
  32. };
  33. const float64 float64Constant[] = {
  34. 0x0000000000000000ULL, /* double 0.0 */
  35. 0x3ff0000000000000ULL, /* double 1.0 */
  36. 0x4000000000000000ULL, /* double 2.0 */
  37. 0x4008000000000000ULL, /* double 3.0 */
  38. 0x4010000000000000ULL, /* double 4.0 */
  39. 0x4014000000000000ULL, /* double 5.0 */
  40. 0x3fe0000000000000ULL, /* double 0.5 */
  41. 0x4024000000000000ULL /* double 10.0 */
  42. };
  43. const float32 float32Constant[] = {
  44. 0x00000000, /* single 0.0 */
  45. 0x3f800000, /* single 1.0 */
  46. 0x40000000, /* single 2.0 */
  47. 0x40400000, /* single 3.0 */
  48. 0x40800000, /* single 4.0 */
  49. 0x40a00000, /* single 5.0 */
  50. 0x3f000000, /* single 0.5 */
  51. 0x41200000 /* single 10.0 */
  52. };
  53. unsigned int getTransferLength(const unsigned int opcode)
  54. {
  55. unsigned int nRc;
  56. switch (opcode & MASK_TRANSFER_LENGTH)
  57. {
  58. case 0x00000000: nRc = 1; break; /* single precision */
  59. case 0x00008000: nRc = 2; break; /* double precision */
  60. case 0x00400000: nRc = 3; break; /* extended precision */
  61. default: nRc = 0;
  62. }
  63. return(nRc);
  64. }
  65. unsigned int getRegisterCount(const unsigned int opcode)
  66. {
  67. unsigned int nRc;
  68. switch (opcode & MASK_REGISTER_COUNT)
  69. {
  70. case 0x00000000: nRc = 4; break;
  71. case 0x00008000: nRc = 1; break;
  72. case 0x00400000: nRc = 2; break;
  73. case 0x00408000: nRc = 3; break;
  74. default: nRc = 0;
  75. }
  76. return(nRc);
  77. }
  78. unsigned int getRoundingPrecision(const unsigned int opcode)
  79. {
  80. unsigned int nRc;
  81. switch (opcode & MASK_ROUNDING_PRECISION)
  82. {
  83. case 0x00000000: nRc = 1; break;
  84. case 0x00000080: nRc = 2; break;
  85. case 0x00080000: nRc = 3; break;
  86. default: nRc = 0;
  87. }
  88. return(nRc);
  89. }
  90. unsigned int getDestinationSize(const unsigned int opcode)
  91. {
  92. unsigned int nRc;
  93. switch (opcode & MASK_DESTINATION_SIZE)
  94. {
  95. case 0x00000000: nRc = typeSingle; break;
  96. case 0x00000080: nRc = typeDouble; break;
  97. case 0x00080000: nRc = typeExtended; break;
  98. default: nRc = typeNone;
  99. }
  100. return(nRc);
  101. }
  102. /* condition code lookup table
  103. index into the table is test code: EQ, NE, ... LT, GT, AL, NV
  104. bit position in short is condition code: NZCV */
  105. static const unsigned short aCC[16] = {
  106. 0xF0F0, // EQ == Z set
  107. 0x0F0F, // NE
  108. 0xCCCC, // CS == C set
  109. 0x3333, // CC
  110. 0xFF00, // MI == N set
  111. 0x00FF, // PL
  112. 0xAAAA, // VS == V set
  113. 0x5555, // VC
  114. 0x0C0C, // HI == C set && Z clear
  115. 0xF3F3, // LS == C clear || Z set
  116. 0xAA55, // GE == (N==V)
  117. 0x55AA, // LT == (N!=V)
  118. 0x0A05, // GT == (!Z && (N==V))
  119. 0xF5FA, // LE == (Z || (N!=V))
  120. 0xFFFF, // AL always
  121. 0 // NV
  122. };
  123. unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
  124. {
  125. return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
  126. }