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