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