1/* Copyright 2009-2013 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	    C_wr(CARRY);
114	    PC += INST_SIZE)
115
116INSTRUCTION(rsubi,
117	    0x09,
118	    INST_TYPE_RD_RA_IMM,
119            CARRY = C_calc(IMM, ~RA, 1);
120	    RD = IMM + ~RA + 1;
121            C_wr(CARRY);
122	    PC += INST_SIZE)
123
124INSTRUCTION(addic,
125	    0x0A,
126            INST_TYPE_RD_RA_IMM,
127            CARRY = C_calc(RA, IMM, C_rd);
128	    RD = RA + IMM + C_rd;
129            C_wr(CARRY);
130	    PC += INST_SIZE)
131
132INSTRUCTION(rsubic,
133	    0x0B,
134            INST_TYPE_RD_RA_IMM,
135            CARRY = C_calc(IMM, ~RA, C_rd);
136	    RD = IMM + ~RA + C_rd;
137            C_wr(CARRY);
138	    PC += INST_SIZE)
139
140INSTRUCTION(addik,
141	    0x0C,
142            INST_TYPE_RD_RA_IMM,
143	    RD = RA + IMM;
144	    PC += INST_SIZE)
145
146INSTRUCTION(rsubik,
147	    0x0D,
148            INST_TYPE_RD_RA_IMM,
149	    RD = IMM + ~RA + 1;
150	    PC += INST_SIZE)
151
152INSTRUCTION(addikc,
153	    0x0E,
154            INST_TYPE_RD_RA_IMM,
155	    RD = RA + IMM + C_rd;
156	    PC += INST_SIZE)
157
158INSTRUCTION(rsubikc,
159	    0x0F,
160            INST_TYPE_RD_RA_IMM,
161            RD = IMM + ~RA + C_rd;
162	    PC += INST_SIZE)
163
164INSTRUCTION(mul,
165	    0x10,
166            INST_TYPE_RD_RA_RB,
167	    RD = RA * RB;
168	    PC += INST_SIZE)
169
170INSTRUCTION(bsrl,
171	    0x11,
172	    INST_TYPE_RD_RA_RB,
173	    RD = (uword)RA >> RB;
174	    PC += INST_SIZE)
175
176INSTRUCTION(bsra,
177	    0x11,
178	    INST_TYPE_RD_RA_RB,
179	    RD = (word)RA >> RB;
180	    PC += INST_SIZE)
181
182INSTRUCTION(bsll,
183	    0x11,
184	    INST_TYPE_RD_RA_RB,
185	    RD = (uword)RA << RB;
186	    PC += INST_SIZE)
187
188INSTRUCTION(idiv,
189	    0x12,
190	    INST_TYPE_RD_RA_RB,
191	    RD = (word) RB / (word) RA;
192	    PC += INST_SIZE)
193
194INSTRUCTION(idivu,
195	    0x12,
196	    INST_TYPE_RD_RA_RB,
197	    RD = (uword) RB / (uword) RA;
198	    PC += INST_SIZE)
199
200INSTRUCTION(muli,
201	    0x18,
202            INST_TYPE_RD_RA_IMM,
203	    RD = RA * IMM;
204	    PC += INST_SIZE)
205
206INSTRUCTION(bsrli,
207	    0x19,
208	    INST_TYPE_RD_RA_IMM5,
209	    RD = (uword)RA >> (IMM & 0x1F);
210	    PC += INST_SIZE)
211
212INSTRUCTION(bsrai,
213	    0x19,
214	    INST_TYPE_RD_RA_IMM5,
215	    RD = (word)RA >> (IMM & 0x1F);
216	    PC += INST_SIZE)
217
218INSTRUCTION(bslli,
219	    0x19,
220	    INST_TYPE_RD_RA_IMM5,
221	    RD = (uword)RA << (IMM & 0x1F);
222	    PC += INST_SIZE)
223
224INSTRUCTION(get,
225            0x1b,
226            INST_TYPE_RD_IMM12,
227            PC += INST_SIZE)
228
229INSTRUCTION(put,
230            0x1b,
231            INST_TYPE_R1_IMM12,
232            PC += INST_SIZE)
233
234INSTRUCTION(nget,
235            0x1b,
236            INST_TYPE_RD_IMM12,
237            PC += INST_SIZE)
238
239INSTRUCTION(nput,
240            0x1b,
241            INST_TYPE_R1_IMM12,
242            PC += INST_SIZE)
243
244INSTRUCTION(cget,
245            0x1b,
246            INST_TYPE_RD_IMM12,
247            PC += INST_SIZE)
248
249INSTRUCTION(cput,
250            0x1b,
251            INST_TYPE_R1_IMM12,
252            PC += INST_SIZE)
253
254INSTRUCTION(ncget,
255            0x1b,
256            INST_TYPE_RD_IMM12,
257            PC += INST_SIZE)
258
259INSTRUCTION(ncput,
260            0x1b,
261            INST_TYPE_R1_IMM12,
262            PC += INST_SIZE)
263
264INSTRUCTION(or,
265	    0x20,
266            INST_TYPE_RD_RA_RB,
267	    RD = RA | RB;
268	    PC += INST_SIZE)
269
270INSTRUCTION(and,
271	    0x21,
272            INST_TYPE_RD_RA_RB,
273	    RD = RA & RB;
274	    PC += INST_SIZE)
275
276INSTRUCTION(xor,
277	    0x22,
278            INST_TYPE_RD_RA_RB,
279	    RD = RA ^ RB;
280	    PC += INST_SIZE)
281
282INSTRUCTION(andn,
283	    0x23,
284            INST_TYPE_RD_RA_RB,
285	    RD = RA & ~RB;
286	    PC += INST_SIZE)
287
288INSTRUCTION(sra,
289	    0x24,
290	    INST_TYPE_RD_RA,
291	    CARRY = (RA & 0x1);
292	    RD = (int) (RA >> 1);
293	    C_wr(CARRY);
294	    PC += INST_SIZE)
295
296INSTRUCTION(src,
297	    0x24,
298            INST_TYPE_RD_RA,
299	    CARRY = (RA & 0x1);
300            RD = ((((int) (RA >> 1)) & 0x7FFFFFFF) | (uword)(C_rd << 31));
301            C_wr(CARRY);
302	    PC += INST_SIZE)
303
304INSTRUCTION(srl,
305	    0x24,
306            INST_TYPE_RD_RA,
307            CARRY = (RA & 0x1);
308	    RD = (uword) ((RA >> 1) & 0x7FFFFFFF);
309            C_wr(CARRY);
310	    PC += INST_SIZE)
311
312INSTRUCTION(sext8,
313	    0x24,
314            INST_TYPE_RD_RA,
315	    RD = MICROBLAZE_SEXT8(RA);
316	    PC += INST_SIZE)
317
318INSTRUCTION(sext16,
319            0x24,
320            INST_TYPE_RD_RA,
321	    RD = MICROBLAZE_SEXT16(RA);
322            PC += INST_SIZE)
323
324INSTRUCTION(wdc,
325            0x24,
326            INST_TYPE_RA_RB,
327            PC += INST_SIZE)
328
329INSTRUCTION(wic,
330            0x24,
331            INST_TYPE_RA_RB,
332            PC += INST_SIZE)
333
334INSTRUCTION(mts,
335	    0x25,
336	    INST_TYPE_SA_RA,
337	    SA = RA;
338	    PC += INST_SIZE)
339
340INSTRUCTION(mfs,
341	    0x25,
342            INST_TYPE_RD_SA,
343	    RD = SA;
344	    PC += INST_SIZE)
345
346INSTRUCTION(br,
347	    0x26,
348	    INST_TYPE_RB,
349	    PC += RB;
350	    BRANCH)
351
352INSTRUCTION(brd,
353            0x26,
354            INST_TYPE_RB,
355            PC += RB;
356	    BRANCH;
357            DELAY_SLOT)
358
359INSTRUCTION(brld,
360	    0x26,
361	    INST_TYPE_RD_RB,
362	    RD = PC;
363	    PC += RB;
364	    BRANCH;
365	    DELAY_SLOT)
366
367INSTRUCTION(bra,
368	    0x26,
369            INST_TYPE_RB,
370	    PC = RB;
371	    BRANCH)
372
373INSTRUCTION(brad,
374            0x26,
375            INST_TYPE_RB,
376            PC = RB;
377	    BRANCH;
378            DELAY_SLOT)
379
380INSTRUCTION(brald,
381	    0x26,
382            INST_TYPE_RD_RB,
383	    RD = PC;
384	    PC = RB;
385	    BRANCH;
386	    DELAY_SLOT)
387
388INSTRUCTION(microblaze_brk,
389	    0x26,
390            INST_TYPE_RD_RB,
391	    RD = PC;
392	    PC = RB;
393            MSR = MSR | BIP_MASK;
394	    BRANCH)
395
396INSTRUCTION(beq,
397	    0x27,
398            INST_TYPE_RA_RB,
399	    if (RA == 0) {
400	      PC += RB;
401	      BRANCH;
402            } else {
403	      PC += INST_SIZE;
404	    })
405
406INSTRUCTION(beqd,
407            0x27,
408            INST_TYPE_RA_RB,
409            if (RA == 0) {
410	      PC += RB;
411	      BRANCH;
412	    } else {
413	      PC += INST_SIZE;
414	    }
415	    DELAY_SLOT)
416
417INSTRUCTION(bne,
418	    0x27,
419            INST_TYPE_RA_RB,
420	    if (RA != 0) {
421	      PC += RB;
422	      BRANCH;
423	    } else {
424	      PC += INST_SIZE;
425	    })
426
427INSTRUCTION(bned,
428            0x27,
429            INST_TYPE_RA_RB,
430            if (RA != 0) {
431	      PC += RB;
432	      BRANCH;
433	    } else {
434	      PC += INST_SIZE;
435	    }
436	    DELAY_SLOT)
437
438INSTRUCTION(blt,
439	    0x27,
440            INST_TYPE_RA_RB,
441	    if (RA < 0) {
442	      PC += RB;
443	      BRANCH;
444	    } else {
445	      PC += INST_SIZE;
446	    })
447
448INSTRUCTION(bltd,
449            0x27,
450            INST_TYPE_RA_RB,
451            if (RA < 0) {
452	      PC += RB;
453	      BRANCH;
454	    } else {
455	      PC += INST_SIZE;
456	    }
457	    DELAY_SLOT)
458
459INSTRUCTION(ble,
460	    0x27,
461            INST_TYPE_RA_RB,
462	    if (RA <= 0) {
463	      PC += RB;
464	      BRANCH;
465	    } else {
466	      PC += INST_SIZE;
467	    })
468
469INSTRUCTION(bled,
470            0x27,
471            INST_TYPE_RA_RB,
472            if (RA <= 0) {
473	      PC += RB;
474	      BRANCH;
475	    } else {
476	      PC += INST_SIZE;
477	    }
478	    DELAY_SLOT)
479
480INSTRUCTION(bgt,
481	    0x27,
482            INST_TYPE_RA_RB,
483	    if (RA > 0) {
484	      PC += RB;
485	      BRANCH;
486	    } else {
487	      PC += INST_SIZE;
488	    })
489
490INSTRUCTION(bgtd,
491            0x27,
492            INST_TYPE_RA_RB,
493            if (RA > 0) {
494	      PC += RB;
495	      BRANCH;
496	    } else {
497	      PC += INST_SIZE;
498	    }
499	    DELAY_SLOT)
500
501INSTRUCTION(bge,
502	    0x27,
503            INST_TYPE_RA_RB,
504	    if (RA >= 0) {
505	      PC += RB;
506	      BRANCH;
507	    } else {
508	      PC += INST_SIZE;
509	    })
510
511INSTRUCTION(bged,
512            0x27,
513            INST_TYPE_RA_RB,
514            if (RA >= 0) {
515	      PC += RB;
516	      BRANCH;
517	    } else {
518	      PC += INST_SIZE;
519	    }
520	    DELAY_SLOT)
521
522INSTRUCTION(ori,
523	    0x28,
524            INST_TYPE_RD_RA_IMM,
525	    RD = RA | IMM;
526	    PC += INST_SIZE)
527
528INSTRUCTION(andi,
529	    0x29,
530            INST_TYPE_RD_RA_IMM,
531	    RD = RA & IMM;
532	    PC += INST_SIZE)
533
534INSTRUCTION(xori,
535	    0x2A,
536            INST_TYPE_RD_RA_IMM,
537	    RD = RA ^ IMM;
538	    PC += INST_SIZE)
539
540INSTRUCTION(andni,
541	    0x2B,
542            INST_TYPE_RD_RA_IMM,
543	    RD = RA & ~IMM;
544	    PC += INST_SIZE)
545
546INSTRUCTION(imm,
547	    0x2C,
548	    INST_TYPE_IMM,
549	    IMM_H = IMM_L;
550	    PC += INST_SIZE)
551
552INSTRUCTION(rtsd,
553	    0x2D,
554            INST_TYPE_RA_IMM,
555	    PC = RA + IMM;
556    	    BRANCH;
557	    DELAY_SLOT)
558
559INSTRUCTION(rtid,
560	    0x2D,
561            INST_TYPE_RA_IMM,
562	    PC = RA + IMM;
563	    MSR = MSR | INTR_EN_MASK;
564	    BRANCH;
565	    DELAY_SLOT)
566
567INSTRUCTION(rtbd,
568	    0x2D,
569	    INST_TYPE_RA_IMM,
570	    PC = RA + IMM;
571	    MSR = MSR & ~BIP_MASK;
572	    BRANCH;
573            DELAY_SLOT;)
574
575INSTRUCTION(bri,
576	    0x2E,
577            INST_TYPE_IMM,
578	    PC += IMM;
579	    BRANCH)
580
581INSTRUCTION(brid,
582            0x2E,
583            INST_TYPE_IMM,
584            PC += IMM;
585	    BRANCH;
586            DELAY_SLOT)
587
588INSTRUCTION(brlid,
589	    0x2E,
590            INST_TYPE_RD_IMM,
591	    RD = PC;
592	    PC += IMM;
593	    BRANCH;
594	    DELAY_SLOT)
595
596INSTRUCTION(brai,
597	    0x2E,
598            INST_TYPE_IMM,
599	    PC = IMM;
600	    BRANCH)
601
602INSTRUCTION(braid,
603            0x2E,
604            INST_TYPE_IMM,
605            PC = IMM;
606	    BRANCH;
607            DELAY_SLOT)
608
609INSTRUCTION(bralid,
610	    0x2E,
611	    INST_TYPE_RD_IMM,
612	    RD = PC;
613	    PC = IMM;
614	    BRANCH;
615	    DELAY_SLOT)
616
617INSTRUCTION(brki,
618	    0x2E,
619            INST_TYPE_RD_IMM,
620	    RD = PC;
621	    PC = IMM;
622            MSR = MSR | BIP_MASK;
623	    BRANCH)
624
625INSTRUCTION(beqi,
626	    0x2F,
627            INST_TYPE_RA_IMM,
628	    if (RA == 0) {
629	      PC += IMM;
630	      BRANCH;
631	    } else {
632	      PC += INST_SIZE;
633	    })
634
635INSTRUCTION(beqid,
636            0x2F,
637            INST_TYPE_RA_IMM,
638            if (RA == 0) {
639	      PC += IMM;
640	      BRANCH;
641	    } else {
642	      PC += INST_SIZE;
643	    }
644	    DELAY_SLOT)
645
646INSTRUCTION(bnei,
647	    0x2F,
648            INST_TYPE_RA_IMM,
649	    if (RA != 0) {
650	      PC += IMM;
651	      BRANCH;
652	    } else {
653	      PC += INST_SIZE;
654	    })
655
656INSTRUCTION(bneid,
657            0x2F,
658            INST_TYPE_RA_IMM,
659            if (RA != 0) {
660	      PC += IMM;
661	      BRANCH;
662	    } else {
663	      PC += INST_SIZE;
664	    }
665	    DELAY_SLOT)
666
667INSTRUCTION(blti,
668	    0x2F,
669            INST_TYPE_RA_IMM,
670	    if (RA < 0) {
671	      PC += IMM;
672	      BRANCH;
673	    } else {
674	      PC += INST_SIZE;
675	    })
676
677INSTRUCTION(bltid,
678            0x2F,
679            INST_TYPE_RA_IMM,
680            if (RA < 0) {
681	      PC += IMM;
682	      BRANCH;
683	    } else {
684	      PC += INST_SIZE;
685	    }
686	    DELAY_SLOT)
687
688INSTRUCTION(blei,
689	    0x2F,
690            INST_TYPE_RA_IMM,
691	    if (RA <= 0) {
692	      PC += IMM;
693	      BRANCH;
694	    } else {
695	      PC += INST_SIZE;
696	    })
697
698INSTRUCTION(bleid,
699            0x2F,
700            INST_TYPE_RA_IMM,
701            if (RA <= 0) {
702	      PC += IMM;
703	      BRANCH;
704	    } else {
705	      PC += INST_SIZE;
706	    }
707	    DELAY_SLOT)
708
709INSTRUCTION(bgti,
710	    0x2F,
711            INST_TYPE_RA_IMM,
712	    if (RA > 0) {
713	      PC += IMM;
714	      BRANCH;
715	    } else {
716	      PC += INST_SIZE;
717	    })
718
719INSTRUCTION(bgtid,
720            0x2F,
721            INST_TYPE_RA_IMM,
722            if (RA > 0) {
723	      PC += IMM;
724	      BRANCH;
725	    } else {
726	      PC += INST_SIZE;
727	    }
728	    DELAY_SLOT)
729
730INSTRUCTION(bgei,
731	    0x2F,
732            INST_TYPE_RA_IMM,
733	    if (RA >= 0) {
734	      PC += IMM;
735	      BRANCH;
736	    } else {
737	      PC += INST_SIZE;
738	    })
739
740INSTRUCTION(bgeid,
741            0x2F,
742            INST_TYPE_RA_IMM,
743            if (RA >= 0) {
744	      PC += IMM;
745	      BRANCH;
746	    } else {
747	      PC += INST_SIZE;
748	    }
749	    DELAY_SLOT)
750
751INSTRUCTION(lbu,
752	    0x30,
753            INST_TYPE_RD_RA_RB,
754	    RD = (MEM_RD_UBYTE(RA + RB));
755	    PC += INST_SIZE)
756
757INSTRUCTION(lhu,
758	    0x31,
759	    INST_TYPE_RD_RA_RB,
760	    RD = (MEM_RD_UHALF((RA + RB) & ~0x1));
761	    PC += INST_SIZE)
762
763INSTRUCTION(lw,
764	    0x32,
765            INST_TYPE_RD_RA_RB,
766	    RD = (MEM_RD_WORD((RA + RB) & ~0x3));
767	    PC += INST_SIZE)
768
769INSTRUCTION(sb,
770	    0x34,
771            INST_TYPE_RD_RA_RB,
772	    MEM_WR_BYTE(RA + RB, RD);
773	    PC += INST_SIZE)
774
775INSTRUCTION(sh,
776	    0x35,
777            INST_TYPE_RD_RA_RB,
778	    MEM_WR_HALF((RA + RB) & ~0x1, RD);
779	    PC += INST_SIZE)
780
781INSTRUCTION(sw,
782	    0x36,
783            INST_TYPE_RD_RA_RB,
784	    MEM_WR_WORD((RA + RB) & ~0x3, RD);
785	    PC += INST_SIZE)
786
787INSTRUCTION(lbui,
788	    0x38,
789            INST_TYPE_RD_RA_IMM,
790	    RD = (MEM_RD_UBYTE(RA + IMM));
791	    PC += INST_SIZE)
792
793INSTRUCTION(lhui,
794	    0x39,
795            INST_TYPE_RD_RA_IMM,
796	    RD = (MEM_RD_UHALF((RA+IMM) & ~0x1));
797	    PC += INST_SIZE)
798
799INSTRUCTION(lwi,
800	    0x3A,
801            INST_TYPE_RD_RA_IMM,
802	    RD = (MEM_RD_WORD((RA+IMM) & ~0x3));
803	    PC += INST_SIZE)
804
805INSTRUCTION(sbi,
806	    0x3C,
807            INST_TYPE_RD_RA_IMM,
808	    MEM_WR_BYTE(RA + IMM, RD);
809	    PC += INST_SIZE)
810
811INSTRUCTION(shi,
812	    0x3D,
813            INST_TYPE_RD_RA_IMM,
814	    MEM_WR_HALF((RA + IMM) & ~0x1, RD);
815	    PC += INST_SIZE)
816
817INSTRUCTION(swi,
818	    0x3E,
819            INST_TYPE_RD_RA_IMM,
820	    MEM_WR_WORD((RA + IMM) & ~0x3, RD);
821	    PC += INST_SIZE)
822