1 1.1 christos /* TI PRU opcode list. 2 1.1.1.5 christos Copyright (C) 2014-2025 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