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