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