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