Commit | Line | Data |
---|---|---|
11146849 | 1 | /* TI PRU opcode list. |
82704155 | 2 | Copyright (C) 2014-2019 Free Software Foundation, Inc. |
11146849 DD |
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 | ||
a1aa5e81 | 88 | /* This is the opcode table used by the PRU GNU as and disassembler. */ |
11146849 DD |
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 |