fpudasm.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Hey EMACS -*- linux-c -*- */
  2. /* $Id: fpudasm.c 2268 2006-11-06 17:18:51Z roms $ */
  3. /* TiEmu - Tiemu Is an EMUlator
  4. *
  5. * Copyright (c) 2000-2001, Thomas Corvazier, Romain Liévin
  6. * Copyright (c) 2001-2003, Romain Liévin
  7. * Copyright (c) 2003, Julien Blache
  8. * Copyright (c) 2004, Romain Liévin
  9. * Copyright (c) 2005, Romain Liévin
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  24. */
  25. /*
  26. A pseudo-FPU disassembler.
  27. Many informations comes from the TI's BCD artihmetic package:
  28. <ftp://ftp.ti.com/pub/graph-ti/calc-apps/89/asm/exec.inc>
  29. */
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <stdint.h>
  33. typedef struct
  34. {
  35. uint16_t code;
  36. const char* name;
  37. } TUPLE;
  38. // 6 chars max
  39. TUPLE operators[9] = {
  40. { 0x0000, "FCMP" }, { 0x1000, "FADD" }, { 0x2000, "FDIV" }, { 0x3000, "FMUL" },
  41. { 0x4000, "FSUB" }, { 0x5000, "FINTRZ" }, { 0x6000, "FMOVE" }, { 0x7000, "FNEG" },
  42. { 0x8000, "FTST" },
  43. };
  44. // 7 chars max
  45. TUPLE sizes[6] = {
  46. { 0x0000, "BYTE"}, { 0x0200, "WORD"}, { 0x0400, "LONG"},
  47. { 0x0600, "SINGLE"}, { 0x0800, "DOUBLE"}, { 0x0a00, "UNSGNED"},
  48. };
  49. // 11 chars max
  50. TUPLE srcs[21] = {
  51. { 0x0000, "FP0"}, { 0x0010, "FP1"}, { 0x0020, "FP2"}, { 0x0030, "FP3"},
  52. { 0x0040, "FP4"}, { 0x0050, "FP5"}, { 0x0060, "FP6"}, { 0x0070, "FP7"},
  53. { 0x0080, "D0"}, { 0x0090, "D1"}, { 0x00a0, "D2"}, { 0x00b0, "D3"},
  54. { 0x00c0, "D4"}, { 0x00d0, "D5"}, { 0x00e0, "D6"}, { 0x00f0, "D7"},
  55. { 0x0100, "IMMED_LONG"}, { 0x0110, "IMMED_SHORT"}, { 0x0120, "FRAME_OFF"},
  56. { 0x0130, "EFFECT_ADDR"}, { 0x0140, "IMMED_ZERO"},
  57. };
  58. // 11 chars max
  59. TUPLE dsts[11] = {
  60. { 0x0000, "R0"}, { 0x0001, "R1"}, { 0x0002, "R2"}, { 0x0003, "R3"},
  61. { 0x0004, "R4"}, { 0x0005, "R5"}, { 0x0006, "R6"}, { 0x0007, "R7"},
  62. { 0x0008, "FRAME_OFF"}, { 0x0009, "EFFECT_ADDR"}, { 0x000a, "RETURN_REG"},
  63. };
  64. #define GET_OPERATOR(x) ((x) & 0xf000)
  65. #define GET_SIZE(x) ((x) & 0x0e00)
  66. #define GET_SRC(x) ((x) & 0x01f0)
  67. #define GET_DST(x) ((x) & 0x000f)
  68. /*
  69. ; BCD arithmetic package
  70. ***************************************************************************
  71. * OPERATOR / OPERAND WORD *
  72. * *
  73. * | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | *
  74. * +---------------+-----------+-------------------+---------------+ *
  75. * | OPERATOR | SIZE | SRC OPERAND | DEST OPERAND | *
  76. * +---------------+-----------+-------------------+---------------+ *
  77. * FCMP 0 BYTE 0 FP0 0 R0 (FP or D) 0 *
  78. * FADD 1 WORD 1 | | *
  79. * FDIV 2 LONG 2 FP7 7 R7 (FP or D) 7 *
  80. * FMUL 3 SINGLE 3 D0 8 FRAME_OFF 8 *
  81. * FSUB 4 DOUBLE 4 | EFFECT_ADDR 9 *
  82. * FINTRZ 5 UNSGNED 5 D7 15 RETURN_REG 10 *
  83. * FMOVE 6 IMMED_LONG 16 *
  84. * FNEG 7 IMMED_SHORT 17 *
  85. * FTST 8 FRAME_OFF 18 *
  86. * EFFECT_ADDR 19 *
  87. * IMMED_ZERO 20 *
  88. ***************************************************************************
  89. bcdCmp = 0x0000
  90. bcdAdd = 0x1000
  91. bcdDiv = 0x2000
  92. bcdMul = 0x3000
  93. bcdSub = 0x4000
  94. bcdIntz = 0x5000
  95. bcdMove = 0x6000
  96. bcdNeg = 0x7000
  97. bcdTst = 0x8000
  98. bcdByte = 0x0000
  99. bcdWord = 0x0200
  100. bcdLong = 0x0400
  101. bcdSingle = 0x0600
  102. bcdDouble = 0x0800
  103. bcdUnsigned = 0x0A00
  104. ; Source operand
  105. bcdFP0 = 0x0000
  106. bcdFP1 = 0x0010
  107. bcdFP2 = 0x0020
  108. bcdFP3 = 0x0030
  109. bcdFP4 = 0x0040
  110. bcdFP5 = 0x0050
  111. bcdFP6 = 0x0060
  112. bcdFP7 = 0x0070
  113. bcdD0 = 0x0080
  114. bcdD1 = 0x0090
  115. bcdD2 = 0x00A0
  116. bcdD3 = 0x00B0
  117. bcdD4 = 0x00C0
  118. bcdD5 = 0x00D0
  119. bcdD6 = 0x00E0
  120. bcdD7 = 0x00F0
  121. bcdLongImm = 0x0100
  122. bcdShortImm = 0x0110
  123. bcdFrameSrc = 0x0120
  124. bcdAbsSrc = 0x0130
  125. bcdZeroImm = 0x0140
  126. ; Destination operand
  127. bcdR0 = 0x0000
  128. bcdR1 = 0x0001
  129. bcdR2 = 0x0002
  130. bcdR3 = 0x0003
  131. bcdR4 = 0x0004
  132. bcdR5 = 0x0005
  133. bcdR6 = 0x0006
  134. bcdR7 = 0x0007
  135. bcdFrameDest = 0x0008
  136. bcdAbsDest = 0x0009
  137. bcdRetReg = 0x000A
  138. */
  139. /*
  140. Input: FPU opcode in 'code'
  141. Output: FPU disassembled in 'buf'. sizeof(buf) >= 6+1+7+1+11+1+11 = 38
  142. */
  143. int DasmFPU(uint16_t code, char *buf)
  144. {
  145. int operator = GET_OPERATOR(code);
  146. int size = GET_SIZE(code);
  147. int src = GET_SRC(code);
  148. int dst = GET_DST(code);
  149. int idx[4] = { 0 };
  150. int i;
  151. int j = 0;
  152. for(i = 0; i < (int)(sizeof(operators) / sizeof(TUPLE)); i++)
  153. {
  154. if(operators[i].code == operator)
  155. {
  156. idx[j++] = i;
  157. break;
  158. }
  159. }
  160. for(i = 0; i < (int)(sizeof(sizes) / sizeof(TUPLE)); i++)
  161. {
  162. if(sizes[i].code == size)
  163. {
  164. idx[j++] = i;
  165. break;
  166. }
  167. }
  168. for(i = 0; i < (int)(sizeof(srcs) / sizeof(TUPLE)); i++)
  169. {
  170. if(srcs[i].code == src)
  171. {
  172. idx[j++] = i;
  173. break;
  174. }
  175. }
  176. for(i = 0; i < (int)(sizeof(dsts) / sizeof(TUPLE)); i++)
  177. {
  178. if(dsts[i].code == dst)
  179. {
  180. idx[j++] = i;
  181. break;
  182. }
  183. }
  184. sprintf(buf, "%s.%s %s,%s",
  185. operators[idx[0]].name, sizes[idx[1]].name,
  186. srcs[idx[2]].name, dsts[idx[3]].name);
  187. return 0;
  188. }