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 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 236