123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /* Copyright 2016-2022 Free Software Foundation, Inc.
- Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
- This file is part of the PRU simulator.
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
- /*
- PRU Instruction Set Architecture
- INSTRUCTION (NAME,
- SEMANTICS)
- */
- INSTRUCTION (add,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 + OP2;
- CARRY = (((uint64_t) RS1 + (uint64_t) OP2) >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (adc,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 + OP2 + CARRY;
- CARRY = (((uint64_t) RS1 + (uint64_t) OP2 + (uint64_t) CARRY)
- >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (sub,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 - OP2;
- CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (suc,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 - OP2 - CARRY;
- CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) CARRY)
- >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (rsb,
- OP2 = (IO ? IMM8 : RS2);
- RD = OP2 - RS1;
- CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (rsc,
- OP2 = (IO ? IMM8 : RS2);
- RD = OP2 - RS1 - CARRY;
- CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) CARRY)
- >> RD_WIDTH) & 1;
- PC++)
- INSTRUCTION (lsl,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 << (OP2 & 0x1f);
- PC++)
- INSTRUCTION (lsr,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 >> (OP2 & 0x1f);
- PC++)
- INSTRUCTION (and,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 & OP2;
- PC++)
- INSTRUCTION (or,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 | OP2;
- PC++)
- INSTRUCTION (xor,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 ^ OP2;
- PC++)
- INSTRUCTION (not,
- RD = ~RS1;
- PC++)
- INSTRUCTION (min,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 < OP2 ? RS1 : OP2;
- PC++)
- INSTRUCTION (max,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 > OP2 ? RS1 : OP2;
- PC++)
- INSTRUCTION (clr,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 & ~(1u << (OP2 & 0x1f));
- PC++)
- INSTRUCTION (set,
- OP2 = (IO ? IMM8 : RS2);
- RD = RS1 | (1u << (OP2 & 0x1f));
- PC++)
- INSTRUCTION (jmp,
- OP2 = (IO ? IMM16 : RS2);
- PC = OP2)
- INSTRUCTION (jal,
- OP2 = (IO ? IMM16 : RS2);
- RD = PC + 1;
- PC = OP2)
- INSTRUCTION (ldi,
- RD = IMM16;
- PC++)
- INSTRUCTION (halt,
- pru_sim_syscall (sd, cpu);
- PC++)
- INSTRUCTION (slp,
- if (!WAKEONSTATUS)
- {
- RAISE_SIGINT (sd);
- }
- else
- {
- PC++;
- })
- INSTRUCTION (qbgt,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qbge,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qblt,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qble,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qbeq,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qbne,
- OP2 = (IO ? IMM8 : RS2);
- PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qba,
- OP2 = (IO ? IMM8 : RS2);
- PC = PC + BROFF)
- INSTRUCTION (qbbs,
- OP2 = (IO ? IMM8 : RS2);
- PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (qbbc,
- OP2 = (IO ? IMM8 : RS2);
- PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1))
- INSTRUCTION (lbbo,
- pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
- BURSTLEN, RD_REGN, RDB);
- PC++)
- INSTRUCTION (sbbo,
- pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2),
- BURSTLEN, RD_REGN, RDB);
- PC++)
- INSTRUCTION (lbco,
- pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
- BURSTLEN, RD_REGN, RDB);
- PC++)
- INSTRUCTION (sbco,
- pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2),
- BURSTLEN, RD_REGN, RDB);
- PC++)
- INSTRUCTION (xin,
- DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
- PC++)
- INSTRUCTION (xout,
- DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
- PC++)
- INSTRUCTION (xchg,
- DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH);
- PC++)
- INSTRUCTION (sxin,
- sim_io_eprintf (sd, "SXIN instruction not supported by sim\n");
- RAISE_SIGILL (sd))
- INSTRUCTION (sxout,
- sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n");
- RAISE_SIGILL (sd))
- INSTRUCTION (sxchg,
- sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n");
- RAISE_SIGILL (sd))
- INSTRUCTION (loop,
- OP2 = (IO ? IMM8 + 1 : RS2_w0);
- if (OP2 == 0)
- {
- PC = LOOPEND;
- }
- else
- {
- LOOPTOP = PC + 1;
- LOOPEND = PC + LOOP_JMPOFFS;
- LOOPCNT = OP2;
- LOOP_IN_PROGRESS = 1;
- PC++;
- })
- INSTRUCTION (iloop,
- OP2 = (IO ? IMM8 + 1 : RS2_w0);
- if (OP2 == 0)
- {
- PC = LOOPEND;
- }
- else
- {
- LOOPTOP = PC + 1;
- LOOPEND = PC + LOOP_JMPOFFS;
- LOOPCNT = OP2;
- LOOP_IN_PROGRESS = 1;
- PC++;
- })
- INSTRUCTION (lmbd,
- {
- int lmbd_i;
- OP2 = (IO ? IMM8 : RS2);
- for (lmbd_i = RS1_WIDTH - 1; lmbd_i >= 0; lmbd_i--)
- {
- if (!(((RS1 >> lmbd_i) ^ OP2) & 1))
- break;
- }
- RD = (lmbd_i < 0) ? 32 : lmbd_i;
- PC++;
- })
|