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