pru.isa 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* Copyright 2016-2022 Free Software Foundation, Inc.
  2. Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
  3. This file is part of the PRU simulator.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, see <http://www.gnu.org/licenses/>. */
  14. /*
  15. PRU Instruction Set Architecture
  16. INSTRUCTION (NAME,
  17. SEMANTICS)
  18. */
  19. INSTRUCTION (add,
  20. OP2 = (IO ? IMM8 : RS2);
  21. RD = RS1 + OP2;
  22. CARRY = (((uint64_t) RS1 + (uint64_t) OP2) >> RD_WIDTH) & 1;
  23. PC++)
  24. INSTRUCTION (adc,
  25. OP2 = (IO ? IMM8 : RS2);
  26. RD = RS1 + OP2 + CARRY;
  27. CARRY = (((uint64_t) RS1 + (uint64_t) OP2 + (uint64_t) CARRY)
  28. >> RD_WIDTH) & 1;
  29. PC++)
  30. INSTRUCTION (sub,
  31. OP2 = (IO ? IMM8 : RS2);
  32. RD = RS1 - OP2;
  33. CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1;
  34. PC++)
  35. INSTRUCTION (suc,
  36. OP2 = (IO ? IMM8 : RS2);
  37. RD = RS1 - OP2 - CARRY;
  38. CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) CARRY)
  39. >> RD_WIDTH) & 1;
  40. PC++)
  41. INSTRUCTION (rsb,
  42. OP2 = (IO ? IMM8 : RS2);
  43. RD = OP2 - RS1;
  44. CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1;
  45. PC++)
  46. INSTRUCTION (rsc,
  47. OP2 = (IO ? IMM8 : RS2);
  48. RD = OP2 - RS1 - CARRY;
  49. CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) CARRY)
  50. >> RD_WIDTH) & 1;
  51. PC++)
  52. INSTRUCTION (lsl,
  53. OP2 = (IO ? IMM8 : RS2);
  54. RD = RS1 << (OP2 & 0x1f);
  55. PC++)
  56. INSTRUCTION (lsr,
  57. OP2 = (IO ? IMM8 : RS2);
  58. RD = RS1 >> (OP2 & 0x1f);
  59. PC++)
  60. INSTRUCTION (and,
  61. OP2 = (IO ? IMM8 : RS2);
  62. RD = RS1 & OP2;
  63. PC++)
  64. INSTRUCTION (or,
  65. OP2 = (IO ? IMM8 : RS2);
  66. RD = RS1 | OP2;
  67. PC++)
  68. INSTRUCTION (xor,
  69. OP2 = (IO ? IMM8 : RS2);
  70. RD = RS1 ^ OP2;
  71. PC++)
  72. INSTRUCTION (not,
  73. RD = ~RS1;
  74. PC++)
  75. INSTRUCTION (min,
  76. OP2 = (IO ? IMM8 : RS2);
  77. RD = RS1 < OP2 ? RS1 : OP2;
  78. PC++)
  79. INSTRUCTION (max,
  80. OP2 = (IO ? IMM8 : RS2);
  81. RD = RS1 > OP2 ? RS1 : OP2;
  82. PC++)
  83. INSTRUCTION (clr,
  84. OP2 = (IO ? IMM8 : RS2);
  85. RD = RS1 & ~(1u << (OP2 & 0x1f));
  86. PC++)
  87. INSTRUCTION (set,
  88. OP2 = (IO ? IMM8 : RS2);
  89. RD = RS1 | (1u << (OP2 & 0x1f));
  90. PC++)
  91. INSTRUCTION (jmp,
  92. OP2 = (IO ? IMM16 : RS2);
  93. PC = OP2)
  94. INSTRUCTION (jal,
  95. OP2 = (IO ? IMM16 : RS2);
  96. RD = PC + 1;
  97. PC = OP2)
  98. INSTRUCTION (ldi,
  99. RD = IMM16;
  100. PC++)
  101. INSTRUCTION (halt,
  102. pru_sim_syscall (sd, cpu);
  103. PC++)
  104. INSTRUCTION (slp,
  105. if (!WAKEONSTATUS)
  106. {
  107. RAISE_SIGINT (sd);
  108. }
  109. else
  110. {
  111. PC++;
  112. })
  113. INSTRUCTION (qbgt,
  114. OP2 = (IO ? IMM8 : RS2);
  115. PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1))
  116. INSTRUCTION (qbge,
  117. OP2 = (IO ? IMM8 : RS2);
  118. PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1))
  119. INSTRUCTION (qblt,
  120. OP2 = (IO ? IMM8 : RS2);
  121. PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1))
  122. INSTRUCTION (qble,
  123. OP2 = (IO ? IMM8 : RS2);
  124. PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1))
  125. INSTRUCTION (qbeq,
  126. OP2 = (IO ? IMM8 : RS2);
  127. PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1))
  128. INSTRUCTION (qbne,
  129. OP2 = (IO ? IMM8 : RS2);
  130. PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1))
  131. INSTRUCTION (qba,
  132. OP2 = (IO ? IMM8 : RS2);
  133. PC = PC + BROFF)
  134. INSTRUCTION (qbbs,
  135. OP2 = (IO ? IMM8 : RS2);
  136. PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
  137. INSTRUCTION (qbbc,
  138. OP2 = (IO ? IMM8 : RS2);
  139. PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
  140. INSTRUCTION (lbbo,
  141. pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
  142. BURSTLEN, RD_REGN, RDB);
  143. PC++)
  144. INSTRUCTION (sbbo,
  145. pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
  146. BURSTLEN, RD_REGN, RDB);
  147. PC++)
  148. INSTRUCTION (lbco,
  149. pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
  150. BURSTLEN, RD_REGN, RDB);
  151. PC++)
  152. INSTRUCTION (sbco,
  153. pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
  154. BURSTLEN, RD_REGN, RDB);
  155. PC++)
  156. INSTRUCTION (xin,
  157. DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
  158. PC++)
  159. INSTRUCTION (xout,
  160. DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
  161. PC++)
  162. INSTRUCTION (xchg,
  163. DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
  164. PC++)
  165. INSTRUCTION (sxin,
  166. sim_io_eprintf (sd, "SXIN instruction not supported by sim\n");
  167. RAISE_SIGILL (sd))
  168. INSTRUCTION (sxout,
  169. sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n");
  170. RAISE_SIGILL (sd))
  171. INSTRUCTION (sxchg,
  172. sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n");
  173. RAISE_SIGILL (sd))
  174. INSTRUCTION (loop,
  175. OP2 = (IO ? IMM8 + 1 : RS2_w0);
  176. if (OP2 == 0)
  177. {
  178. PC = LOOPEND;
  179. }
  180. else
  181. {
  182. LOOPTOP = PC + 1;
  183. LOOPEND = PC + LOOP_JMPOFFS;
  184. LOOPCNT = OP2;
  185. LOOP_IN_PROGRESS = 1;
  186. PC++;
  187. })
  188. INSTRUCTION (iloop,
  189. OP2 = (IO ? IMM8 + 1 : RS2_w0);
  190. if (OP2 == 0)
  191. {
  192. PC = LOOPEND;
  193. }
  194. else
  195. {
  196. LOOPTOP = PC + 1;
  197. LOOPEND = PC + LOOP_JMPOFFS;
  198. LOOPCNT = OP2;
  199. LOOP_IN_PROGRESS = 1;
  200. PC++;
  201. })
  202. INSTRUCTION (lmbd,
  203. {
  204. int lmbd_i;
  205. OP2 = (IO ? IMM8 : RS2);
  206. for (lmbd_i = RS1_WIDTH - 1; lmbd_i >= 0; lmbd_i--)
  207. {
  208. if (!(((RS1 >> lmbd_i) ^ OP2) & 1))
  209. break;
  210. }
  211. RD = (lmbd_i < 0) ? 32 : lmbd_i;
  212. PC++;
  213. })