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