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