1/* Copyright 2009-2024 Free Software Foundation, Inc.
2
3   This file is part of the Xilinx MicroBlaze simulator.
4
5   This library is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
17
18/*
19 *  MICROBLAZE Instruction Set Architecture
20 *
21 *  INSTRUCTION(NAME,
22 *              OPCODE,
23 *              TYPE,
24 *              SEMANTICS)
25 *
26 */
27
28INSTRUCTION(add,
29              0x00,
30              INST_TYPE_RD_RA_RB,
31              CARRY = C_calc(RA, RB, 0);
32              RD = RA + RB;
33              C_wr(CARRY);
34              PC += INST_SIZE)
35
36INSTRUCTION(rsub,
37              0x01,
38            INST_TYPE_RD_RA_RB,
39              CARRY = C_calc(RB, ~RA, 1);
40              RD = RB + ~RA + 1;
41            C_wr(CARRY);
42              PC += INST_SIZE)
43
44INSTRUCTION(addc,
45              0x02,
46            INST_TYPE_RD_RA_RB,
47              CARRY = C_calc(RA, RB, C_rd);
48              RD = RA + RB + C_rd;
49              C_wr(CARRY);
50              PC += INST_SIZE)
51
52INSTRUCTION(rsubc,
53              0x03,
54            INST_TYPE_RD_RA_RB,
55              CARRY = C_calc(RB, ~RA, C_rd);
56              RD = RB + ~RA + C_rd;
57            C_wr(CARRY);
58              PC += INST_SIZE)
59
60INSTRUCTION(addk,
61              0x04,
62            INST_TYPE_RD_RA_RB,
63              RD = RA + RB;
64              PC += INST_SIZE)
65
66INSTRUCTION(rsubk,
67              0x05,
68            INST_TYPE_RD_RA_RB,
69              RD = RB + ~RA + 1;
70              PC += INST_SIZE)
71
72INSTRUCTION(cmp,
73            0x05,
74            INST_TYPE_RD_RA_RB,
75            {
76                int tmp_reg = RB + ~RA + 1;
77                if ((RB & 0x80000000) ^ (RA & 0x80000000)) {
78                    tmp_reg = ((tmp_reg & 0x7fffffff) | (RB & 0x80000000));
79                }
80                RD = tmp_reg;
81                PC += INST_SIZE;
82              })
83
84INSTRUCTION(cmpu,
85            0x05,
86            INST_TYPE_RD_RA_RB,
87            {
88                int tmp_reg = RB + ~RA + 1;
89                if ((RB & 0x80000000) ^ (RA & 0x80000000)) {
90                    tmp_reg = ((tmp_reg & 0x7fffffff) | (RA & 0x80000000));
91                }
92                RD = tmp_reg;
93                PC += INST_SIZE;
94              })
95
96INSTRUCTION(addkc,
97              0x06,
98            INST_TYPE_RD_RA_RB,
99              RD = RA + RB + C_rd;
100              PC += INST_SIZE)
101
102INSTRUCTION(rsubkc,
103              0x07,
104            INST_TYPE_RD_RA_RB,
105              RD = RB + ~RA + C_rd;
106              PC += INST_SIZE)
107
108INSTRUCTION(addi,
109              0x08,
110              INST_TYPE_RD_RA_IMM,
111            CARRY = C_calc(RA, IMM, 0);
112              RD = RA + IMM;
113              TRACE_REGISTER (cpu, "r%i = r%i + %i", rd, ra, IMM);
114              C_wr(CARRY);
115              PC += INST_SIZE)
116
117INSTRUCTION(rsubi,
118              0x09,
119              INST_TYPE_RD_RA_IMM,
120            CARRY = C_calc(IMM, ~RA, 1);
121              RD = IMM + ~RA + 1;
122            C_wr(CARRY);
123              PC += INST_SIZE)
124
125INSTRUCTION(addic,
126              0x0A,
127            INST_TYPE_RD_RA_IMM,
128            CARRY = C_calc(RA, IMM, C_rd);
129              RD = RA + IMM + C_rd;
130            C_wr(CARRY);
131              PC += INST_SIZE)
132
133INSTRUCTION(rsubic,
134              0x0B,
135            INST_TYPE_RD_RA_IMM,
136            CARRY = C_calc(IMM, ~RA, C_rd);
137              RD = IMM + ~RA + C_rd;
138            C_wr(CARRY);
139              PC += INST_SIZE)
140
141INSTRUCTION(addik,
142              0x0C,
143            INST_TYPE_RD_RA_IMM,
144              RD = RA + IMM;
145              PC += INST_SIZE)
146
147INSTRUCTION(rsubik,
148              0x0D,
149            INST_TYPE_RD_RA_IMM,
150              RD = IMM + ~RA + 1;
151              PC += INST_SIZE)
152
153INSTRUCTION(addikc,
154              0x0E,
155            INST_TYPE_RD_RA_IMM,
156              RD = RA + IMM + C_rd;
157              PC += INST_SIZE)
158
159INSTRUCTION(rsubikc,
160              0x0F,
161            INST_TYPE_RD_RA_IMM,
162            RD = IMM + ~RA + C_rd;
163              PC += INST_SIZE)
164
165INSTRUCTION(mul,
166              0x10,
167            INST_TYPE_RD_RA_RB,
168              RD = RA * RB;
169              PC += INST_SIZE)
170
171INSTRUCTION(bsrl,
172              0x11,
173              INST_TYPE_RD_RA_RB,
174              RD = (unsigned_4)RA >> RB;
175              PC += INST_SIZE)
176
177INSTRUCTION(bsra,
178              0x11,
179              INST_TYPE_RD_RA_RB,
180              RD = (signed_4)RA >> RB;
181              PC += INST_SIZE)
182
183INSTRUCTION(bsll,
184              0x11,
185              INST_TYPE_RD_RA_RB,
186              RD = (unsigned_4)RA << RB;
187              PC += INST_SIZE)
188
189INSTRUCTION(idiv,
190              0x12,
191              INST_TYPE_RD_RA_RB,
192              RD = (signed_4) RB / (signed_4) RA;
193              PC += INST_SIZE)
194
195INSTRUCTION(idivu,
196              0x12,
197              INST_TYPE_RD_RA_RB,
198              RD = (unsigned_4) RB / (unsigned_4) RA;
199              PC += INST_SIZE)
200
201INSTRUCTION(muli,
202              0x18,
203            INST_TYPE_RD_RA_IMM,
204              RD = RA * IMM;
205              PC += INST_SIZE)
206
207INSTRUCTION(bsrli,
208              0x19,
209              INST_TYPE_RD_RA_IMM5,
210              RD = (unsigned_4)RA >> (IMM & 0x1F);
211              PC += INST_SIZE)
212
213INSTRUCTION(bsrai,
214              0x19,
215              INST_TYPE_RD_RA_IMM5,
216              RD = (signed_4)RA >> (IMM & 0x1F);
217              PC += INST_SIZE)
218
219INSTRUCTION(bslli,
220              0x19,
221              INST_TYPE_RD_RA_IMM5,
222              RD = (unsigned_4)RA << (IMM & 0x1F);
223              PC += INST_SIZE)
224
225INSTRUCTION(get,
226            0x1b,
227            INST_TYPE_RD_IMM12,
228            PC += INST_SIZE)
229
230INSTRUCTION(put,
231            0x1b,
232            INST_TYPE_R1_IMM12,
233            PC += INST_SIZE)
234
235INSTRUCTION(nget,
236            0x1b,
237            INST_TYPE_RD_IMM12,
238            PC += INST_SIZE)
239
240INSTRUCTION(nput,
241            0x1b,
242            INST_TYPE_R1_IMM12,
243            PC += INST_SIZE)
244
245INSTRUCTION(cget,
246            0x1b,
247            INST_TYPE_RD_IMM12,
248            PC += INST_SIZE)
249
250INSTRUCTION(cput,
251            0x1b,
252            INST_TYPE_R1_IMM12,
253            PC += INST_SIZE)
254
255INSTRUCTION(ncget,
256            0x1b,
257            INST_TYPE_RD_IMM12,
258            PC += INST_SIZE)
259
260INSTRUCTION(ncput,
261            0x1b,
262            INST_TYPE_R1_IMM12,
263            PC += INST_SIZE)
264
265INSTRUCTION(microblaze_or,
266              0x20,
267            INST_TYPE_RD_RA_RB,
268              RD = RA | RB;
269              PC += INST_SIZE)
270
271INSTRUCTION(microblaze_and,
272              0x21,
273            INST_TYPE_RD_RA_RB,
274              RD = RA & RB;
275              PC += INST_SIZE)
276
277INSTRUCTION(microblaze_xor,
278              0x22,
279            INST_TYPE_RD_RA_RB,
280              RD = RA ^ RB;
281              PC += INST_SIZE)
282
283INSTRUCTION(andn,
284              0x23,
285            INST_TYPE_RD_RA_RB,
286              RD = RA & ~RB;
287              PC += INST_SIZE)
288
289INSTRUCTION(sra,
290              0x24,
291              INST_TYPE_RD_RA,
292              CARRY = (RA & 0x1);
293              RD = (int) (RA >> 1);
294              C_wr(CARRY);
295              PC += INST_SIZE)
296
297INSTRUCTION(src,
298              0x24,
299            INST_TYPE_RD_RA,
300              CARRY = (RA & 0x1);
301            RD = ((((int) (RA >> 1)) & 0x7FFFFFFF) | (unsigned_4)(C_rd << 31));
302            C_wr(CARRY);
303              PC += INST_SIZE)
304
305INSTRUCTION(srl,
306              0x24,
307            INST_TYPE_RD_RA,
308            CARRY = (RA & 0x1);
309              RD = (unsigned_4) ((RA >> 1) & 0x7FFFFFFF);
310            C_wr(CARRY);
311              PC += INST_SIZE)
312
313INSTRUCTION(sext8,
314              0x24,
315            INST_TYPE_RD_RA,
316              RD = MICROBLAZE_SEXT8(RA);
317              PC += INST_SIZE)
318
319INSTRUCTION(sext16,
320            0x24,
321            INST_TYPE_RD_RA,
322              RD = MICROBLAZE_SEXT16(RA);
323            PC += INST_SIZE)
324
325INSTRUCTION(wdc,
326            0x24,
327            INST_TYPE_RA_RB,
328            PC += INST_SIZE)
329
330INSTRUCTION(wic,
331            0x24,
332            INST_TYPE_RA_RB,
333            PC += INST_SIZE)
334
335INSTRUCTION(mts,
336              0x25,
337              INST_TYPE_SA_RA,
338              SA = RA;
339              PC += INST_SIZE)
340
341INSTRUCTION(mfs,
342              0x25,
343            INST_TYPE_RD_SA,
344              RD = SA;
345              PC += INST_SIZE)
346
347INSTRUCTION(br,
348              0x26,
349              INST_TYPE_RB,
350              PC += RB;
351              BRANCH)
352
353INSTRUCTION(brd,
354            0x26,
355            INST_TYPE_RB,
356            PC += RB;
357              BRANCH;
358            DELAY_SLOT)
359
360INSTRUCTION(brld,
361              0x26,
362              INST_TYPE_RD_RB,
363              RD = PC;
364              PC += RB;
365              BRANCH;
366              DELAY_SLOT)
367
368INSTRUCTION(bra,
369              0x26,
370            INST_TYPE_RB,
371              PC = RB;
372              BRANCH)
373
374INSTRUCTION(brad,
375            0x26,
376            INST_TYPE_RB,
377            PC = RB;
378              BRANCH;
379            DELAY_SLOT)
380
381INSTRUCTION(brald,
382              0x26,
383            INST_TYPE_RD_RB,
384              RD = PC;
385              PC = RB;
386              BRANCH;
387              DELAY_SLOT)
388
389INSTRUCTION(microblaze_brk,
390              0x26,
391            INST_TYPE_RD_RB,
392              RD = PC;
393              PC = RB;
394            MSR = MSR | BIP_MASK;
395              BRANCH)
396
397INSTRUCTION(beq,
398              0x27,
399            INST_TYPE_RA_RB,
400              if (RA == 0) {
401                PC += RB;
402                BRANCH;
403            } else {
404                PC += INST_SIZE;
405              })
406
407INSTRUCTION(beqd,
408            0x27,
409            INST_TYPE_RA_RB,
410            if (RA == 0) {
411                PC += RB;
412                BRANCH;
413              } else {
414                PC += INST_SIZE;
415              }
416              DELAY_SLOT)
417
418INSTRUCTION(bne,
419              0x27,
420            INST_TYPE_RA_RB,
421              if (RA != 0) {
422                PC += RB;
423                BRANCH;
424              } else {
425                PC += INST_SIZE;
426              })
427
428INSTRUCTION(bned,
429            0x27,
430            INST_TYPE_RA_RB,
431            if (RA != 0) {
432                PC += RB;
433                BRANCH;
434              } else {
435                PC += INST_SIZE;
436              }
437              DELAY_SLOT)
438
439INSTRUCTION(blt,
440              0x27,
441            INST_TYPE_RA_RB,
442              if (RA < 0) {
443                PC += RB;
444                BRANCH;
445              } else {
446                PC += INST_SIZE;
447              })
448
449INSTRUCTION(bltd,
450            0x27,
451            INST_TYPE_RA_RB,
452            if (RA < 0) {
453                PC += RB;
454                BRANCH;
455              } else {
456                PC += INST_SIZE;
457              }
458              DELAY_SLOT)
459
460INSTRUCTION(ble,
461              0x27,
462            INST_TYPE_RA_RB,
463              if (RA <= 0) {
464                PC += RB;
465                BRANCH;
466              } else {
467                PC += INST_SIZE;
468              })
469
470INSTRUCTION(bled,
471            0x27,
472            INST_TYPE_RA_RB,
473            if (RA <= 0) {
474                PC += RB;
475                BRANCH;
476              } else {
477                PC += INST_SIZE;
478              }
479              DELAY_SLOT)
480
481INSTRUCTION(bgt,
482              0x27,
483            INST_TYPE_RA_RB,
484              if (RA > 0) {
485                PC += RB;
486                BRANCH;
487              } else {
488                PC += INST_SIZE;
489              })
490
491INSTRUCTION(bgtd,
492            0x27,
493            INST_TYPE_RA_RB,
494            if (RA > 0) {
495                PC += RB;
496                BRANCH;
497              } else {
498                PC += INST_SIZE;
499              }
500              DELAY_SLOT)
501
502INSTRUCTION(bge,
503              0x27,
504            INST_TYPE_RA_RB,
505              if (RA >= 0) {
506                PC += RB;
507                BRANCH;
508              } else {
509                PC += INST_SIZE;
510              })
511
512INSTRUCTION(bged,
513            0x27,
514            INST_TYPE_RA_RB,
515            if (RA >= 0) {
516                PC += RB;
517                BRANCH;
518              } else {
519                PC += INST_SIZE;
520              }
521              DELAY_SLOT)
522
523INSTRUCTION(ori,
524              0x28,
525            INST_TYPE_RD_RA_IMM,
526              RD = RA | IMM;
527              PC += INST_SIZE)
528
529INSTRUCTION(andi,
530              0x29,
531            INST_TYPE_RD_RA_IMM,
532              RD = RA & IMM;
533              PC += INST_SIZE)
534
535INSTRUCTION(xori,
536              0x2A,
537            INST_TYPE_RD_RA_IMM,
538              RD = RA ^ IMM;
539              PC += INST_SIZE)
540
541INSTRUCTION(andni,
542              0x2B,
543            INST_TYPE_RD_RA_IMM,
544              RD = RA & ~IMM;
545              PC += INST_SIZE)
546
547INSTRUCTION(imm,
548              0x2C,
549              INST_TYPE_IMM,
550              IMM_H = IMM_L;
551              PC += INST_SIZE)
552
553INSTRUCTION(rtsd,
554              0x2D,
555            INST_TYPE_RA_IMM,
556              PC = RA + IMM;
557              BRANCH;
558              DELAY_SLOT)
559
560INSTRUCTION(rtid,
561              0x2D,
562            INST_TYPE_RA_IMM,
563              PC = RA + IMM;
564              MSR = MSR | INTR_EN_MASK;
565              BRANCH;
566              DELAY_SLOT)
567
568INSTRUCTION(rtbd,
569              0x2D,
570              INST_TYPE_RA_IMM,
571              PC = RA + IMM;
572              MSR = MSR & ~BIP_MASK;
573              BRANCH;
574            DELAY_SLOT;)
575
576INSTRUCTION(bri,
577              0x2E,
578            INST_TYPE_IMM,
579              PC += IMM;
580              BRANCH)
581
582INSTRUCTION(brid,
583            0x2E,
584            INST_TYPE_IMM,
585            PC += IMM;
586              BRANCH;
587            DELAY_SLOT)
588
589INSTRUCTION(brlid,
590              0x2E,
591            INST_TYPE_RD_IMM,
592              RD = PC;
593              PC += IMM;
594              BRANCH;
595              DELAY_SLOT)
596
597INSTRUCTION(brai,
598              0x2E,
599            INST_TYPE_IMM,
600              PC = IMM;
601              BRANCH)
602
603INSTRUCTION(braid,
604            0x2E,
605            INST_TYPE_IMM,
606            PC = IMM;
607              BRANCH;
608            DELAY_SLOT)
609
610INSTRUCTION(bralid,
611              0x2E,
612              INST_TYPE_RD_IMM,
613              RD = PC;
614              PC = IMM;
615              BRANCH;
616              DELAY_SLOT)
617
618INSTRUCTION(brki,
619              0x2E,
620            INST_TYPE_RD_IMM,
621              RD = PC;
622              PC = IMM;
623            MSR = MSR | BIP_MASK;
624              BRANCH)
625
626INSTRUCTION(beqi,
627              0x2F,
628            INST_TYPE_RA_IMM,
629              if (RA == 0) {
630                PC += IMM;
631                BRANCH;
632              } else {
633                PC += INST_SIZE;
634              })
635
636INSTRUCTION(beqid,
637            0x2F,
638            INST_TYPE_RA_IMM,
639            if (RA == 0) {
640                PC += IMM;
641                BRANCH;
642              } else {
643                PC += INST_SIZE;
644              }
645              DELAY_SLOT)
646
647INSTRUCTION(bnei,
648              0x2F,
649            INST_TYPE_RA_IMM,
650              if (RA != 0) {
651                PC += IMM;
652                BRANCH;
653              } else {
654                PC += INST_SIZE;
655              })
656
657INSTRUCTION(bneid,
658            0x2F,
659            INST_TYPE_RA_IMM,
660            if (RA != 0) {
661                PC += IMM;
662                BRANCH;
663              } else {
664                PC += INST_SIZE;
665              }
666              DELAY_SLOT)
667
668INSTRUCTION(blti,
669              0x2F,
670            INST_TYPE_RA_IMM,
671              if (RA < 0) {
672                PC += IMM;
673                BRANCH;
674              } else {
675                PC += INST_SIZE;
676              })
677
678INSTRUCTION(bltid,
679            0x2F,
680            INST_TYPE_RA_IMM,
681            if (RA < 0) {
682                PC += IMM;
683                BRANCH;
684              } else {
685                PC += INST_SIZE;
686              }
687              DELAY_SLOT)
688
689INSTRUCTION(blei,
690              0x2F,
691            INST_TYPE_RA_IMM,
692              if (RA <= 0) {
693                PC += IMM;
694                BRANCH;
695              } else {
696                PC += INST_SIZE;
697              })
698
699INSTRUCTION(bleid,
700            0x2F,
701            INST_TYPE_RA_IMM,
702            if (RA <= 0) {
703                PC += IMM;
704                BRANCH;
705              } else {
706                PC += INST_SIZE;
707              }
708              DELAY_SLOT)
709
710INSTRUCTION(bgti,
711              0x2F,
712            INST_TYPE_RA_IMM,
713              if (RA > 0) {
714                PC += IMM;
715                BRANCH;
716              } else {
717                PC += INST_SIZE;
718              })
719
720INSTRUCTION(bgtid,
721            0x2F,
722            INST_TYPE_RA_IMM,
723            if (RA > 0) {
724                PC += IMM;
725                BRANCH;
726              } else {
727                PC += INST_SIZE;
728              }
729              DELAY_SLOT)
730
731INSTRUCTION(bgei,
732              0x2F,
733            INST_TYPE_RA_IMM,
734              if (RA >= 0) {
735                PC += IMM;
736                BRANCH;
737              } else {
738                PC += INST_SIZE;
739              })
740
741INSTRUCTION(bgeid,
742            0x2F,
743            INST_TYPE_RA_IMM,
744            if (RA >= 0) {
745                PC += IMM;
746                BRANCH;
747              } else {
748                PC += INST_SIZE;
749              }
750              DELAY_SLOT)
751
752INSTRUCTION(lbu,
753              0x30,
754            INST_TYPE_RD_RA_RB,
755              RD = (MEM_RD_UBYTE(RA + RB));
756              PC += INST_SIZE)
757
758INSTRUCTION(lhu,
759              0x31,
760              INST_TYPE_RD_RA_RB,
761              RD = (MEM_RD_UHALF((RA + RB) & ~0x1));
762              PC += INST_SIZE)
763
764INSTRUCTION(lw,
765              0x32,
766            INST_TYPE_RD_RA_RB,
767              RD = (MEM_RD_WORD((RA + RB) & ~0x3));
768              PC += INST_SIZE)
769
770INSTRUCTION(sb,
771              0x34,
772            INST_TYPE_RD_RA_RB,
773              MEM_WR_BYTE(RA + RB, RD);
774              PC += INST_SIZE)
775
776INSTRUCTION(sh,
777              0x35,
778            INST_TYPE_RD_RA_RB,
779              MEM_WR_HALF((RA + RB) & ~0x1, RD);
780              PC += INST_SIZE)
781
782INSTRUCTION(sw,
783              0x36,
784            INST_TYPE_RD_RA_RB,
785              MEM_WR_WORD((RA + RB) & ~0x3, RD);
786              PC += INST_SIZE)
787
788INSTRUCTION(lbui,
789              0x38,
790            INST_TYPE_RD_RA_IMM,
791              RD = (MEM_RD_UBYTE(RA + IMM));
792              PC += INST_SIZE)
793
794INSTRUCTION(lhui,
795              0x39,
796            INST_TYPE_RD_RA_IMM,
797              RD = (MEM_RD_UHALF((RA+IMM) & ~0x1));
798              PC += INST_SIZE)
799
800INSTRUCTION(lwi,
801              0x3A,
802            INST_TYPE_RD_RA_IMM,
803              RD = (MEM_RD_WORD((RA+IMM) & ~0x3));
804              PC += INST_SIZE)
805
806INSTRUCTION(sbi,
807              0x3C,
808            INST_TYPE_RD_RA_IMM,
809              MEM_WR_BYTE(RA + IMM, RD);
810              PC += INST_SIZE)
811
812INSTRUCTION(shi,
813              0x3D,
814            INST_TYPE_RD_RA_IMM,
815              MEM_WR_HALF((RA + IMM) & ~0x1, RD);
816              PC += INST_SIZE)
817
818INSTRUCTION(swi,
819              0x3E,
820            INST_TYPE_RD_RA_IMM,
821              MEM_WR_WORD((RA + IMM) & ~0x3, RD);
822              PC += INST_SIZE)
823