xref: /netbsd-src/external/gpl3/gdb/dist/sim/pru/pru.isa (revision 4439cfd0acf9c7dc90625e5cd83b2317a9ab8967)
1/* Copyright 2016-2024 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	     CARRY = !CARRY;
44	     PC++)
45
46INSTRUCTION (suc,
47	     OP2 = (IO ? IMM8 : RS2);
48	     RD = RS1 - OP2 - !CARRY;
49	     CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) !CARRY)
50		      >> RD_WIDTH) & 1;
51	     CARRY = !CARRY;
52	     PC++)
53
54INSTRUCTION (rsb,
55	     OP2 = (IO ? IMM8 : RS2);
56	     RD = OP2 - RS1;
57	     CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1;
58	     CARRY = !CARRY;
59	     PC++)
60
61INSTRUCTION (rsc,
62	     OP2 = (IO ? IMM8 : RS2);
63	     RD = OP2 - RS1 - !CARRY;
64	     CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) !CARRY)
65		      >> RD_WIDTH) & 1;
66	     CARRY = !CARRY;
67	     PC++)
68
69INSTRUCTION (lsl,
70	     OP2 = (IO ? IMM8 : RS2);
71	     RD = RS1 << (OP2 & 0x1f);
72	     PC++)
73
74INSTRUCTION (lsr,
75	     OP2 = (IO ? IMM8 : RS2);
76	     RD = RS1 >> (OP2 & 0x1f);
77	     PC++)
78
79INSTRUCTION (and,
80	     OP2 = (IO ? IMM8 : RS2);
81	     RD = RS1 & OP2;
82	     PC++)
83
84INSTRUCTION (or,
85	     OP2 = (IO ? IMM8 : RS2);
86	     RD = RS1 | OP2;
87	     PC++)
88
89INSTRUCTION (xor,
90	     OP2 = (IO ? IMM8 : RS2);
91	     RD = RS1 ^ OP2;
92	     PC++)
93
94INSTRUCTION (not,
95	     RD = ~RS1;
96	     PC++)
97
98INSTRUCTION (min,
99	     OP2 = (IO ? IMM8 : RS2);
100	     RD = RS1 < OP2 ? RS1 : OP2;
101	     PC++)
102
103INSTRUCTION (max,
104	     OP2 = (IO ? IMM8 : RS2);
105	     RD = RS1 > OP2 ? RS1 : OP2;
106	     PC++)
107
108INSTRUCTION (clr,
109	     OP2 = (IO ? IMM8 : RS2);
110	     RD = RS1 & ~(1u << (OP2 & 0x1f));
111	     PC++)
112
113INSTRUCTION (set,
114	     OP2 = (IO ? IMM8 : RS2);
115	     RD = RS1 | (1u << (OP2 & 0x1f));
116	     PC++)
117
118INSTRUCTION (jmp,
119	     OP2 = (IO ? IMM16 : RS2);
120	     PC = OP2)
121
122INSTRUCTION (jal,
123	     OP2 = (IO ? IMM16 : RS2);
124	     RD = PC + 1;
125	     PC = OP2)
126
127INSTRUCTION (ldi,
128	     RD = IMM16;
129	     PC++)
130
131INSTRUCTION (halt,
132	     pru_sim_syscall (sd, cpu);
133	     PC++)
134
135INSTRUCTION (slp,
136	     if (!WAKEONSTATUS)
137	      {
138		RAISE_SIGINT (sd);
139	      }
140	     else
141	      {
142		PC++;
143	      })
144
145INSTRUCTION (qbgt,
146	     OP2 = (IO ? IMM8 : RS2);
147	     PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1))
148
149INSTRUCTION (qbge,
150	     OP2 = (IO ? IMM8 : RS2);
151	     PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1))
152
153INSTRUCTION (qblt,
154	     OP2 = (IO ? IMM8 : RS2);
155	     PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1))
156
157INSTRUCTION (qble,
158	     OP2 = (IO ? IMM8 : RS2);
159	     PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1))
160
161INSTRUCTION (qbeq,
162	     OP2 = (IO ? IMM8 : RS2);
163	     PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1))
164
165INSTRUCTION (qbne,
166	     OP2 = (IO ? IMM8 : RS2);
167	     PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1))
168
169INSTRUCTION (qba,
170	     OP2 = (IO ? IMM8 : RS2);
171	     PC = PC + BROFF)
172
173INSTRUCTION (qbbs,
174	     OP2 = (IO ? IMM8 : RS2);
175	     PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
176
177INSTRUCTION (qbbc,
178	     OP2 = (IO ? IMM8 : RS2);
179	     PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
180
181INSTRUCTION (lbbo,
182	     pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
183			   BURSTLEN, RD_REGN, RDB);
184	     PC++)
185
186INSTRUCTION (sbbo,
187	     pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
188			   BURSTLEN, RD_REGN, RDB);
189	     PC++)
190
191INSTRUCTION (lbco,
192	     pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
193			   BURSTLEN, RD_REGN, RDB);
194	     PC++)
195
196INSTRUCTION (sbco,
197	     pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
198			   BURSTLEN, RD_REGN, RDB);
199	     PC++)
200
201INSTRUCTION (xin,
202	     DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
203	     PC++)
204
205INSTRUCTION (xout,
206	     DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
207	     PC++)
208
209INSTRUCTION (xchg,
210	     DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
211	     PC++)
212
213INSTRUCTION (sxin,
214	     sim_io_eprintf (sd, "SXIN instruction not supported by sim\n");
215	     RAISE_SIGILL (sd))
216
217INSTRUCTION (sxout,
218	     sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n");
219	     RAISE_SIGILL (sd))
220
221INSTRUCTION (sxchg,
222	     sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n");
223	     RAISE_SIGILL (sd))
224
225INSTRUCTION (loop,
226	     OP2 = (IO ? IMM8 + 1 : RS2_w0);
227	     if (OP2 == 0)
228	      {
229		PC = PC + LOOP_JMPOFFS;
230	      }
231	     else
232	      {
233		LOOPTOP = PC + 1;
234		LOOPEND = PC + LOOP_JMPOFFS;
235		LOOPCNT = OP2;
236		LOOP_IN_PROGRESS = 1;
237		PC++;
238	     })
239
240INSTRUCTION (iloop,
241	     OP2 = (IO ? IMM8 + 1 : RS2_w0);
242	     if (OP2 == 0)
243	      {
244		PC = PC + LOOP_JMPOFFS;
245	      }
246	     else
247	      {
248		LOOPTOP = PC + 1;
249		LOOPEND = PC + LOOP_JMPOFFS;
250		LOOPCNT = OP2;
251		LOOP_IN_PROGRESS = 1;
252		PC++;
253	     })
254
255INSTRUCTION (lmbd,
256	     {
257	     int lmbd_i;
258
259	     OP2 = (IO ? IMM8 : RS2);
260
261	     for (lmbd_i = RS1_WIDTH - 1; lmbd_i >= 0; lmbd_i--)
262	       {
263		 if (!(((RS1 >> lmbd_i) ^ OP2) & 1))
264		   break;
265	       }
266	     RD = (lmbd_i < 0) ? 32 : lmbd_i;
267	     PC++;
268	     })
269