xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/pru-opc.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1e6c7e151Schristos /* TI PRU opcode list.
2*c42dbd0eSchristos    Copyright (C) 2014-2022 Free Software Foundation, Inc.
3e6c7e151Schristos    Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4e6c7e151Schristos 
5e6c7e151Schristos    This file is part of the GNU opcodes library.
6e6c7e151Schristos 
7e6c7e151Schristos    This library is free software; you can redistribute it and/or modify
8e6c7e151Schristos    it under the terms of the GNU General Public License as published by
9e6c7e151Schristos    the Free Software Foundation; either version 3, or (at your option)
10e6c7e151Schristos    any later version.
11e6c7e151Schristos 
12e6c7e151Schristos    It is distributed in the hope that it will be useful, but WITHOUT
13e6c7e151Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14e6c7e151Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15e6c7e151Schristos    License for more details.
16e6c7e151Schristos 
17e6c7e151Schristos    You should have received a copy of the GNU General Public License
18e6c7e151Schristos    along with this file; see the file COPYING.  If not, write to the
19e6c7e151Schristos    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20e6c7e151Schristos    MA 02110-1301, USA.  */
21e6c7e151Schristos 
22e6c7e151Schristos /* Source:
23e6c7e151Schristos    http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit  */
24e6c7e151Schristos 
25e6c7e151Schristos #include "sysdep.h"
26e6c7e151Schristos #include <stdio.h>
27e6c7e151Schristos #include "opcode/pru.h"
28e6c7e151Schristos 
29e6c7e151Schristos /* Register string table.  */
30e6c7e151Schristos 
31e6c7e151Schristos #define DECLARE_REG(name, index)		\
32e6c7e151Schristos   { #name ".b0", (index), RSEL_7_0 },		\
33e6c7e151Schristos   { #name ".b1", (index), RSEL_15_8 },		\
34e6c7e151Schristos   { #name ".b2", (index), RSEL_23_16 },		\
35e6c7e151Schristos   { #name ".b3", (index), RSEL_31_24 },		\
36e6c7e151Schristos   { #name ".w0", (index), RSEL_15_0 },		\
37e6c7e151Schristos   { #name ".w1", (index), RSEL_23_8 },		\
38e6c7e151Schristos   { #name ".w2", (index), RSEL_31_16 },		\
39e6c7e151Schristos   { #name , (index), RSEL_31_0 }
40e6c7e151Schristos 
41e6c7e151Schristos const struct pru_reg pru_regs[] = {
42e6c7e151Schristos   /* Standard register names.  */
43e6c7e151Schristos   DECLARE_REG (r0, 0),
44e6c7e151Schristos   DECLARE_REG (r1, 1),
45e6c7e151Schristos   DECLARE_REG (sp, 2),		/* Stack pointer.  */
46e6c7e151Schristos   DECLARE_REG (ra, 3),		/* Return address.  */
47e6c7e151Schristos   DECLARE_REG (fp, 4),		/* Frame pointer.  */
48e6c7e151Schristos   DECLARE_REG (r5, 5),
49e6c7e151Schristos   DECLARE_REG (r6, 6),
50e6c7e151Schristos   DECLARE_REG (r7, 7),
51e6c7e151Schristos   DECLARE_REG (r8, 8),
52e6c7e151Schristos   DECLARE_REG (r9, 9),
53e6c7e151Schristos   DECLARE_REG (r10, 10),
54e6c7e151Schristos   DECLARE_REG (r11, 11),
55e6c7e151Schristos   DECLARE_REG (r12, 12),
56e6c7e151Schristos   DECLARE_REG (r13, 13),
57e6c7e151Schristos   DECLARE_REG (r14, 14),
58e6c7e151Schristos   DECLARE_REG (r15, 15),
59e6c7e151Schristos   DECLARE_REG (r16, 16),
60e6c7e151Schristos   DECLARE_REG (r17, 17),
61e6c7e151Schristos   DECLARE_REG (r18, 18),
62e6c7e151Schristos   DECLARE_REG (r19, 19),
63e6c7e151Schristos   DECLARE_REG (r20, 20),
64e6c7e151Schristos   DECLARE_REG (r21, 21),
65e6c7e151Schristos   DECLARE_REG (r22, 22),
66e6c7e151Schristos   DECLARE_REG (r23, 23),
67e6c7e151Schristos   DECLARE_REG (r24, 24),
68e6c7e151Schristos   DECLARE_REG (r25, 25),
69e6c7e151Schristos   DECLARE_REG (r26, 26),
70e6c7e151Schristos   DECLARE_REG (r27, 27),
71e6c7e151Schristos   DECLARE_REG (r28, 28),
72e6c7e151Schristos   DECLARE_REG (r29, 29),
73e6c7e151Schristos   DECLARE_REG (r30, 30),
74e6c7e151Schristos   DECLARE_REG (r31, 31),
75e6c7e151Schristos 
76e6c7e151Schristos   /* Alternative names for special registers.  */
77e6c7e151Schristos   DECLARE_REG (r2, 2),
78e6c7e151Schristos   DECLARE_REG (r3, 3),
79e6c7e151Schristos   DECLARE_REG (r4, 4)
80e6c7e151Schristos };
81e6c7e151Schristos 
82e6c7e151Schristos #define PRU_NUM_REGS \
83e6c7e151Schristos        ((sizeof pru_regs) / (sizeof (pru_regs[0])))
84e6c7e151Schristos const int pru_num_regs = PRU_NUM_REGS;
85e6c7e151Schristos 
86e6c7e151Schristos #undef PRU_NUM_REGS
87e6c7e151Schristos 
88e6c7e151Schristos /* This is the opcode table used by the PRU GNU as and disassembler.  */
89e6c7e151Schristos const struct pru_opcode pru_opcodes[] =
90e6c7e151Schristos {
91e6c7e151Schristos   /* { name, args,
92e6c7e151Schristos        match, mask, pinfo, overflow_msg } */
93e6c7e151Schristos #define DECLARE_FORMAT1_OPCODE(str, subop) \
94e6c7e151Schristos   { #str, prui_ ## str, "d,s,b", \
95e6c7e151Schristos     OP_MATCH_ ## subop, OP_MASK_FMT1_OP | OP_MASK_SUBOP, 0, \
96e6c7e151Schristos     unsigned_immed8_overflow }
97e6c7e151Schristos 
98e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (add, ADD),
99e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (adc, ADC),
100e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (sub, SUB),
101e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (suc, SUC),
102e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (lsl, LSL),
103e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (lsr, LSR),
104e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (rsb, RSB),
105e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (rsc, RSC),
106e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (and, AND),
107e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (or, OR),
108e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (xor, XOR),
109e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (min, MIN),
110e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (max, MAX),
111e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (clr, CLR),
112e6c7e151Schristos   DECLARE_FORMAT1_OPCODE (set, SET),
113e6c7e151Schristos 
114e6c7e151Schristos   { "not", prui_not, "d,s",
115e6c7e151Schristos    OP_MATCH_NOT | OP_MASK_IO,
116e6c7e151Schristos    OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IO, 0, no_overflow},
117e6c7e151Schristos 
118e6c7e151Schristos   { "jmp", prui_jmp, "j",
119e6c7e151Schristos    OP_MATCH_JMP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
120e6c7e151Schristos   { "jal", prui_jal, "d,j",
121e6c7e151Schristos    OP_MATCH_JAL, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
122e6c7e151Schristos   { "ldi", prui_ldi, "d,W",
123e6c7e151Schristos    OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
124*c42dbd0eSchristos   { "lmbd", prui_lmbd, "d,s,b",
125*c42dbd0eSchristos    OP_MATCH_LMBD, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed8_overflow},
126e6c7e151Schristos   { "halt", prui_halt, "",
127e6c7e151Schristos    OP_MATCH_HALT, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
128e6c7e151Schristos   { "slp", prui_slp, "w",
129e6c7e151Schristos    OP_MATCH_SLP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
130e6c7e151Schristos 
131e6c7e151Schristos   { "xin", prui_xin, "x,D,n",
132e6c7e151Schristos    OP_MATCH_XIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
133e6c7e151Schristos   { "xout", prui_xout, "x,D,n",
134e6c7e151Schristos    OP_MATCH_XOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
135e6c7e151Schristos   { "xchg", prui_xchg, "x,D,n",
136e6c7e151Schristos    OP_MATCH_XCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
137e6c7e151Schristos   { "sxin", prui_sxin, "x,D,n",
138e6c7e151Schristos    OP_MATCH_SXIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
139e6c7e151Schristos   { "sxout", prui_sxout, "x,D,n",
140e6c7e151Schristos    OP_MATCH_SXOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
141e6c7e151Schristos   { "sxchg", prui_sxchg, "x,D,n",
142e6c7e151Schristos    OP_MATCH_SXCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
143e6c7e151Schristos 
144e6c7e151Schristos   { "loop", prui_loop, "O,B",
145e6c7e151Schristos    OP_MATCH_LOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
146e6c7e151Schristos   { "iloop", prui_loop, "O,B",
147e6c7e151Schristos    OP_MATCH_ILOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
148e6c7e151Schristos 
149e6c7e151Schristos   { "qbgt", prui_qbgt, "o,s,b",
150e6c7e151Schristos    OP_MATCH_QBGT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
151e6c7e151Schristos   { "qbge", prui_qbge, "o,s,b",
152e6c7e151Schristos    OP_MATCH_QBGE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
153e6c7e151Schristos   { "qblt", prui_qblt, "o,s,b",
154e6c7e151Schristos    OP_MATCH_QBLT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
155e6c7e151Schristos   { "qble", prui_qble, "o,s,b",
156e6c7e151Schristos    OP_MATCH_QBLE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
157e6c7e151Schristos   { "qbeq", prui_qbeq, "o,s,b",
158e6c7e151Schristos    OP_MATCH_QBEQ, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
159e6c7e151Schristos   { "qbne", prui_qbne, "o,s,b",
160e6c7e151Schristos    OP_MATCH_QBNE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
161e6c7e151Schristos   { "qba", prui_qba, "o",
162e6c7e151Schristos    OP_MATCH_QBA, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
163e6c7e151Schristos 
164e6c7e151Schristos   { "qbbs", prui_qbbs, "o,s,b",
165e6c7e151Schristos    OP_MATCH_QBBS, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
166e6c7e151Schristos   { "qbbc", prui_qbbc, "o,s,b",
167e6c7e151Schristos    OP_MATCH_QBBC, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
168e6c7e151Schristos 
169e6c7e151Schristos   { "lbbo", prui_lbbo, "D,S,b,l",
170e6c7e151Schristos    OP_MATCH_LBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
171e6c7e151Schristos    unsigned_immed8_overflow},
172e6c7e151Schristos   { "sbbo", prui_sbbo, "D,S,b,l",
173e6c7e151Schristos    OP_MATCH_SBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
174e6c7e151Schristos    unsigned_immed8_overflow},
175e6c7e151Schristos   { "lbco", prui_lbco, "D,c,b,l",
176e6c7e151Schristos    OP_MATCH_LBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
177e6c7e151Schristos    unsigned_immed8_overflow},
178e6c7e151Schristos   { "sbco", prui_sbco, "D,c,b,l",
179e6c7e151Schristos    OP_MATCH_SBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
180e6c7e151Schristos    unsigned_immed8_overflow},
181e6c7e151Schristos 
182e6c7e151Schristos   /* Fill in the default values for the real-instruction arguments.
183e6c7e151Schristos      The assembler will not do it!  */
184e6c7e151Schristos   { "nop", prui_or, "",
185e6c7e151Schristos    OP_MATCH_OR
186e6c7e151Schristos      | (RSEL_31_0 << OP_SH_RS2SEL) | (0 << OP_SH_RS2)
187e6c7e151Schristos      | (RSEL_31_0 << OP_SH_RS1SEL) | (0 << OP_SH_RS1)
188e6c7e151Schristos      | (RSEL_31_0 << OP_SH_RDSEL) | (0 << OP_SH_RD),
189e6c7e151Schristos    OP_MASK_FMT1_OP | OP_MASK_SUBOP
190e6c7e151Schristos      | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_RS1SEL | OP_MASK_RS1
191e6c7e151Schristos      | OP_MASK_RDSEL | OP_MASK_RD | OP_MASK_IO,
192e6c7e151Schristos    PRU_INSN_MACRO, no_overflow},
193e6c7e151Schristos   { "mov", prui_or, "d,s",
194e6c7e151Schristos    OP_MATCH_OR | (0 << OP_SH_IMM8) | OP_MASK_IO,
195e6c7e151Schristos    OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IMM8 | OP_MASK_IO,
196e6c7e151Schristos    PRU_INSN_MACRO, no_overflow},
197e6c7e151Schristos   { "ret", prui_jmp, "",
198e6c7e151Schristos    OP_MATCH_JMP
199e6c7e151Schristos      | (RSEL_31_16 << OP_SH_RS2SEL) | (3 << OP_SH_RS2),
200e6c7e151Schristos    OP_MASK_FMT2_OP | OP_MASK_SUBOP
201e6c7e151Schristos      | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_IO,
202e6c7e151Schristos    PRU_INSN_MACRO, unsigned_immed16_overflow},
203e6c7e151Schristos   { "call", prui_jal, "j",
204e6c7e151Schristos    OP_MATCH_JAL
205e6c7e151Schristos      | (RSEL_31_16 << OP_SH_RDSEL) | (3 << OP_SH_RD),
206e6c7e151Schristos    OP_MASK_FMT2_OP | OP_MASK_SUBOP
207e6c7e151Schristos      | OP_MASK_RDSEL | OP_MASK_RD,
208e6c7e151Schristos    PRU_INSN_MACRO, unsigned_immed16_overflow},
209e6c7e151Schristos 
210e6c7e151Schristos   { "wbc", prui_qbbs, "s,b",
211e6c7e151Schristos    OP_MATCH_QBBS | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
212e6c7e151Schristos    OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
213e6c7e151Schristos    PRU_INSN_MACRO, qbranch_target_overflow},
214e6c7e151Schristos   { "wbs", prui_qbbc, "s,b",
215e6c7e151Schristos    OP_MATCH_QBBC | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
216e6c7e151Schristos    OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
217e6c7e151Schristos    PRU_INSN_MACRO, qbranch_target_overflow},
218e6c7e151Schristos 
219e6c7e151Schristos   { "fill", prui_xin, "D,n",
220e6c7e151Schristos    OP_MATCH_XIN | (254 << OP_SH_XFR_WBA),
221e6c7e151Schristos    OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
222e6c7e151Schristos    PRU_INSN_MACRO, unsigned_immed8_overflow},
223e6c7e151Schristos   { "zero", prui_xin, "D,n",
224e6c7e151Schristos    OP_MATCH_XIN | (255 << OP_SH_XFR_WBA),
225e6c7e151Schristos    OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
226e6c7e151Schristos    PRU_INSN_MACRO, unsigned_immed8_overflow},
227e6c7e151Schristos 
228e6c7e151Schristos   { "ldi32", prui_ldi, "R,i",
229e6c7e151Schristos    OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP,
230e6c7e151Schristos    PRU_INSN_LDI32, unsigned_immed32_overflow},
231e6c7e151Schristos };
232e6c7e151Schristos 
233e6c7e151Schristos #define PRU_NUM_OPCODES \
234e6c7e151Schristos        ((sizeof pru_opcodes) / (sizeof (pru_opcodes[0])))
235e6c7e151Schristos const int bfd_pru_num_opcodes = PRU_NUM_OPCODES;
236e6c7e151Schristos 
237e6c7e151Schristos #undef PRU_NUM_OPCODES
238