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