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