pru-opc.c revision 1.1.1.2 1 1.1 christos /* TI PRU opcode list.
2 1.1.1.2 christos Copyright (C) 2014-2020 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 christos { "halt", prui_halt, "",
125 1.1 christos OP_MATCH_HALT, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
126 1.1 christos { "slp", prui_slp, "w",
127 1.1 christos OP_MATCH_SLP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
128 1.1 christos
129 1.1 christos { "xin", prui_xin, "x,D,n",
130 1.1 christos OP_MATCH_XIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
131 1.1 christos { "xout", prui_xout, "x,D,n",
132 1.1 christos OP_MATCH_XOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
133 1.1 christos { "xchg", prui_xchg, "x,D,n",
134 1.1 christos OP_MATCH_XCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
135 1.1 christos { "sxin", prui_sxin, "x,D,n",
136 1.1 christos OP_MATCH_SXIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
137 1.1 christos { "sxout", prui_sxout, "x,D,n",
138 1.1 christos OP_MATCH_SXOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
139 1.1 christos { "sxchg", prui_sxchg, "x,D,n",
140 1.1 christos OP_MATCH_SXCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
141 1.1 christos
142 1.1 christos { "loop", prui_loop, "O,B",
143 1.1 christos OP_MATCH_LOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
144 1.1 christos { "iloop", prui_loop, "O,B",
145 1.1 christos OP_MATCH_ILOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
146 1.1 christos
147 1.1 christos { "qbgt", prui_qbgt, "o,s,b",
148 1.1 christos OP_MATCH_QBGT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
149 1.1 christos { "qbge", prui_qbge, "o,s,b",
150 1.1 christos OP_MATCH_QBGE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
151 1.1 christos { "qblt", prui_qblt, "o,s,b",
152 1.1 christos OP_MATCH_QBLT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
153 1.1 christos { "qble", prui_qble, "o,s,b",
154 1.1 christos OP_MATCH_QBLE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
155 1.1 christos { "qbeq", prui_qbeq, "o,s,b",
156 1.1 christos OP_MATCH_QBEQ, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
157 1.1 christos { "qbne", prui_qbne, "o,s,b",
158 1.1 christos OP_MATCH_QBNE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
159 1.1 christos { "qba", prui_qba, "o",
160 1.1 christos OP_MATCH_QBA, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
161 1.1 christos
162 1.1 christos { "qbbs", prui_qbbs, "o,s,b",
163 1.1 christos OP_MATCH_QBBS, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
164 1.1 christos { "qbbc", prui_qbbc, "o,s,b",
165 1.1 christos OP_MATCH_QBBC, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
166 1.1 christos
167 1.1 christos { "lbbo", prui_lbbo, "D,S,b,l",
168 1.1 christos OP_MATCH_LBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
169 1.1 christos unsigned_immed8_overflow},
170 1.1 christos { "sbbo", prui_sbbo, "D,S,b,l",
171 1.1 christos OP_MATCH_SBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
172 1.1 christos unsigned_immed8_overflow},
173 1.1 christos { "lbco", prui_lbco, "D,c,b,l",
174 1.1 christos OP_MATCH_LBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
175 1.1 christos unsigned_immed8_overflow},
176 1.1 christos { "sbco", prui_sbco, "D,c,b,l",
177 1.1 christos OP_MATCH_SBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
178 1.1 christos unsigned_immed8_overflow},
179 1.1 christos
180 1.1 christos /* Fill in the default values for the real-instruction arguments.
181 1.1 christos The assembler will not do it! */
182 1.1 christos { "nop", prui_or, "",
183 1.1 christos OP_MATCH_OR
184 1.1 christos | (RSEL_31_0 << OP_SH_RS2SEL) | (0 << OP_SH_RS2)
185 1.1 christos | (RSEL_31_0 << OP_SH_RS1SEL) | (0 << OP_SH_RS1)
186 1.1 christos | (RSEL_31_0 << OP_SH_RDSEL) | (0 << OP_SH_RD),
187 1.1 christos OP_MASK_FMT1_OP | OP_MASK_SUBOP
188 1.1 christos | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_RS1SEL | OP_MASK_RS1
189 1.1 christos | OP_MASK_RDSEL | OP_MASK_RD | OP_MASK_IO,
190 1.1 christos PRU_INSN_MACRO, no_overflow},
191 1.1 christos { "mov", prui_or, "d,s",
192 1.1 christos OP_MATCH_OR | (0 << OP_SH_IMM8) | OP_MASK_IO,
193 1.1 christos OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IMM8 | OP_MASK_IO,
194 1.1 christos PRU_INSN_MACRO, no_overflow},
195 1.1 christos { "ret", prui_jmp, "",
196 1.1 christos OP_MATCH_JMP
197 1.1 christos | (RSEL_31_16 << OP_SH_RS2SEL) | (3 << OP_SH_RS2),
198 1.1 christos OP_MASK_FMT2_OP | OP_MASK_SUBOP
199 1.1 christos | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_IO,
200 1.1 christos PRU_INSN_MACRO, unsigned_immed16_overflow},
201 1.1 christos { "call", prui_jal, "j",
202 1.1 christos OP_MATCH_JAL
203 1.1 christos | (RSEL_31_16 << OP_SH_RDSEL) | (3 << OP_SH_RD),
204 1.1 christos OP_MASK_FMT2_OP | OP_MASK_SUBOP
205 1.1 christos | OP_MASK_RDSEL | OP_MASK_RD,
206 1.1 christos PRU_INSN_MACRO, unsigned_immed16_overflow},
207 1.1 christos
208 1.1 christos { "wbc", prui_qbbs, "s,b",
209 1.1 christos OP_MATCH_QBBS | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
210 1.1 christos OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
211 1.1 christos PRU_INSN_MACRO, qbranch_target_overflow},
212 1.1 christos { "wbs", prui_qbbc, "s,b",
213 1.1 christos OP_MATCH_QBBC | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
214 1.1 christos OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
215 1.1 christos PRU_INSN_MACRO, qbranch_target_overflow},
216 1.1 christos
217 1.1 christos { "fill", prui_xin, "D,n",
218 1.1 christos OP_MATCH_XIN | (254 << OP_SH_XFR_WBA),
219 1.1 christos OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
220 1.1 christos PRU_INSN_MACRO, unsigned_immed8_overflow},
221 1.1 christos { "zero", prui_xin, "D,n",
222 1.1 christos OP_MATCH_XIN | (255 << OP_SH_XFR_WBA),
223 1.1 christos OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
224 1.1 christos PRU_INSN_MACRO, unsigned_immed8_overflow},
225 1.1 christos
226 1.1 christos { "ldi32", prui_ldi, "R,i",
227 1.1 christos OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP,
228 1.1 christos PRU_INSN_LDI32, unsigned_immed32_overflow},
229 1.1 christos };
230 1.1 christos
231 1.1 christos #define PRU_NUM_OPCODES \
232 1.1 christos ((sizeof pru_opcodes) / (sizeof (pru_opcodes[0])))
233 1.1 christos const int bfd_pru_num_opcodes = PRU_NUM_OPCODES;
234 1.1 christos
235 1.1 christos #undef PRU_NUM_OPCODES
236