Update year range in copyright notice of all files.
[external/binutils.git] / opcodes / pru-opc.c
1 /* TI PRU opcode list.
2    Copyright (C) 2014-2017 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, disassembler
89    and soon GDB.  */
90 const struct pru_opcode pru_opcodes[] =
91 {
92   /* { name, args,
93        match, mask, pinfo, overflow_msg } */
94 #define DECLARE_FORMAT1_OPCODE(str, subop) \
95   { #str, prui_ ## str, "d,s,b", \
96     OP_MATCH_ ## subop, OP_MASK_FMT1_OP | OP_MASK_SUBOP, 0, \
97     unsigned_immed8_overflow }
98
99   DECLARE_FORMAT1_OPCODE (add, ADD),
100   DECLARE_FORMAT1_OPCODE (adc, ADC),
101   DECLARE_FORMAT1_OPCODE (sub, SUB),
102   DECLARE_FORMAT1_OPCODE (suc, SUC),
103   DECLARE_FORMAT1_OPCODE (lsl, LSL),
104   DECLARE_FORMAT1_OPCODE (lsr, LSR),
105   DECLARE_FORMAT1_OPCODE (rsb, RSB),
106   DECLARE_FORMAT1_OPCODE (rsc, RSC),
107   DECLARE_FORMAT1_OPCODE (and, AND),
108   DECLARE_FORMAT1_OPCODE (or, OR),
109   DECLARE_FORMAT1_OPCODE (xor, XOR),
110   DECLARE_FORMAT1_OPCODE (min, MIN),
111   DECLARE_FORMAT1_OPCODE (max, MAX),
112   DECLARE_FORMAT1_OPCODE (clr, CLR),
113   DECLARE_FORMAT1_OPCODE (set, SET),
114
115   { "not", prui_not, "d,s",
116    OP_MATCH_NOT | OP_MASK_IO,
117    OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IO, 0, no_overflow},
118
119   { "jmp", prui_jmp, "j",
120    OP_MATCH_JMP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
121   { "jal", prui_jal, "d,j",
122    OP_MATCH_JAL, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
123   { "ldi", prui_ldi, "d,W",
124    OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, unsigned_immed16_overflow},
125   { "halt", prui_halt, "",
126    OP_MATCH_HALT, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
127   { "slp", prui_slp, "w",
128    OP_MATCH_SLP, OP_MASK_FMT2_OP | OP_MASK_SUBOP, 0, no_overflow},
129
130   { "xin", prui_xin, "x,D,n",
131    OP_MATCH_XIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
132   { "xout", prui_xout, "x,D,n",
133    OP_MATCH_XOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
134   { "xchg", prui_xchg, "x,D,n",
135    OP_MATCH_XCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
136   { "sxin", prui_sxin, "x,D,n",
137    OP_MATCH_SXIN, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
138   { "sxout", prui_sxout, "x,D,n",
139    OP_MATCH_SXOUT, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
140   { "sxchg", prui_sxchg, "x,D,n",
141    OP_MATCH_SXCHG, OP_MASK_XFR_OP, 0, unsigned_immed8_overflow},
142
143   { "loop", prui_loop, "O,B",
144    OP_MATCH_LOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
145   { "iloop", prui_loop, "O,B",
146    OP_MATCH_ILOOP, OP_MASK_LOOP_OP, 0, unsigned_immed8_overflow},
147
148   { "qbgt", prui_qbgt, "o,s,b",
149    OP_MATCH_QBGT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
150   { "qbge", prui_qbge, "o,s,b",
151    OP_MATCH_QBGE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
152   { "qblt", prui_qblt, "o,s,b",
153    OP_MATCH_QBLT, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
154   { "qble", prui_qble, "o,s,b",
155    OP_MATCH_QBLE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
156   { "qbeq", prui_qbeq, "o,s,b",
157    OP_MATCH_QBEQ, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
158   { "qbne", prui_qbne, "o,s,b",
159    OP_MATCH_QBNE, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
160   { "qba", prui_qba, "o",
161    OP_MATCH_QBA, OP_MASK_FMT4_OP | OP_MASK_CMP, 0, qbranch_target_overflow},
162
163   { "qbbs", prui_qbbs, "o,s,b",
164    OP_MATCH_QBBS, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
165   { "qbbc", prui_qbbc, "o,s,b",
166    OP_MATCH_QBBC, OP_MASK_FMT5_OP | OP_MASK_BCMP, 0, qbranch_target_overflow},
167
168   { "lbbo", prui_lbbo, "D,S,b,l",
169    OP_MATCH_LBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
170    unsigned_immed8_overflow},
171   { "sbbo", prui_sbbo, "D,S,b,l",
172    OP_MATCH_SBBO, OP_MASK_FMT6AB_OP | OP_MASK_LOADSTORE, 0,
173    unsigned_immed8_overflow},
174   { "lbco", prui_lbco, "D,c,b,l",
175    OP_MATCH_LBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
176    unsigned_immed8_overflow},
177   { "sbco", prui_sbco, "D,c,b,l",
178    OP_MATCH_SBCO, OP_MASK_FMT6CD_OP | OP_MASK_LOADSTORE, 0,
179    unsigned_immed8_overflow},
180
181   /* Fill in the default values for the real-instruction arguments.
182      The assembler will not do it!  */
183   { "nop", prui_or, "",
184    OP_MATCH_OR
185      | (RSEL_31_0 << OP_SH_RS2SEL) | (0 << OP_SH_RS2)
186      | (RSEL_31_0 << OP_SH_RS1SEL) | (0 << OP_SH_RS1)
187      | (RSEL_31_0 << OP_SH_RDSEL) | (0 << OP_SH_RD),
188    OP_MASK_FMT1_OP | OP_MASK_SUBOP
189      | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_RS1SEL | OP_MASK_RS1
190      | OP_MASK_RDSEL | OP_MASK_RD | OP_MASK_IO,
191    PRU_INSN_MACRO, no_overflow},
192   { "mov", prui_or, "d,s",
193    OP_MATCH_OR | (0 << OP_SH_IMM8) | OP_MASK_IO,
194    OP_MASK_FMT1_OP | OP_MASK_SUBOP | OP_MASK_IMM8 | OP_MASK_IO,
195    PRU_INSN_MACRO, no_overflow},
196   { "ret", prui_jmp, "",
197    OP_MATCH_JMP
198      | (RSEL_31_16 << OP_SH_RS2SEL) | (3 << OP_SH_RS2),
199    OP_MASK_FMT2_OP | OP_MASK_SUBOP
200      | OP_MASK_RS2SEL | OP_MASK_RS2 | OP_MASK_IO,
201    PRU_INSN_MACRO, unsigned_immed16_overflow},
202   { "call", prui_jal, "j",
203    OP_MATCH_JAL
204      | (RSEL_31_16 << OP_SH_RDSEL) | (3 << OP_SH_RD),
205    OP_MASK_FMT2_OP | OP_MASK_SUBOP
206      | OP_MASK_RDSEL | OP_MASK_RD,
207    PRU_INSN_MACRO, unsigned_immed16_overflow},
208
209   { "wbc", prui_qbbs, "s,b",
210    OP_MATCH_QBBS | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
211    OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
212    PRU_INSN_MACRO, qbranch_target_overflow},
213   { "wbs", prui_qbbc, "s,b",
214    OP_MATCH_QBBC | (0 << OP_SH_BROFF98) | (0 << OP_SH_BROFF70),
215    OP_MASK_FMT5_OP | OP_MASK_BCMP | OP_MASK_BROFF,
216    PRU_INSN_MACRO, qbranch_target_overflow},
217
218   { "fill", prui_xin, "D,n",
219    OP_MATCH_XIN | (254 << OP_SH_XFR_WBA),
220    OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
221    PRU_INSN_MACRO, unsigned_immed8_overflow},
222   { "zero", prui_xin, "D,n",
223    OP_MATCH_XIN | (255 << OP_SH_XFR_WBA),
224    OP_MASK_XFR_OP | OP_MASK_XFR_WBA,
225    PRU_INSN_MACRO, unsigned_immed8_overflow},
226
227   { "ldi32", prui_ldi, "R,i",
228    OP_MATCH_LDI, OP_MASK_FMT2_OP | OP_MASK_SUBOP,
229    PRU_INSN_LDI32, unsigned_immed32_overflow},
230 };
231
232 #define PRU_NUM_OPCODES \
233        ((sizeof pru_opcodes) / (sizeof (pru_opcodes[0])))
234 const int bfd_pru_num_opcodes = PRU_NUM_OPCODES;
235
236 #undef PRU_NUM_OPCODES