pru-opc.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* TI PRU opcode list.
  2. Copyright (C) 2014-2022 Free Software Foundation, Inc.
  3. Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
  4. This file is part of the GNU opcodes library.
  5. This library 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 3, or (at your option)
  8. any later version.
  9. It is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this file; see the file COPYING. If not, write to the
  15. Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. /* Source:
  18. http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit */
  19. #include "sysdep.h"
  20. #include <stdio.h>
  21. #include "opcode/pru.h"
  22. /* Register string table. */
  23. #define DECLARE_REG(name, index) \
  24. { #name ".b0", (index), RSEL_7_0 }, \
  25. { #name ".b1", (index), RSEL_15_8 }, \
  26. { #name ".b2", (index), RSEL_23_16 }, \
  27. { #name ".b3", (index), RSEL_31_24 }, \
  28. { #name ".w0", (index), RSEL_15_0 }, \
  29. { #name ".w1", (index), RSEL_23_8 }, \
  30. { #name ".w2", (index), RSEL_31_16 }, \
  31. { #name , (index), RSEL_31_0 }
  32. const struct pru_reg pru_regs[] = {
  33. /* Standard register names. */
  34. DECLARE_REG (r0, 0),
  35. DECLARE_REG (r1, 1),
  36. DECLARE_REG (sp, 2), /* Stack pointer. */
  37. DECLARE_REG (ra, 3), /* Return address. */
  38. DECLARE_REG (fp, 4), /* Frame pointer. */
  39. DECLARE_REG (r5, 5),
  40. DECLARE_REG (r6, 6),
  41. DECLARE_REG (r7, 7),
  42. DECLARE_REG (r8, 8),
  43. DECLARE_REG (r9, 9),
  44. DECLARE_REG (r10, 10),
  45. DECLARE_REG (r11, 11),
  46. DECLARE_REG (r12, 12),
  47. DECLARE_REG (r13, 13),
  48. DECLARE_REG (r14, 14),
  49. DECLARE_REG (r15, 15),
  50. DECLARE_REG (r16, 16),
  51. DECLARE_REG (r17, 17),
  52. DECLARE_REG (r18, 18),
  53. DECLARE_REG (r19, 19),
  54. DECLARE_REG (r20, 20),
  55. DECLARE_REG (r21, 21),
  56. DECLARE_REG (r22, 22),
  57. DECLARE_REG (r23, 23),
  58. DECLARE_REG (r24, 24),
  59. DECLARE_REG (r25, 25),
  60. DECLARE_REG (r26, 26),
  61. DECLARE_REG (r27, 27),
  62. DECLARE_REG (r28, 28),
  63. DECLARE_REG (r29, 29),
  64. DECLARE_REG (r30, 30),
  65. DECLARE_REG (r31, 31),
  66. /* Alternative names for special registers. */
  67. DECLARE_REG (r2, 2),
  68. DECLARE_REG (r3, 3),
  69. DECLARE_REG (r4, 4)
  70. };
  71. #define PRU_NUM_REGS \
  72. ((sizeof pru_regs) / (sizeof (pru_regs[0])))
  73. const int pru_num_regs = PRU_NUM_REGS;
  74. #undef PRU_NUM_REGS
  75. /* This is the opcode table used by the PRU GNU as and disassembler. */
  76. const struct pru_opcode pru_opcodes[] =
  77. {
  78. /* { name, args,
  79. match, mask, pinfo, overflow_msg } */
  80. #define DECLARE_FORMAT1_OPCODE(str, subop) \
  81. { #str, prui_ ## str, "d,s,b", \
  82. OP_MATCH_ ## subop, OP_MASK_FMT1_OP | OP_MASK_SUBOP, 0, \
  83. unsigned_immed8_overflow }
  84. DECLARE_FORMAT1_OPCODE (add, ADD),
  85. DECLARE_FORMAT1_OPCODE (adc, ADC),
  86. DECLARE_FORMAT1_OPCODE (sub, SUB),
  87. DECLARE_FORMAT1_OPCODE (suc, SUC),
  88. DECLARE_FORMAT1_OPCODE (lsl, LSL),
  89. DECLARE_FORMAT1_OPCODE (lsr, LSR),
  90. DECLARE_FORMAT1_OPCODE (rsb, RSB),
  91. DECLARE_FORMAT1_OPCODE (rsc, RSC),
  92. DECLARE_FORMAT1_OPCODE (and, AND),
  93. DECLARE_FORMAT1_OPCODE (or, OR),
  94. DECLARE_FORMAT1_OPCODE (xor, XOR),
  95. DECLARE_FORMAT1_OPCODE (min, MIN),
  96. DECLARE_FORMAT1_OPCODE (max, MAX),
  97. DECLARE_FORMAT1_OPCODE (clr, CLR),
  98. DECLARE_FORMAT1_OPCODE (set, SET),
  99. { "not", prui_not, "d,s",
  100. OP_MATCH_NOT | OP_MASK_IO,
  101. OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IO, 0, no_overflow},
  102. { "jmp", prui_jmp, "j",
  103. OP_MATCH_JMP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
  104. { "jal", prui_jal, "d,j",
  105. OP_MATCH_JAL, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
  106. { "ldi", prui_ldi, "d,W",
  107. OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
  108. { "lmbd", prui_lmbd, "d,s,b",
  109. OP_MATCH_LMBD, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed8_overflow},
  110. { "halt", prui_halt, "",
  111. OP_MATCH_HALT, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
  112. { "slp", prui_slp, "w",
  113. OP_MATCH_SLP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
  114. { "xin", prui_xin, "x,D,n",
  115. OP_MATCH_XIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  116. { "xout", prui_xout, "x,D,n",
  117. OP_MATCH_XOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  118. { "xchg", prui_xchg, "x,D,n",
  119. OP_MATCH_XCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  120. { "sxin", prui_sxin, "x,D,n",
  121. OP_MATCH_SXIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  122. { "sxout", prui_sxout, "x,D,n",
  123. OP_MATCH_SXOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  124. { "sxchg", prui_sxchg, "x,D,n",
  125. OP_MATCH_SXCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
  126. { "loop", prui_loop, "O,B",
  127. OP_MATCH_LOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
  128. { "iloop", prui_loop, "O,B",
  129. OP_MATCH_ILOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
  130. { "qbgt", prui_qbgt, "o,s,b",
  131. OP_MATCH_QBGT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  132. { "qbge", prui_qbge, "o,s,b",
  133. OP_MATCH_QBGE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  134. { "qblt", prui_qblt, "o,s,b",
  135. OP_MATCH_QBLT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  136. { "qble", prui_qble, "o,s,b",
  137. OP_MATCH_QBLE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  138. { "qbeq", prui_qbeq, "o,s,b",
  139. OP_MATCH_QBEQ, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  140. { "qbne", prui_qbne, "o,s,b",
  141. OP_MATCH_QBNE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  142. { "qba", prui_qba, "o",
  143. OP_MATCH_QBA, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
  144. { "qbbs", prui_qbbs, "o,s,b",
  145. OP_MATCH_QBBS, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
  146. { "qbbc", prui_qbbc, "o,s,b",
  147. OP_MATCH_QBBC, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
  148. { "lbbo", prui_lbbo, "D,S,b,l",
  149. OP_MATCH_LBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
  150. unsigned_immed8_overflow},
  151. { "sbbo", prui_sbbo, "D,S,b,l",
  152. OP_MATCH_SBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
  153. unsigned_immed8_overflow},
  154. { "lbco", prui_lbco, "D,c,b,l",
  155. OP_MATCH_LBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
  156. unsigned_immed8_overflow},
  157. { "sbco", prui_sbco, "D,c,b,l",
  158. OP_MATCH_SBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
  159. unsigned_immed8_overflow},
  160. /* Fill in the default values for the real-instruction arguments.
  161. The assembler will not do it! */
  162. { "nop", prui_or, "",
  163. OP_MATCH_OR
  164. | (RSEL_31_0 << OP_SH_RS2SEL) | (0 << OP_SH_RS2)
  165. | (RSEL_31_0 << OP_SH_RS1SEL) | (0 << OP_SH_RS1)
  166. | (RSEL_31_0 << OP_SH_RDSEL) | (0 << OP_SH_RD),
  167. OP_MASK_FMT1_OP | OP_MASK_SUBOP
  168. | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_RS1SEL | OP_MASK_RS1
  169. | OP_MASK_RDSEL | OP_MASK_RD | OP_MASK_IO,
  170. PRU_INSN_MACRO, no_overflow},
  171. { "mov", prui_or, "d,s",
  172. OP_MATCH_OR | (0 << OP_SH_IMM8) | OP_MASK_IO,
  173. OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IMM8 | OP_MASK_IO,
  174. PRU_INSN_MACRO, no_overflow},
  175. { "ret", prui_jmp, "",
  176. OP_MATCH_JMP
  177. | (RSEL_31_16 << OP_SH_RS2SEL) | (3 << OP_SH_RS2),
  178. OP_MASK_FMT2_OP | OP_MASK_SUBOP
  179. | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_IO,
  180. PRU_INSN_MACRO, unsigned_immed16_overflow},
  181. { "call", prui_jal, "j",
  182. OP_MATCH_JAL
  183. | (RSEL_31_16 << OP_SH_RDSEL) | (3 << OP_SH_RD),
  184. OP_MASK_FMT2_OP | OP_MASK_SUBOP
  185. | OP_MASK_RDSEL | OP_MASK_RD,
  186. PRU_INSN_MACRO, unsigned_immed16_overflow},
  187. { "wbc", prui_qbbs, "s,b",
  188. OP_MATCH_QBBS | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
  189. OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
  190. PRU_INSN_MACRO, qbranch_target_overflow},
  191. { "wbs", prui_qbbc, "s,b",
  192. OP_MATCH_QBBC | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
  193. OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
  194. PRU_INSN_MACRO, qbranch_target_overflow},
  195. { "fill", prui_xin, "D,n",
  196. OP_MATCH_XIN | (254 << OP_SH_XFR_WBA),
  197. OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
  198. PRU_INSN_MACRO, unsigned_immed8_overflow},
  199. { "zero", prui_xin, "D,n",
  200. OP_MATCH_XIN | (255 << OP_SH_XFR_WBA),
  201. OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
  202. PRU_INSN_MACRO, unsigned_immed8_overflow},
  203. { "ldi32", prui_ldi, "R,i",
  204. OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP,
  205. PRU_INSN_LDI32, unsigned_immed32_overflow},
  206. };
  207. #define PRU_NUM_OPCODES \
  208. ((sizeof pru_opcodes) / (sizeof (pru_opcodes[0])))
  209. const int bfd_pru_num_opcodes = PRU_NUM_OPCODES;
  210. #undef PRU_NUM_OPCODES