2002-03-12 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / mips.igen
1 // -*- C -*-
2 //
3 // <insn> ::=
4 // <insn-word> { "+" <insn-word> }
5 // ":" <format-name>
6 // ":" <filter-flags>
7 // ":" <options>
8 // ":" <name>
9 // <nl>
10 // { <insn-model> }
11 // { <insn-mnemonic> }
12 // <code-block>
13 //
14
15
16 // IGEN config - mips16
17 // :option:16::insn-bit-size:16
18 // :option:16::hi-bit-nr:15
19 :option:16::insn-specifying-widths:true
20 :option:16::gen-delayed-branch:false
21
22 // IGEN config - mips32/64..
23 // :option:32::insn-bit-size:32
24 // :option:32::hi-bit-nr:31
25 :option:32::insn-specifying-widths:true
26 :option:32::gen-delayed-branch:false
27
28
29 // Generate separate simulators for each target
30 // :option:::multi-sim:true
31
32
33 // Models known by this simulator are defined below.
34 //
35 // When placing models in the instruction descriptions, please place
36 // them one per line, in the order given here.
37
38 // MIPS ISAs:
39 //
40 // Instructions and related functions for these models are included in
41 // this file.
42 :model:::mipsI:mips3000:
43 :model:::mipsII:mips6000:
44 :model:::mipsIII:mips4000:
45 :model:::mipsIV:mips8000:
46 :model:::mipsV:mipsisaV:
47 :model:::mips32:mipsisa32:
48 :model:::mips64:mipsisa64:
49
50 // Vendor ISAs:
51 //
52 // Standard MIPS ISA instructions used for these models are listed here,
53 // as are functions needed by those standard instructions. Instructions
54 // which are model-dependent and which are not in the standard MIPS ISAs
55 // (or which pre-date or use different encodings than the standard
56 // instructions) are (for the most part) in separate .igen files.
57 :model:::vr4100:mips4100: // vr.igen
58 :model:::vr5000:mips5000:
59 :model:::r3900:mips3900: // tx.igen
60
61 // MIPS Application Specific Extensions (ASEs)
62 //
63 // Instructions for the ASEs are in separate .igen files.
64 :model:::mips16:mips16: // m16.igen (and m16.dc)
65
66
67 // Pseudo instructions known by IGEN
68 :internal::::illegal:
69 {
70 SignalException (ReservedInstruction, 0);
71 }
72
73
74 // Pseudo instructions known by interp.c
75 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
76 000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
77 "rsvd <OP>"
78 {
79 SignalException (ReservedInstruction, instruction_0);
80 }
81
82
83
84 // Helper:
85 //
86 // Simulate a 32 bit delayslot instruction
87 //
88
89 :function:::address_word:delayslot32:address_word target
90 {
91 instruction_word delay_insn;
92 sim_events_slip (SD, 1);
93 DSPC = CIA;
94 CIA = CIA + 4; /* NOTE not mips16 */
95 STATE |= simDELAYSLOT;
96 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
97 ENGINE_ISSUE_PREFIX_HOOK();
98 idecode_issue (CPU_, delay_insn, (CIA));
99 STATE &= ~simDELAYSLOT;
100 return target;
101 }
102
103 :function:::address_word:nullify_next_insn32:
104 {
105 sim_events_slip (SD, 1);
106 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
107 return CIA + 8;
108 }
109
110
111 // Helper:
112 //
113 // Calculate an effective address given a base and an offset.
114 //
115
116 :function:::address_word:loadstore_ea:address_word base, address_word offset
117 *mipsI:
118 *mipsII:
119 *mipsIII:
120 *mipsIV:
121 *mipsV:
122 *mips32:
123 *vr4100:
124 *vr5000:
125 *r3900:
126 {
127 return base + offset;
128 }
129
130 :function:::address_word:loadstore_ea:address_word base, address_word offset
131 *mips64:
132 {
133 #if 0 /* XXX FIXME: enable this only after some additional testing. */
134 /* If in user mode and UX is not set, use 32-bit compatibility effective
135 address computations as defined in the MIPS64 Architecture for
136 Programmers Volume III, Revision 0.95, section 4.9. */
137 if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX))
138 == (ksu_user << status_KSU_shift))
139 return (address_word)((signed32)base + (signed32)offset);
140 #endif
141 return base + offset;
142 }
143
144
145 // Helper:
146 //
147 // Check that an access to a HI/LO register meets timing requirements
148 //
149 // The following requirements exist:
150 //
151 // - A MT {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
152 // - A OP {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
153 // - A MF {HI,LO} read was not corrupted by a preceeding MT{LO,HI} update
154 // corruption occures when MT{LO,HI} is preceeded by a OP {HI,LO}.
155 //
156
157 :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
158 {
159 if (history->mf.timestamp + 3 > time)
160 {
161 sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
162 itable[MY_INDEX].name,
163 new, (long) CIA,
164 (long) history->mf.cia);
165 return 0;
166 }
167 return 1;
168 }
169
170 :function:::int:check_mt_hilo:hilo_history *history
171 *mipsI:
172 *mipsII:
173 *mipsIII:
174 *mipsIV:
175 *mipsV:
176 *vr4100:
177 *vr5000:
178 {
179 signed64 time = sim_events_time (SD);
180 int ok = check_mf_cycles (SD_, history, time, "MT");
181 history->mt.timestamp = time;
182 history->mt.cia = CIA;
183 return ok;
184 }
185
186 :function:::int:check_mt_hilo:hilo_history *history
187 *mips32:
188 *mips64:
189 *r3900:
190 {
191 signed64 time = sim_events_time (SD);
192 history->mt.timestamp = time;
193 history->mt.cia = CIA;
194 return 1;
195 }
196
197
198 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
199 *mipsI:
200 *mipsII:
201 *mipsIII:
202 *mipsIV:
203 *mipsV:
204 *mips32:
205 *mips64:
206 *vr4100:
207 *vr5000:
208 *r3900:
209 {
210 signed64 time = sim_events_time (SD);
211 int ok = 1;
212 if (peer != NULL
213 && peer->mt.timestamp > history->op.timestamp
214 && history->mt.timestamp < history->op.timestamp
215 && ! (history->mf.timestamp > history->op.timestamp
216 && history->mf.timestamp < peer->mt.timestamp)
217 && ! (peer->mf.timestamp > history->op.timestamp
218 && peer->mf.timestamp < peer->mt.timestamp))
219 {
220 /* The peer has been written to since the last OP yet we have
221 not */
222 sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
223 itable[MY_INDEX].name,
224 (long) CIA,
225 (long) history->op.cia,
226 (long) peer->mt.cia);
227 ok = 0;
228 }
229 history->mf.timestamp = time;
230 history->mf.cia = CIA;
231 return ok;
232 }
233
234
235
236 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
237 *mipsI:
238 *mipsII:
239 *mipsIII:
240 *mipsIV:
241 *mipsV:
242 *vr4100:
243 *vr5000:
244 {
245 signed64 time = sim_events_time (SD);
246 int ok = (check_mf_cycles (SD_, hi, time, "OP")
247 && check_mf_cycles (SD_, lo, time, "OP"));
248 hi->op.timestamp = time;
249 lo->op.timestamp = time;
250 hi->op.cia = CIA;
251 lo->op.cia = CIA;
252 return ok;
253 }
254
255 // The r3900 mult and multu insns _can_ be exectuted immediatly after
256 // a mf{hi,lo}
257 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
258 *mips32:
259 *mips64:
260 *r3900:
261 {
262 /* FIXME: could record the fact that a stall occured if we want */
263 signed64 time = sim_events_time (SD);
264 hi->op.timestamp = time;
265 lo->op.timestamp = time;
266 hi->op.cia = CIA;
267 lo->op.cia = CIA;
268 return 1;
269 }
270
271
272 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
273 *mipsI:
274 *mipsII:
275 *mipsIII:
276 *mipsIV:
277 *mipsV:
278 *mips32:
279 *mips64:
280 *vr4100:
281 *vr5000:
282 *r3900:
283 {
284 signed64 time = sim_events_time (SD);
285 int ok = (check_mf_cycles (SD_, hi, time, "OP")
286 && check_mf_cycles (SD_, lo, time, "OP"));
287 hi->op.timestamp = time;
288 lo->op.timestamp = time;
289 hi->op.cia = CIA;
290 lo->op.cia = CIA;
291 return ok;
292 }
293
294
295 // Helper:
296 //
297 // Check that the 64-bit instruction can currently be used, and signal
298 // a ReservedInstruction exception if not.
299 //
300
301 :function:::void:check_u64:instruction_word insn
302 *mipsIII:
303 *mipsIV:
304 *mipsV:
305 *vr4100:
306 *vr5000:
307 {
308 // The check should be similar to mips64 for any with PX/UX bit equivalents.
309 }
310
311 :function:::void:check_u64:instruction_word insn
312 *mips64:
313 {
314 #if 0 /* XXX FIXME: enable this only after some additional testing. */
315 if (UserMode && (SR & (status_UX|status_PX)) == 0)
316 SignalException (ReservedInstruction, insn);
317 #endif
318 }
319
320
321
322 //
323 // MIPS Architecture:
324 //
325 // CPU Instruction Set (mipsI - mipsV, mips32, mips64)
326 //
327
328
329
330 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
331 "add r<RD>, r<RS>, r<RT>"
332 *mipsI:
333 *mipsII:
334 *mipsIII:
335 *mipsIV:
336 *mipsV:
337 *mips32:
338 *mips64:
339 *vr4100:
340 *vr5000:
341 *r3900:
342 {
343 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
344 {
345 ALU32_BEGIN (GPR[RS]);
346 ALU32_ADD (GPR[RT]);
347 ALU32_END (GPR[RD]); /* This checks for overflow. */
348 }
349 TRACE_ALU_RESULT (GPR[RD]);
350 }
351
352
353
354 001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
355 "addi r<RT>, r<RS>, <IMMEDIATE>"
356 *mipsI:
357 *mipsII:
358 *mipsIII:
359 *mipsIV:
360 *mipsV:
361 *mips32:
362 *mips64:
363 *vr4100:
364 *vr5000:
365 *r3900:
366 {
367 TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
368 {
369 ALU32_BEGIN (GPR[RS]);
370 ALU32_ADD (EXTEND16 (IMMEDIATE));
371 ALU32_END (GPR[RT]); /* This checks for overflow. */
372 }
373 TRACE_ALU_RESULT (GPR[RT]);
374 }
375
376
377
378 :function:::void:do_addiu:int rs, int rt, unsigned16 immediate
379 {
380 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
381 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
382 TRACE_ALU_RESULT (GPR[rt]);
383 }
384
385 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
386 "addiu r<RT>, r<RS>, <IMMEDIATE>"
387 *mipsI:
388 *mipsII:
389 *mipsIII:
390 *mipsIV:
391 *mipsV:
392 *mips32:
393 *mips64:
394 *vr4100:
395 *vr5000:
396 *r3900:
397 {
398 do_addiu (SD_, RS, RT, IMMEDIATE);
399 }
400
401
402
403 :function:::void:do_addu:int rs, int rt, int rd
404 {
405 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
406 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
407 TRACE_ALU_RESULT (GPR[rd]);
408 }
409
410 000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
411 "addu r<RD>, r<RS>, r<RT>"
412 *mipsI:
413 *mipsII:
414 *mipsIII:
415 *mipsIV:
416 *mipsV:
417 *mips32:
418 *mips64:
419 *vr4100:
420 *vr5000:
421 *r3900:
422 {
423 do_addu (SD_, RS, RT, RD);
424 }
425
426
427
428 :function:::void:do_and:int rs, int rt, int rd
429 {
430 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
431 GPR[rd] = GPR[rs] & GPR[rt];
432 TRACE_ALU_RESULT (GPR[rd]);
433 }
434
435 000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
436 "and r<RD>, r<RS>, r<RT>"
437 *mipsI:
438 *mipsII:
439 *mipsIII:
440 *mipsIV:
441 *mipsV:
442 *mips32:
443 *mips64:
444 *vr4100:
445 *vr5000:
446 *r3900:
447 {
448 do_and (SD_, RS, RT, RD);
449 }
450
451
452
453 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
454 "andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
455 *mipsI:
456 *mipsII:
457 *mipsIII:
458 *mipsIV:
459 *mipsV:
460 *mips32:
461 *mips64:
462 *vr4100:
463 *vr5000:
464 *r3900:
465 {
466 TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
467 GPR[RT] = GPR[RS] & IMMEDIATE;
468 TRACE_ALU_RESULT (GPR[RT]);
469 }
470
471
472
473 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
474 "beq r<RS>, r<RT>, <OFFSET>"
475 *mipsI:
476 *mipsII:
477 *mipsIII:
478 *mipsIV:
479 *mipsV:
480 *mips32:
481 *mips64:
482 *vr4100:
483 *vr5000:
484 *r3900:
485 {
486 address_word offset = EXTEND16 (OFFSET) << 2;
487 check_branch_bug ();
488 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
489 {
490 mark_branch_bug (NIA+offset);
491 DELAY_SLOT (NIA + offset);
492 }
493 }
494
495
496
497 010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
498 "beql r<RS>, r<RT>, <OFFSET>"
499 *mipsII:
500 *mipsIII:
501 *mipsIV:
502 *mipsV:
503 *mips32:
504 *mips64:
505 *vr4100:
506 *vr5000:
507 *r3900:
508 {
509 address_word offset = EXTEND16 (OFFSET) << 2;
510 check_branch_bug ();
511 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
512 {
513 mark_branch_bug (NIA+offset);
514 DELAY_SLOT (NIA + offset);
515 }
516 else
517 NULLIFY_NEXT_INSTRUCTION ();
518 }
519
520
521
522 000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
523 "bgez r<RS>, <OFFSET>"
524 *mipsI:
525 *mipsII:
526 *mipsIII:
527 *mipsIV:
528 *mipsV:
529 *mips32:
530 *mips64:
531 *vr4100:
532 *vr5000:
533 *r3900:
534 {
535 address_word offset = EXTEND16 (OFFSET) << 2;
536 check_branch_bug ();
537 if ((signed_word) GPR[RS] >= 0)
538 {
539 mark_branch_bug (NIA+offset);
540 DELAY_SLOT (NIA + offset);
541 }
542 }
543
544
545
546 000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
547 "bgezal r<RS>, <OFFSET>"
548 *mipsI:
549 *mipsII:
550 *mipsIII:
551 *mipsIV:
552 *mipsV:
553 *mips32:
554 *mips64:
555 *vr4100:
556 *vr5000:
557 *r3900:
558 {
559 address_word offset = EXTEND16 (OFFSET) << 2;
560 check_branch_bug ();
561 RA = (CIA + 8);
562 if ((signed_word) GPR[RS] >= 0)
563 {
564 mark_branch_bug (NIA+offset);
565 DELAY_SLOT (NIA + offset);
566 }
567 }
568
569
570
571 000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
572 "bgezall r<RS>, <OFFSET>"
573 *mipsII:
574 *mipsIII:
575 *mipsIV:
576 *mipsV:
577 *mips32:
578 *mips64:
579 *vr4100:
580 *vr5000:
581 *r3900:
582 {
583 address_word offset = EXTEND16 (OFFSET) << 2;
584 check_branch_bug ();
585 RA = (CIA + 8);
586 /* NOTE: The branch occurs AFTER the next instruction has been
587 executed */
588 if ((signed_word) GPR[RS] >= 0)
589 {
590 mark_branch_bug (NIA+offset);
591 DELAY_SLOT (NIA + offset);
592 }
593 else
594 NULLIFY_NEXT_INSTRUCTION ();
595 }
596
597
598
599 000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
600 "bgezl r<RS>, <OFFSET>"
601 *mipsII:
602 *mipsIII:
603 *mipsIV:
604 *mipsV:
605 *mips32:
606 *mips64:
607 *vr4100:
608 *vr5000:
609 *r3900:
610 {
611 address_word offset = EXTEND16 (OFFSET) << 2;
612 check_branch_bug ();
613 if ((signed_word) GPR[RS] >= 0)
614 {
615 mark_branch_bug (NIA+offset);
616 DELAY_SLOT (NIA + offset);
617 }
618 else
619 NULLIFY_NEXT_INSTRUCTION ();
620 }
621
622
623
624 000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
625 "bgtz r<RS>, <OFFSET>"
626 *mipsI:
627 *mipsII:
628 *mipsIII:
629 *mipsIV:
630 *mipsV:
631 *mips32:
632 *mips64:
633 *vr4100:
634 *vr5000:
635 *r3900:
636 {
637 address_word offset = EXTEND16 (OFFSET) << 2;
638 check_branch_bug ();
639 if ((signed_word) GPR[RS] > 0)
640 {
641 mark_branch_bug (NIA+offset);
642 DELAY_SLOT (NIA + offset);
643 }
644 }
645
646
647
648 010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
649 "bgtzl r<RS>, <OFFSET>"
650 *mipsII:
651 *mipsIII:
652 *mipsIV:
653 *mipsV:
654 *mips32:
655 *mips64:
656 *vr4100:
657 *vr5000:
658 *r3900:
659 {
660 address_word offset = EXTEND16 (OFFSET) << 2;
661 check_branch_bug ();
662 /* NOTE: The branch occurs AFTER the next instruction has been
663 executed */
664 if ((signed_word) GPR[RS] > 0)
665 {
666 mark_branch_bug (NIA+offset);
667 DELAY_SLOT (NIA + offset);
668 }
669 else
670 NULLIFY_NEXT_INSTRUCTION ();
671 }
672
673
674
675 000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
676 "blez r<RS>, <OFFSET>"
677 *mipsI:
678 *mipsII:
679 *mipsIII:
680 *mipsIV:
681 *mipsV:
682 *mips32:
683 *mips64:
684 *vr4100:
685 *vr5000:
686 *r3900:
687 {
688 address_word offset = EXTEND16 (OFFSET) << 2;
689 check_branch_bug ();
690 /* NOTE: The branch occurs AFTER the next instruction has been
691 executed */
692 if ((signed_word) GPR[RS] <= 0)
693 {
694 mark_branch_bug (NIA+offset);
695 DELAY_SLOT (NIA + offset);
696 }
697 }
698
699
700
701 010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
702 "bgezl r<RS>, <OFFSET>"
703 *mipsII:
704 *mipsIII:
705 *mipsIV:
706 *mipsV:
707 *mips32:
708 *mips64:
709 *vr4100:
710 *vr5000:
711 *r3900:
712 {
713 address_word offset = EXTEND16 (OFFSET) << 2;
714 check_branch_bug ();
715 if ((signed_word) GPR[RS] <= 0)
716 {
717 mark_branch_bug (NIA+offset);
718 DELAY_SLOT (NIA + offset);
719 }
720 else
721 NULLIFY_NEXT_INSTRUCTION ();
722 }
723
724
725
726 000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
727 "bltz r<RS>, <OFFSET>"
728 *mipsI:
729 *mipsII:
730 *mipsIII:
731 *mipsIV:
732 *mipsV:
733 *mips32:
734 *mips64:
735 *vr4100:
736 *vr5000:
737 *r3900:
738 {
739 address_word offset = EXTEND16 (OFFSET) << 2;
740 check_branch_bug ();
741 if ((signed_word) GPR[RS] < 0)
742 {
743 mark_branch_bug (NIA+offset);
744 DELAY_SLOT (NIA + offset);
745 }
746 }
747
748
749
750 000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
751 "bltzal r<RS>, <OFFSET>"
752 *mipsI:
753 *mipsII:
754 *mipsIII:
755 *mipsIV:
756 *mipsV:
757 *mips32:
758 *mips64:
759 *vr4100:
760 *vr5000:
761 *r3900:
762 {
763 address_word offset = EXTEND16 (OFFSET) << 2;
764 check_branch_bug ();
765 RA = (CIA + 8);
766 /* NOTE: The branch occurs AFTER the next instruction has been
767 executed */
768 if ((signed_word) GPR[RS] < 0)
769 {
770 mark_branch_bug (NIA+offset);
771 DELAY_SLOT (NIA + offset);
772 }
773 }
774
775
776
777 000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
778 "bltzall r<RS>, <OFFSET>"
779 *mipsII:
780 *mipsIII:
781 *mipsIV:
782 *mipsV:
783 *mips32:
784 *mips64:
785 *vr4100:
786 *vr5000:
787 *r3900:
788 {
789 address_word offset = EXTEND16 (OFFSET) << 2;
790 check_branch_bug ();
791 RA = (CIA + 8);
792 if ((signed_word) GPR[RS] < 0)
793 {
794 mark_branch_bug (NIA+offset);
795 DELAY_SLOT (NIA + offset);
796 }
797 else
798 NULLIFY_NEXT_INSTRUCTION ();
799 }
800
801
802
803 000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
804 "bltzl r<RS>, <OFFSET>"
805 *mipsII:
806 *mipsIII:
807 *mipsIV:
808 *mipsV:
809 *mips32:
810 *mips64:
811 *vr4100:
812 *vr5000:
813 *r3900:
814 {
815 address_word offset = EXTEND16 (OFFSET) << 2;
816 check_branch_bug ();
817 /* NOTE: The branch occurs AFTER the next instruction has been
818 executed */
819 if ((signed_word) GPR[RS] < 0)
820 {
821 mark_branch_bug (NIA+offset);
822 DELAY_SLOT (NIA + offset);
823 }
824 else
825 NULLIFY_NEXT_INSTRUCTION ();
826 }
827
828
829
830 000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
831 "bne r<RS>, r<RT>, <OFFSET>"
832 *mipsI:
833 *mipsII:
834 *mipsIII:
835 *mipsIV:
836 *mipsV:
837 *mips32:
838 *mips64:
839 *vr4100:
840 *vr5000:
841 *r3900:
842 {
843 address_word offset = EXTEND16 (OFFSET) << 2;
844 check_branch_bug ();
845 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
846 {
847 mark_branch_bug (NIA+offset);
848 DELAY_SLOT (NIA + offset);
849 }
850 }
851
852
853
854 010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
855 "bnel r<RS>, r<RT>, <OFFSET>"
856 *mipsII:
857 *mipsIII:
858 *mipsIV:
859 *mipsV:
860 *mips32:
861 *mips64:
862 *vr4100:
863 *vr5000:
864 *r3900:
865 {
866 address_word offset = EXTEND16 (OFFSET) << 2;
867 check_branch_bug ();
868 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
869 {
870 mark_branch_bug (NIA+offset);
871 DELAY_SLOT (NIA + offset);
872 }
873 else
874 NULLIFY_NEXT_INSTRUCTION ();
875 }
876
877
878
879 000000,20.CODE,001101:SPECIAL:32::BREAK
880 "break %#lx<CODE>"
881 *mipsI:
882 *mipsII:
883 *mipsIII:
884 *mipsIV:
885 *mipsV:
886 *mips32:
887 *mips64:
888 *vr4100:
889 *vr5000:
890 *r3900:
891 {
892 /* Check for some break instruction which are reserved for use by the simulator. */
893 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
894 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
895 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
896 {
897 sim_engine_halt (SD, CPU, NULL, cia,
898 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
899 }
900 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
901 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
902 {
903 if (STATE & simDELAYSLOT)
904 PC = cia - 4; /* reference the branch instruction */
905 else
906 PC = cia;
907 SignalException (BreakPoint, instruction_0);
908 }
909
910 else
911 {
912 /* If we get this far, we're not an instruction reserved by the sim. Raise
913 the exception. */
914 SignalException (BreakPoint, instruction_0);
915 }
916 }
917
918
919
920 011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO
921 "clo r<RD>, r<RS>"
922 *mips32:
923 *mips64:
924 {
925 unsigned32 temp = GPR[RS];
926 unsigned32 i, mask;
927 if (RT != RD)
928 Unpredictable();
929 TRACE_ALU_INPUT1 (GPR[RS]);
930 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
931 {
932 if ((temp & mask) == 0)
933 break;
934 mask >>= 1;
935 }
936 GPR[RD] = EXTEND32 (i);
937 TRACE_ALU_RESULT (GPR[RD]);
938 }
939
940
941
942 011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ
943 "clz r<RD>, r<RS>"
944 *mips32:
945 *mips64:
946 {
947 unsigned32 temp = GPR[RS];
948 unsigned32 i, mask;
949 if (RT != RD)
950 Unpredictable();
951 TRACE_ALU_INPUT1 (GPR[RS]);
952 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
953 {
954 if ((temp & mask) != 0)
955 break;
956 mask >>= 1;
957 }
958 GPR[RD] = EXTEND32 (i);
959 TRACE_ALU_RESULT (GPR[RD]);
960 }
961
962
963
964 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
965 "dadd r<RD>, r<RS>, r<RT>"
966 *mipsIII:
967 *mipsIV:
968 *mipsV:
969 *mips64:
970 *vr4100:
971 *vr5000:
972 {
973 check_u64 (SD_, instruction_0);
974 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
975 {
976 ALU64_BEGIN (GPR[RS]);
977 ALU64_ADD (GPR[RT]);
978 ALU64_END (GPR[RD]); /* This checks for overflow. */
979 }
980 TRACE_ALU_RESULT (GPR[RD]);
981 }
982
983
984
985 011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
986 "daddi r<RT>, r<RS>, <IMMEDIATE>"
987 *mipsIII:
988 *mipsIV:
989 *mipsV:
990 *mips64:
991 *vr4100:
992 *vr5000:
993 {
994 check_u64 (SD_, instruction_0);
995 TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
996 {
997 ALU64_BEGIN (GPR[RS]);
998 ALU64_ADD (EXTEND16 (IMMEDIATE));
999 ALU64_END (GPR[RT]); /* This checks for overflow. */
1000 }
1001 TRACE_ALU_RESULT (GPR[RT]);
1002 }
1003
1004
1005
1006 :function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
1007 {
1008 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
1009 GPR[rt] = GPR[rs] + EXTEND16 (immediate);
1010 TRACE_ALU_RESULT (GPR[rt]);
1011 }
1012
1013 011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
1014 "daddiu r<RT>, r<RS>, <IMMEDIATE>"
1015 *mipsIII:
1016 *mipsIV:
1017 *mipsV:
1018 *mips64:
1019 *vr4100:
1020 *vr5000:
1021 {
1022 check_u64 (SD_, instruction_0);
1023 do_daddiu (SD_, RS, RT, IMMEDIATE);
1024 }
1025
1026
1027
1028 :function:::void:do_daddu:int rs, int rt, int rd
1029 {
1030 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1031 GPR[rd] = GPR[rs] + GPR[rt];
1032 TRACE_ALU_RESULT (GPR[rd]);
1033 }
1034
1035 000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
1036 "daddu r<RD>, r<RS>, r<RT>"
1037 *mipsIII:
1038 *mipsIV:
1039 *mipsV:
1040 *mips64:
1041 *vr4100:
1042 *vr5000:
1043 {
1044 check_u64 (SD_, instruction_0);
1045 do_daddu (SD_, RS, RT, RD);
1046 }
1047
1048
1049
1050 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
1051 "dclo r<RD>, r<RS>"
1052 *mips64:
1053 {
1054 unsigned64 temp = GPR[RS];
1055 unsigned32 i;
1056 unsigned64 mask;
1057 check_u64 (SD_, instruction_0);
1058 if (RT != RD)
1059 Unpredictable();
1060 TRACE_ALU_INPUT1 (GPR[RS]);
1061 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
1062 {
1063 if ((temp & mask) == 0)
1064 break;
1065 mask >>= 1;
1066 }
1067 GPR[RD] = EXTEND32 (i);
1068 TRACE_ALU_RESULT (GPR[RD]);
1069 }
1070
1071
1072
1073 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
1074 "dclz r<RD>, r<RS>"
1075 *mips64:
1076 {
1077 unsigned64 temp = GPR[RS];
1078 unsigned32 i;
1079 unsigned64 mask;
1080 check_u64 (SD_, instruction_0);
1081 if (RT != RD)
1082 Unpredictable();
1083 TRACE_ALU_INPUT1 (GPR[RS]);
1084 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
1085 {
1086 if ((temp & mask) != 0)
1087 break;
1088 mask >>= 1;
1089 }
1090 GPR[RD] = EXTEND32 (i);
1091 TRACE_ALU_RESULT (GPR[RD]);
1092 }
1093
1094
1095
1096 :function:::void:do_ddiv:int rs, int rt
1097 {
1098 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1099 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1100 {
1101 signed64 n = GPR[rs];
1102 signed64 d = GPR[rt];
1103 signed64 hi;
1104 signed64 lo;
1105 if (d == 0)
1106 {
1107 lo = SIGNED64 (0x8000000000000000);
1108 hi = 0;
1109 }
1110 else if (d == -1 && n == SIGNED64 (0x8000000000000000))
1111 {
1112 lo = SIGNED64 (0x8000000000000000);
1113 hi = 0;
1114 }
1115 else
1116 {
1117 lo = (n / d);
1118 hi = (n % d);
1119 }
1120 HI = hi;
1121 LO = lo;
1122 }
1123 TRACE_ALU_RESULT2 (HI, LO);
1124 }
1125
1126 000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
1127 "ddiv r<RS>, r<RT>"
1128 *mipsIII:
1129 *mipsIV:
1130 *mipsV:
1131 *mips64:
1132 *vr4100:
1133 *vr5000:
1134 {
1135 check_u64 (SD_, instruction_0);
1136 do_ddiv (SD_, RS, RT);
1137 }
1138
1139
1140
1141 :function:::void:do_ddivu:int rs, int rt
1142 {
1143 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1144 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1145 {
1146 unsigned64 n = GPR[rs];
1147 unsigned64 d = GPR[rt];
1148 unsigned64 hi;
1149 unsigned64 lo;
1150 if (d == 0)
1151 {
1152 lo = SIGNED64 (0x8000000000000000);
1153 hi = 0;
1154 }
1155 else
1156 {
1157 lo = (n / d);
1158 hi = (n % d);
1159 }
1160 HI = hi;
1161 LO = lo;
1162 }
1163 TRACE_ALU_RESULT2 (HI, LO);
1164 }
1165
1166 000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
1167 "ddivu r<RS>, r<RT>"
1168 *mipsIII:
1169 *mipsIV:
1170 *mipsV:
1171 *mips64:
1172 *vr4100:
1173 *vr5000:
1174 {
1175 check_u64 (SD_, instruction_0);
1176 do_ddivu (SD_, RS, RT);
1177 }
1178
1179
1180
1181 :function:::void:do_div:int rs, int rt
1182 {
1183 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1184 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1185 {
1186 signed32 n = GPR[rs];
1187 signed32 d = GPR[rt];
1188 if (d == 0)
1189 {
1190 LO = EXTEND32 (0x80000000);
1191 HI = EXTEND32 (0);
1192 }
1193 else if (n == SIGNED32 (0x80000000) && d == -1)
1194 {
1195 LO = EXTEND32 (0x80000000);
1196 HI = EXTEND32 (0);
1197 }
1198 else
1199 {
1200 LO = EXTEND32 (n / d);
1201 HI = EXTEND32 (n % d);
1202 }
1203 }
1204 TRACE_ALU_RESULT2 (HI, LO);
1205 }
1206
1207 000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
1208 "div r<RS>, r<RT>"
1209 *mipsI:
1210 *mipsII:
1211 *mipsIII:
1212 *mipsIV:
1213 *mipsV:
1214 *mips32:
1215 *mips64:
1216 *vr4100:
1217 *vr5000:
1218 *r3900:
1219 {
1220 do_div (SD_, RS, RT);
1221 }
1222
1223
1224
1225 :function:::void:do_divu:int rs, int rt
1226 {
1227 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1228 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1229 {
1230 unsigned32 n = GPR[rs];
1231 unsigned32 d = GPR[rt];
1232 if (d == 0)
1233 {
1234 LO = EXTEND32 (0x80000000);
1235 HI = EXTEND32 (0);
1236 }
1237 else
1238 {
1239 LO = EXTEND32 (n / d);
1240 HI = EXTEND32 (n % d);
1241 }
1242 }
1243 TRACE_ALU_RESULT2 (HI, LO);
1244 }
1245
1246 000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
1247 "divu r<RS>, r<RT>"
1248 *mipsI:
1249 *mipsII:
1250 *mipsIII:
1251 *mipsIV:
1252 *mipsV:
1253 *mips32:
1254 *mips64:
1255 *vr4100:
1256 *vr5000:
1257 *r3900:
1258 {
1259 do_divu (SD_, RS, RT);
1260 }
1261
1262
1263
1264 :function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
1265 {
1266 unsigned64 lo;
1267 unsigned64 hi;
1268 unsigned64 m00;
1269 unsigned64 m01;
1270 unsigned64 m10;
1271 unsigned64 m11;
1272 unsigned64 mid;
1273 int sign;
1274 unsigned64 op1 = GPR[rs];
1275 unsigned64 op2 = GPR[rt];
1276 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1277 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1278 /* make signed multiply unsigned */
1279 sign = 0;
1280 if (signed_p)
1281 {
1282 if (op1 < 0)
1283 {
1284 op1 = - op1;
1285 ++sign;
1286 }
1287 if (op2 < 0)
1288 {
1289 op2 = - op2;
1290 ++sign;
1291 }
1292 }
1293 /* multiply out the 4 sub products */
1294 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
1295 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
1296 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
1297 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
1298 /* add the products */
1299 mid = ((unsigned64) VH4_8 (m00)
1300 + (unsigned64) VL4_8 (m10)
1301 + (unsigned64) VL4_8 (m01));
1302 lo = U8_4 (mid, m00);
1303 hi = (m11
1304 + (unsigned64) VH4_8 (mid)
1305 + (unsigned64) VH4_8 (m01)
1306 + (unsigned64) VH4_8 (m10));
1307 /* fix the sign */
1308 if (sign & 1)
1309 {
1310 lo = -lo;
1311 if (lo == 0)
1312 hi = -hi;
1313 else
1314 hi = -hi - 1;
1315 }
1316 /* save the result HI/LO (and a gpr) */
1317 LO = lo;
1318 HI = hi;
1319 if (rd != 0)
1320 GPR[rd] = lo;
1321 TRACE_ALU_RESULT2 (HI, LO);
1322 }
1323
1324 :function:::void:do_dmult:int rs, int rt, int rd
1325 {
1326 do_dmultx (SD_, rs, rt, rd, 1);
1327 }
1328
1329 000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
1330 "dmult r<RS>, r<RT>"
1331 *mipsIII:
1332 *mipsIV:
1333 *mipsV:
1334 *mips64:
1335 *vr4100:
1336 {
1337 check_u64 (SD_, instruction_0);
1338 do_dmult (SD_, RS, RT, 0);
1339 }
1340
1341 000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
1342 "dmult r<RS>, r<RT>":RD == 0
1343 "dmult r<RD>, r<RS>, r<RT>"
1344 *vr5000:
1345 {
1346 check_u64 (SD_, instruction_0);
1347 do_dmult (SD_, RS, RT, RD);
1348 }
1349
1350
1351
1352 :function:::void:do_dmultu:int rs, int rt, int rd
1353 {
1354 do_dmultx (SD_, rs, rt, rd, 0);
1355 }
1356
1357 000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
1358 "dmultu r<RS>, r<RT>"
1359 *mipsIII:
1360 *mipsIV:
1361 *mipsV:
1362 *mips64:
1363 *vr4100:
1364 {
1365 check_u64 (SD_, instruction_0);
1366 do_dmultu (SD_, RS, RT, 0);
1367 }
1368
1369 000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
1370 "dmultu r<RD>, r<RS>, r<RT>":RD == 0
1371 "dmultu r<RS>, r<RT>"
1372 *vr5000:
1373 {
1374 check_u64 (SD_, instruction_0);
1375 do_dmultu (SD_, RS, RT, RD);
1376 }
1377
1378 :function:::void:do_dsll:int rt, int rd, int shift
1379 {
1380 TRACE_ALU_INPUT2 (GPR[rt], shift);
1381 GPR[rd] = GPR[rt] << shift;
1382 TRACE_ALU_RESULT (GPR[rd]);
1383 }
1384
1385 000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
1386 "dsll r<RD>, r<RT>, <SHIFT>"
1387 *mipsIII:
1388 *mipsIV:
1389 *mipsV:
1390 *mips64:
1391 *vr4100:
1392 *vr5000:
1393 {
1394 check_u64 (SD_, instruction_0);
1395 do_dsll (SD_, RT, RD, SHIFT);
1396 }
1397
1398
1399 000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
1400 "dsll32 r<RD>, r<RT>, <SHIFT>"
1401 *mipsIII:
1402 *mipsIV:
1403 *mipsV:
1404 *mips64:
1405 *vr4100:
1406 *vr5000:
1407 {
1408 int s = 32 + SHIFT;
1409 check_u64 (SD_, instruction_0);
1410 TRACE_ALU_INPUT2 (GPR[RT], s);
1411 GPR[RD] = GPR[RT] << s;
1412 TRACE_ALU_RESULT (GPR[RD]);
1413 }
1414
1415 :function:::void:do_dsllv:int rs, int rt, int rd
1416 {
1417 int s = MASKED64 (GPR[rs], 5, 0);
1418 TRACE_ALU_INPUT2 (GPR[rt], s);
1419 GPR[rd] = GPR[rt] << s;
1420 TRACE_ALU_RESULT (GPR[rd]);
1421 }
1422
1423 000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
1424 "dsllv r<RD>, r<RT>, r<RS>"
1425 *mipsIII:
1426 *mipsIV:
1427 *mipsV:
1428 *mips64:
1429 *vr4100:
1430 *vr5000:
1431 {
1432 check_u64 (SD_, instruction_0);
1433 do_dsllv (SD_, RS, RT, RD);
1434 }
1435
1436 :function:::void:do_dsra:int rt, int rd, int shift
1437 {
1438 TRACE_ALU_INPUT2 (GPR[rt], shift);
1439 GPR[rd] = ((signed64) GPR[rt]) >> shift;
1440 TRACE_ALU_RESULT (GPR[rd]);
1441 }
1442
1443
1444 000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
1445 "dsra r<RD>, r<RT>, <SHIFT>"
1446 *mipsIII:
1447 *mipsIV:
1448 *mipsV:
1449 *mips64:
1450 *vr4100:
1451 *vr5000:
1452 {
1453 check_u64 (SD_, instruction_0);
1454 do_dsra (SD_, RT, RD, SHIFT);
1455 }
1456
1457
1458 000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
1459 "dsra32 r<RD>, r<RT>, <SHIFT>"
1460 *mipsIII:
1461 *mipsIV:
1462 *mipsV:
1463 *mips64:
1464 *vr4100:
1465 *vr5000:
1466 {
1467 int s = 32 + SHIFT;
1468 check_u64 (SD_, instruction_0);
1469 TRACE_ALU_INPUT2 (GPR[RT], s);
1470 GPR[RD] = ((signed64) GPR[RT]) >> s;
1471 TRACE_ALU_RESULT (GPR[RD]);
1472 }
1473
1474
1475 :function:::void:do_dsrav:int rs, int rt, int rd
1476 {
1477 int s = MASKED64 (GPR[rs], 5, 0);
1478 TRACE_ALU_INPUT2 (GPR[rt], s);
1479 GPR[rd] = ((signed64) GPR[rt]) >> s;
1480 TRACE_ALU_RESULT (GPR[rd]);
1481 }
1482
1483 000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
1484 "dsrav r<RD>, r<RT>, r<RS>"
1485 *mipsIII:
1486 *mipsIV:
1487 *mipsV:
1488 *mips64:
1489 *vr4100:
1490 *vr5000:
1491 {
1492 check_u64 (SD_, instruction_0);
1493 do_dsrav (SD_, RS, RT, RD);
1494 }
1495
1496 :function:::void:do_dsrl:int rt, int rd, int shift
1497 {
1498 TRACE_ALU_INPUT2 (GPR[rt], shift);
1499 GPR[rd] = (unsigned64) GPR[rt] >> shift;
1500 TRACE_ALU_RESULT (GPR[rd]);
1501 }
1502
1503
1504 000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
1505 "dsrl r<RD>, r<RT>, <SHIFT>"
1506 *mipsIII:
1507 *mipsIV:
1508 *mipsV:
1509 *mips64:
1510 *vr4100:
1511 *vr5000:
1512 {
1513 check_u64 (SD_, instruction_0);
1514 do_dsrl (SD_, RT, RD, SHIFT);
1515 }
1516
1517
1518 000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
1519 "dsrl32 r<RD>, r<RT>, <SHIFT>"
1520 *mipsIII:
1521 *mipsIV:
1522 *mipsV:
1523 *mips64:
1524 *vr4100:
1525 *vr5000:
1526 {
1527 int s = 32 + SHIFT;
1528 check_u64 (SD_, instruction_0);
1529 TRACE_ALU_INPUT2 (GPR[RT], s);
1530 GPR[RD] = (unsigned64) GPR[RT] >> s;
1531 TRACE_ALU_RESULT (GPR[RD]);
1532 }
1533
1534
1535 :function:::void:do_dsrlv:int rs, int rt, int rd
1536 {
1537 int s = MASKED64 (GPR[rs], 5, 0);
1538 TRACE_ALU_INPUT2 (GPR[rt], s);
1539 GPR[rd] = (unsigned64) GPR[rt] >> s;
1540 TRACE_ALU_RESULT (GPR[rd]);
1541 }
1542
1543
1544
1545 000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
1546 "dsrlv r<RD>, r<RT>, r<RS>"
1547 *mipsIII:
1548 *mipsIV:
1549 *mipsV:
1550 *mips64:
1551 *vr4100:
1552 *vr5000:
1553 {
1554 check_u64 (SD_, instruction_0);
1555 do_dsrlv (SD_, RS, RT, RD);
1556 }
1557
1558
1559 000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
1560 "dsub r<RD>, r<RS>, r<RT>"
1561 *mipsIII:
1562 *mipsIV:
1563 *mipsV:
1564 *mips64:
1565 *vr4100:
1566 *vr5000:
1567 {
1568 check_u64 (SD_, instruction_0);
1569 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1570 {
1571 ALU64_BEGIN (GPR[RS]);
1572 ALU64_SUB (GPR[RT]);
1573 ALU64_END (GPR[RD]); /* This checks for overflow. */
1574 }
1575 TRACE_ALU_RESULT (GPR[RD]);
1576 }
1577
1578
1579 :function:::void:do_dsubu:int rs, int rt, int rd
1580 {
1581 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1582 GPR[rd] = GPR[rs] - GPR[rt];
1583 TRACE_ALU_RESULT (GPR[rd]);
1584 }
1585
1586 000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
1587 "dsubu r<RD>, r<RS>, r<RT>"
1588 *mipsIII:
1589 *mipsIV:
1590 *mipsV:
1591 *mips64:
1592 *vr4100:
1593 *vr5000:
1594 {
1595 check_u64 (SD_, instruction_0);
1596 do_dsubu (SD_, RS, RT, RD);
1597 }
1598
1599
1600 000010,26.INSTR_INDEX:NORMAL:32::J
1601 "j <INSTR_INDEX>"
1602 *mipsI:
1603 *mipsII:
1604 *mipsIII:
1605 *mipsIV:
1606 *mipsV:
1607 *mips32:
1608 *mips64:
1609 *vr4100:
1610 *vr5000:
1611 *r3900:
1612 {
1613 /* NOTE: The region used is that of the delay slot NIA and NOT the
1614 current instruction */
1615 address_word region = (NIA & MASK (63, 28));
1616 DELAY_SLOT (region | (INSTR_INDEX << 2));
1617 }
1618
1619
1620 000011,26.INSTR_INDEX:NORMAL:32::JAL
1621 "jal <INSTR_INDEX>"
1622 *mipsI:
1623 *mipsII:
1624 *mipsIII:
1625 *mipsIV:
1626 *mipsV:
1627 *mips32:
1628 *mips64:
1629 *vr4100:
1630 *vr5000:
1631 *r3900:
1632 {
1633 /* NOTE: The region used is that of the delay slot and NOT the
1634 current instruction */
1635 address_word region = (NIA & MASK (63, 28));
1636 GPR[31] = CIA + 8;
1637 DELAY_SLOT (region | (INSTR_INDEX << 2));
1638 }
1639
1640 000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
1641 "jalr r<RS>":RD == 31
1642 "jalr r<RD>, r<RS>"
1643 *mipsI:
1644 *mipsII:
1645 *mipsIII:
1646 *mipsIV:
1647 *mipsV:
1648 *mips32:
1649 *mips64:
1650 *vr4100:
1651 *vr5000:
1652 *r3900:
1653 {
1654 address_word temp = GPR[RS];
1655 GPR[RD] = CIA + 8;
1656 DELAY_SLOT (temp);
1657 }
1658
1659
1660 000000,5.RS,000000000000000,001000:SPECIAL:32::JR
1661 "jr r<RS>"
1662 *mipsI:
1663 *mipsII:
1664 *mipsIII:
1665 *mipsIV:
1666 *mipsV:
1667 *mips32:
1668 *mips64:
1669 *vr4100:
1670 *vr5000:
1671 *r3900:
1672 {
1673 DELAY_SLOT (GPR[RS]);
1674 }
1675
1676
1677 :function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
1678 {
1679 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1680 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
1681 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
1682 unsigned int byte;
1683 address_word paddr;
1684 int uncached;
1685 unsigned64 memval;
1686 address_word vaddr;
1687
1688 vaddr = loadstore_ea (SD_, base, offset);
1689 if ((vaddr & access) != 0)
1690 {
1691 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
1692 }
1693 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1694 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1695 LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
1696 byte = ((vaddr & mask) ^ bigendiancpu);
1697 return (memval >> (8 * byte));
1698 }
1699
1700 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
1701 {
1702 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1703 address_word reverseendian = (ReverseEndian ? -1 : 0);
1704 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1705 unsigned int byte;
1706 unsigned int word;
1707 address_word paddr;
1708 int uncached;
1709 unsigned64 memval;
1710 address_word vaddr;
1711 int nr_lhs_bits;
1712 int nr_rhs_bits;
1713 unsigned_word lhs_mask;
1714 unsigned_word temp;
1715
1716 vaddr = loadstore_ea (SD_, base, offset);
1717 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1718 paddr = (paddr ^ (reverseendian & mask));
1719 if (BigEndianMem == 0)
1720 paddr = paddr & ~access;
1721
1722 /* compute where within the word/mem we are */
1723 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
1724 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
1725 nr_lhs_bits = 8 * byte + 8;
1726 nr_rhs_bits = 8 * access - 8 * byte;
1727 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
1728
1729 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
1730 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
1731 (long) ((unsigned64) paddr >> 32), (long) paddr,
1732 word, byte, nr_lhs_bits, nr_rhs_bits); */
1733
1734 LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
1735 if (word == 0)
1736 {
1737 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
1738 temp = (memval << nr_rhs_bits);
1739 }
1740 else
1741 {
1742 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
1743 temp = (memval >> nr_lhs_bits);
1744 }
1745 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
1746 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
1747
1748 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
1749 (long) ((unsigned64) memval >> 32), (long) memval,
1750 (long) ((unsigned64) temp >> 32), (long) temp,
1751 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
1752 (long) (rt >> 32), (long) rt); */
1753 return rt;
1754 }
1755
1756 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
1757 {
1758 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1759 address_word reverseendian = (ReverseEndian ? -1 : 0);
1760 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1761 unsigned int byte;
1762 address_word paddr;
1763 int uncached;
1764 unsigned64 memval;
1765 address_word vaddr;
1766
1767 vaddr = loadstore_ea (SD_, base, offset);
1768 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1769 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
1770 paddr = (paddr ^ (reverseendian & mask));
1771 if (BigEndianMem != 0)
1772 paddr = paddr & ~access;
1773 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
1774 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
1775 LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
1776 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
1777 (long) paddr, byte, (long) paddr, (long) memval); */
1778 {
1779 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
1780 rt &= ~screen;
1781 rt |= (memval >> (8 * byte)) & screen;
1782 }
1783 return rt;
1784 }
1785
1786
1787 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
1788 "lb r<RT>, <OFFSET>(r<BASE>)"
1789 *mipsI:
1790 *mipsII:
1791 *mipsIII:
1792 *mipsIV:
1793 *mipsV:
1794 *mips32:
1795 *mips64:
1796 *vr4100:
1797 *vr5000:
1798 *r3900:
1799 {
1800 GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
1801 }
1802
1803
1804 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
1805 "lbu r<RT>, <OFFSET>(r<BASE>)"
1806 *mipsI:
1807 *mipsII:
1808 *mipsIII:
1809 *mipsIV:
1810 *mipsV:
1811 *mips32:
1812 *mips64:
1813 *vr4100:
1814 *vr5000:
1815 *r3900:
1816 {
1817 GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
1818 }
1819
1820
1821 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
1822 "ld r<RT>, <OFFSET>(r<BASE>)"
1823 *mipsIII:
1824 *mipsIV:
1825 *mipsV:
1826 *mips64:
1827 *vr4100:
1828 *vr5000:
1829 {
1830 check_u64 (SD_, instruction_0);
1831 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1832 }
1833
1834
1835 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
1836 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1837 *mipsII:
1838 *mipsIII:
1839 *mipsIV:
1840 *mipsV:
1841 *mips32:
1842 *mips64:
1843 *vr4100:
1844 *vr5000:
1845 *r3900:
1846 {
1847 COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1848 }
1849
1850
1851
1852
1853 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
1854 "ldl r<RT>, <OFFSET>(r<BASE>)"
1855 *mipsIII:
1856 *mipsIV:
1857 *mipsV:
1858 *mips64:
1859 *vr4100:
1860 *vr5000:
1861 {
1862 check_u64 (SD_, instruction_0);
1863 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1864 }
1865
1866
1867 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
1868 "ldr r<RT>, <OFFSET>(r<BASE>)"
1869 *mipsIII:
1870 *mipsIV:
1871 *mipsV:
1872 *mips64:
1873 *vr4100:
1874 *vr5000:
1875 {
1876 check_u64 (SD_, instruction_0);
1877 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1878 }
1879
1880
1881 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
1882 "lh r<RT>, <OFFSET>(r<BASE>)"
1883 *mipsI:
1884 *mipsII:
1885 *mipsIII:
1886 *mipsIV:
1887 *mipsV:
1888 *mips32:
1889 *mips64:
1890 *vr4100:
1891 *vr5000:
1892 *r3900:
1893 {
1894 GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
1895 }
1896
1897
1898 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
1899 "lhu r<RT>, <OFFSET>(r<BASE>)"
1900 *mipsI:
1901 *mipsII:
1902 *mipsIII:
1903 *mipsIV:
1904 *mipsV:
1905 *mips32:
1906 *mips64:
1907 *vr4100:
1908 *vr5000:
1909 *r3900:
1910 {
1911 GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
1912 }
1913
1914
1915 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
1916 "ll r<RT>, <OFFSET>(r<BASE>)"
1917 *mipsII:
1918 *mipsIII:
1919 *mipsIV:
1920 *mipsV:
1921 *mips32:
1922 *mips64:
1923 *vr4100:
1924 *vr5000:
1925 {
1926 address_word base = GPR[BASE];
1927 address_word offset = EXTEND16 (OFFSET);
1928 {
1929 address_word vaddr = loadstore_ea (SD_, base, offset);
1930 address_word paddr;
1931 int uncached;
1932 if ((vaddr & 3) != 0)
1933 {
1934 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
1935 }
1936 else
1937 {
1938 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1939 {
1940 unsigned64 memval = 0;
1941 unsigned64 memval1 = 0;
1942 unsigned64 mask = 0x7;
1943 unsigned int shift = 2;
1944 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
1945 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
1946 unsigned int byte;
1947 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
1948 LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
1949 byte = ((vaddr & mask) ^ (bigend << shift));
1950 GPR[RT] = EXTEND32 (memval >> (8 * byte));
1951 LLBIT = 1;
1952 }
1953 }
1954 }
1955 }
1956
1957
1958 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
1959 "lld r<RT>, <OFFSET>(r<BASE>)"
1960 *mipsIII:
1961 *mipsIV:
1962 *mipsV:
1963 *mips64:
1964 *vr4100:
1965 *vr5000:
1966 {
1967 address_word base = GPR[BASE];
1968 address_word offset = EXTEND16 (OFFSET);
1969 check_u64 (SD_, instruction_0);
1970 {
1971 address_word vaddr = loadstore_ea (SD_, base, offset);
1972 address_word paddr;
1973 int uncached;
1974 if ((vaddr & 7) != 0)
1975 {
1976 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
1977 }
1978 else
1979 {
1980 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1981 {
1982 unsigned64 memval = 0;
1983 unsigned64 memval1 = 0;
1984 LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
1985 GPR[RT] = memval;
1986 LLBIT = 1;
1987 }
1988 }
1989 }
1990 }
1991
1992
1993 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
1994 "lui r<RT>, %#lx<IMMEDIATE>"
1995 *mipsI:
1996 *mipsII:
1997 *mipsIII:
1998 *mipsIV:
1999 *mipsV:
2000 *mips32:
2001 *mips64:
2002 *vr4100:
2003 *vr5000:
2004 *r3900:
2005 {
2006 TRACE_ALU_INPUT1 (IMMEDIATE);
2007 GPR[RT] = EXTEND32 (IMMEDIATE << 16);
2008 TRACE_ALU_RESULT (GPR[RT]);
2009 }
2010
2011
2012 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
2013 "lw r<RT>, <OFFSET>(r<BASE>)"
2014 *mipsI:
2015 *mipsII:
2016 *mipsIII:
2017 *mipsIV:
2018 *mipsV:
2019 *mips32:
2020 *mips64:
2021 *vr4100:
2022 *vr5000:
2023 *r3900:
2024 {
2025 GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
2026 }
2027
2028
2029 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
2030 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2031 *mipsI:
2032 *mipsII:
2033 *mipsIII:
2034 *mipsIV:
2035 *mipsV:
2036 *mips32:
2037 *mips64:
2038 *vr4100:
2039 *vr5000:
2040 *r3900:
2041 {
2042 COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
2043 }
2044
2045
2046 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
2047 "lwl r<RT>, <OFFSET>(r<BASE>)"
2048 *mipsI:
2049 *mipsII:
2050 *mipsIII:
2051 *mipsIV:
2052 *mipsV:
2053 *mips32:
2054 *mips64:
2055 *vr4100:
2056 *vr5000:
2057 *r3900:
2058 {
2059 GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
2060 }
2061
2062
2063 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
2064 "lwr r<RT>, <OFFSET>(r<BASE>)"
2065 *mipsI:
2066 *mipsII:
2067 *mipsIII:
2068 *mipsIV:
2069 *mipsV:
2070 *mips32:
2071 *mips64:
2072 *vr4100:
2073 *vr5000:
2074 *r3900:
2075 {
2076 GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
2077 }
2078
2079
2080 100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU
2081 "lwu r<RT>, <OFFSET>(r<BASE>)"
2082 *mipsIII:
2083 *mipsIV:
2084 *mipsV:
2085 *mips64:
2086 *vr4100:
2087 *vr5000:
2088 {
2089 check_u64 (SD_, instruction_0);
2090 GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
2091 }
2092
2093
2094
2095 011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD
2096 "madd r<RS>, r<RT>"
2097 *mips32:
2098 *mips64:
2099 {
2100 signed64 temp;
2101 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2102 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2103 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2104 + ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
2105 LO = EXTEND32 (temp);
2106 HI = EXTEND32 (VH4_8 (temp));
2107 TRACE_ALU_RESULT2 (HI, LO);
2108 }
2109
2110
2111
2112 011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU
2113 "maddu r<RS>, r<RT>"
2114 *mips32:
2115 *mips64:
2116 {
2117 unsigned64 temp;
2118 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2119 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2120 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2121 + ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
2122 LO = EXTEND32 (temp);
2123 HI = EXTEND32 (VH4_8 (temp));
2124 TRACE_ALU_RESULT2 (HI, LO);
2125 }
2126
2127
2128 :function:::void:do_mfhi:int rd
2129 {
2130 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
2131 TRACE_ALU_INPUT1 (HI);
2132 GPR[rd] = HI;
2133 TRACE_ALU_RESULT (GPR[rd]);
2134 }
2135
2136 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
2137 "mfhi r<RD>"
2138 *mipsI:
2139 *mipsII:
2140 *mipsIII:
2141 *mipsIV:
2142 *mipsV:
2143 *mips32:
2144 *mips64:
2145 *vr4100:
2146 *vr5000:
2147 *r3900:
2148 {
2149 do_mfhi (SD_, RD);
2150 }
2151
2152
2153
2154 :function:::void:do_mflo:int rd
2155 {
2156 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
2157 TRACE_ALU_INPUT1 (LO);
2158 GPR[rd] = LO;
2159 TRACE_ALU_RESULT (GPR[rd]);
2160 }
2161
2162 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
2163 "mflo r<RD>"
2164 *mipsI:
2165 *mipsII:
2166 *mipsIII:
2167 *mipsIV:
2168 *mipsV:
2169 *mips32:
2170 *mips64:
2171 *vr4100:
2172 *vr5000:
2173 *r3900:
2174 {
2175 do_mflo (SD_, RD);
2176 }
2177
2178
2179
2180 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
2181 "movn r<RD>, r<RS>, r<RT>"
2182 *mipsIV:
2183 *mipsV:
2184 *mips32:
2185 *mips64:
2186 *vr5000:
2187 {
2188 if (GPR[RT] != 0)
2189 GPR[RD] = GPR[RS];
2190 }
2191
2192
2193
2194 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
2195 "movz r<RD>, r<RS>, r<RT>"
2196 *mipsIV:
2197 *mipsV:
2198 *mips32:
2199 *mips64:
2200 *vr5000:
2201 {
2202 if (GPR[RT] == 0)
2203 GPR[RD] = GPR[RS];
2204 }
2205
2206
2207
2208 011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB
2209 "msub r<RS>, r<RT>"
2210 *mips32:
2211 *mips64:
2212 {
2213 signed64 temp;
2214 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2215 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2216 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2217 - ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
2218 LO = EXTEND32 (temp);
2219 HI = EXTEND32 (VH4_8 (temp));
2220 TRACE_ALU_RESULT2 (HI, LO);
2221 }
2222
2223
2224
2225 011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU
2226 "msubu r<RS>, r<RT>"
2227 *mips32:
2228 *mips64:
2229 {
2230 unsigned64 temp;
2231 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2232 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2233 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2234 - ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
2235 LO = EXTEND32 (temp);
2236 HI = EXTEND32 (VH4_8 (temp));
2237 TRACE_ALU_RESULT2 (HI, LO);
2238 }
2239
2240
2241
2242 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
2243 "mthi r<RS>"
2244 *mipsI:
2245 *mipsII:
2246 *mipsIII:
2247 *mipsIV:
2248 *mipsV:
2249 *mips32:
2250 *mips64:
2251 *vr4100:
2252 *vr5000:
2253 *r3900:
2254 {
2255 check_mt_hilo (SD_, HIHISTORY);
2256 HI = GPR[RS];
2257 }
2258
2259
2260
2261 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
2262 "mtlo r<RS>"
2263 *mipsI:
2264 *mipsII:
2265 *mipsIII:
2266 *mipsIV:
2267 *mipsV:
2268 *mips32:
2269 *mips64:
2270 *vr4100:
2271 *vr5000:
2272 *r3900:
2273 {
2274 check_mt_hilo (SD_, LOHISTORY);
2275 LO = GPR[RS];
2276 }
2277
2278
2279
2280 011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL
2281 "mul r<RD>, r<RS>, r<RT>"
2282 *mips32:
2283 *mips64:
2284 {
2285 signed64 prod;
2286 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2287 prod = (((signed64)(signed32) GPR[RS])
2288 * ((signed64)(signed32) GPR[RT]));
2289 GPR[RD] = EXTEND32 (VL4_8 (prod));
2290 TRACE_ALU_RESULT (GPR[RD]);
2291 }
2292
2293
2294
2295 :function:::void:do_mult:int rs, int rt, int rd
2296 {
2297 signed64 prod;
2298 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2299 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2300 prod = (((signed64)(signed32) GPR[rs])
2301 * ((signed64)(signed32) GPR[rt]));
2302 LO = EXTEND32 (VL4_8 (prod));
2303 HI = EXTEND32 (VH4_8 (prod));
2304 if (rd != 0)
2305 GPR[rd] = LO;
2306 TRACE_ALU_RESULT2 (HI, LO);
2307 }
2308
2309 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
2310 "mult r<RS>, r<RT>"
2311 *mipsI:
2312 *mipsII:
2313 *mipsIII:
2314 *mipsIV:
2315 *mipsV:
2316 *mips32:
2317 *mips64:
2318 *vr4100:
2319 {
2320 do_mult (SD_, RS, RT, 0);
2321 }
2322
2323
2324 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
2325 "mult r<RS>, r<RT>":RD == 0
2326 "mult r<RD>, r<RS>, r<RT>"
2327 *vr5000:
2328 *r3900:
2329 {
2330 do_mult (SD_, RS, RT, RD);
2331 }
2332
2333
2334 :function:::void:do_multu:int rs, int rt, int rd
2335 {
2336 unsigned64 prod;
2337 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2338 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2339 prod = (((unsigned64)(unsigned32) GPR[rs])
2340 * ((unsigned64)(unsigned32) GPR[rt]));
2341 LO = EXTEND32 (VL4_8 (prod));
2342 HI = EXTEND32 (VH4_8 (prod));
2343 if (rd != 0)
2344 GPR[rd] = LO;
2345 TRACE_ALU_RESULT2 (HI, LO);
2346 }
2347
2348 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
2349 "multu r<RS>, r<RT>"
2350 *mipsI:
2351 *mipsII:
2352 *mipsIII:
2353 *mipsIV:
2354 *mipsV:
2355 *mips32:
2356 *mips64:
2357 *vr4100:
2358 {
2359 do_multu (SD_, RS, RT, 0);
2360 }
2361
2362 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
2363 "multu r<RS>, r<RT>":RD == 0
2364 "multu r<RD>, r<RS>, r<RT>"
2365 *vr5000:
2366 *r3900:
2367 {
2368 do_multu (SD_, RS, RT, RD);
2369 }
2370
2371
2372 :function:::void:do_nor:int rs, int rt, int rd
2373 {
2374 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2375 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
2376 TRACE_ALU_RESULT (GPR[rd]);
2377 }
2378
2379 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
2380 "nor r<RD>, r<RS>, r<RT>"
2381 *mipsI:
2382 *mipsII:
2383 *mipsIII:
2384 *mipsIV:
2385 *mipsV:
2386 *mips32:
2387 *mips64:
2388 *vr4100:
2389 *vr5000:
2390 *r3900:
2391 {
2392 do_nor (SD_, RS, RT, RD);
2393 }
2394
2395
2396 :function:::void:do_or:int rs, int rt, int rd
2397 {
2398 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2399 GPR[rd] = (GPR[rs] | GPR[rt]);
2400 TRACE_ALU_RESULT (GPR[rd]);
2401 }
2402
2403 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
2404 "or r<RD>, r<RS>, r<RT>"
2405 *mipsI:
2406 *mipsII:
2407 *mipsIII:
2408 *mipsIV:
2409 *mipsV:
2410 *mips32:
2411 *mips64:
2412 *vr4100:
2413 *vr5000:
2414 *r3900:
2415 {
2416 do_or (SD_, RS, RT, RD);
2417 }
2418
2419
2420
2421 :function:::void:do_ori:int rs, int rt, unsigned immediate
2422 {
2423 TRACE_ALU_INPUT2 (GPR[rs], immediate);
2424 GPR[rt] = (GPR[rs] | immediate);
2425 TRACE_ALU_RESULT (GPR[rt]);
2426 }
2427
2428 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
2429 "ori r<RT>, r<RS>, %#lx<IMMEDIATE>"
2430 *mipsI:
2431 *mipsII:
2432 *mipsIII:
2433 *mipsIV:
2434 *mipsV:
2435 *mips32:
2436 *mips64:
2437 *vr4100:
2438 *vr5000:
2439 *r3900:
2440 {
2441 do_ori (SD_, RS, RT, IMMEDIATE);
2442 }
2443
2444
2445 110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF
2446 "pref <HINT>, <OFFSET>(r<BASE>)"
2447 *mipsIV:
2448 *mipsV:
2449 *mips32:
2450 *mips64:
2451 *vr5000:
2452 {
2453 address_word base = GPR[BASE];
2454 address_word offset = EXTEND16 (OFFSET);
2455 {
2456 address_word vaddr = loadstore_ea (SD_, base, offset);
2457 address_word paddr;
2458 int uncached;
2459 {
2460 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2461 Prefetch(uncached,paddr,vaddr,isDATA,HINT);
2462 }
2463 }
2464 }
2465
2466
2467 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
2468 {
2469 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2470 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
2471 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
2472 unsigned int byte;
2473 address_word paddr;
2474 int uncached;
2475 unsigned64 memval;
2476 address_word vaddr;
2477
2478 vaddr = loadstore_ea (SD_, base, offset);
2479 if ((vaddr & access) != 0)
2480 {
2481 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
2482 }
2483 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2484 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
2485 byte = ((vaddr & mask) ^ bigendiancpu);
2486 memval = (word << (8 * byte));
2487 StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
2488 }
2489
2490 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
2491 {
2492 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2493 address_word reverseendian = (ReverseEndian ? -1 : 0);
2494 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2495 unsigned int byte;
2496 unsigned int word;
2497 address_word paddr;
2498 int uncached;
2499 unsigned64 memval;
2500 address_word vaddr;
2501 int nr_lhs_bits;
2502 int nr_rhs_bits;
2503
2504 vaddr = loadstore_ea (SD_, base, offset);
2505 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2506 paddr = (paddr ^ (reverseendian & mask));
2507 if (BigEndianMem == 0)
2508 paddr = paddr & ~access;
2509
2510 /* compute where within the word/mem we are */
2511 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
2512 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
2513 nr_lhs_bits = 8 * byte + 8;
2514 nr_rhs_bits = 8 * access - 8 * byte;
2515 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
2516 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
2517 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
2518 (long) ((unsigned64) paddr >> 32), (long) paddr,
2519 word, byte, nr_lhs_bits, nr_rhs_bits); */
2520
2521 if (word == 0)
2522 {
2523 memval = (rt >> nr_rhs_bits);
2524 }
2525 else
2526 {
2527 memval = (rt << nr_lhs_bits);
2528 }
2529 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
2530 (long) ((unsigned64) rt >> 32), (long) rt,
2531 (long) ((unsigned64) memval >> 32), (long) memval); */
2532 StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
2533 }
2534
2535 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
2536 {
2537 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2538 address_word reverseendian = (ReverseEndian ? -1 : 0);
2539 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2540 unsigned int byte;
2541 address_word paddr;
2542 int uncached;
2543 unsigned64 memval;
2544 address_word vaddr;
2545
2546 vaddr = loadstore_ea (SD_, base, offset);
2547 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2548 paddr = (paddr ^ (reverseendian & mask));
2549 if (BigEndianMem != 0)
2550 paddr &= ~access;
2551 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
2552 memval = (rt << (byte * 8));
2553 StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
2554 }
2555
2556
2557 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
2558 "sb r<RT>, <OFFSET>(r<BASE>)"
2559 *mipsI:
2560 *mipsII:
2561 *mipsIII:
2562 *mipsIV:
2563 *mipsV:
2564 *mips32:
2565 *mips64:
2566 *vr4100:
2567 *vr5000:
2568 *r3900:
2569 {
2570 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2571 }
2572
2573
2574 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
2575 "sc r<RT>, <OFFSET>(r<BASE>)"
2576 *mipsII:
2577 *mipsIII:
2578 *mipsIV:
2579 *mipsV:
2580 *mips32:
2581 *mips64:
2582 *vr4100:
2583 *vr5000:
2584 {
2585 unsigned32 instruction = instruction_0;
2586 address_word base = GPR[BASE];
2587 address_word offset = EXTEND16 (OFFSET);
2588 {
2589 address_word vaddr = loadstore_ea (SD_, base, offset);
2590 address_word paddr;
2591 int uncached;
2592 if ((vaddr & 3) != 0)
2593 {
2594 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
2595 }
2596 else
2597 {
2598 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2599 {
2600 unsigned64 memval = 0;
2601 unsigned64 memval1 = 0;
2602 unsigned64 mask = 0x7;
2603 unsigned int byte;
2604 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
2605 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
2606 memval = ((unsigned64) GPR[RT] << (8 * byte));
2607 if (LLBIT)
2608 {
2609 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
2610 }
2611 GPR[RT] = LLBIT;
2612 }
2613 }
2614 }
2615 }
2616
2617
2618 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
2619 "scd r<RT>, <OFFSET>(r<BASE>)"
2620 *mipsIII:
2621 *mipsIV:
2622 *mipsV:
2623 *mips64:
2624 *vr4100:
2625 *vr5000:
2626 {
2627 address_word base = GPR[BASE];
2628 address_word offset = EXTEND16 (OFFSET);
2629 check_u64 (SD_, instruction_0);
2630 {
2631 address_word vaddr = loadstore_ea (SD_, base, offset);
2632 address_word paddr;
2633 int uncached;
2634 if ((vaddr & 7) != 0)
2635 {
2636 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
2637 }
2638 else
2639 {
2640 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2641 {
2642 unsigned64 memval = 0;
2643 unsigned64 memval1 = 0;
2644 memval = GPR[RT];
2645 if (LLBIT)
2646 {
2647 StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
2648 }
2649 GPR[RT] = LLBIT;
2650 }
2651 }
2652 }
2653 }
2654
2655
2656 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
2657 "sd r<RT>, <OFFSET>(r<BASE>)"
2658 *mipsIII:
2659 *mipsIV:
2660 *mipsV:
2661 *mips64:
2662 *vr4100:
2663 *vr5000:
2664 {
2665 check_u64 (SD_, instruction_0);
2666 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2667 }
2668
2669
2670 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
2671 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2672 *mipsII:
2673 *mipsIII:
2674 *mipsIV:
2675 *mipsV:
2676 *mips32:
2677 *mips64:
2678 *vr4100:
2679 *vr5000:
2680 {
2681 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
2682 }
2683
2684
2685 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
2686 "sdl r<RT>, <OFFSET>(r<BASE>)"
2687 *mipsIII:
2688 *mipsIV:
2689 *mipsV:
2690 *mips64:
2691 *vr4100:
2692 *vr5000:
2693 {
2694 check_u64 (SD_, instruction_0);
2695 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2696 }
2697
2698
2699 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
2700 "sdr r<RT>, <OFFSET>(r<BASE>)"
2701 *mipsIII:
2702 *mipsIV:
2703 *mipsV:
2704 *mips64:
2705 *vr4100:
2706 *vr5000:
2707 {
2708 check_u64 (SD_, instruction_0);
2709 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2710 }
2711
2712
2713 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
2714 "sh r<RT>, <OFFSET>(r<BASE>)"
2715 *mipsI:
2716 *mipsII:
2717 *mipsIII:
2718 *mipsIV:
2719 *mipsV:
2720 *mips32:
2721 *mips64:
2722 *vr4100:
2723 *vr5000:
2724 *r3900:
2725 {
2726 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2727 }
2728
2729
2730 :function:::void:do_sll:int rt, int rd, int shift
2731 {
2732 unsigned32 temp = (GPR[rt] << shift);
2733 TRACE_ALU_INPUT2 (GPR[rt], shift);
2734 GPR[rd] = EXTEND32 (temp);
2735 TRACE_ALU_RESULT (GPR[rd]);
2736 }
2737
2738 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa
2739 "nop":RD == 0 && RT == 0 && SHIFT == 0
2740 "sll r<RD>, r<RT>, <SHIFT>"
2741 *mipsI:
2742 *mipsII:
2743 *mipsIII:
2744 *mipsIV:
2745 *mipsV:
2746 *vr4100:
2747 *vr5000:
2748 *r3900:
2749 {
2750 /* Skip shift for NOP, so that there won't be lots of extraneous
2751 trace output. */
2752 if (RD != 0 || RT != 0 || SHIFT != 0)
2753 do_sll (SD_, RT, RD, SHIFT);
2754 }
2755
2756 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb
2757 "nop":RD == 0 && RT == 0 && SHIFT == 0
2758 "ssnop":RD == 0 && RT == 0 && SHIFT == 1
2759 "sll r<RD>, r<RT>, <SHIFT>"
2760 *mips32:
2761 *mips64:
2762 {
2763 /* Skip shift for NOP and SSNOP, so that there won't be lots of
2764 extraneous trace output. */
2765 if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1))
2766 do_sll (SD_, RT, RD, SHIFT);
2767 }
2768
2769
2770 :function:::void:do_sllv:int rs, int rt, int rd
2771 {
2772 int s = MASKED (GPR[rs], 4, 0);
2773 unsigned32 temp = (GPR[rt] << s);
2774 TRACE_ALU_INPUT2 (GPR[rt], s);
2775 GPR[rd] = EXTEND32 (temp);
2776 TRACE_ALU_RESULT (GPR[rd]);
2777 }
2778
2779 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
2780 "sllv r<RD>, r<RT>, r<RS>"
2781 *mipsI:
2782 *mipsII:
2783 *mipsIII:
2784 *mipsIV:
2785 *mipsV:
2786 *mips32:
2787 *mips64:
2788 *vr4100:
2789 *vr5000:
2790 *r3900:
2791 {
2792 do_sllv (SD_, RS, RT, RD);
2793 }
2794
2795
2796 :function:::void:do_slt:int rs, int rt, int rd
2797 {
2798 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2799 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
2800 TRACE_ALU_RESULT (GPR[rd]);
2801 }
2802
2803 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
2804 "slt r<RD>, r<RS>, r<RT>"
2805 *mipsI:
2806 *mipsII:
2807 *mipsIII:
2808 *mipsIV:
2809 *mipsV:
2810 *mips32:
2811 *mips64:
2812 *vr4100:
2813 *vr5000:
2814 *r3900:
2815 {
2816 do_slt (SD_, RS, RT, RD);
2817 }
2818
2819
2820 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
2821 {
2822 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2823 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
2824 TRACE_ALU_RESULT (GPR[rt]);
2825 }
2826
2827 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
2828 "slti r<RT>, r<RS>, <IMMEDIATE>"
2829 *mipsI:
2830 *mipsII:
2831 *mipsIII:
2832 *mipsIV:
2833 *mipsV:
2834 *mips32:
2835 *mips64:
2836 *vr4100:
2837 *vr5000:
2838 *r3900:
2839 {
2840 do_slti (SD_, RS, RT, IMMEDIATE);
2841 }
2842
2843
2844 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
2845 {
2846 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2847 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
2848 TRACE_ALU_RESULT (GPR[rt]);
2849 }
2850
2851 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
2852 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
2853 *mipsI:
2854 *mipsII:
2855 *mipsIII:
2856 *mipsIV:
2857 *mipsV:
2858 *mips32:
2859 *mips64:
2860 *vr4100:
2861 *vr5000:
2862 *r3900:
2863 {
2864 do_sltiu (SD_, RS, RT, IMMEDIATE);
2865 }
2866
2867
2868
2869 :function:::void:do_sltu:int rs, int rt, int rd
2870 {
2871 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2872 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
2873 TRACE_ALU_RESULT (GPR[rd]);
2874 }
2875
2876 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
2877 "sltu r<RD>, r<RS>, r<RT>"
2878 *mipsI:
2879 *mipsII:
2880 *mipsIII:
2881 *mipsIV:
2882 *mipsV:
2883 *mips32:
2884 *mips64:
2885 *vr4100:
2886 *vr5000:
2887 *r3900:
2888 {
2889 do_sltu (SD_, RS, RT, RD);
2890 }
2891
2892
2893 :function:::void:do_sra:int rt, int rd, int shift
2894 {
2895 signed32 temp = (signed32) GPR[rt] >> shift;
2896 TRACE_ALU_INPUT2 (GPR[rt], shift);
2897 GPR[rd] = EXTEND32 (temp);
2898 TRACE_ALU_RESULT (GPR[rd]);
2899 }
2900
2901 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
2902 "sra r<RD>, r<RT>, <SHIFT>"
2903 *mipsI:
2904 *mipsII:
2905 *mipsIII:
2906 *mipsIV:
2907 *mipsV:
2908 *mips32:
2909 *mips64:
2910 *vr4100:
2911 *vr5000:
2912 *r3900:
2913 {
2914 do_sra (SD_, RT, RD, SHIFT);
2915 }
2916
2917
2918
2919 :function:::void:do_srav:int rs, int rt, int rd
2920 {
2921 int s = MASKED (GPR[rs], 4, 0);
2922 signed32 temp = (signed32) GPR[rt] >> s;
2923 TRACE_ALU_INPUT2 (GPR[rt], s);
2924 GPR[rd] = EXTEND32 (temp);
2925 TRACE_ALU_RESULT (GPR[rd]);
2926 }
2927
2928 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
2929 "srav r<RD>, r<RT>, r<RS>"
2930 *mipsI:
2931 *mipsII:
2932 *mipsIII:
2933 *mipsIV:
2934 *mipsV:
2935 *mips32:
2936 *mips64:
2937 *vr4100:
2938 *vr5000:
2939 *r3900:
2940 {
2941 do_srav (SD_, RS, RT, RD);
2942 }
2943
2944
2945
2946 :function:::void:do_srl:int rt, int rd, int shift
2947 {
2948 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
2949 TRACE_ALU_INPUT2 (GPR[rt], shift);
2950 GPR[rd] = EXTEND32 (temp);
2951 TRACE_ALU_RESULT (GPR[rd]);
2952 }
2953
2954 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
2955 "srl r<RD>, r<RT>, <SHIFT>"
2956 *mipsI:
2957 *mipsII:
2958 *mipsIII:
2959 *mipsIV:
2960 *mipsV:
2961 *mips32:
2962 *mips64:
2963 *vr4100:
2964 *vr5000:
2965 *r3900:
2966 {
2967 do_srl (SD_, RT, RD, SHIFT);
2968 }
2969
2970
2971 :function:::void:do_srlv:int rs, int rt, int rd
2972 {
2973 int s = MASKED (GPR[rs], 4, 0);
2974 unsigned32 temp = (unsigned32) GPR[rt] >> s;
2975 TRACE_ALU_INPUT2 (GPR[rt], s);
2976 GPR[rd] = EXTEND32 (temp);
2977 TRACE_ALU_RESULT (GPR[rd]);
2978 }
2979
2980 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
2981 "srlv r<RD>, r<RT>, r<RS>"
2982 *mipsI:
2983 *mipsII:
2984 *mipsIII:
2985 *mipsIV:
2986 *mipsV:
2987 *mips32:
2988 *mips64:
2989 *vr4100:
2990 *vr5000:
2991 *r3900:
2992 {
2993 do_srlv (SD_, RS, RT, RD);
2994 }
2995
2996
2997 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
2998 "sub r<RD>, r<RS>, r<RT>"
2999 *mipsI:
3000 *mipsII:
3001 *mipsIII:
3002 *mipsIV:
3003 *mipsV:
3004 *mips32:
3005 *mips64:
3006 *vr4100:
3007 *vr5000:
3008 *r3900:
3009 {
3010 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
3011 {
3012 ALU32_BEGIN (GPR[RS]);
3013 ALU32_SUB (GPR[RT]);
3014 ALU32_END (GPR[RD]); /* This checks for overflow. */
3015 }
3016 TRACE_ALU_RESULT (GPR[RD]);
3017 }
3018
3019
3020 :function:::void:do_subu:int rs, int rt, int rd
3021 {
3022 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3023 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
3024 TRACE_ALU_RESULT (GPR[rd]);
3025 }
3026
3027 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
3028 "subu r<RD>, r<RS>, r<RT>"
3029 *mipsI:
3030 *mipsII:
3031 *mipsIII:
3032 *mipsIV:
3033 *mipsV:
3034 *mips32:
3035 *mips64:
3036 *vr4100:
3037 *vr5000:
3038 *r3900:
3039 {
3040 do_subu (SD_, RS, RT, RD);
3041 }
3042
3043
3044 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
3045 "sw r<RT>, <OFFSET>(r<BASE>)"
3046 *mipsI:
3047 *mipsII:
3048 *mipsIII:
3049 *mipsIV:
3050 *mipsV:
3051 *mips32:
3052 *mips64:
3053 *vr4100:
3054 *r3900:
3055 *vr5000:
3056 {
3057 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3058 }
3059
3060
3061 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
3062 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3063 *mipsI:
3064 *mipsII:
3065 *mipsIII:
3066 *mipsIV:
3067 *mipsV:
3068 *mips32:
3069 *mips64:
3070 *vr4100:
3071 *vr5000:
3072 *r3900:
3073 {
3074 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
3075 }
3076
3077
3078 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
3079 "swl r<RT>, <OFFSET>(r<BASE>)"
3080 *mipsI:
3081 *mipsII:
3082 *mipsIII:
3083 *mipsIV:
3084 *mipsV:
3085 *mips32:
3086 *mips64:
3087 *vr4100:
3088 *vr5000:
3089 *r3900:
3090 {
3091 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3092 }
3093
3094
3095 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
3096 "swr r<RT>, <OFFSET>(r<BASE>)"
3097 *mipsI:
3098 *mipsII:
3099 *mipsIII:
3100 *mipsIV:
3101 *mipsV:
3102 *mips32:
3103 *mips64:
3104 *vr4100:
3105 *vr5000:
3106 *r3900:
3107 {
3108 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3109 }
3110
3111
3112 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
3113 "sync":STYPE == 0
3114 "sync <STYPE>"
3115 *mipsII:
3116 *mipsIII:
3117 *mipsIV:
3118 *mipsV:
3119 *mips32:
3120 *mips64:
3121 *vr4100:
3122 *vr5000:
3123 *r3900:
3124 {
3125 SyncOperation (STYPE);
3126 }
3127
3128
3129 000000,20.CODE,001100:SPECIAL:32::SYSCALL
3130 "syscall %#lx<CODE>"
3131 *mipsI:
3132 *mipsII:
3133 *mipsIII:
3134 *mipsIV:
3135 *mipsV:
3136 *mips32:
3137 *mips64:
3138 *vr4100:
3139 *vr5000:
3140 *r3900:
3141 {
3142 SignalException (SystemCall, instruction_0);
3143 }
3144
3145
3146 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
3147 "teq r<RS>, r<RT>"
3148 *mipsII:
3149 *mipsIII:
3150 *mipsIV:
3151 *mipsV:
3152 *mips32:
3153 *mips64:
3154 *vr4100:
3155 *vr5000:
3156 {
3157 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
3158 SignalException (Trap, instruction_0);
3159 }
3160
3161
3162 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
3163 "teqi r<RS>, <IMMEDIATE>"
3164 *mipsII:
3165 *mipsIII:
3166 *mipsIV:
3167 *mipsV:
3168 *mips32:
3169 *mips64:
3170 *vr4100:
3171 *vr5000:
3172 {
3173 if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
3174 SignalException (Trap, instruction_0);
3175 }
3176
3177
3178 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
3179 "tge r<RS>, r<RT>"
3180 *mipsII:
3181 *mipsIII:
3182 *mipsIV:
3183 *mipsV:
3184 *mips32:
3185 *mips64:
3186 *vr4100:
3187 *vr5000:
3188 {
3189 if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
3190 SignalException (Trap, instruction_0);
3191 }
3192
3193
3194 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
3195 "tgei r<RS>, <IMMEDIATE>"
3196 *mipsII:
3197 *mipsIII:
3198 *mipsIV:
3199 *mipsV:
3200 *mips32:
3201 *mips64:
3202 *vr4100:
3203 *vr5000:
3204 {
3205 if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
3206 SignalException (Trap, instruction_0);
3207 }
3208
3209
3210 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
3211 "tgeiu r<RS>, <IMMEDIATE>"
3212 *mipsII:
3213 *mipsIII:
3214 *mipsIV:
3215 *mipsV:
3216 *mips32:
3217 *mips64:
3218 *vr4100:
3219 *vr5000:
3220 {
3221 if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
3222 SignalException (Trap, instruction_0);
3223 }
3224
3225
3226 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
3227 "tgeu r<RS>, r<RT>"
3228 *mipsII:
3229 *mipsIII:
3230 *mipsIV:
3231 *mipsV:
3232 *mips32:
3233 *mips64:
3234 *vr4100:
3235 *vr5000:
3236 {
3237 if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
3238 SignalException (Trap, instruction_0);
3239 }
3240
3241
3242 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
3243 "tlt r<RS>, r<RT>"
3244 *mipsII:
3245 *mipsIII:
3246 *mipsIV:
3247 *mipsV:
3248 *mips32:
3249 *mips64:
3250 *vr4100:
3251 *vr5000:
3252 {
3253 if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
3254 SignalException (Trap, instruction_0);
3255 }
3256
3257
3258 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
3259 "tlti r<RS>, <IMMEDIATE>"
3260 *mipsII:
3261 *mipsIII:
3262 *mipsIV:
3263 *mipsV:
3264 *mips32:
3265 *mips64:
3266 *vr4100:
3267 *vr5000:
3268 {
3269 if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
3270 SignalException (Trap, instruction_0);
3271 }
3272
3273
3274 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
3275 "tltiu r<RS>, <IMMEDIATE>"
3276 *mipsII:
3277 *mipsIII:
3278 *mipsIV:
3279 *mipsV:
3280 *mips32:
3281 *mips64:
3282 *vr4100:
3283 *vr5000:
3284 {
3285 if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
3286 SignalException (Trap, instruction_0);
3287 }
3288
3289
3290 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
3291 "tltu r<RS>, r<RT>"
3292 *mipsII:
3293 *mipsIII:
3294 *mipsIV:
3295 *mipsV:
3296 *mips32:
3297 *mips64:
3298 *vr4100:
3299 *vr5000:
3300 {
3301 if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
3302 SignalException (Trap, instruction_0);
3303 }
3304
3305
3306 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
3307 "tne r<RS>, r<RT>"
3308 *mipsII:
3309 *mipsIII:
3310 *mipsIV:
3311 *mipsV:
3312 *mips32:
3313 *mips64:
3314 *vr4100:
3315 *vr5000:
3316 {
3317 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
3318 SignalException (Trap, instruction_0);
3319 }
3320
3321
3322 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
3323 "tne r<RS>, <IMMEDIATE>"
3324 *mipsII:
3325 *mipsIII:
3326 *mipsIV:
3327 *mipsV:
3328 *mips32:
3329 *mips64:
3330 *vr4100:
3331 *vr5000:
3332 {
3333 if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
3334 SignalException (Trap, instruction_0);
3335 }
3336
3337
3338 :function:::void:do_xor:int rs, int rt, int rd
3339 {
3340 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3341 GPR[rd] = GPR[rs] ^ GPR[rt];
3342 TRACE_ALU_RESULT (GPR[rd]);
3343 }
3344
3345 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
3346 "xor r<RD>, r<RS>, r<RT>"
3347 *mipsI:
3348 *mipsII:
3349 *mipsIII:
3350 *mipsIV:
3351 *mipsV:
3352 *mips32:
3353 *mips64:
3354 *vr4100:
3355 *vr5000:
3356 *r3900:
3357 {
3358 do_xor (SD_, RS, RT, RD);
3359 }
3360
3361
3362 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
3363 {
3364 TRACE_ALU_INPUT2 (GPR[rs], immediate);
3365 GPR[rt] = GPR[rs] ^ immediate;
3366 TRACE_ALU_RESULT (GPR[rt]);
3367 }
3368
3369 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
3370 "xori r<RT>, r<RS>, %#lx<IMMEDIATE>"
3371 *mipsI:
3372 *mipsII:
3373 *mipsIII:
3374 *mipsIV:
3375 *mipsV:
3376 *mips32:
3377 *mips64:
3378 *vr4100:
3379 *vr5000:
3380 *r3900:
3381 {
3382 do_xori (SD_, RS, RT, IMMEDIATE);
3383 }
3384
3385 \f
3386 //
3387 // MIPS Architecture:
3388 //
3389 // FPU Instruction Set (COP1 & COP1X)
3390 //
3391
3392
3393 :%s::::FMT:int fmt
3394 {
3395 switch (fmt)
3396 {
3397 case fmt_single: return "s";
3398 case fmt_double: return "d";
3399 case fmt_word: return "w";
3400 case fmt_long: return "l";
3401 default: return "?";
3402 }
3403 }
3404
3405 :%s::::X:int x
3406 {
3407 switch (x)
3408 {
3409 case 0: return "f";
3410 case 1: return "t";
3411 default: return "?";
3412 }
3413 }
3414
3415 :%s::::TF:int tf
3416 {
3417 if (tf)
3418 return "t";
3419 else
3420 return "f";
3421 }
3422
3423 :%s::::ND:int nd
3424 {
3425 if (nd)
3426 return "l";
3427 else
3428 return "";
3429 }
3430
3431 :%s::::COND:int cond
3432 {
3433 switch (cond)
3434 {
3435 case 00: return "f";
3436 case 01: return "un";
3437 case 02: return "eq";
3438 case 03: return "ueq";
3439 case 04: return "olt";
3440 case 05: return "ult";
3441 case 06: return "ole";
3442 case 07: return "ule";
3443 case 010: return "sf";
3444 case 011: return "ngle";
3445 case 012: return "seq";
3446 case 013: return "ngl";
3447 case 014: return "lt";
3448 case 015: return "nge";
3449 case 016: return "le";
3450 case 017: return "ngt";
3451 default: return "?";
3452 }
3453 }
3454
3455
3456 // Helpers:
3457 //
3458 // Check that the given FPU format is usable, and signal a
3459 // ReservedInstruction exception if not.
3460 //
3461
3462 // check_fmt checks that the format is single or double.
3463 :function:::void:check_fmt:int fmt, instruction_word insn
3464 *mipsI:
3465 *mipsII:
3466 *mipsIII:
3467 *mipsIV:
3468 *mipsV:
3469 *mips32:
3470 *mips64:
3471 *vr4100:
3472 *vr5000:
3473 *r3900:
3474 {
3475 if ((fmt != fmt_single) && (fmt != fmt_double))
3476 SignalException (ReservedInstruction, insn);
3477 }
3478
3479 // check_fmt_p checks that the format is single, double, or paired single.
3480 :function:::void:check_fmt_p:int fmt, instruction_word insn
3481 *mipsI:
3482 *mipsII:
3483 *mipsIII:
3484 *mipsIV:
3485 *mips32:
3486 *vr4100:
3487 *vr5000:
3488 *r3900:
3489 {
3490 /* None of these ISAs support Paired Single, so just fall back to
3491 the single/double check. */
3492 check_fmt (SD_, fmt, insn);
3493 }
3494
3495 :function:::void:check_fmt_p:int fmt, instruction_word insn
3496 *mipsV:
3497 *mips64:
3498 {
3499 #if 0 /* XXX FIXME: FP code doesn't yet support paired single ops. */
3500 if ((fmt != fmt_single) && (fmt != fmt_double)
3501 && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
3502 SignalException (ReservedInstruction, insn);
3503 #else
3504 check_fmt (SD_, fmt, insn);
3505 #endif
3506 }
3507
3508
3509 // Helper:
3510 //
3511 // Check that the FPU is currently usable, and signal a CoProcessorUnusable
3512 // exception if not.
3513 //
3514
3515 :function:::void:check_fpu:
3516 *mipsI:
3517 *mipsII:
3518 *mipsIII:
3519 *mipsIV:
3520 *mipsV:
3521 *mips32:
3522 *mips64:
3523 *vr4100:
3524 *vr5000:
3525 *r3900:
3526 {
3527 if (! COP_Usable (1))
3528 SignalExceptionCoProcessorUnusable (1);
3529 }
3530
3531
3532 010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
3533 "abs.%s<FMT> f<FD>, f<FS>"
3534 *mipsI:
3535 *mipsII:
3536 *mipsIII:
3537 *mipsIV:
3538 *mipsV:
3539 *mips32:
3540 *mips64:
3541 *vr4100:
3542 *vr5000:
3543 *r3900:
3544 {
3545 int fmt = FMT;
3546 check_fpu (SD_);
3547 check_fmt_p (SD_, fmt, instruction_0);
3548 StoreFPR(FD,fmt,AbsoluteValue(ValueFPR(FS,fmt),fmt));
3549 }
3550
3551
3552
3553 010001,10,3.FMT,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
3554 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
3555 *mipsI:
3556 *mipsII:
3557 *mipsIII:
3558 *mipsIV:
3559 *mipsV:
3560 *mips32:
3561 *mips64:
3562 *vr4100:
3563 *vr5000:
3564 *r3900:
3565 {
3566 int fmt = FMT;
3567 check_fpu (SD_);
3568 check_fmt_p (SD_, fmt, instruction_0);
3569 StoreFPR(FD,fmt,Add(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
3570 }
3571
3572
3573
3574 // BC1F
3575 // BC1FL
3576 // BC1T
3577 // BC1TL
3578
3579 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
3580 "bc1%s<TF>%s<ND> <OFFSET>"
3581 *mipsI:
3582 *mipsII:
3583 *mipsIII:
3584 {
3585 check_fpu (SD_);
3586 check_branch_bug ();
3587 TRACE_BRANCH_INPUT (PREVCOC1());
3588 if (PREVCOC1() == TF)
3589 {
3590 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3591 TRACE_BRANCH_RESULT (dest);
3592 mark_branch_bug (dest);
3593 DELAY_SLOT (dest);
3594 }
3595 else if (ND)
3596 {
3597 TRACE_BRANCH_RESULT (0);
3598 NULLIFY_NEXT_INSTRUCTION ();
3599 }
3600 else
3601 {
3602 TRACE_BRANCH_RESULT (NIA);
3603 }
3604 }
3605
3606 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
3607 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
3608 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
3609 *mipsIV:
3610 *mipsV:
3611 *mips32:
3612 *mips64:
3613 #*vr4100:
3614 *vr5000:
3615 *r3900:
3616 {
3617 check_fpu (SD_);
3618 check_branch_bug ();
3619 if (GETFCC(CC) == TF)
3620 {
3621 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3622 mark_branch_bug (dest);
3623 DELAY_SLOT (dest);
3624 }
3625 else if (ND)
3626 {
3627 NULLIFY_NEXT_INSTRUCTION ();
3628 }
3629 }
3630
3631
3632
3633
3634
3635
3636 // C.EQ.S
3637 // C.EQ.D
3638 // ...
3639
3640 :function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
3641 {
3642 int less;
3643 int equal;
3644 int unordered;
3645 int condition;
3646 unsigned64 ofs = ValueFPR (fs, fmt);
3647 unsigned64 oft = ValueFPR (ft, fmt);
3648 if (NaN (ofs, fmt) || NaN (oft, fmt))
3649 {
3650 if (FCSR & FP_ENABLE (IO))
3651 {
3652 FCSR |= FP_CAUSE (IO);
3653 SignalExceptionFPE ();
3654 }
3655 less = 0;
3656 equal = 0;
3657 unordered = 1;
3658 }
3659 else
3660 {
3661 less = Less (ofs, oft, fmt);
3662 equal = Equal (ofs, oft, fmt);
3663 unordered = 0;
3664 }
3665 condition = (((cond & (1 << 2)) && less)
3666 || ((cond & (1 << 1)) && equal)
3667 || ((cond & (1 << 0)) && unordered));
3668 SETFCC (cc, condition);
3669 }
3670
3671 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta
3672 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
3673 *mipsI:
3674 *mipsII:
3675 *mipsIII:
3676 {
3677 int fmt = FMT;
3678 check_fpu (SD_);
3679 check_fmt_p (SD_, fmt, instruction_0);
3680 do_c_cond_fmt (SD_, fmt, FT, FS, 0, COND, instruction_0);
3681 }
3682
3683 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb
3684 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
3685 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
3686 *mipsIV:
3687 *mipsV:
3688 *mips32:
3689 *mips64:
3690 *vr4100:
3691 *vr5000:
3692 *r3900:
3693 {
3694 int fmt = FMT;
3695 check_fpu (SD_);
3696 check_fmt_p (SD_, fmt, instruction_0);
3697 do_c_cond_fmt (SD_, fmt, FT, FS, CC, COND, instruction_0);
3698 }
3699
3700
3701 010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64,f::CEIL.L.fmt
3702 "ceil.l.%s<FMT> f<FD>, f<FS>"
3703 *mipsIII:
3704 *mipsIV:
3705 *mipsV:
3706 *mips64:
3707 *vr4100:
3708 *vr5000:
3709 *r3900:
3710 {
3711 int fmt = FMT;
3712 check_fpu (SD_);
3713 check_fmt (SD_, fmt, instruction_0);
3714 StoreFPR(FD,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_long));
3715 }
3716
3717
3718 010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
3719 *mipsII:
3720 *mipsIII:
3721 *mipsIV:
3722 *mipsV:
3723 *mips32:
3724 *mips64:
3725 *vr4100:
3726 *vr5000:
3727 *r3900:
3728 {
3729 int fmt = FMT;
3730 check_fpu (SD_);
3731 check_fmt (SD_, fmt, instruction_0);
3732 StoreFPR(FD,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_word));
3733 }
3734
3735
3736 // CFC1
3737 // CTC1
3738 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32,f::CxC1
3739 "c%s<X>c1 r<RT>, f<FS>"
3740 *mipsI:
3741 *mipsII:
3742 *mipsIII:
3743 {
3744 check_fpu (SD_);
3745 if (X)
3746 {
3747 if (FS == 0)
3748 PENDING_FILL(FCR0IDX,VL4_8(GPR[RT]));
3749 else if (FS == 31)
3750 PENDING_FILL(FCR31IDX,VL4_8(GPR[RT]));
3751 /* else NOP */
3752 PENDING_SCHED(FCSR, FCR31 & (1<<23), 1, 23);
3753 }
3754 else
3755 { /* control from */
3756 if (FS == 0)
3757 PENDING_FILL(RT, EXTEND32 (FCR0));
3758 else if (FS == 31)
3759 PENDING_FILL(RT, EXTEND32 (FCR31));
3760 /* else NOP */
3761 }
3762 }
3763 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32,f::CxC1
3764 "c%s<X>c1 r<RT>, f<FS>"
3765 *mipsIV:
3766 *mipsV:
3767 *mips32:
3768 *mips64:
3769 *vr4100:
3770 *vr5000:
3771 *r3900:
3772 {
3773 check_fpu (SD_);
3774 if (X)
3775 {
3776 /* control to */
3777 TRACE_ALU_INPUT1 (GPR[RT]);
3778 if (FS == 0)
3779 {
3780 FCR0 = VL4_8(GPR[RT]);
3781 TRACE_ALU_RESULT (FCR0);
3782 }
3783 else if (FS == 31)
3784 {
3785 FCR31 = VL4_8(GPR[RT]);
3786 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
3787 TRACE_ALU_RESULT (FCR31);
3788 }
3789 else
3790 {
3791 TRACE_ALU_RESULT0 ();
3792 }
3793 /* else NOP */
3794 }
3795 else
3796 { /* control from */
3797 if (FS == 0)
3798 {
3799 TRACE_ALU_INPUT1 (FCR0);
3800 GPR[RT] = EXTEND32 (FCR0);
3801 }
3802 else if (FS == 31)
3803 {
3804 TRACE_ALU_INPUT1 (FCR31);
3805 GPR[RT] = EXTEND32 (FCR31);
3806 }
3807 TRACE_ALU_RESULT (GPR[RT]);
3808 /* else NOP */
3809 }
3810 }
3811
3812
3813 //
3814 // FIXME: Does not correctly differentiate between mips*
3815 //
3816 010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt
3817 "cvt.d.%s<FMT> f<FD>, f<FS>"
3818 *mipsI:
3819 *mipsII:
3820 *mipsIII:
3821 *mipsIV:
3822 *mipsV:
3823 *mips32:
3824 *mips64:
3825 *vr4100:
3826 *vr5000:
3827 *r3900:
3828 {
3829 int fmt = FMT;
3830 check_fpu (SD_);
3831 {
3832 if ((fmt == fmt_double) | 0)
3833 SignalException (ReservedInstruction, instruction_0);
3834 else
3835 StoreFPR(FD,fmt_double,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_double));
3836 }
3837 }
3838
3839
3840 010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64,f::CVT.L.fmt
3841 "cvt.l.%s<FMT> f<FD>, f<FS>"
3842 *mipsIII:
3843 *mipsIV:
3844 *mipsV:
3845 *mips64:
3846 *vr4100:
3847 *vr5000:
3848 *r3900:
3849 {
3850 int fmt = FMT;
3851 check_fpu (SD_);
3852 {
3853 if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
3854 SignalException (ReservedInstruction, instruction_0);
3855 else
3856 StoreFPR(FD,fmt_long,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_long));
3857 }
3858 }
3859
3860
3861 //
3862 // FIXME: Does not correctly differentiate between mips*
3863 //
3864 010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
3865 "cvt.s.%s<FMT> f<FD>, f<FS>"
3866 *mipsI:
3867 *mipsII:
3868 *mipsIII:
3869 *mipsIV:
3870 *mipsV:
3871 *mips32:
3872 *mips64:
3873 *vr4100:
3874 *vr5000:
3875 *r3900:
3876 {
3877 int fmt = FMT;
3878 check_fpu (SD_);
3879 {
3880 if ((fmt == fmt_single) | 0)
3881 SignalException (ReservedInstruction, instruction_0);
3882 else
3883 StoreFPR(FD,fmt_single,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_single));
3884 }
3885 }
3886
3887
3888 010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
3889 "cvt.w.%s<FMT> f<FD>, f<FS>"
3890 *mipsI:
3891 *mipsII:
3892 *mipsIII:
3893 *mipsIV:
3894 *mipsV:
3895 *mips32:
3896 *mips64:
3897 *vr4100:
3898 *vr5000:
3899 *r3900:
3900 {
3901 int fmt = FMT;
3902 check_fpu (SD_);
3903 {
3904 if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
3905 SignalException (ReservedInstruction, instruction_0);
3906 else
3907 StoreFPR(FD,fmt_word,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_word));
3908 }
3909 }
3910
3911
3912 010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt
3913 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
3914 *mipsI:
3915 *mipsII:
3916 *mipsIII:
3917 *mipsIV:
3918 *mipsV:
3919 *mips32:
3920 *mips64:
3921 *vr4100:
3922 *vr5000:
3923 *r3900:
3924 {
3925 int fmt = FMT;
3926 check_fpu (SD_);
3927 check_fmt (SD_, fmt, instruction_0);
3928 StoreFPR(FD,fmt,Divide(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
3929 }
3930
3931
3932 // DMFC1
3933 // DMTC1
3934 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64,f::DMxC1
3935 "dm%s<X>c1 r<RT>, f<FS>"
3936 *mipsIII:
3937 {
3938 check_fpu (SD_);
3939 check_u64 (SD_, instruction_0);
3940 if (X)
3941 {
3942 if (SizeFGR() == 64)
3943 PENDING_FILL((FS + FGRIDX),GPR[RT]);
3944 else if ((FS & 0x1) == 0)
3945 {
3946 PENDING_FILL(((FS + 1) + FGRIDX),VH4_8(GPR[RT]));
3947 PENDING_FILL((FS + FGRIDX),VL4_8(GPR[RT]));
3948 }
3949 }
3950 else
3951 {
3952 if (SizeFGR() == 64)
3953 PENDING_FILL(RT,FGR[FS]);
3954 else if ((FS & 0x1) == 0)
3955 PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
3956 else
3957 {
3958 if (STATE_VERBOSE_P(SD))
3959 sim_io_eprintf (SD,
3960 "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n",
3961 (long) CIA);
3962 PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
3963 }
3964 }
3965 }
3966 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64,f::DMxC1
3967 "dm%s<X>c1 r<RT>, f<FS>"
3968 *mipsIV:
3969 *mipsV:
3970 *mips64:
3971 *vr4100:
3972 *vr5000:
3973 *r3900:
3974 {
3975 check_fpu (SD_);
3976 check_u64 (SD_, instruction_0);
3977 if (X)
3978 {
3979 if (SizeFGR() == 64)
3980 StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
3981 else if ((FS & 0x1) == 0)
3982 StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
3983 }
3984 else
3985 {
3986 if (SizeFGR() == 64)
3987 GPR[RT] = FGR[FS];
3988 else if ((FS & 0x1) == 0)
3989 GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
3990 else
3991 {
3992 if (STATE_VERBOSE_P(SD))
3993 sim_io_eprintf (SD,
3994 "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n",
3995 (long) CIA);
3996 GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
3997 }
3998 }
3999 }
4000
4001
4002 010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64,f::FLOOR.L.fmt
4003 "floor.l.%s<FMT> f<FD>, f<FS>"
4004 *mipsIII:
4005 *mipsIV:
4006 *mipsV:
4007 *mips64:
4008 *vr4100:
4009 *vr5000:
4010 *r3900:
4011 {
4012 int fmt = FMT;
4013 check_fpu (SD_);
4014 check_fmt (SD_, fmt, instruction_0);
4015 StoreFPR(FD,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_long));
4016 }
4017
4018
4019 010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt
4020 "floor.w.%s<FMT> f<FD>, f<FS>"
4021 *mipsII:
4022 *mipsIII:
4023 *mipsIV:
4024 *mipsV:
4025 *mips32:
4026 *mips64:
4027 *vr4100:
4028 *vr5000:
4029 *r3900:
4030 {
4031 int fmt = FMT;
4032 check_fpu (SD_);
4033 check_fmt (SD_, fmt, instruction_0);
4034 StoreFPR(FD,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_word));
4035 }
4036
4037
4038 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1
4039 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
4040 *mipsII:
4041 *mipsIII:
4042 *mipsIV:
4043 *mipsV:
4044 *mips32:
4045 *mips64:
4046 *vr4100:
4047 *vr5000:
4048 *r3900:
4049 {
4050 check_fpu (SD_);
4051 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
4052 }
4053
4054
4055 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1
4056 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
4057 *mipsIV:
4058 *mipsV:
4059 *mips64:
4060 *vr5000:
4061 {
4062 check_fpu (SD_);
4063 check_u64 (SD_, instruction_0);
4064 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
4065 }
4066
4067
4068
4069 110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1
4070 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
4071 *mipsI:
4072 *mipsII:
4073 *mipsIII:
4074 *mipsIV:
4075 *mipsV:
4076 *mips32:
4077 *mips64:
4078 *vr4100:
4079 *vr5000:
4080 *r3900:
4081 {
4082 check_fpu (SD_);
4083 COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
4084 }
4085
4086
4087 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:64,f::LWXC1
4088 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
4089 *mipsIV:
4090 *mipsV:
4091 *mips64:
4092 *vr5000:
4093 {
4094 check_fpu (SD_);
4095 check_u64 (SD_, instruction_0);
4096 COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
4097 }
4098
4099
4100
4101 //
4102 // FIXME: Not correct for mips*
4103 //
4104 010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D
4105 "madd.d f<FD>, f<FR>, f<FS>, f<FT>"
4106 *mipsIV:
4107 *mipsV:
4108 *mips64:
4109 *vr5000:
4110 {
4111 check_fpu (SD_);
4112 {
4113 StoreFPR(FD,fmt_double,Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double));
4114 }
4115 }
4116
4117
4118 010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S
4119 "madd.s f<FD>, f<FR>, f<FS>, f<FT>"
4120 *mipsIV:
4121 *mipsV:
4122 *mips64:
4123 *vr5000:
4124 {
4125 check_fpu (SD_);
4126 {
4127 StoreFPR(FD,fmt_single,Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single));
4128 }
4129 }
4130
4131
4132 // MFC1
4133 // MTC1
4134 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32,f::MxC1
4135 "m%s<X>c1 r<RT>, f<FS>"
4136 *mipsI:
4137 *mipsII:
4138 *mipsIII:
4139 {
4140 check_fpu (SD_);
4141 if (X)
4142 { /*MTC1*/
4143 if (SizeFGR() == 64)
4144 {
4145 if (STATE_VERBOSE_P(SD))
4146 sim_io_eprintf (SD,
4147 "Warning: PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n",
4148 (long) CIA);
4149 PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
4150 }
4151 else
4152 PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT]));
4153 }
4154 else /*MFC1*/
4155 PENDING_FILL (RT, EXTEND32 (FGR[FS]));
4156 }
4157 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32,f::MxC1
4158 "m%s<X>c1 r<RT>, f<FS>"
4159 *mipsIV:
4160 *mipsV:
4161 *mips32:
4162 *mips64:
4163 *vr4100:
4164 *vr5000:
4165 *r3900:
4166 {
4167 int fs = FS;
4168 check_fpu (SD_);
4169 if (X)
4170 /*MTC1*/
4171 StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
4172 else /*MFC1*/
4173 GPR[RT] = EXTEND32 (FGR[FS]);
4174 }
4175
4176
4177 010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt
4178 "mov.%s<FMT> f<FD>, f<FS>"
4179 *mipsI:
4180 *mipsII:
4181 *mipsIII:
4182 *mipsIV:
4183 *mipsV:
4184 *mips32:
4185 *mips64:
4186 *vr4100:
4187 *vr5000:
4188 *r3900:
4189 {
4190 int fmt = FMT;
4191 check_fpu (SD_);
4192 check_fmt_p (SD_, fmt, instruction_0);
4193 StoreFPR(FD,fmt,ValueFPR(FS,fmt));
4194 }
4195
4196
4197 // MOVF
4198 // MOVT
4199 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf
4200 "mov%s<TF> r<RD>, r<RS>, <CC>"
4201 *mipsIV:
4202 *mipsV:
4203 *mips32:
4204 *mips64:
4205 *vr5000:
4206 {
4207 check_fpu (SD_);
4208 if (GETFCC(CC) == TF)
4209 GPR[RD] = GPR[RS];
4210 }
4211
4212
4213 // MOVF.fmt
4214 // MOVT.fmt
4215 010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt
4216 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
4217 *mipsIV:
4218 *mipsV:
4219 *mips32:
4220 *mips64:
4221 *vr5000:
4222 {
4223 int fmt = FMT;
4224 check_fpu (SD_);
4225 {
4226 if (GETFCC(CC) == TF)
4227 StoreFPR (FD, fmt, ValueFPR (FS, fmt));
4228 else
4229 StoreFPR (FD, fmt, ValueFPR (FD, fmt));
4230 }
4231 }
4232
4233
4234 010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt
4235 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
4236 *mipsIV:
4237 *mipsV:
4238 *mips32:
4239 *mips64:
4240 *vr5000:
4241 {
4242 check_fpu (SD_);
4243 if (GPR[RT] != 0)
4244 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
4245 else
4246 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
4247 }
4248
4249
4250 // MOVT see MOVtf
4251
4252
4253 // MOVT.fmt see MOVtf.fmt
4254
4255
4256
4257 010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt
4258 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
4259 *mipsIV:
4260 *mipsV:
4261 *mips32:
4262 *mips64:
4263 *vr5000:
4264 {
4265 check_fpu (SD_);
4266 if (GPR[RT] == 0)
4267 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
4268 else
4269 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
4270 }
4271
4272
4273 // MSUB.fmt
4274 010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32,f::MSUB.D
4275 "msub.d f<FD>, f<FR>, f<FS>, f<FT>"
4276 *mipsIV:
4277 *mipsV:
4278 *mips64:
4279 *vr5000:
4280 {
4281 check_fpu (SD_);
4282 StoreFPR(FD,fmt_double,Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double));
4283 }
4284
4285
4286 // MSUB.fmt
4287 010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32,f::MSUB.S
4288 "msub.s f<FD>, f<FR>, f<FS>, f<FT>"
4289 *mipsIV:
4290 *mipsV:
4291 *mips64:
4292 *vr5000:
4293 {
4294 check_fpu (SD_);
4295 StoreFPR(FD,fmt_single,Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single));
4296 }
4297
4298
4299 // MTC1 see MxC1
4300
4301
4302 010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
4303 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
4304 *mipsI:
4305 *mipsII:
4306 *mipsIII:
4307 *mipsIV:
4308 *mipsV:
4309 *mips32:
4310 *mips64:
4311 *vr4100:
4312 *vr5000:
4313 *r3900:
4314 {
4315 int fmt = FMT;
4316 check_fpu (SD_);
4317 check_fmt_p (SD_, fmt, instruction_0);
4318 StoreFPR(FD,fmt,Multiply(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
4319 }
4320
4321
4322 010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt
4323 "neg.%s<FMT> f<FD>, f<FS>"
4324 *mipsI:
4325 *mipsII:
4326 *mipsIII:
4327 *mipsIV:
4328 *mipsV:
4329 *mips32:
4330 *mips64:
4331 *vr4100:
4332 *vr5000:
4333 *r3900:
4334 {
4335 int fmt = FMT;
4336 check_fpu (SD_);
4337 check_fmt_p (SD_, fmt, instruction_0);
4338 StoreFPR(FD,fmt,Negate(ValueFPR(FS,fmt),fmt));
4339 }
4340
4341
4342 // NMADD.fmt
4343 010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32,f::NMADD.D
4344 "nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
4345 *mipsIV:
4346 *mipsV:
4347 *mips64:
4348 *vr5000:
4349 {
4350 check_fpu (SD_);
4351 StoreFPR(FD,fmt_double,Negate(Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double));
4352 }
4353
4354
4355 // NMADD.fmt
4356 010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32,f::NMADD.S
4357 "nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
4358 *mipsIV:
4359 *mipsV:
4360 *mips64:
4361 *vr5000:
4362 {
4363 check_fpu (SD_);
4364 StoreFPR(FD,fmt_single,Negate(Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single));
4365 }
4366
4367
4368 // NMSUB.fmt
4369 010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32,f::NMSUB.D
4370 "nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
4371 *mipsIV:
4372 *mipsV:
4373 *mips64:
4374 *vr5000:
4375 {
4376 check_fpu (SD_);
4377 StoreFPR(FD,fmt_double,Negate(Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double));
4378 }
4379
4380
4381 // NMSUB.fmt
4382 010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32,f::NMSUB.S
4383 "nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
4384 *mipsIV:
4385 *mipsV:
4386 *mips64:
4387 *vr5000:
4388 {
4389 check_fpu (SD_);
4390 StoreFPR(FD,fmt_single,Negate(Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single));
4391 }
4392
4393
4394 010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:64::PREFX
4395 "prefx <HINT>, r<INDEX>(r<BASE>)"
4396 *mipsIV:
4397 *mipsV:
4398 *mips64:
4399 *vr5000:
4400 {
4401 address_word base = GPR[BASE];
4402 address_word index = GPR[INDEX];
4403 {
4404 address_word vaddr = loadstore_ea (SD_, base, index);
4405 address_word paddr;
4406 int uncached;
4407 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
4408 Prefetch(uncached,paddr,vaddr,isDATA,HINT);
4409 }
4410 }
4411
4412 010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
4413 "recip.%s<FMT> f<FD>, f<FS>"
4414 *mipsIV:
4415 *mipsV:
4416 *mips64:
4417 *vr5000:
4418 {
4419 int fmt = FMT;
4420 check_fpu (SD_);
4421 check_fmt (SD_, fmt, instruction_0);
4422 StoreFPR(FD,fmt,Recip(ValueFPR(FS,fmt),fmt));
4423 }
4424
4425
4426 010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64,f::ROUND.L.fmt
4427 "round.l.%s<FMT> f<FD>, f<FS>"
4428 *mipsIII:
4429 *mipsIV:
4430 *mipsV:
4431 *mips64:
4432 *vr4100:
4433 *vr5000:
4434 *r3900:
4435 {
4436 int fmt = FMT;
4437 check_fpu (SD_);
4438 check_fmt (SD_, fmt, instruction_0);
4439 StoreFPR(FD,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_long));
4440 }
4441
4442
4443 010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt
4444 "round.w.%s<FMT> f<FD>, f<FS>"
4445 *mipsII:
4446 *mipsIII:
4447 *mipsIV:
4448 *mipsV:
4449 *mips32:
4450 *mips64:
4451 *vr4100:
4452 *vr5000:
4453 *r3900:
4454 {
4455 int fmt = FMT;
4456 check_fpu (SD_);
4457 check_fmt (SD_, fmt, instruction_0);
4458 StoreFPR(FD,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_word));
4459 }
4460
4461
4462 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
4463 *mipsIV:
4464 *mipsV:
4465 *mips64:
4466 "rsqrt.%s<FMT> f<FD>, f<FS>"
4467 *vr5000:
4468 {
4469 int fmt = FMT;
4470 check_fpu (SD_);
4471 check_fmt (SD_, fmt, instruction_0);
4472 StoreFPR(FD,fmt,Recip(SquareRoot(ValueFPR(FS,fmt),fmt),fmt));
4473 }
4474
4475
4476 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1
4477 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
4478 *mipsII:
4479 *mipsIII:
4480 *mipsIV:
4481 *mipsV:
4482 *mips32:
4483 *mips64:
4484 *vr4100:
4485 *vr5000:
4486 *r3900:
4487 {
4488 check_fpu (SD_);
4489 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
4490 }
4491
4492
4493 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1
4494 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
4495 *mipsIV:
4496 *mipsV:
4497 *mips64:
4498 *vr5000:
4499 {
4500 check_fpu (SD_);
4501 check_u64 (SD_, instruction_0);
4502 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
4503 }
4504
4505
4506 010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt
4507 "sqrt.%s<FMT> f<FD>, f<FS>"
4508 *mipsII:
4509 *mipsIII:
4510 *mipsIV:
4511 *mipsV:
4512 *mips32:
4513 *mips64:
4514 *vr4100:
4515 *vr5000:
4516 *r3900:
4517 {
4518 int fmt = FMT;
4519 check_fpu (SD_);
4520 check_fmt (SD_, fmt, instruction_0);
4521 StoreFPR(FD,fmt,(SquareRoot(ValueFPR(FS,fmt),fmt)));
4522 }
4523
4524
4525 010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt
4526 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
4527 *mipsI:
4528 *mipsII:
4529 *mipsIII:
4530 *mipsIV:
4531 *mipsV:
4532 *mips32:
4533 *mips64:
4534 *vr4100:
4535 *vr5000:
4536 *r3900:
4537 {
4538 int fmt = FMT;
4539 check_fpu (SD_);
4540 check_fmt_p (SD_, fmt, instruction_0);
4541 StoreFPR(FD,fmt,Sub(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
4542 }
4543
4544
4545
4546 111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1
4547 "swc1 f<FT>, <OFFSET>(r<BASE>)"
4548 *mipsI:
4549 *mipsII:
4550 *mipsIII:
4551 *mipsIV:
4552 *mipsV:
4553 *mips32:
4554 *mips64:
4555 *vr4100:
4556 *vr5000:
4557 *r3900:
4558 {
4559 address_word base = GPR[BASE];
4560 address_word offset = EXTEND16 (OFFSET);
4561 check_fpu (SD_);
4562 {
4563 address_word vaddr = loadstore_ea (SD_, base, offset);
4564 address_word paddr;
4565 int uncached;
4566 if ((vaddr & 3) != 0)
4567 {
4568 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
4569 }
4570 else
4571 {
4572 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4573 {
4574 uword64 memval = 0;
4575 uword64 memval1 = 0;
4576 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4577 address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
4578 address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
4579 unsigned int byte;
4580 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4581 byte = ((vaddr & mask) ^ bigendiancpu);
4582 memval = (((uword64)COP_SW(((instruction_0 >> 26) & 0x3),FT)) << (8 * byte));
4583 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4584 }
4585 }
4586 }
4587 }
4588
4589
4590 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1
4591 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
4592 *mipsIV:
4593 *mipsV:
4594 *mips64:
4595 *vr5000:
4596 {
4597
4598 address_word base = GPR[BASE];
4599 address_word index = GPR[INDEX];
4600 check_fpu (SD_);
4601 check_u64 (SD_, instruction_0);
4602 {
4603 address_word vaddr = loadstore_ea (SD_, base, index);
4604 address_word paddr;
4605 int uncached;
4606 if ((vaddr & 3) != 0)
4607 {
4608 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
4609 }
4610 else
4611 {
4612 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4613 {
4614 unsigned64 memval = 0;
4615 unsigned64 memval1 = 0;
4616 unsigned64 mask = 0x7;
4617 unsigned int byte;
4618 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
4619 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
4620 memval = (((unsigned64)COP_SW(1,FS)) << (8 * byte));
4621 {
4622 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4623 }
4624 }
4625 }
4626 }
4627 }
4628
4629
4630 010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64,f::TRUNC.L.fmt
4631 "trunc.l.%s<FMT> f<FD>, f<FS>"
4632 *mipsIII:
4633 *mipsIV:
4634 *mipsV:
4635 *mips64:
4636 *vr4100:
4637 *vr5000:
4638 *r3900:
4639 {
4640 int fmt = FMT;
4641 check_fpu (SD_);
4642 check_fmt (SD_, fmt, instruction_0);
4643 StoreFPR(FD,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_long));
4644 }
4645
4646
4647 010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W
4648 "trunc.w.%s<FMT> f<FD>, f<FS>"
4649 *mipsII:
4650 *mipsIII:
4651 *mipsIV:
4652 *mipsV:
4653 *mips32:
4654 *mips64:
4655 *vr4100:
4656 *vr5000:
4657 *r3900:
4658 {
4659 int fmt = FMT;
4660 check_fpu (SD_);
4661 check_fmt (SD_, fmt, instruction_0);
4662 StoreFPR(FD,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_word));
4663 }
4664
4665 \f
4666 //
4667 // MIPS Architecture:
4668 //
4669 // System Control Instruction Set (COP0)
4670 //
4671
4672
4673 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4674 "bc0f <OFFSET>"
4675 *mipsI:
4676 *mipsII:
4677 *mipsIII:
4678 *mipsIV:
4679 *mipsV:
4680 *mips32:
4681 *mips64:
4682 *vr4100:
4683 *vr5000:
4684
4685 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4686 "bc0f <OFFSET>"
4687 // stub needed for eCos as tx39 hardware bug workaround
4688 *r3900:
4689 {
4690 /* do nothing */
4691 }
4692
4693
4694 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
4695 "bc0fl <OFFSET>"
4696 *mipsI:
4697 *mipsII:
4698 *mipsIII:
4699 *mipsIV:
4700 *mipsV:
4701 *mips32:
4702 *mips64:
4703 *vr4100:
4704 *vr5000:
4705
4706
4707 010000,01000,00001,16.OFFSET:COP0:32::BC0T
4708 "bc0t <OFFSET>"
4709 *mipsI:
4710 *mipsII:
4711 *mipsIII:
4712 *mipsIV:
4713 *mipsV:
4714 *mips32:
4715 *mips64:
4716 *vr4100:
4717
4718
4719 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
4720 "bc0tl <OFFSET>"
4721 *mipsI:
4722 *mipsII:
4723 *mipsIII:
4724 *mipsIV:
4725 *mipsV:
4726 *mips32:
4727 *mips64:
4728 *vr4100:
4729 *vr5000:
4730
4731
4732 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
4733 "cache <OP>, <OFFSET>(r<BASE>)"
4734 *mipsIII:
4735 *mipsIV:
4736 *mipsV:
4737 *mips32:
4738 *mips64:
4739 *vr4100:
4740 *vr5000:
4741 *r3900:
4742 {
4743 address_word base = GPR[BASE];
4744 address_word offset = EXTEND16 (OFFSET);
4745 {
4746 address_word vaddr = loadstore_ea (SD_, base, offset);
4747 address_word paddr;
4748 int uncached;
4749 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
4750 CacheOp(OP,vaddr,paddr,instruction_0);
4751 }
4752 }
4753
4754
4755 010000,1,0000000000000000000,111001:COP0:32::DI
4756 "di"
4757 *mipsI:
4758 *mipsII:
4759 *mipsIII:
4760 *mipsIV:
4761 *mipsV:
4762 *vr4100:
4763 *vr5000:
4764
4765
4766 010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
4767 "dmfc0 r<RT>, r<RD>"
4768 *mipsIII:
4769 *mipsIV:
4770 *mipsV:
4771 *mips64:
4772 {
4773 check_u64 (SD_, instruction_0);
4774 DecodeCoproc (instruction_0);
4775 }
4776
4777
4778 010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
4779 "dmtc0 r<RT>, r<RD>"
4780 *mipsIII:
4781 *mipsIV:
4782 *mipsV:
4783 *mips64:
4784 {
4785 check_u64 (SD_, instruction_0);
4786 DecodeCoproc (instruction_0);
4787 }
4788
4789
4790 010000,1,0000000000000000000,111000:COP0:32::EI
4791 "ei"
4792 *mipsI:
4793 *mipsII:
4794 *mipsIII:
4795 *mipsIV:
4796 *mipsV:
4797 *mips64:
4798 *vr4100:
4799 *vr5000:
4800
4801
4802 010000,1,0000000000000000000,011000:COP0:32::ERET
4803 "eret"
4804 *mipsIII:
4805 *mipsIV:
4806 *mipsV:
4807 *mips32:
4808 *mips64:
4809 *vr4100:
4810 *vr5000:
4811 {
4812 if (SR & status_ERL)
4813 {
4814 /* Oops, not yet available */
4815 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
4816 NIA = EPC;
4817 SR &= ~status_ERL;
4818 }
4819 else
4820 {
4821 NIA = EPC;
4822 SR &= ~status_EXL;
4823 }
4824 }
4825
4826
4827 010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
4828 "mfc0 r<RT>, r<RD> # <REGX>"
4829 *mipsI:
4830 *mipsII:
4831 *mipsIII:
4832 *mipsIV:
4833 *mipsV:
4834 *mips32:
4835 *mips64:
4836 *vr4100:
4837 *vr5000:
4838 *r3900:
4839 {
4840 TRACE_ALU_INPUT0 ();
4841 DecodeCoproc (instruction_0);
4842 TRACE_ALU_RESULT (GPR[RT]);
4843 }
4844
4845 010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
4846 "mtc0 r<RT>, r<RD> # <REGX>"
4847 *mipsI:
4848 *mipsII:
4849 *mipsIII:
4850 *mipsIV:
4851 *mipsV:
4852 *mips32:
4853 *mips64:
4854 *vr4100:
4855 *vr5000:
4856 *r3900:
4857 {
4858 DecodeCoproc (instruction_0);
4859 }
4860
4861
4862 010000,1,0000000000000000000,010000:COP0:32::RFE
4863 "rfe"
4864 *mipsI:
4865 *mipsII:
4866 *mipsIII:
4867 *mipsIV:
4868 *mipsV:
4869 *vr4100:
4870 *vr5000:
4871 *r3900:
4872 {
4873 DecodeCoproc (instruction_0);
4874 }
4875
4876
4877 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
4878 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
4879 *mipsI:
4880 *mipsII:
4881 *mipsIII:
4882 *mipsIV:
4883 *mipsV:
4884 *mips32:
4885 *mips64:
4886 *vr4100:
4887 *r3900:
4888 {
4889 DecodeCoproc (instruction_0);
4890 }
4891
4892
4893
4894 010000,1,0000000000000000000,001000:COP0:32::TLBP
4895 "tlbp"
4896 *mipsI:
4897 *mipsII:
4898 *mipsIII:
4899 *mipsIV:
4900 *mipsV:
4901 *mips32:
4902 *mips64:
4903 *vr4100:
4904 *vr5000:
4905
4906
4907 010000,1,0000000000000000000,000001:COP0:32::TLBR
4908 "tlbr"
4909 *mipsI:
4910 *mipsII:
4911 *mipsIII:
4912 *mipsIV:
4913 *mipsV:
4914 *mips32:
4915 *mips64:
4916 *vr4100:
4917 *vr5000:
4918
4919
4920 010000,1,0000000000000000000,000010:COP0:32::TLBWI
4921 "tlbwi"
4922 *mipsI:
4923 *mipsII:
4924 *mipsIII:
4925 *mipsIV:
4926 *mipsV:
4927 *mips32:
4928 *mips64:
4929 *vr4100:
4930 *vr5000:
4931
4932
4933 010000,1,0000000000000000000,000110:COP0:32::TLBWR
4934 "tlbwr"
4935 *mipsI:
4936 *mipsII:
4937 *mipsIII:
4938 *mipsIV:
4939 *mipsV:
4940 *mips32:
4941 *mips64:
4942 *vr4100:
4943 *vr5000:
4944
4945 \f
4946 :include:::m16.igen
4947 :include:::tx.igen
4948 :include:::vr.igen
4949 \f
This page took 0.131853 seconds and 4 git commands to generate.