vr.igen 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // -*- C -*-
  2. //
  3. // NEC specific instructions
  4. //
  5. :%s::::MFHI:int hi
  6. {
  7. return hi ? "hi" : "";
  8. }
  9. :%s::::SAT:int s
  10. {
  11. return s ? "s" : "";
  12. }
  13. :%s::::UNS:int u
  14. {
  15. return u ? "u" : "";
  16. }
  17. // Simulate the various kinds of multiply and multiply-accumulate instructions.
  18. // Perform an operation of the form:
  19. //
  20. // LHS (+/-) GPR[RS] * GPR[RT]
  21. //
  22. // and store it in the 64-bit accumulator. Optionally copy either LO or
  23. // HI into a general purpose register.
  24. //
  25. // - RD is the destination register of the LO or HI move
  26. // - RS are RT are the multiplication source registers
  27. // - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator,
  28. // false if it should be 0.
  29. // - STORE_HI_P is true if HI should be stored in RD, false if LO should be.
  30. // - UNSIGNED_P is true if the operation should be unsigned.
  31. // - SATURATE_P is true if the result should be saturated to a 32-bit value.
  32. // - SUBTRACT_P is true if the right hand side should be subtraced from LHS,
  33. // false if it should be added.
  34. // - SHORT_P is true if RS and RT must be 16-bit numbers.
  35. // - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a
  36. // concatenation of the low 32 bits of HI and LO.
  37. :function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
  38. {
  39. uint64_t lhs, x, y, xcut, ycut, product, result;
  40. check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
  41. lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
  42. x = GPR[rs];
  43. y = GPR[rt];
  44. /* Work out the canonical form of X and Y from their significant bits. */
  45. if (!short_p)
  46. {
  47. /* Normal sign-extension rule for 32-bit operands. */
  48. xcut = EXTEND32 (x);
  49. ycut = EXTEND32 (y);
  50. }
  51. else if (unsigned_p)
  52. {
  53. /* Operands must be zero-extended 16-bit numbers. */
  54. xcut = x & 0xffff;
  55. ycut = y & 0xffff;
  56. }
  57. else
  58. {
  59. /* Likewise but sign-extended. */
  60. xcut = EXTEND16 (x);
  61. ycut = EXTEND16 (y);
  62. }
  63. if (x != xcut || y != ycut)
  64. sim_engine_abort (SD, CPU, CIA,
  65. "invalid multiplication operand at 0x%08lx\n",
  66. (long) CIA);
  67. TRACE_ALU_INPUT2 (x, y);
  68. product = (unsigned_p
  69. ? V8_4 (x, 1) * V8_4 (y, 1)
  70. : EXTEND32 (x) * EXTEND32 (y));
  71. result = (subtract_p ? lhs - product : lhs + product);
  72. if (saturate_p)
  73. {
  74. /* Saturate the result to 32 bits. An unsigned, unsaturated
  75. result is zero-extended to 64 bits, but unsigned overflow
  76. causes all 64 bits to be set. */
  77. if (!unsigned_p && (uint64_t) EXTEND32 (result) != result)
  78. result = ((int64_t) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
  79. else if (unsigned_p && (result >> 32) != 0)
  80. result = (uint64_t) 0 - 1;
  81. }
  82. TRACE_ALU_RESULT (result);
  83. if (double_p)
  84. LO = result;
  85. else
  86. {
  87. LO = EXTEND32 (result);
  88. HI = EXTEND32 (VH4_8 (result));
  89. }
  90. if (rd != 0)
  91. GPR[rd] = store_hi_p ? HI : LO;
  92. }
  93. // VR4100 instructions.
  94. 000000,5.RS,5.RT,00000,00000,101000::32::MADD16
  95. "madd16 r<RS>, r<RT>"
  96. *vr4100:
  97. {
  98. do_vr_mul_op (SD_, 0, RS, RT,
  99. 1 /* accumulate */,
  100. 0 /* store in LO */,
  101. 0 /* signed arithmetic */,
  102. 0 /* don't saturate */,
  103. 0 /* don't subtract */,
  104. 1 /* short */,
  105. 0 /* single */);
  106. }
  107. 000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
  108. "dmadd16 r<RS>, r<RT>"
  109. *vr4100:
  110. {
  111. do_vr_mul_op (SD_, 0, RS, RT,
  112. 1 /* accumulate */,
  113. 0 /* store in LO */,
  114. 0 /* signed arithmetic */,
  115. 0 /* don't saturate */,
  116. 0 /* don't subtract */,
  117. 1 /* short */,
  118. 1 /* double */);
  119. }
  120. // VR4120 and VR4130 instructions.
  121. 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
  122. "dmacc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
  123. *vr4120:
  124. {
  125. do_vr_mul_op (SD_, RD, RS, RT,
  126. 1 /* accumulate */,
  127. MFHI, UNS, SAT,
  128. 0 /* don't subtract */,
  129. SAT /* short */,
  130. 1 /* double */);
  131. }
  132. 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
  133. "macc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
  134. *vr4120:
  135. {
  136. do_vr_mul_op (SD_, RD, RS, RT,
  137. 1 /* accumulate */,
  138. MFHI, UNS, SAT,
  139. 0 /* don't subtract */,
  140. SAT /* short */,
  141. 0 /* single */);
  142. }
  143. // VR5400 and VR5500 instructions.
  144. 000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
  145. "mul%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
  146. *vr5400:
  147. *vr5500:
  148. {
  149. do_vr_mul_op (SD_, RD, RS, RT,
  150. 0 /* don't accumulate */,
  151. MFHI, UNS,
  152. 0 /* don't saturate */,
  153. 0 /* don't subtract */,
  154. 0 /* not short */,
  155. 0 /* single */);
  156. }
  157. 000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
  158. "muls%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
  159. *vr5400:
  160. *vr5500:
  161. {
  162. do_vr_mul_op (SD_, RD, RS, RT,
  163. 0 /* don't accumulate */,
  164. MFHI, UNS,
  165. 0 /* don't saturate */,
  166. 1 /* subtract */,
  167. 0 /* not short */,
  168. 0 /* single */);
  169. }
  170. 000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
  171. "macc%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
  172. *vr5400:
  173. *vr5500:
  174. {
  175. do_vr_mul_op (SD_, RD, RS, RT,
  176. 1 /* accumulate */,
  177. MFHI, UNS,
  178. 0 /* don't saturate */,
  179. 0 /* don't subtract */,
  180. 0 /* not short */,
  181. 0 /* single */);
  182. }
  183. 000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
  184. "msac%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
  185. *vr5400:
  186. *vr5500:
  187. {
  188. do_vr_mul_op (SD_, RD, RS, RT,
  189. 1 /* accumulate */,
  190. MFHI, UNS,
  191. 0 /* don't saturate */,
  192. 1 /* subtract */,
  193. 0 /* not short */,
  194. 0 /* single */);
  195. }
  196. 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
  197. "luxc1 f<FD>, r<INDEX>(r<BASE>)"
  198. *vr5500:
  199. {
  200. check_fpu (SD_);
  201. COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
  202. (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
  203. }
  204. 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
  205. "suxc1 f<FS>, r<INDEX>(r<BASE>)"
  206. *vr5500:
  207. {
  208. check_fpu (SD_);
  209. do_store (SD_, AccessLength_DOUBLEWORD,
  210. (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
  211. COP_SD (1, FS));
  212. }
  213. 010000,1,19.*,100000:COP0:32::WAIT
  214. "wait"
  215. *vr5500:
  216. 011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
  217. "mfdr r<RT>, r<DR>"
  218. *vr5400:
  219. *vr5500:
  220. 011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
  221. "mtdr r<RT>, r<DR>"
  222. *vr5400:
  223. *vr5500:
  224. 011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
  225. "dret"
  226. *vr5400:
  227. *vr5500: