1/* Copyright 2016-2020 Free Software Foundation, Inc. 2 Contributed by Dimitar Dimitrov <dimitar@dinux.eu> 3 4 This file is part of the PRU simulator. 5 6 This library is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, see <http://www.gnu.org/licenses/>. */ 18 19/* 20 PRU Instruction Set Architecture 21 22 INSTRUCTION (NAME, 23 SEMANTICS) 24 */ 25 26INSTRUCTION (add, 27 OP2 = (IO ? IMM8 : RS2); 28 RD = RS1 + OP2; 29 CARRY = (((uint64_t) RS1 + (uint64_t) OP2) >> RD_WIDTH) & 1; 30 PC++) 31 32INSTRUCTION (adc, 33 OP2 = (IO ? IMM8 : RS2); 34 RD = RS1 + OP2 + CARRY; 35 CARRY = (((uint64_t) RS1 + (uint64_t) OP2 + (uint64_t) CARRY) 36 >> RD_WIDTH) & 1; 37 PC++) 38 39INSTRUCTION (sub, 40 OP2 = (IO ? IMM8 : RS2); 41 RD = RS1 - OP2; 42 CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1; 43 PC++) 44 45INSTRUCTION (suc, 46 OP2 = (IO ? IMM8 : RS2); 47 RD = RS1 - OP2 - CARRY; 48 CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) CARRY) 49 >> RD_WIDTH) & 1; 50 PC++) 51 52INSTRUCTION (rsb, 53 OP2 = (IO ? IMM8 : RS2); 54 RD = OP2 - RS1; 55 CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1; 56 PC++) 57 58INSTRUCTION (rsc, 59 OP2 = (IO ? IMM8 : RS2); 60 RD = OP2 - RS1 - CARRY; 61 CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) CARRY) 62 >> RD_WIDTH) & 1; 63 PC++) 64 65INSTRUCTION (lsl, 66 OP2 = (IO ? IMM8 : RS2); 67 RD = RS1 << (OP2 & 0x1f); 68 PC++) 69 70INSTRUCTION (lsr, 71 OP2 = (IO ? IMM8 : RS2); 72 RD = RS1 >> (OP2 & 0x1f); 73 PC++) 74 75INSTRUCTION (and, 76 OP2 = (IO ? IMM8 : RS2); 77 RD = RS1 & OP2; 78 PC++) 79 80INSTRUCTION (or, 81 OP2 = (IO ? IMM8 : RS2); 82 RD = RS1 | OP2; 83 PC++) 84 85INSTRUCTION (xor, 86 OP2 = (IO ? IMM8 : RS2); 87 RD = RS1 ^ OP2; 88 PC++) 89 90INSTRUCTION (not, 91 RD = ~RS1; 92 PC++) 93 94INSTRUCTION (min, 95 OP2 = (IO ? IMM8 : RS2); 96 RD = RS1 < OP2 ? RS1 : OP2; 97 PC++) 98 99INSTRUCTION (max, 100 OP2 = (IO ? IMM8 : RS2); 101 RD = RS1 > OP2 ? RS1 : OP2; 102 PC++) 103 104INSTRUCTION (clr, 105 OP2 = (IO ? IMM8 : RS2); 106 RD = RS1 & ~(1u << (OP2 & 0x1f)); 107 PC++) 108 109INSTRUCTION (set, 110 OP2 = (IO ? IMM8 : RS2); 111 RD = RS1 | (1u << (OP2 & 0x1f)); 112 PC++) 113 114INSTRUCTION (jmp, 115 OP2 = (IO ? IMM16 : RS2); 116 PC = OP2) 117 118INSTRUCTION (jal, 119 OP2 = (IO ? IMM16 : RS2); 120 RD = PC + 1; 121 PC = OP2) 122 123INSTRUCTION (ldi, 124 RD = IMM16; 125 PC++) 126 127INSTRUCTION (halt, 128 pru_sim_syscall (sd, cpu); 129 PC++) 130 131INSTRUCTION (slp, 132 if (!WAKEONSTATUS) 133 { 134 RAISE_SIGINT (sd); 135 } 136 else 137 { 138 PC++; 139 }) 140 141INSTRUCTION (qbgt, 142 OP2 = (IO ? IMM8 : RS2); 143 PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1)) 144 145INSTRUCTION (qbge, 146 OP2 = (IO ? IMM8 : RS2); 147 PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1)) 148 149INSTRUCTION (qblt, 150 OP2 = (IO ? IMM8 : RS2); 151 PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1)) 152 153INSTRUCTION (qble, 154 OP2 = (IO ? IMM8 : RS2); 155 PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1)) 156 157INSTRUCTION (qbeq, 158 OP2 = (IO ? IMM8 : RS2); 159 PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1)) 160 161INSTRUCTION (qbne, 162 OP2 = (IO ? IMM8 : RS2); 163 PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1)) 164 165INSTRUCTION (qba, 166 OP2 = (IO ? IMM8 : RS2); 167 PC = PC + BROFF) 168 169INSTRUCTION (qbbs, 170 OP2 = (IO ? IMM8 : RS2); 171 PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1)) 172 173INSTRUCTION (qbbc, 174 OP2 = (IO ? IMM8 : RS2); 175 PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1)) 176 177INSTRUCTION (lbbo, 178 pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2), 179 BURSTLEN, RD_REGN, RDB); 180 PC++) 181 182INSTRUCTION (sbbo, 183 pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2), 184 BURSTLEN, RD_REGN, RDB); 185 PC++) 186 187INSTRUCTION (lbco, 188 pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2), 189 BURSTLEN, RD_REGN, RDB); 190 PC++) 191 192INSTRUCTION (sbco, 193 pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2), 194 BURSTLEN, RD_REGN, RDB); 195 PC++) 196 197INSTRUCTION (xin, 198 DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); 199 PC++) 200 201INSTRUCTION (xout, 202 DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); 203 PC++) 204 205INSTRUCTION (xchg, 206 DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); 207 PC++) 208 209INSTRUCTION (sxin, 210 sim_io_eprintf (sd, "SXIN instruction not supported by sim\n"); 211 RAISE_SIGILL (sd)) 212 213INSTRUCTION (sxout, 214 sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n"); 215 RAISE_SIGILL (sd)) 216 217INSTRUCTION (sxchg, 218 sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n"); 219 RAISE_SIGILL (sd)) 220 221INSTRUCTION (loop, 222 OP2 = (IO ? IMM8 + 1 : RS2_w0); 223 if (OP2 == 0) 224 { 225 PC = LOOPEND; 226 } 227 else 228 { 229 LOOPTOP = PC + 1; 230 LOOPEND = PC + LOOP_JMPOFFS; 231 LOOPCNT = OP2; 232 LOOP_IN_PROGRESS = 1; 233 PC++; 234 }) 235 236INSTRUCTION (iloop, 237 OP2 = (IO ? IMM8 + 1 : RS2_w0); 238 if (OP2 == 0) 239 { 240 PC = LOOPEND; 241 } 242 else 243 { 244 LOOPTOP = PC + 1; 245 LOOPEND = PC + LOOP_JMPOFFS; 246 LOOPCNT = OP2; 247 LOOP_IN_PROGRESS = 1; 248 PC++; 249 }) 250