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