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