Home | History | Annotate | Line # | Download | only in pru
      1 /* Copyright 2016-2024 Free Software Foundation, Inc.
      2    Contributed by Dimitar Dimitrov <dimitar (at) 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 
     26 INSTRUCTION (add,
     27 	     OP2 = (IO ? IMM8 : RS2);
     28 	     RD = RS1 + OP2;
     29 	     CARRY = (((uint64_t) RS1 + (uint64_t) OP2) >> RD_WIDTH) & 1;
     30 	     PC++)
     31 
     32 INSTRUCTION (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 
     39 INSTRUCTION (sub,
     40 	     OP2 = (IO ? IMM8 : RS2);
     41 	     RD = RS1 - OP2;
     42 	     CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1;
     43 	     CARRY = !CARRY;
     44 	     PC++)
     45 
     46 INSTRUCTION (suc,
     47 	     OP2 = (IO ? IMM8 : RS2);
     48 	     RD = RS1 - OP2 - !CARRY;
     49 	     CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) !CARRY)
     50 		      >> RD_WIDTH) & 1;
     51 	     CARRY = !CARRY;
     52 	     PC++)
     53 
     54 INSTRUCTION (rsb,
     55 	     OP2 = (IO ? IMM8 : RS2);
     56 	     RD = OP2 - RS1;
     57 	     CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1;
     58 	     CARRY = !CARRY;
     59 	     PC++)
     60 
     61 INSTRUCTION (rsc,
     62 	     OP2 = (IO ? IMM8 : RS2);
     63 	     RD = OP2 - RS1 - !CARRY;
     64 	     CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) !CARRY)
     65 		      >> RD_WIDTH) & 1;
     66 	     CARRY = !CARRY;
     67 	     PC++)
     68 
     69 INSTRUCTION (lsl,
     70 	     OP2 = (IO ? IMM8 : RS2);
     71 	     RD = RS1 << (OP2 & 0x1f);
     72 	     PC++)
     73 
     74 INSTRUCTION (lsr,
     75 	     OP2 = (IO ? IMM8 : RS2);
     76 	     RD = RS1 >> (OP2 & 0x1f);
     77 	     PC++)
     78 
     79 INSTRUCTION (and,
     80 	     OP2 = (IO ? IMM8 : RS2);
     81 	     RD = RS1 & OP2;
     82 	     PC++)
     83 
     84 INSTRUCTION (or,
     85 	     OP2 = (IO ? IMM8 : RS2);
     86 	     RD = RS1 | OP2;
     87 	     PC++)
     88 
     89 INSTRUCTION (xor,
     90 	     OP2 = (IO ? IMM8 : RS2);
     91 	     RD = RS1 ^ OP2;
     92 	     PC++)
     93 
     94 INSTRUCTION (not,
     95 	     RD = ~RS1;
     96 	     PC++)
     97 
     98 INSTRUCTION (min,
     99 	     OP2 = (IO ? IMM8 : RS2);
    100 	     RD = RS1 < OP2 ? RS1 : OP2;
    101 	     PC++)
    102 
    103 INSTRUCTION (max,
    104 	     OP2 = (IO ? IMM8 : RS2);
    105 	     RD = RS1 > OP2 ? RS1 : OP2;
    106 	     PC++)
    107 
    108 INSTRUCTION (clr,
    109 	     OP2 = (IO ? IMM8 : RS2);
    110 	     RD = RS1 & ~(1u << (OP2 & 0x1f));
    111 	     PC++)
    112 
    113 INSTRUCTION (set,
    114 	     OP2 = (IO ? IMM8 : RS2);
    115 	     RD = RS1 | (1u << (OP2 & 0x1f));
    116 	     PC++)
    117 
    118 INSTRUCTION (jmp,
    119 	     OP2 = (IO ? IMM16 : RS2);
    120 	     PC = OP2)
    121 
    122 INSTRUCTION (jal,
    123 	     OP2 = (IO ? IMM16 : RS2);
    124 	     RD = PC + 1;
    125 	     PC = OP2)
    126 
    127 INSTRUCTION (ldi,
    128 	     RD = IMM16;
    129 	     PC++)
    130 
    131 INSTRUCTION (halt,
    132 	     pru_sim_syscall (sd, cpu);
    133 	     PC++)
    134 
    135 INSTRUCTION (slp,
    136 	     if (!WAKEONSTATUS)
    137 	      {
    138 		RAISE_SIGINT (sd);
    139 	      }
    140 	     else
    141 	      {
    142 		PC++;
    143 	      })
    144 
    145 INSTRUCTION (qbgt,
    146 	     OP2 = (IO ? IMM8 : RS2);
    147 	     PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1))
    148 
    149 INSTRUCTION (qbge,
    150 	     OP2 = (IO ? IMM8 : RS2);
    151 	     PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1))
    152 
    153 INSTRUCTION (qblt,
    154 	     OP2 = (IO ? IMM8 : RS2);
    155 	     PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1))
    156 
    157 INSTRUCTION (qble,
    158 	     OP2 = (IO ? IMM8 : RS2);
    159 	     PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1))
    160 
    161 INSTRUCTION (qbeq,
    162 	     OP2 = (IO ? IMM8 : RS2);
    163 	     PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1))
    164 
    165 INSTRUCTION (qbne,
    166 	     OP2 = (IO ? IMM8 : RS2);
    167 	     PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1))
    168 
    169 INSTRUCTION (qba,
    170 	     OP2 = (IO ? IMM8 : RS2);
    171 	     PC = PC + BROFF)
    172 
    173 INSTRUCTION (qbbs,
    174 	     OP2 = (IO ? IMM8 : RS2);
    175 	     PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
    176 
    177 INSTRUCTION (qbbc,
    178 	     OP2 = (IO ? IMM8 : RS2);
    179 	     PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
    180 
    181 INSTRUCTION (lbbo,
    182 	     pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
    183 			   BURSTLEN, RD_REGN, RDB);
    184 	     PC++)
    185 
    186 INSTRUCTION (sbbo,
    187 	     pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
    188 			   BURSTLEN, RD_REGN, RDB);
    189 	     PC++)
    190 
    191 INSTRUCTION (lbco,
    192 	     pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
    193 			   BURSTLEN, RD_REGN, RDB);
    194 	     PC++)
    195 
    196 INSTRUCTION (sbco,
    197 	     pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
    198 			   BURSTLEN, RD_REGN, RDB);
    199 	     PC++)
    200 
    201 INSTRUCTION (xin,
    202 	     DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
    203 	     PC++)
    204 
    205 INSTRUCTION (xout,
    206 	     DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
    207 	     PC++)
    208 
    209 INSTRUCTION (xchg,
    210 	     DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
    211 	     PC++)
    212 
    213 INSTRUCTION (sxin,
    214 	     sim_io_eprintf (sd, "SXIN instruction not supported by sim\n");
    215 	     RAISE_SIGILL (sd))
    216 
    217 INSTRUCTION (sxout,
    218 	     sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n");
    219 	     RAISE_SIGILL (sd))
    220 
    221 INSTRUCTION (sxchg,
    222 	     sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n");
    223 	     RAISE_SIGILL (sd))
    224 
    225 INSTRUCTION (loop,
    226 	     OP2 = (IO ? IMM8 + 1 : RS2_w0);
    227 	     if (OP2 == 0)
    228 	      {
    229 		PC = PC + LOOP_JMPOFFS;
    230 	      }
    231 	     else
    232 	      {
    233 		LOOPTOP = PC + 1;
    234 		LOOPEND = PC + LOOP_JMPOFFS;
    235 		LOOPCNT = OP2;
    236 		LOOP_IN_PROGRESS = 1;
    237 		PC++;
    238 	     })
    239 
    240 INSTRUCTION (iloop,
    241 	     OP2 = (IO ? IMM8 + 1 : RS2_w0);
    242 	     if (OP2 == 0)
    243 	      {
    244 		PC = PC + LOOP_JMPOFFS;
    245 	      }
    246 	     else
    247 	      {
    248 		LOOPTOP = PC + 1;
    249 		LOOPEND = PC + LOOP_JMPOFFS;
    250 		LOOPCNT = OP2;
    251 		LOOP_IN_PROGRESS = 1;
    252 		PC++;
    253 	     })
    254 
    255 INSTRUCTION (lmbd,
    256 	     {
    257 	     int lmbd_i;
    258 
    259 	     OP2 = (IO ? IMM8 : RS2);
    260 
    261 	     for (lmbd_i = RS1_WIDTH - 1; lmbd_i >= 0; lmbd_i--)
    262 	       {
    263 		 if (!(((RS1 >> lmbd_i) ^ OP2) & 1))
    264 		   break;
    265 	       }
    266 	     RD = (lmbd_i < 0) ? 32 : lmbd_i;
    267 	     PC++;
    268 	     })
    269