1 /* TI PRU opcode list for GAS, the GNU assembler.
2    Copyright (C) 2014-2024 Free Software Foundation, Inc.
3    Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4 
5    This file is part of the GNU opcodes library.
6 
7    GAS/GDB is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11 
12    GAS/GDB is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GAS or GDB; see the file COPYING3.  If not, write to
19    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21 
22 #ifndef _PRU_H_
23 #define _PRU_H_
24 
25 #include "bfd.h"
26 
27 /****************************************************************************
28  * This file contains structures, bit masks and shift counts used
29  * by the GNU toolchain to define the PRU instruction set and
30  * access various opcode fields.
31  ****************************************************************************/
32 
33 /* Identify different overflow situations for error messages.  */
34 enum overflow_type
35 {
36   call_target_overflow = 0,
37   qbranch_target_overflow,
38   address_offset_overflow,
39   signed_immed16_overflow,
40   unsigned_immed32_overflow,
41   unsigned_immed16_overflow,
42   unsigned_immed8_overflow,
43   unsigned_immed5_overflow,
44   no_overflow
45 };
46 
47 enum opcode_format_type
48 {
49   opcode_format1,
50   opcode_format2ab,
51   opcode_format2abl,
52   opcode_format2c,
53   opcode_format2de,
54   opcode_format45,
55   opcode_format6
56 };
57 
58 /* Opcode ID listing. Used for indexing by the simulator.  */
59 enum pru_instr_type
60 {
61   prui_add, prui_adc, prui_sub, prui_suc, prui_lsl, prui_lsr, prui_rsb,
62   prui_rsc, prui_and, prui_or,  prui_xor, prui_min, prui_max, prui_clr,
63   prui_set, prui_not, prui_jmp, prui_jal, prui_ldi, prui_lmbd,
64   prui_halt, prui_slp, prui_xin, prui_xout, prui_xchg, prui_sxin,
65   prui_sxout, prui_sxchg, prui_loop, prui_iloop, prui_qbgt, prui_qbge,
66   prui_qblt, prui_qble, prui_qbeq, prui_qbne, prui_qba, prui_qbbs,
67   prui_qbbc, prui_lbbo, prui_sbbo, prui_lbco, prui_sbco
68 };
69 
70 /* This structure holds information for a particular instruction.
71 
72    The args field is a string describing the operands.  The following
73    letters can appear in the args:
74      b - a 5.3-bit right source register index OR 8-bit unsigned immediate
75      B - same as 'b', but for LOOP instruction where IMM is decremented
76      c - a 5 bit unsigned immediate for constant table offset
77      d - a 5.3-bit destination register index
78      D - a 5.2-bit destination register index
79      E - for internal GAS self-tests only
80      i - a 32-bit immediate or label
81      j - a 5.3-bit right source register index OR 18-bit PC address
82      l - burst length (unsigned 7-bit immediate or r0.b[0-3]) for xLBCO
83      n - burst length (unsigned 7-bit immediate or r0.b[0-3]) for XFR
84      o - a 10-bit signed PC-relative offset
85      O - an 8-bit unsigned PC-relative offset for LOOP termination point
86      R - a 5-bit destination register index
87      s - a 5.3-bit left source register index
88      S - a 5-bit left source register index
89      w - a single bit for "WakeOnStatus"
90      W - a 16-bit unsigned immediate with IO=0 field (LDI)
91      x - an 8-bit XFR wide-bus address immediate
92    Literal ',' character may also appear in the args as delimiter.
93 
94    Most of the macro names are from [1].
95 
96    The pinfo field is INSN_MACRO for a macro.  Otherwise, it is a collection
97    of bits describing the instruction, notably any relevant hazard
98    information.
99 
100    When assembling, the match field contains the opcode template, which
101    is modified by the arguments to produce the actual opcode
102    that is emitted.  If pinfo is INSN_MACRO, then this is 0.
103 
104    If pinfo is INSN_MACRO, the mask field stores the macro identifier.
105    Otherwise this is a bit mask for the relevant portions of the opcode
106    when disassembling.  If the actual opcode anded with the match field
107    equals the opcode field, then we have found the correct instruction.
108 
109   [1] http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit  */
110 
111 struct pru_opcode
112 {
113   const char *name;           /* The name of the instruction.  */
114   enum pru_instr_type type;   /* Instruction type. Used for fast indexing
115                                            by the simulator.  */
116   const char *args;           /* A string describing the arguments for this
117                                            instruction.  */
118   unsigned long match;                  /* The basic opcode for the instruction.  */
119   unsigned long mask;                   /* Mask for the opcode field of the
120                                            instruction.  */
121   unsigned long pinfo;                  /* Is this a real instruction or instruction
122                                            macro?  */
123   enum overflow_type overflow_msg;  /* Used to generate informative
124                                                message when fixup overflows.  */
125 };
126 
127 /* This value is used in the pru_opcode.pinfo field to indicate that the
128    instruction is a macro or pseudo-op.  This requires special treatment by
129    the assembler, and is used by the disassembler to determine whether to
130    check for a nop.  */
131 #define PRU_INSN_MACRO                  0x80000000
132 
133 /* This macro is specially handled throughout the code because it is
134    the only insn to output 2 words (64 bits). */
135 #define PRU_INSN_LDI32                  0x40000000
136 
137 /* Associates a register name with a 5-bit index and 3-bit regsel.  */
138 struct pru_reg
139 {
140   const char *name;           /* Name, e.g. "r10".  */
141   const unsigned int index;   /* Index, e.g. 10.  */
142   const unsigned int regsel;  /* Register field selector, .e.g RSEL_31_0.  */
143 };
144 
145 /* Macros for getting and setting an instruction field.  */
146 #define GET_INSN_FIELD(X, i) \
147   (((i) & OP_MASK_##X) >> OP_SH_##X)
148 #define SET_INSN_FIELD(X, i, v) \
149   ((i) = (((i) & ~OP_MASK_##X) | (((v) << OP_SH_##X) & OP_MASK_##X)))
150 
151 #define CHECK_INSN_FIELD(X, i) \
152   (((i) & OP_MASK_##X) == OP_MATCH_##X)
153 
154 /* Masks, values, shifts and macros for accessing the various opcode fields.  */
155 
156 #define OP_SH_FMT1_OP                             29
157 #define OP_MASK_FMT1_OP                           (0x7u << 29)
158 #define OP_MATCH_FMT1_OP                (0x0u << 29)
159 
160 #define OP_SH_FMT2_OP                             29
161 #define OP_MASK_FMT2_OP                           (0x7u << 29)
162 #define OP_MATCH_FMT2_OP                (0x1u << 29)
163 
164 #define OP_SH_FMT4_OP                             30
165 #define OP_MASK_FMT4_OP                           (0x3u << 30)
166 #define OP_MATCH_FMT4_OP                (0x1u << 30)
167 
168 #define OP_SH_FMT5_OP                             29
169 #define OP_MASK_FMT5_OP                           (0x7u << 29)
170 #define OP_MATCH_FMT5_OP                (0x6u << 29)
171 
172 #define OP_SH_FMT6AB_OP                           29
173 #define OP_MASK_FMT6AB_OP               (0x7u << 29)
174 #define OP_MATCH_FMT6AB_OP              (0x7u << 29)
175 
176 #define OP_SH_FMT6CD_OP                           29
177 #define OP_MASK_FMT6CD_OP               (0x7u << 29)
178 #define OP_MATCH_FMT6CD_OP              (0x4u << 29)
179 
180 /* Generic fields.  */
181 #define OP_SH_SUBOP                     25
182 #define OP_MASK_SUBOP                             (0xfu << 25)
183 
184 #define OP_SH_IO                        24
185 #define OP_MASK_IO                      (0x1u << 24)
186 
187 #define OP_SH_RS2SEL                              21
188 #define OP_MASK_RS2SEL                            (0x7u << 21)
189 #define OP_SH_RS2                       16
190 #define OP_MASK_RS2                     (0x1fu << 16)
191 #define OP_SH_RS1SEL                              13
192 #define OP_MASK_RS1SEL                            (0x7u << 13)
193 #define OP_SH_RS1                       8
194 #define OP_MASK_RS1                     (0x1fu << 8)
195 #define OP_SH_RDSEL                     5
196 #define OP_MASK_RDSEL                             (0x7u << 5)
197 #define OP_SH_RD                        0
198 #define OP_MASK_RD                      (0x1fu << 0)
199 #define OP_SH_IMM8                      16
200 #define OP_MASK_IMM8                              (0xffu << 16)
201 #define OP_SH_IMM16                     8
202 #define OP_MASK_IMM16                             (0xffffu << 8)
203 
204 #define RSEL_7_0                        0u
205 #define RSEL_15_8                       1u
206 #define RSEL_23_16                      2u
207 #define RSEL_31_24                      3u
208 #define RSEL_15_0                       4u
209 #define RSEL_23_8                       5u
210 #define RSEL_31_16                      6u
211 #define RSEL_31_0                       7u
212 #define RSEL_NUM_ITEMS                            8u
213 
214 /* Format 1 specific fields.  */
215 #define SUBOP_ADD                       0u
216 #define SUBOP_ADC                       1u
217 #define SUBOP_SUB                       2u
218 #define SUBOP_SUC                       3u
219 #define SUBOP_LSL                       4u
220 #define SUBOP_LSR                       5u
221 #define SUBOP_RSB                       6u
222 #define SUBOP_RSC                       7u
223 #define SUBOP_AND                       8u
224 #define SUBOP_OR                        9u
225 #define SUBOP_XOR                       10u
226 #define SUBOP_NOT                       11u
227 #define SUBOP_MIN                       12u
228 #define SUBOP_MAX                       13u
229 #define SUBOP_CLR                       14u
230 #define SUBOP_SET                       15u
231 
232 /* Format 2 specific fields.  */
233 #define SUBOP_JMP                       0u
234 #define SUBOP_JAL                       1u
235 #define SUBOP_LDI                       2u
236 #define SUBOP_LMBD                      3u
237 #define SUBOP_SCAN                      4u
238 #define SUBOP_HALT                      5u
239 #define SUBOP_RSVD_FOR_MVIx             6u
240 #define SUBOP_XFR                       7u
241 #define SUBOP_LOOP                      8u
242 #define SUBOP_RSVD_FOR_RFI              14u
243 #define SUBOP_SLP                       15u
244 
245 #define OP_SH_WAKEONSTATUS              23
246 #define OP_MASK_WAKEONSTATUS            (0x1u << 23)
247 
248 /* Format 2 XFR specific fields.  */
249 #define OP_SH_SUBOP_XFR                           23
250 #define OP_MASK_SUBOP_XFR               (3u << 23)
251 #define OP_SH_XFR_WBA                             15
252 #define OP_MASK_XFR_WBA                           (0xffu << 15)
253 #define OP_SH_XFR_S                     14
254 #define OP_MASK_XFR_S                             (1u << 14)
255 #define OP_SH_XFR_LENGTH                7
256 #define OP_MASK_XFR_LENGTH              (0x7fu << 7)
257 
258 #define SUBOP_XFR_XIN                             1u
259 #define SUBOP_XFR_XOUT                            2u
260 #define SUBOP_XFR_XCHG                            3u
261 
262 /* Format 2 LOOP specific fields.  */
263 #define OP_SH_LOOP_INTERRUPTIBLE        15
264 #define OP_MASK_LOOP_INTERRUPTIBLE      (1u << 15)
265 #define OP_SH_LOOP_JMPOFFS              0
266 #define OP_MASK_LOOP_JMPOFFS            (0xffu << 0)
267 
268 /* Format 4 specific fields.  */
269 #define OP_SH_BROFF98                             25
270 #define OP_MASK_BROFF98                           (0x3u << 25)
271 #define OP_SH_BROFF70                             0
272 #define OP_MASK_BROFF70                           (0xffu << 0)
273 #define OP_SH_GT                        29
274 #define OP_MASK_GT                      (0x1u << 29)
275 #define OP_SH_EQ                        28
276 #define OP_MASK_EQ                      (0x1u << 28)
277 #define OP_SH_LT                        27
278 #define OP_MASK_LT                      (0x1u << 27)
279 #define OP_MASK_CMP                     (OP_MASK_GT | OP_MASK_EQ | OP_MASK_LT)
280 
281 
282 /* Format 5 specific fields.  */
283 #define OP_SH_BS                        28
284 #define OP_MASK_BS                      (0x1u << 28)
285 #define OP_SH_BC                        27
286 #define OP_MASK_BC                      (0x1u << 27)
287 #define OP_MASK_BCMP                              (OP_MASK_BS | OP_MASK_BC)
288 
289 /* Format 6 specific fields.  */
290 #define OP_SH_LOADSTORE                           28
291 #define OP_MASK_LOADSTORE               (0x1u << 28)
292 #define OP_SH_BURSTLEN64                25
293 #define OP_MASK_BURSTLEN64              (0x7u << 25)
294 #define OP_SH_BURSTLEN31                13
295 #define OP_MASK_BURSTLEN31              (0x7u << 13)
296 #define OP_SH_CB                        8
297 #define OP_MASK_CB                      (0x1fu << 8)
298 #define OP_SH_BURSTLEN0                           7
299 #define OP_MASK_BURSTLEN0               (0x1u << 7)
300 #define OP_SH_RDB                       5
301 #define OP_MASK_RDB                     (0x3u << 5)
302 
303 #define LSSBBO_BYTECOUNT_R0_BITS7_0     124u
304 #define LSBBO_BYTECOUNT_R0_BITS15_8     125u
305 #define LSBBO_BYTECOUNT_R0_BITS23_16    126u
306 #define LSBBO_BYTECOUNT_R0_BITS31_24    127u
307 
308 /* The following macros define the opcode matches for each
309    instruction code & OP_MASK_INST == OP_MATCH_INST.  */
310 #define OP_MATCH_ADD          (OP_MATCH_FMT1_OP | (SUBOP_ADD << OP_SH_SUBOP))
311 #define OP_MATCH_ADC          (OP_MATCH_FMT1_OP | (SUBOP_ADC << OP_SH_SUBOP))
312 #define OP_MATCH_SUB          (OP_MATCH_FMT1_OP | (SUBOP_SUB << OP_SH_SUBOP))
313 #define OP_MATCH_SUC          (OP_MATCH_FMT1_OP | (SUBOP_SUC << OP_SH_SUBOP))
314 #define OP_MATCH_LSL          (OP_MATCH_FMT1_OP | (SUBOP_LSL << OP_SH_SUBOP))
315 #define OP_MATCH_LSR          (OP_MATCH_FMT1_OP | (SUBOP_LSR << OP_SH_SUBOP))
316 #define OP_MATCH_RSB          (OP_MATCH_FMT1_OP | (SUBOP_RSB << OP_SH_SUBOP))
317 #define OP_MATCH_RSC          (OP_MATCH_FMT1_OP | (SUBOP_RSC << OP_SH_SUBOP))
318 #define OP_MATCH_AND          (OP_MATCH_FMT1_OP | (SUBOP_AND << OP_SH_SUBOP))
319 #define OP_MATCH_OR (OP_MATCH_FMT1_OP | (SUBOP_OR << OP_SH_SUBOP))
320 #define OP_MATCH_XOR          (OP_MATCH_FMT1_OP | (SUBOP_XOR << OP_SH_SUBOP))
321 #define OP_MATCH_NOT          (OP_MATCH_FMT1_OP | (SUBOP_NOT << OP_SH_SUBOP))
322 #define OP_MATCH_MIN          (OP_MATCH_FMT1_OP | (SUBOP_MIN << OP_SH_SUBOP))
323 #define OP_MATCH_MAX          (OP_MATCH_FMT1_OP | (SUBOP_MAX << OP_SH_SUBOP))
324 #define OP_MATCH_CLR          (OP_MATCH_FMT1_OP | (SUBOP_CLR << OP_SH_SUBOP))
325 #define OP_MATCH_SET          (OP_MATCH_FMT1_OP | (SUBOP_SET << OP_SH_SUBOP))
326 
327 #define OP_MATCH_JMP          (OP_MATCH_FMT2_OP | (SUBOP_JMP << OP_SH_SUBOP))
328 #define OP_MATCH_JAL          (OP_MATCH_FMT2_OP | (SUBOP_JAL << OP_SH_SUBOP))
329 #define OP_MATCH_LDI          (OP_MATCH_FMT2_OP | (SUBOP_LDI << OP_SH_SUBOP))
330 #define OP_MATCH_LMBD         (OP_MATCH_FMT2_OP | (SUBOP_LMBD << OP_SH_SUBOP))
331 #define OP_MATCH_SCAN         (OP_MATCH_FMT2_OP | (SUBOP_SCAN << OP_SH_SUBOP))
332 #define OP_MATCH_HALT         (OP_MATCH_FMT2_OP | (SUBOP_HALT << OP_SH_SUBOP))
333 #define OP_MATCH_SLP          (OP_MATCH_FMT2_OP | (SUBOP_SLP << OP_SH_SUBOP))
334 #define OP_MATCH_XFR          (OP_MATCH_FMT2_OP | (SUBOP_XFR << OP_SH_SUBOP))
335 #define OP_MATCH_SXFR         (OP_MATCH_XFR | OP_MASK_XFR_S)
336 #define OP_MATCH_XIN          (OP_MATCH_XFR | (SUBOP_XFR_XIN << OP_SH_SUBOP_XFR))
337 #define OP_MATCH_XOUT         (OP_MATCH_XFR | (SUBOP_XFR_XOUT << OP_SH_SUBOP_XFR))
338 #define OP_MATCH_XCHG         (OP_MATCH_XFR | (SUBOP_XFR_XCHG << OP_SH_SUBOP_XFR))
339 #define OP_MATCH_SXIN         (OP_MATCH_SXFR | (SUBOP_XFR_XIN << OP_SH_SUBOP_XFR))
340 #define OP_MATCH_SXOUT        (OP_MATCH_SXFR | (SUBOP_XFR_XOUT << OP_SH_SUBOP_XFR))
341 #define OP_MATCH_SXCHG        (OP_MATCH_SXFR | (SUBOP_XFR_XCHG << OP_SH_SUBOP_XFR))
342 #define OP_MATCH_LOOP         (OP_MATCH_FMT2_OP | (SUBOP_LOOP << OP_SH_SUBOP))
343 #define OP_MATCH_ILOOP        (OP_MATCH_FMT2_OP | (SUBOP_LOOP << OP_SH_SUBOP) \
344                                | OP_MASK_LOOP_INTERRUPTIBLE)
345 
346 #define OP_MATCH_QBGT         (OP_MATCH_FMT4_OP | OP_MASK_GT)
347 #define OP_MATCH_QBGE         (OP_MATCH_FMT4_OP | OP_MASK_GT | OP_MASK_EQ)
348 #define OP_MATCH_QBLT         (OP_MATCH_FMT4_OP | OP_MASK_LT)
349 #define OP_MATCH_QBLE         (OP_MATCH_FMT4_OP | OP_MASK_LT | OP_MASK_EQ)
350 #define OP_MATCH_QBEQ         (OP_MATCH_FMT4_OP | OP_MASK_EQ)
351 #define OP_MATCH_QBNE         (OP_MATCH_FMT4_OP | OP_MASK_GT | OP_MASK_LT)
352 #define OP_MATCH_QBA          (OP_MATCH_FMT4_OP | OP_MASK_GT | OP_MASK_LT \
353                                | OP_MASK_EQ)
354 
355 #define OP_MATCH_QBBS         (OP_MATCH_FMT5_OP | OP_MASK_BS)
356 #define OP_MATCH_QBBC         (OP_MATCH_FMT5_OP | OP_MASK_BC)
357 
358 #define OP_MATCH_LBBO         (OP_MATCH_FMT6AB_OP | OP_MASK_LOADSTORE)
359 #define OP_MATCH_SBBO         (OP_MATCH_FMT6AB_OP)
360 #define OP_MATCH_LBCO         (OP_MATCH_FMT6CD_OP | OP_MASK_LOADSTORE)
361 #define OP_MATCH_SBCO         (OP_MATCH_FMT6CD_OP)
362 
363 /* Some special extractions.  */
364 #define OP_MASK_BROFF                     (OP_MASK_BROFF98 | OP_MASK_BROFF70)
365 
366 #define GET_BROFF_URAW(i)       \
367   ((GET_INSN_FIELD (BROFF98, i) << 8) | (GET_INSN_FIELD (BROFF70, i) << 0))
368 
369 #define GET_BROFF_SIGNED(i)     \
370   ((long)(GET_BROFF_URAW (i) - (!!(GET_BROFF_URAW (i) & (1 << 9)) << 10)))
371 
372 #define SET_BROFF_URAW(i, v)                  \
373   do {                                                  \
374       SET_INSN_FIELD (BROFF98, (i), (v) >> 8);    \
375       SET_INSN_FIELD (BROFF70, (i), (v) & 0xff);  \
376   } while (0)
377 
378 #define GET_BURSTLEN(i)         \
379   ( (GET_INSN_FIELD (BURSTLEN64, (i)) << 4) |   \
380     (GET_INSN_FIELD (BURSTLEN31, (i)) << 1) |   \
381     (GET_INSN_FIELD (BURSTLEN0, (i)) << 0))
382 
383 #define SET_BURSTLEN(i, v)                    \
384   do {                                                  \
385       SET_INSN_FIELD (BURSTLEN64, (i), (v) >> 4); \
386       SET_INSN_FIELD (BURSTLEN31, (i), (v) >> 1); \
387       SET_INSN_FIELD (BURSTLEN0, (i), (v) >> 0);  \
388   } while (0)
389 
390 /* Miscellaneous helpers.  */
391 #define OP_MASK_XFR_OP                  (OP_MASK_FMT2_OP | OP_MASK_SUBOP \
392                                          | OP_MASK_SUBOP_XFR | OP_MASK_XFR_S)
393 
394 #define OP_MASK_LOOP_OP                 (OP_MASK_FMT2_OP | OP_MASK_SUBOP \
395                                          | OP_MASK_LOOP_INTERRUPTIBLE)
396 
397 /* These are the data structures we use to hold the instruction information.  */
398 extern const struct pru_opcode pru_opcodes[];
399 extern const int bfd_pru_num_opcodes;
400 
401 /* These are the data structures used to hold the register information.  */
402 extern const struct pru_reg pru_regs[];
403 extern const int pru_num_regs;
404 
405 /* Machine-independent macro for number of opcodes.  */
406 #define NUMOPCODES bfd_pru_num_opcodes
407 #define NUMREGISTERS pru_num_regs;
408 
409 /* This is made extern so that the assembler can use it to find out
410    what instruction caused an error.  */
411 extern const struct pru_opcode *pru_find_opcode (unsigned long);
412 
413 #endif /* _PRU_H */
414