2002-02-27 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / mips.igen
1 // -*- C -*-
2 //
3 // In mips.igen, the semantics for many of the instructions were created
4 // using code generated by gencode. Those semantic segments could be
5 // greatly simplified.
6 //
7 // <insn> ::=
8 // <insn-word> { "+" <insn-word> }
9 // ":" <format-name>
10 // ":" <filter-flags>
11 // ":" <options>
12 // ":" <name>
13 // <nl>
14 // { <insn-model> }
15 // { <insn-mnemonic> }
16 // <code-block>
17 //
18
19
20 // IGEN config - mips16
21 // :option:16::insn-bit-size:16
22 // :option:16::hi-bit-nr:15
23 :option:16::insn-specifying-widths:true
24 :option:16::gen-delayed-branch:false
25
26 // IGEN config - mips32/64..
27 // :option:32::insn-bit-size:32
28 // :option:32::hi-bit-nr:31
29 :option:32::insn-specifying-widths:true
30 :option:32::gen-delayed-branch:false
31
32
33 // Generate separate simulators for each target
34 // :option:::multi-sim:true
35
36
37 // Models known by this simulator are defined below.
38 //
39 // When placing models in the instruction descriptions, please place
40 // them one per line, in the order given here.
41
42 // MIPS ISAs:
43 //
44 // Instructions and related functions for these models are included in
45 // this file.
46 :model:::mipsI:mips3000:
47 :model:::mipsII:mips6000:
48 :model:::mipsIII:mips4000:
49 :model:::mipsIV:mips8000:
50 :model:::mipsV:mipsisaV:
51
52 // Vendor ISAs:
53 //
54 // Standard MIPS ISA instructions used for these models are listed here,
55 // as are functions needed by those standard instructions. Instructions
56 // which are model-dependent and which are not in the standard MIPS ISAs
57 // (or which pre-date or use different encodings than the standard
58 // instructions) are (for the most part) in separate .igen files.
59 :model:::vr4100:mips4100: // vr.igen
60 :model:::vr5000:mips5000:
61 :model:::r3900:mips3900: // tx.igen
62
63 // MIPS Application Specific Extensions (ASEs)
64 //
65 // Instructions for the ASEs are in separate .igen files.
66 :model:::mips16:mips16: // m16.igen (and m16.dc)
67
68
69 // Pseudo instructions known by IGEN
70 :internal::::illegal:
71 {
72 SignalException (ReservedInstruction, 0);
73 }
74
75
76 // Pseudo instructions known by interp.c
77 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
78 000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
79 "rsvd <OP>"
80 {
81 SignalException (ReservedInstruction, instruction_0);
82 }
83
84
85
86 // Helper:
87 //
88 // Simulate a 32 bit delayslot instruction
89 //
90
91 :function:::address_word:delayslot32:address_word target
92 {
93 instruction_word delay_insn;
94 sim_events_slip (SD, 1);
95 DSPC = CIA;
96 CIA = CIA + 4; /* NOTE not mips16 */
97 STATE |= simDELAYSLOT;
98 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
99 ENGINE_ISSUE_PREFIX_HOOK();
100 idecode_issue (CPU_, delay_insn, (CIA));
101 STATE &= ~simDELAYSLOT;
102 return target;
103 }
104
105 :function:::address_word:nullify_next_insn32:
106 {
107 sim_events_slip (SD, 1);
108 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
109 return CIA + 8;
110 }
111
112 // Helper:
113 //
114 // Check that an access to a HI/LO register meets timing requirements
115 //
116 // The following requirements exist:
117 //
118 // - A MT {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
119 // - A OP {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
120 // - A MF {HI,LO} read was not corrupted by a preceeding MT{LO,HI} update
121 // corruption occures when MT{LO,HI} is preceeded by a OP {HI,LO}.
122 //
123
124 :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
125 {
126 if (history->mf.timestamp + 3 > time)
127 {
128 sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
129 itable[MY_INDEX].name,
130 new, (long) CIA,
131 (long) history->mf.cia);
132 return 0;
133 }
134 return 1;
135 }
136
137 :function:::int:check_mt_hilo:hilo_history *history
138 *mipsI:
139 *mipsII:
140 *mipsIII:
141 *mipsIV:
142 *mipsV:
143 *vr4100:
144 *vr5000:
145 {
146 signed64 time = sim_events_time (SD);
147 int ok = check_mf_cycles (SD_, history, time, "MT");
148 history->mt.timestamp = time;
149 history->mt.cia = CIA;
150 return ok;
151 }
152
153 :function:::int:check_mt_hilo:hilo_history *history
154 *r3900:
155 {
156 signed64 time = sim_events_time (SD);
157 history->mt.timestamp = time;
158 history->mt.cia = CIA;
159 return 1;
160 }
161
162
163 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
164 *mipsI:
165 *mipsII:
166 *mipsIII:
167 *mipsIV:
168 *mipsV:
169 *vr4100:
170 *vr5000:
171 *r3900:
172 {
173 signed64 time = sim_events_time (SD);
174 int ok = 1;
175 if (peer != NULL
176 && peer->mt.timestamp > history->op.timestamp
177 && history->mt.timestamp < history->op.timestamp
178 && ! (history->mf.timestamp > history->op.timestamp
179 && history->mf.timestamp < peer->mt.timestamp)
180 && ! (peer->mf.timestamp > history->op.timestamp
181 && peer->mf.timestamp < peer->mt.timestamp))
182 {
183 /* The peer has been written to since the last OP yet we have
184 not */
185 sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
186 itable[MY_INDEX].name,
187 (long) CIA,
188 (long) history->op.cia,
189 (long) peer->mt.cia);
190 ok = 0;
191 }
192 history->mf.timestamp = time;
193 history->mf.cia = CIA;
194 return ok;
195 }
196
197
198
199 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
200 *mipsI:
201 *mipsII:
202 *mipsIII:
203 *mipsIV:
204 *mipsV:
205 *vr4100:
206 *vr5000:
207 {
208 signed64 time = sim_events_time (SD);
209 int ok = (check_mf_cycles (SD_, hi, time, "OP")
210 && check_mf_cycles (SD_, lo, time, "OP"));
211 hi->op.timestamp = time;
212 lo->op.timestamp = time;
213 hi->op.cia = CIA;
214 lo->op.cia = CIA;
215 return ok;
216 }
217
218 // The r3900 mult and multu insns _can_ be exectuted immediatly after
219 // a mf{hi,lo}
220 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
221 *r3900:
222 {
223 /* FIXME: could record the fact that a stall occured if we want */
224 signed64 time = sim_events_time (SD);
225 hi->op.timestamp = time;
226 lo->op.timestamp = time;
227 hi->op.cia = CIA;
228 lo->op.cia = CIA;
229 return 1;
230 }
231
232
233 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
234 *mipsI:
235 *mipsII:
236 *mipsIII:
237 *mipsIV:
238 *mipsV:
239 *vr4100:
240 *vr5000:
241 *r3900:
242 {
243 signed64 time = sim_events_time (SD);
244 int ok = (check_mf_cycles (SD_, hi, time, "OP")
245 && check_mf_cycles (SD_, lo, time, "OP"));
246 hi->op.timestamp = time;
247 lo->op.timestamp = time;
248 hi->op.cia = CIA;
249 lo->op.cia = CIA;
250 return ok;
251 }
252
253
254
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
1433 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
1434 "lb r<RT>, <OFFSET>(r<BASE>)"
1435 *mipsI:
1436 *mipsII:
1437 *mipsIII:
1438 *mipsIV:
1439 *mipsV:
1440 *vr4100:
1441 *vr5000:
1442 *r3900:
1443 {
1444 GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
1445 }
1446
1447
1448 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
1449 "lbu r<RT>, <OFFSET>(r<BASE>)"
1450 *mipsI:
1451 *mipsII:
1452 *mipsIII:
1453 *mipsIV:
1454 *mipsV:
1455 *vr4100:
1456 *vr5000:
1457 *r3900:
1458 {
1459 GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
1460 }
1461
1462
1463 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
1464 "ld r<RT>, <OFFSET>(r<BASE>)"
1465 *mipsIII:
1466 *mipsIV:
1467 *mipsV:
1468 *vr4100:
1469 *vr5000:
1470 {
1471 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1472 }
1473
1474
1475 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
1476 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1477 *mipsII:
1478 *mipsIII:
1479 *mipsIV:
1480 *mipsV:
1481 *vr4100:
1482 *vr5000:
1483 *r3900:
1484 {
1485 COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1486 }
1487
1488
1489
1490
1491 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
1492 "ldl r<RT>, <OFFSET>(r<BASE>)"
1493 *mipsIII:
1494 *mipsIV:
1495 *mipsV:
1496 *vr4100:
1497 *vr5000:
1498 {
1499 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1500 }
1501
1502
1503 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
1504 "ldr r<RT>, <OFFSET>(r<BASE>)"
1505 *mipsIII:
1506 *mipsIV:
1507 *mipsV:
1508 *vr4100:
1509 *vr5000:
1510 {
1511 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1512 }
1513
1514
1515 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
1516 "lh r<RT>, <OFFSET>(r<BASE>)"
1517 *mipsI:
1518 *mipsII:
1519 *mipsIII:
1520 *mipsIV:
1521 *mipsV:
1522 *vr4100:
1523 *vr5000:
1524 *r3900:
1525 {
1526 GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
1527 }
1528
1529
1530 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
1531 "lhu r<RT>, <OFFSET>(r<BASE>)"
1532 *mipsI:
1533 *mipsII:
1534 *mipsIII:
1535 *mipsIV:
1536 *mipsV:
1537 *vr4100:
1538 *vr5000:
1539 *r3900:
1540 {
1541 GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
1542 }
1543
1544
1545 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
1546 "ll r<RT>, <OFFSET>(r<BASE>)"
1547 *mipsII:
1548 *mipsIII:
1549 *mipsIV:
1550 *mipsV:
1551 *vr4100:
1552 *vr5000:
1553 {
1554 unsigned32 instruction = instruction_0;
1555 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
1556 int destreg = ((instruction >> 16) & 0x0000001F);
1557 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
1558 {
1559 address_word vaddr = ((unsigned64)op1 + offset);
1560 address_word paddr;
1561 int uncached;
1562 if ((vaddr & 3) != 0)
1563 {
1564 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
1565 }
1566 else
1567 {
1568 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1569 {
1570 unsigned64 memval = 0;
1571 unsigned64 memval1 = 0;
1572 unsigned64 mask = 0x7;
1573 unsigned int shift = 2;
1574 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
1575 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
1576 unsigned int byte;
1577 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
1578 LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
1579 byte = ((vaddr & mask) ^ (bigend << shift));
1580 GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
1581 LLBIT = 1;
1582 }
1583 }
1584 }
1585 }
1586
1587
1588 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
1589 "lld r<RT>, <OFFSET>(r<BASE>)"
1590 *mipsIII:
1591 *mipsIV:
1592 *mipsV:
1593 *vr4100:
1594 *vr5000:
1595 {
1596 unsigned32 instruction = instruction_0;
1597 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
1598 int destreg = ((instruction >> 16) & 0x0000001F);
1599 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
1600 {
1601 address_word vaddr = ((unsigned64)op1 + offset);
1602 address_word paddr;
1603 int uncached;
1604 if ((vaddr & 7) != 0)
1605 {
1606 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
1607 }
1608 else
1609 {
1610 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1611 {
1612 unsigned64 memval = 0;
1613 unsigned64 memval1 = 0;
1614 LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
1615 GPR[destreg] = memval;
1616 LLBIT = 1;
1617 }
1618 }
1619 }
1620 }
1621
1622
1623 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
1624 "lui r<RT>, <IMMEDIATE>"
1625 *mipsI:
1626 *mipsII:
1627 *mipsIII:
1628 *mipsIV:
1629 *mipsV:
1630 *vr4100:
1631 *vr5000:
1632 *r3900:
1633 {
1634 TRACE_ALU_INPUT1 (IMMEDIATE);
1635 GPR[RT] = EXTEND32 (IMMEDIATE << 16);
1636 TRACE_ALU_RESULT (GPR[RT]);
1637 }
1638
1639
1640 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
1641 "lw r<RT>, <OFFSET>(r<BASE>)"
1642 *mipsI:
1643 *mipsII:
1644 *mipsIII:
1645 *mipsIV:
1646 *mipsV:
1647 *vr4100:
1648 *vr5000:
1649 *r3900:
1650 {
1651 GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
1652 }
1653
1654
1655 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
1656 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1657 *mipsI:
1658 *mipsII:
1659 *mipsIII:
1660 *mipsIV:
1661 *mipsV:
1662 *vr4100:
1663 *vr5000:
1664 *r3900:
1665 {
1666 COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
1667 }
1668
1669
1670 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
1671 {
1672 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1673 address_word reverseendian = (ReverseEndian ? -1 : 0);
1674 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1675 unsigned int byte;
1676 unsigned int word;
1677 address_word paddr;
1678 int uncached;
1679 unsigned64 memval;
1680 address_word vaddr;
1681 int nr_lhs_bits;
1682 int nr_rhs_bits;
1683 unsigned_word lhs_mask;
1684 unsigned_word temp;
1685
1686 vaddr = base + offset;
1687 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1688 paddr = (paddr ^ (reverseendian & mask));
1689 if (BigEndianMem == 0)
1690 paddr = paddr & ~access;
1691
1692 /* compute where within the word/mem we are */
1693 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
1694 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
1695 nr_lhs_bits = 8 * byte + 8;
1696 nr_rhs_bits = 8 * access - 8 * byte;
1697 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
1698
1699 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
1700 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
1701 (long) ((unsigned64) paddr >> 32), (long) paddr,
1702 word, byte, nr_lhs_bits, nr_rhs_bits); */
1703
1704 LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
1705 if (word == 0)
1706 {
1707 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
1708 temp = (memval << nr_rhs_bits);
1709 }
1710 else
1711 {
1712 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
1713 temp = (memval >> nr_lhs_bits);
1714 }
1715 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
1716 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
1717
1718 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
1719 (long) ((unsigned64) memval >> 32), (long) memval,
1720 (long) ((unsigned64) temp >> 32), (long) temp,
1721 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
1722 (long) (rt >> 32), (long) rt); */
1723 return rt;
1724 }
1725
1726
1727 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
1728 "lwl r<RT>, <OFFSET>(r<BASE>)"
1729 *mipsI:
1730 *mipsII:
1731 *mipsIII:
1732 *mipsIV:
1733 *mipsV:
1734 *vr4100:
1735 *vr5000:
1736 *r3900:
1737 {
1738 GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
1739 }
1740
1741
1742 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
1743 {
1744 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1745 address_word reverseendian = (ReverseEndian ? -1 : 0);
1746 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1747 unsigned int byte;
1748 address_word paddr;
1749 int uncached;
1750 unsigned64 memval;
1751 address_word vaddr;
1752
1753 vaddr = base + offset;
1754 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1755 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
1756 paddr = (paddr ^ (reverseendian & mask));
1757 if (BigEndianMem != 0)
1758 paddr = paddr & ~access;
1759 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
1760 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
1761 LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
1762 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
1763 (long) paddr, byte, (long) paddr, (long) memval); */
1764 {
1765 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
1766 rt &= ~screen;
1767 rt |= (memval >> (8 * byte)) & screen;
1768 }
1769 return rt;
1770 }
1771
1772
1773 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
1774 "lwr r<RT>, <OFFSET>(r<BASE>)"
1775 *mipsI:
1776 *mipsII:
1777 *mipsIII:
1778 *mipsIV:
1779 *mipsV:
1780 *vr4100:
1781 *vr5000:
1782 *r3900:
1783 {
1784 GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
1785 }
1786
1787
1788 100111,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWU
1789 "lwu r<RT>, <OFFSET>(r<BASE>)"
1790 *mipsIII:
1791 *mipsIV:
1792 *mipsV:
1793 *vr4100:
1794 *vr5000:
1795 {
1796 GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
1797 }
1798
1799
1800 :function:::void:do_mfhi:int rd
1801 {
1802 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
1803 TRACE_ALU_INPUT1 (HI);
1804 GPR[rd] = HI;
1805 TRACE_ALU_RESULT (GPR[rd]);
1806 }
1807
1808 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
1809 "mfhi r<RD>"
1810 *mipsI:
1811 *mipsII:
1812 *mipsIII:
1813 *mipsIV:
1814 *mipsV:
1815 *vr4100:
1816 *vr5000:
1817 *r3900:
1818 {
1819 do_mfhi (SD_, RD);
1820 }
1821
1822
1823
1824 :function:::void:do_mflo:int rd
1825 {
1826 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
1827 TRACE_ALU_INPUT1 (LO);
1828 GPR[rd] = LO;
1829 TRACE_ALU_RESULT (GPR[rd]);
1830 }
1831
1832 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
1833 "mflo r<RD>"
1834 *mipsI:
1835 *mipsII:
1836 *mipsIII:
1837 *mipsIV:
1838 *mipsV:
1839 *vr4100:
1840 *vr5000:
1841 *r3900:
1842 {
1843 do_mflo (SD_, RD);
1844 }
1845
1846
1847
1848 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
1849 "movn r<RD>, r<RS>, r<RT>"
1850 *mipsIV:
1851 *mipsV:
1852 *vr5000:
1853 {
1854 if (GPR[RT] != 0)
1855 GPR[RD] = GPR[RS];
1856 }
1857
1858
1859
1860 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
1861 "movz r<RD>, r<RS>, r<RT>"
1862 *mipsIV:
1863 *mipsV:
1864 *vr5000:
1865 {
1866 if (GPR[RT] == 0)
1867 GPR[RD] = GPR[RS];
1868 }
1869
1870
1871
1872 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
1873 "mthi r<RS>"
1874 *mipsI:
1875 *mipsII:
1876 *mipsIII:
1877 *mipsIV:
1878 *mipsV:
1879 *vr4100:
1880 *vr5000:
1881 *r3900:
1882 {
1883 check_mt_hilo (SD_, HIHISTORY);
1884 HI = GPR[RS];
1885 }
1886
1887
1888
1889 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
1890 "mtlo r<RS>"
1891 *mipsI:
1892 *mipsII:
1893 *mipsIII:
1894 *mipsIV:
1895 *mipsV:
1896 *vr4100:
1897 *vr5000:
1898 *r3900:
1899 {
1900 check_mt_hilo (SD_, LOHISTORY);
1901 LO = GPR[RS];
1902 }
1903
1904
1905
1906 :function:::void:do_mult:int rs, int rt, int rd
1907 {
1908 signed64 prod;
1909 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1910 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1911 prod = (((signed64)(signed32) GPR[rs])
1912 * ((signed64)(signed32) GPR[rt]));
1913 LO = EXTEND32 (VL4_8 (prod));
1914 HI = EXTEND32 (VH4_8 (prod));
1915 if (rd != 0)
1916 GPR[rd] = LO;
1917 TRACE_ALU_RESULT2 (HI, LO);
1918 }
1919
1920 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
1921 "mult r<RS>, r<RT>"
1922 *mipsI:
1923 *mipsII:
1924 *mipsIII:
1925 *mipsIV:
1926 *mipsV:
1927 *vr4100:
1928 {
1929 do_mult (SD_, RS, RT, 0);
1930 }
1931
1932
1933 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
1934 "mult r<RS>, r<RT>":RD == 0
1935 "mult r<RD>, r<RS>, r<RT>"
1936 *vr5000:
1937 *r3900:
1938 {
1939 do_mult (SD_, RS, RT, RD);
1940 }
1941
1942
1943 :function:::void:do_multu:int rs, int rt, int rd
1944 {
1945 unsigned64 prod;
1946 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1947 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1948 prod = (((unsigned64)(unsigned32) GPR[rs])
1949 * ((unsigned64)(unsigned32) GPR[rt]));
1950 LO = EXTEND32 (VL4_8 (prod));
1951 HI = EXTEND32 (VH4_8 (prod));
1952 if (rd != 0)
1953 GPR[rd] = LO;
1954 TRACE_ALU_RESULT2 (HI, LO);
1955 }
1956
1957 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
1958 "multu r<RS>, r<RT>"
1959 *mipsI:
1960 *mipsII:
1961 *mipsIII:
1962 *mipsIV:
1963 *mipsV:
1964 *vr4100:
1965 {
1966 do_multu (SD_, RS, RT, 0);
1967 }
1968
1969 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
1970 "multu r<RS>, r<RT>":RD == 0
1971 "multu r<RD>, r<RS>, r<RT>"
1972 *vr5000:
1973 *r3900:
1974 {
1975 do_multu (SD_, RS, RT, RD);
1976 }
1977
1978
1979 :function:::void:do_nor:int rs, int rt, int rd
1980 {
1981 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1982 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
1983 TRACE_ALU_RESULT (GPR[rd]);
1984 }
1985
1986 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
1987 "nor r<RD>, r<RS>, r<RT>"
1988 *mipsI:
1989 *mipsII:
1990 *mipsIII:
1991 *mipsIV:
1992 *mipsV:
1993 *vr4100:
1994 *vr5000:
1995 *r3900:
1996 {
1997 do_nor (SD_, RS, RT, RD);
1998 }
1999
2000
2001 :function:::void:do_or:int rs, int rt, int rd
2002 {
2003 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2004 GPR[rd] = (GPR[rs] | GPR[rt]);
2005 TRACE_ALU_RESULT (GPR[rd]);
2006 }
2007
2008 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
2009 "or r<RD>, r<RS>, r<RT>"
2010 *mipsI:
2011 *mipsII:
2012 *mipsIII:
2013 *mipsIV:
2014 *mipsV:
2015 *vr4100:
2016 *vr5000:
2017 *r3900:
2018 {
2019 do_or (SD_, RS, RT, RD);
2020 }
2021
2022
2023
2024 :function:::void:do_ori:int rs, int rt, unsigned immediate
2025 {
2026 TRACE_ALU_INPUT2 (GPR[rs], immediate);
2027 GPR[rt] = (GPR[rs] | immediate);
2028 TRACE_ALU_RESULT (GPR[rt]);
2029 }
2030
2031 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
2032 "ori r<RT>, r<RS>, <IMMEDIATE>"
2033 *mipsI:
2034 *mipsII:
2035 *mipsIII:
2036 *mipsIV:
2037 *mipsV:
2038 *vr4100:
2039 *vr5000:
2040 *r3900:
2041 {
2042 do_ori (SD_, RS, RT, IMMEDIATE);
2043 }
2044
2045
2046 110011,5.RS,nnnnn,16.OFFSET:NORMAL:32::PREF
2047 *mipsIV:
2048 *mipsV:
2049 *vr5000:
2050 {
2051 unsigned32 instruction = instruction_0;
2052 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
2053 int hint = ((instruction >> 16) & 0x0000001F);
2054 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
2055 {
2056 address_word vaddr = ((unsigned64)op1 + offset);
2057 address_word paddr;
2058 int uncached;
2059 {
2060 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2061 Prefetch(uncached,paddr,vaddr,isDATA,hint);
2062 }
2063 }
2064 }
2065
2066 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
2067 {
2068 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2069 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
2070 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
2071 unsigned int byte;
2072 address_word paddr;
2073 int uncached;
2074 unsigned64 memval;
2075 address_word vaddr;
2076
2077 vaddr = base + offset;
2078 if ((vaddr & access) != 0)
2079 {
2080 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
2081 }
2082 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2083 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
2084 byte = ((vaddr & mask) ^ bigendiancpu);
2085 memval = (word << (8 * byte));
2086 StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
2087 }
2088
2089
2090 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
2091 "sb r<RT>, <OFFSET>(r<BASE>)"
2092 *mipsI:
2093 *mipsII:
2094 *mipsIII:
2095 *mipsIV:
2096 *mipsV:
2097 *vr4100:
2098 *vr5000:
2099 *r3900:
2100 {
2101 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2102 }
2103
2104
2105 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
2106 "sc r<RT>, <OFFSET>(r<BASE>)"
2107 *mipsII:
2108 *mipsIII:
2109 *mipsIV:
2110 *mipsV:
2111 *vr4100:
2112 *vr5000:
2113 {
2114 unsigned32 instruction = instruction_0;
2115 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
2116 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
2117 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
2118 {
2119 address_word vaddr = ((unsigned64)op1 + offset);
2120 address_word paddr;
2121 int uncached;
2122 if ((vaddr & 3) != 0)
2123 {
2124 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
2125 }
2126 else
2127 {
2128 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2129 {
2130 unsigned64 memval = 0;
2131 unsigned64 memval1 = 0;
2132 unsigned64 mask = 0x7;
2133 unsigned int byte;
2134 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
2135 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
2136 memval = ((unsigned64) op2 << (8 * byte));
2137 if (LLBIT)
2138 {
2139 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
2140 }
2141 GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
2142 }
2143 }
2144 }
2145 }
2146
2147
2148 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
2149 "scd r<RT>, <OFFSET>(r<BASE>)"
2150 *mipsIII:
2151 *mipsIV:
2152 *mipsV:
2153 *vr4100:
2154 *vr5000:
2155 {
2156 unsigned32 instruction = instruction_0;
2157 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
2158 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
2159 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
2160 {
2161 address_word vaddr = ((unsigned64)op1 + offset);
2162 address_word paddr;
2163 int uncached;
2164 if ((vaddr & 7) != 0)
2165 {
2166 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
2167 }
2168 else
2169 {
2170 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2171 {
2172 unsigned64 memval = 0;
2173 unsigned64 memval1 = 0;
2174 memval = op2;
2175 if (LLBIT)
2176 {
2177 StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
2178 }
2179 GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
2180 }
2181 }
2182 }
2183 }
2184
2185
2186 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
2187 "sd r<RT>, <OFFSET>(r<BASE>)"
2188 *mipsIII:
2189 *mipsIV:
2190 *mipsV:
2191 *vr4100:
2192 *vr5000:
2193 {
2194 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2195 }
2196
2197
2198 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
2199 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2200 *mipsII:
2201 *mipsIII:
2202 *mipsIV:
2203 *mipsV:
2204 *vr4100:
2205 *vr5000:
2206 {
2207 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
2208 }
2209
2210
2211 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
2212 "sdl r<RT>, <OFFSET>(r<BASE>)"
2213 *mipsIII:
2214 *mipsIV:
2215 *mipsV:
2216 *vr4100:
2217 *vr5000:
2218 {
2219 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2220 }
2221
2222
2223 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
2224 "sdr r<RT>, <OFFSET>(r<BASE>)"
2225 *mipsIII:
2226 *mipsIV:
2227 *mipsV:
2228 *vr4100:
2229 *vr5000:
2230 {
2231 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2232 }
2233
2234
2235 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
2236 "sh r<RT>, <OFFSET>(r<BASE>)"
2237 *mipsI:
2238 *mipsII:
2239 *mipsIII:
2240 *mipsIV:
2241 *mipsV:
2242 *vr4100:
2243 *vr5000:
2244 *r3900:
2245 {
2246 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2247 }
2248
2249
2250 :function:::void:do_sll:int rt, int rd, int shift
2251 {
2252 unsigned32 temp = (GPR[rt] << shift);
2253 TRACE_ALU_INPUT2 (GPR[rt], shift);
2254 GPR[rd] = EXTEND32 (temp);
2255 TRACE_ALU_RESULT (GPR[rd]);
2256 }
2257
2258 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLL
2259 "nop":RD == 0 && RT == 0 && SHIFT == 0
2260 "sll r<RD>, r<RT>, <SHIFT>"
2261 *mipsI:
2262 *mipsII:
2263 *mipsIII:
2264 *mipsIV:
2265 *mipsV:
2266 *vr4100:
2267 *vr5000:
2268 *r3900:
2269 {
2270 /* Skip shift for NOP, so that there won't be lots of extraneous
2271 trace output. */
2272 if (RD != 0 || RT != 0 || SHIFT != 0)
2273 do_sll (SD_, RT, RD, SHIFT);
2274 }
2275
2276
2277 :function:::void:do_sllv:int rs, int rt, int rd
2278 {
2279 int s = MASKED (GPR[rs], 4, 0);
2280 unsigned32 temp = (GPR[rt] << s);
2281 TRACE_ALU_INPUT2 (GPR[rt], s);
2282 GPR[rd] = EXTEND32 (temp);
2283 TRACE_ALU_RESULT (GPR[rd]);
2284 }
2285
2286 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
2287 "sllv r<RD>, r<RT>, r<RS>"
2288 *mipsI:
2289 *mipsII:
2290 *mipsIII:
2291 *mipsIV:
2292 *mipsV:
2293 *vr4100:
2294 *vr5000:
2295 *r3900:
2296 {
2297 do_sllv (SD_, RS, RT, RD);
2298 }
2299
2300
2301 :function:::void:do_slt:int rs, int rt, int rd
2302 {
2303 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2304 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
2305 TRACE_ALU_RESULT (GPR[rd]);
2306 }
2307
2308 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
2309 "slt r<RD>, r<RS>, r<RT>"
2310 *mipsI:
2311 *mipsII:
2312 *mipsIII:
2313 *mipsIV:
2314 *mipsV:
2315 *vr4100:
2316 *vr5000:
2317 *r3900:
2318 {
2319 do_slt (SD_, RS, RT, RD);
2320 }
2321
2322
2323 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
2324 {
2325 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2326 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
2327 TRACE_ALU_RESULT (GPR[rt]);
2328 }
2329
2330 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
2331 "slti r<RT>, r<RS>, <IMMEDIATE>"
2332 *mipsI:
2333 *mipsII:
2334 *mipsIII:
2335 *mipsIV:
2336 *mipsV:
2337 *vr4100:
2338 *vr5000:
2339 *r3900:
2340 {
2341 do_slti (SD_, RS, RT, IMMEDIATE);
2342 }
2343
2344
2345 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
2346 {
2347 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2348 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
2349 TRACE_ALU_RESULT (GPR[rt]);
2350 }
2351
2352 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
2353 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
2354 *mipsI:
2355 *mipsII:
2356 *mipsIII:
2357 *mipsIV:
2358 *mipsV:
2359 *vr4100:
2360 *vr5000:
2361 *r3900:
2362 {
2363 do_sltiu (SD_, RS, RT, IMMEDIATE);
2364 }
2365
2366
2367
2368 :function:::void:do_sltu:int rs, int rt, int rd
2369 {
2370 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2371 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
2372 TRACE_ALU_RESULT (GPR[rd]);
2373 }
2374
2375 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
2376 "sltu r<RD>, r<RS>, r<RT>"
2377 *mipsI:
2378 *mipsII:
2379 *mipsIII:
2380 *mipsIV:
2381 *mipsV:
2382 *vr4100:
2383 *vr5000:
2384 *r3900:
2385 {
2386 do_sltu (SD_, RS, RT, RD);
2387 }
2388
2389
2390 :function:::void:do_sra:int rt, int rd, int shift
2391 {
2392 signed32 temp = (signed32) GPR[rt] >> shift;
2393 TRACE_ALU_INPUT2 (GPR[rt], shift);
2394 GPR[rd] = EXTEND32 (temp);
2395 TRACE_ALU_RESULT (GPR[rd]);
2396 }
2397
2398 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
2399 "sra r<RD>, r<RT>, <SHIFT>"
2400 *mipsI:
2401 *mipsII:
2402 *mipsIII:
2403 *mipsIV:
2404 *mipsV:
2405 *vr4100:
2406 *vr5000:
2407 *r3900:
2408 {
2409 do_sra (SD_, RT, RD, SHIFT);
2410 }
2411
2412
2413
2414 :function:::void:do_srav:int rs, int rt, int rd
2415 {
2416 int s = MASKED (GPR[rs], 4, 0);
2417 signed32 temp = (signed32) GPR[rt] >> s;
2418 TRACE_ALU_INPUT2 (GPR[rt], s);
2419 GPR[rd] = EXTEND32 (temp);
2420 TRACE_ALU_RESULT (GPR[rd]);
2421 }
2422
2423 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
2424 "srav r<RD>, r<RT>, r<RS>"
2425 *mipsI:
2426 *mipsII:
2427 *mipsIII:
2428 *mipsIV:
2429 *mipsV:
2430 *vr4100:
2431 *vr5000:
2432 *r3900:
2433 {
2434 do_srav (SD_, RS, RT, RD);
2435 }
2436
2437
2438
2439 :function:::void:do_srl:int rt, int rd, int shift
2440 {
2441 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
2442 TRACE_ALU_INPUT2 (GPR[rt], shift);
2443 GPR[rd] = EXTEND32 (temp);
2444 TRACE_ALU_RESULT (GPR[rd]);
2445 }
2446
2447 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
2448 "srl r<RD>, r<RT>, <SHIFT>"
2449 *mipsI:
2450 *mipsII:
2451 *mipsIII:
2452 *mipsIV:
2453 *mipsV:
2454 *vr4100:
2455 *vr5000:
2456 *r3900:
2457 {
2458 do_srl (SD_, RT, RD, SHIFT);
2459 }
2460
2461
2462 :function:::void:do_srlv:int rs, int rt, int rd
2463 {
2464 int s = MASKED (GPR[rs], 4, 0);
2465 unsigned32 temp = (unsigned32) GPR[rt] >> s;
2466 TRACE_ALU_INPUT2 (GPR[rt], s);
2467 GPR[rd] = EXTEND32 (temp);
2468 TRACE_ALU_RESULT (GPR[rd]);
2469 }
2470
2471 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
2472 "srlv r<RD>, r<RT>, r<RS>"
2473 *mipsI:
2474 *mipsII:
2475 *mipsIII:
2476 *mipsIV:
2477 *mipsV:
2478 *vr4100:
2479 *vr5000:
2480 *r3900:
2481 {
2482 do_srlv (SD_, RS, RT, RD);
2483 }
2484
2485
2486 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
2487 "sub r<RD>, r<RS>, r<RT>"
2488 *mipsI:
2489 *mipsII:
2490 *mipsIII:
2491 *mipsIV:
2492 *mipsV:
2493 *vr4100:
2494 *vr5000:
2495 *r3900:
2496 {
2497 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2498 {
2499 ALU32_BEGIN (GPR[RS]);
2500 ALU32_SUB (GPR[RT]);
2501 ALU32_END (GPR[RD]); /* This checks for overflow. */
2502 }
2503 TRACE_ALU_RESULT (GPR[RD]);
2504 }
2505
2506
2507 :function:::void:do_subu:int rs, int rt, int rd
2508 {
2509 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2510 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
2511 TRACE_ALU_RESULT (GPR[rd]);
2512 }
2513
2514 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
2515 "subu r<RD>, r<RS>, r<RT>"
2516 *mipsI:
2517 *mipsII:
2518 *mipsIII:
2519 *mipsIV:
2520 *mipsV:
2521 *vr4100:
2522 *vr5000:
2523 *r3900:
2524 {
2525 do_subu (SD_, RS, RT, RD);
2526 }
2527
2528
2529 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
2530 "sw r<RT>, <OFFSET>(r<BASE>)"
2531 *mipsI:
2532 *mipsII:
2533 *mipsIII:
2534 *mipsIV:
2535 *mipsV:
2536 *vr4100:
2537 *r3900:
2538 *vr5000:
2539 {
2540 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2541 }
2542
2543
2544 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
2545 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2546 *mipsI:
2547 *mipsII:
2548 *mipsIII:
2549 *mipsIV:
2550 *mipsV:
2551 *vr4100:
2552 *vr5000:
2553 *r3900:
2554 {
2555 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
2556 }
2557
2558
2559
2560 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
2561 {
2562 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2563 address_word reverseendian = (ReverseEndian ? -1 : 0);
2564 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2565 unsigned int byte;
2566 unsigned int word;
2567 address_word paddr;
2568 int uncached;
2569 unsigned64 memval;
2570 address_word vaddr;
2571 int nr_lhs_bits;
2572 int nr_rhs_bits;
2573
2574 vaddr = base + offset;
2575 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2576 paddr = (paddr ^ (reverseendian & mask));
2577 if (BigEndianMem == 0)
2578 paddr = paddr & ~access;
2579
2580 /* compute where within the word/mem we are */
2581 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
2582 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
2583 nr_lhs_bits = 8 * byte + 8;
2584 nr_rhs_bits = 8 * access - 8 * byte;
2585 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
2586 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
2587 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
2588 (long) ((unsigned64) paddr >> 32), (long) paddr,
2589 word, byte, nr_lhs_bits, nr_rhs_bits); */
2590
2591 if (word == 0)
2592 {
2593 memval = (rt >> nr_rhs_bits);
2594 }
2595 else
2596 {
2597 memval = (rt << nr_lhs_bits);
2598 }
2599 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
2600 (long) ((unsigned64) rt >> 32), (long) rt,
2601 (long) ((unsigned64) memval >> 32), (long) memval); */
2602 StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
2603 }
2604
2605
2606 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
2607 "swl r<RT>, <OFFSET>(r<BASE>)"
2608 *mipsI:
2609 *mipsII:
2610 *mipsIII:
2611 *mipsIV:
2612 *mipsV:
2613 *vr4100:
2614 *vr5000:
2615 *r3900:
2616 {
2617 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2618 }
2619
2620
2621 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
2622 {
2623 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2624 address_word reverseendian = (ReverseEndian ? -1 : 0);
2625 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2626 unsigned int byte;
2627 address_word paddr;
2628 int uncached;
2629 unsigned64 memval;
2630 address_word vaddr;
2631
2632 vaddr = base + offset;
2633 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2634 paddr = (paddr ^ (reverseendian & mask));
2635 if (BigEndianMem != 0)
2636 paddr &= ~access;
2637 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
2638 memval = (rt << (byte * 8));
2639 StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
2640 }
2641
2642 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
2643 "swr r<RT>, <OFFSET>(r<BASE>)"
2644 *mipsI:
2645 *mipsII:
2646 *mipsIII:
2647 *mipsIV:
2648 *mipsV:
2649 *vr4100:
2650 *vr5000:
2651 *r3900:
2652 {
2653 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2654 }
2655
2656
2657 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
2658 "sync":STYPE == 0
2659 "sync <STYPE>"
2660 *mipsII:
2661 *mipsIII:
2662 *mipsIV:
2663 *mipsV:
2664 *vr4100:
2665 *vr5000:
2666 *r3900:
2667 {
2668 SyncOperation (STYPE);
2669 }
2670
2671
2672 000000,20.CODE,001100:SPECIAL:32::SYSCALL
2673 "syscall <CODE>"
2674 *mipsI:
2675 *mipsII:
2676 *mipsIII:
2677 *mipsIV:
2678 *mipsV:
2679 *vr4100:
2680 *vr5000:
2681 *r3900:
2682 {
2683 SignalException(SystemCall, instruction_0);
2684 }
2685
2686
2687 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
2688 "teq r<RS>, r<RT>"
2689 *mipsII:
2690 *mipsIII:
2691 *mipsIV:
2692 *mipsV:
2693 *vr4100:
2694 *vr5000:
2695 {
2696 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
2697 SignalException(Trap, instruction_0);
2698 }
2699
2700
2701 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
2702 "teqi r<RS>, <IMMEDIATE>"
2703 *mipsII:
2704 *mipsIII:
2705 *mipsIV:
2706 *mipsV:
2707 *vr4100:
2708 *vr5000:
2709 {
2710 if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
2711 SignalException(Trap, instruction_0);
2712 }
2713
2714
2715 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
2716 "tge r<RS>, r<RT>"
2717 *mipsII:
2718 *mipsIII:
2719 *mipsIV:
2720 *mipsV:
2721 *vr4100:
2722 *vr5000:
2723 {
2724 if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
2725 SignalException(Trap, instruction_0);
2726 }
2727
2728
2729 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
2730 "tgei r<RS>, <IMMEDIATE>"
2731 *mipsII:
2732 *mipsIII:
2733 *mipsIV:
2734 *mipsV:
2735 *vr4100:
2736 *vr5000:
2737 {
2738 if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
2739 SignalException(Trap, instruction_0);
2740 }
2741
2742
2743 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
2744 "tgeiu r<RS>, <IMMEDIATE>"
2745 *mipsII:
2746 *mipsIII:
2747 *mipsIV:
2748 *mipsV:
2749 *vr4100:
2750 *vr5000:
2751 {
2752 if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
2753 SignalException(Trap, instruction_0);
2754 }
2755
2756
2757 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
2758 "tgeu r<RS>, r<RT>"
2759 *mipsII:
2760 *mipsIII:
2761 *mipsIV:
2762 *mipsV:
2763 *vr4100:
2764 *vr5000:
2765 {
2766 if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
2767 SignalException(Trap, instruction_0);
2768 }
2769
2770
2771 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
2772 "tlt r<RS>, r<RT>"
2773 *mipsII:
2774 *mipsIII:
2775 *mipsIV:
2776 *mipsV:
2777 *vr4100:
2778 *vr5000:
2779 {
2780 if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
2781 SignalException(Trap, instruction_0);
2782 }
2783
2784
2785 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
2786 "tlti r<RS>, <IMMEDIATE>"
2787 *mipsII:
2788 *mipsIII:
2789 *mipsIV:
2790 *mipsV:
2791 *vr4100:
2792 *vr5000:
2793 {
2794 if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
2795 SignalException(Trap, instruction_0);
2796 }
2797
2798
2799 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
2800 "tltiu r<RS>, <IMMEDIATE>"
2801 *mipsII:
2802 *mipsIII:
2803 *mipsIV:
2804 *mipsV:
2805 *vr4100:
2806 *vr5000:
2807 {
2808 if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
2809 SignalException(Trap, instruction_0);
2810 }
2811
2812
2813 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
2814 "tltu r<RS>, r<RT>"
2815 *mipsII:
2816 *mipsIII:
2817 *mipsIV:
2818 *mipsV:
2819 *vr4100:
2820 *vr5000:
2821 {
2822 if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
2823 SignalException(Trap, instruction_0);
2824 }
2825
2826
2827 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
2828 "tne r<RS>, r<RT>"
2829 *mipsII:
2830 *mipsIII:
2831 *mipsIV:
2832 *mipsV:
2833 *vr4100:
2834 *vr5000:
2835 {
2836 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2837 SignalException(Trap, instruction_0);
2838 }
2839
2840
2841 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
2842 "tne r<RS>, <IMMEDIATE>"
2843 *mipsII:
2844 *mipsIII:
2845 *mipsIV:
2846 *mipsV:
2847 *vr4100:
2848 *vr5000:
2849 {
2850 if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
2851 SignalException(Trap, instruction_0);
2852 }
2853
2854
2855 :function:::void:do_xor:int rs, int rt, int rd
2856 {
2857 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2858 GPR[rd] = GPR[rs] ^ GPR[rt];
2859 TRACE_ALU_RESULT (GPR[rd]);
2860 }
2861
2862 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
2863 "xor r<RD>, r<RS>, r<RT>"
2864 *mipsI:
2865 *mipsII:
2866 *mipsIII:
2867 *mipsIV:
2868 *mipsV:
2869 *vr4100:
2870 *vr5000:
2871 *r3900:
2872 {
2873 do_xor (SD_, RS, RT, RD);
2874 }
2875
2876
2877 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
2878 {
2879 TRACE_ALU_INPUT2 (GPR[rs], immediate);
2880 GPR[rt] = GPR[rs] ^ immediate;
2881 TRACE_ALU_RESULT (GPR[rt]);
2882 }
2883
2884 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
2885 "xori r<RT>, r<RS>, <IMMEDIATE>"
2886 *mipsI:
2887 *mipsII:
2888 *mipsIII:
2889 *mipsIV:
2890 *mipsV:
2891 *vr4100:
2892 *vr5000:
2893 *r3900:
2894 {
2895 do_xori (SD_, RS, RT, IMMEDIATE);
2896 }
2897
2898 \f
2899 //
2900 // MIPS Architecture:
2901 //
2902 // FPU Instruction Set (COP1 & COP1X)
2903 //
2904
2905
2906 :%s::::FMT:int fmt
2907 {
2908 switch (fmt)
2909 {
2910 case fmt_single: return "s";
2911 case fmt_double: return "d";
2912 case fmt_word: return "w";
2913 case fmt_long: return "l";
2914 default: return "?";
2915 }
2916 }
2917
2918 :%s::::X:int x
2919 {
2920 switch (x)
2921 {
2922 case 0: return "f";
2923 case 1: return "t";
2924 default: return "?";
2925 }
2926 }
2927
2928 :%s::::TF:int tf
2929 {
2930 if (tf)
2931 return "t";
2932 else
2933 return "f";
2934 }
2935
2936 :%s::::ND:int nd
2937 {
2938 if (nd)
2939 return "l";
2940 else
2941 return "";
2942 }
2943
2944 :%s::::COND:int cond
2945 {
2946 switch (cond)
2947 {
2948 case 00: return "f";
2949 case 01: return "un";
2950 case 02: return "eq";
2951 case 03: return "ueq";
2952 case 04: return "olt";
2953 case 05: return "ult";
2954 case 06: return "ole";
2955 case 07: return "ule";
2956 case 010: return "sf";
2957 case 011: return "ngle";
2958 case 012: return "seq";
2959 case 013: return "ngl";
2960 case 014: return "lt";
2961 case 015: return "nge";
2962 case 016: return "le";
2963 case 017: return "ngt";
2964 default: return "?";
2965 }
2966 }
2967
2968
2969 010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
2970 "abs.%s<FMT> f<FD>, f<FS>"
2971 *mipsI:
2972 *mipsII:
2973 *mipsIII:
2974 *mipsIV:
2975 *mipsV:
2976 *vr4100:
2977 *vr5000:
2978 *r3900:
2979 {
2980 unsigned32 instruction = instruction_0;
2981 int destreg = ((instruction >> 6) & 0x0000001F);
2982 int fs = ((instruction >> 11) & 0x0000001F);
2983 int format = ((instruction >> 21) & 0x00000007);
2984 {
2985 if ((format != fmt_single) && (format != fmt_double))
2986 SignalException(ReservedInstruction,instruction);
2987 else
2988 StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));
2989 }
2990 }
2991
2992
2993
2994 010001,10,3.FMT,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
2995 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
2996 *mipsI:
2997 *mipsII:
2998 *mipsIII:
2999 *mipsIV:
3000 *mipsV:
3001 *vr4100:
3002 *vr5000:
3003 *r3900:
3004 {
3005 unsigned32 instruction = instruction_0;
3006 int destreg = ((instruction >> 6) & 0x0000001F);
3007 int fs = ((instruction >> 11) & 0x0000001F);
3008 int ft = ((instruction >> 16) & 0x0000001F);
3009 int format = ((instruction >> 21) & 0x00000007);
3010 {
3011 if ((format != fmt_single) && (format != fmt_double))
3012 SignalException(ReservedInstruction, instruction);
3013 else
3014 StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));
3015 }
3016 }
3017
3018
3019
3020 // BC1F
3021 // BC1FL
3022 // BC1T
3023 // BC1TL
3024
3025 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
3026 "bc1%s<TF>%s<ND> <OFFSET>"
3027 *mipsI:
3028 *mipsII:
3029 *mipsIII:
3030 {
3031 check_branch_bug ();
3032 TRACE_BRANCH_INPUT (PREVCOC1());
3033 if (PREVCOC1() == TF)
3034 {
3035 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3036 TRACE_BRANCH_RESULT (dest);
3037 mark_branch_bug (dest);
3038 DELAY_SLOT (dest);
3039 }
3040 else if (ND)
3041 {
3042 TRACE_BRANCH_RESULT (0);
3043 NULLIFY_NEXT_INSTRUCTION ();
3044 }
3045 else
3046 {
3047 TRACE_BRANCH_RESULT (NIA);
3048 }
3049 }
3050
3051 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
3052 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
3053 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
3054 *mipsIV:
3055 *mipsV:
3056 #*vr4100:
3057 *vr5000:
3058 *r3900:
3059 {
3060 check_branch_bug ();
3061 if (GETFCC(CC) == TF)
3062 {
3063 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3064 mark_branch_bug (dest);
3065 DELAY_SLOT (dest);
3066 }
3067 else if (ND)
3068 {
3069 NULLIFY_NEXT_INSTRUCTION ();
3070 }
3071 }
3072
3073
3074
3075
3076
3077
3078 // C.EQ.S
3079 // C.EQ.D
3080 // ...
3081
3082 :function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
3083 {
3084 if ((fmt != fmt_single) && (fmt != fmt_double))
3085 SignalException (ReservedInstruction, insn);
3086 else
3087 {
3088 int less;
3089 int equal;
3090 int unordered;
3091 int condition;
3092 unsigned64 ofs = ValueFPR (fs, fmt);
3093 unsigned64 oft = ValueFPR (ft, fmt);
3094 if (NaN (ofs, fmt) || NaN (oft, fmt))
3095 {
3096 if (FCSR & FP_ENABLE (IO))
3097 {
3098 FCSR |= FP_CAUSE (IO);
3099 SignalExceptionFPE ();
3100 }
3101 less = 0;
3102 equal = 0;
3103 unordered = 1;
3104 }
3105 else
3106 {
3107 less = Less (ofs, oft, fmt);
3108 equal = Equal (ofs, oft, fmt);
3109 unordered = 0;
3110 }
3111 condition = (((cond & (1 << 2)) && less)
3112 || ((cond & (1 << 1)) && equal)
3113 || ((cond & (1 << 0)) && unordered));
3114 SETFCC (cc, condition);
3115 }
3116 }
3117
3118 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32::C.cond.fmta
3119 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
3120 *mipsI:
3121 *mipsII:
3122 *mipsIII:
3123 {
3124 do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0);
3125 }
3126
3127 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32::C.cond.fmtb
3128 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
3129 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
3130 *mipsIV:
3131 *mipsV:
3132 *vr4100:
3133 *vr5000:
3134 *r3900:
3135 {
3136 do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0);
3137 }
3138
3139
3140 010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64::CEIL.L.fmt
3141 "ceil.l.%s<FMT> f<FD>, f<FS>"
3142 *mipsIII:
3143 *mipsIV:
3144 *mipsV:
3145 *vr4100:
3146 *vr5000:
3147 *r3900:
3148 {
3149 unsigned32 instruction = instruction_0;
3150 int destreg = ((instruction >> 6) & 0x0000001F);
3151 int fs = ((instruction >> 11) & 0x0000001F);
3152 int format = ((instruction >> 21) & 0x00000007);
3153 {
3154 if ((format != fmt_single) && (format != fmt_double))
3155 SignalException(ReservedInstruction,instruction);
3156 else
3157 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long));
3158 }
3159 }
3160
3161
3162 010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32::CEIL.W
3163 *mipsII:
3164 *mipsIII:
3165 *mipsIV:
3166 *mipsV:
3167 *vr4100:
3168 *vr5000:
3169 *r3900:
3170 {
3171 unsigned32 instruction = instruction_0;
3172 int destreg = ((instruction >> 6) & 0x0000001F);
3173 int fs = ((instruction >> 11) & 0x0000001F);
3174 int format = ((instruction >> 21) & 0x00000007);
3175 {
3176 if ((format != fmt_single) && (format != fmt_double))
3177 SignalException(ReservedInstruction,instruction);
3178 else
3179 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word));
3180 }
3181 }
3182
3183
3184 // CFC1
3185 // CTC1
3186 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32::CxC1
3187 "c%s<X>c1 r<RT>, f<FS>"
3188 *mipsI:
3189 *mipsII:
3190 *mipsIII:
3191 {
3192 if (X)
3193 {
3194 if (FS == 0)
3195 PENDING_FILL(FCR0IDX,VL4_8(GPR[RT]));
3196 else if (FS == 31)
3197 PENDING_FILL(FCR31IDX,VL4_8(GPR[RT]));
3198 /* else NOP */
3199 PENDING_SCHED(FCSR, FCR31 & (1<<23), 1, 23);
3200 }
3201 else
3202 { /* control from */
3203 if (FS == 0)
3204 PENDING_FILL(RT,SIGNEXTEND(FCR0,32));
3205 else if (FS == 31)
3206 PENDING_FILL(RT,SIGNEXTEND(FCR31,32));
3207 /* else NOP */
3208 }
3209 }
3210 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32::CxC1
3211 "c%s<X>c1 r<RT>, f<FS>"
3212 *mipsIV:
3213 *mipsV:
3214 *vr4100:
3215 *vr5000:
3216 *r3900:
3217 {
3218 if (X)
3219 {
3220 /* control to */
3221 TRACE_ALU_INPUT1 (GPR[RT]);
3222 if (FS == 0)
3223 {
3224 FCR0 = VL4_8(GPR[RT]);
3225 TRACE_ALU_RESULT (FCR0);
3226 }
3227 else if (FS == 31)
3228 {
3229 FCR31 = VL4_8(GPR[RT]);
3230 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
3231 TRACE_ALU_RESULT (FCR31);
3232 }
3233 else
3234 {
3235 TRACE_ALU_RESULT0 ();
3236 }
3237 /* else NOP */
3238 }
3239 else
3240 { /* control from */
3241 if (FS == 0)
3242 {
3243 TRACE_ALU_INPUT1 (FCR0);
3244 GPR[RT] = SIGNEXTEND (FCR0, 32);
3245 }
3246 else if (FS == 31)
3247 {
3248 TRACE_ALU_INPUT1 (FCR31);
3249 GPR[RT] = SIGNEXTEND (FCR31, 32);
3250 }
3251 TRACE_ALU_RESULT (GPR[RT]);
3252 /* else NOP */
3253 }
3254 }
3255
3256
3257 //
3258 // FIXME: Does not correctly differentiate between mips*
3259 //
3260 010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32::CVT.D.fmt
3261 "cvt.d.%s<FMT> f<FD>, f<FS>"
3262 *mipsI:
3263 *mipsII:
3264 *mipsIII:
3265 *mipsIV:
3266 *mipsV:
3267 *vr4100:
3268 *vr5000:
3269 *r3900:
3270 {
3271 unsigned32 instruction = instruction_0;
3272 int destreg = ((instruction >> 6) & 0x0000001F);
3273 int fs = ((instruction >> 11) & 0x0000001F);
3274 int format = ((instruction >> 21) & 0x00000007);
3275 {
3276 if ((format == fmt_double) | 0)
3277 SignalException(ReservedInstruction,instruction);
3278 else
3279 StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double));
3280 }
3281 }
3282
3283
3284 010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64::CVT.L.fmt
3285 "cvt.l.%s<FMT> f<FD>, f<FS>"
3286 *mipsIII:
3287 *mipsIV:
3288 *mipsV:
3289 *vr4100:
3290 *vr5000:
3291 *r3900:
3292 {
3293 unsigned32 instruction = instruction_0;
3294 int destreg = ((instruction >> 6) & 0x0000001F);
3295 int fs = ((instruction >> 11) & 0x0000001F);
3296 int format = ((instruction >> 21) & 0x00000007);
3297 {
3298 if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word)))
3299 SignalException(ReservedInstruction,instruction);
3300 else
3301 StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long));
3302 }
3303 }
3304
3305
3306 //
3307 // FIXME: Does not correctly differentiate between mips*
3308 //
3309 010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32::CVT.S.fmt
3310 "cvt.s.%s<FMT> f<FD>, f<FS>"
3311 *mipsI:
3312 *mipsII:
3313 *mipsIII:
3314 *mipsIV:
3315 *mipsV:
3316 *vr4100:
3317 *vr5000:
3318 *r3900:
3319 {
3320 unsigned32 instruction = instruction_0;
3321 int destreg = ((instruction >> 6) & 0x0000001F);
3322 int fs = ((instruction >> 11) & 0x0000001F);
3323 int format = ((instruction >> 21) & 0x00000007);
3324 {
3325 if ((format == fmt_single) | 0)
3326 SignalException(ReservedInstruction,instruction);
3327 else
3328 StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single));
3329 }
3330 }
3331
3332
3333 010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32::CVT.W.fmt
3334 "cvt.w.%s<FMT> f<FD>, f<FS>"
3335 *mipsI:
3336 *mipsII:
3337 *mipsIII:
3338 *mipsIV:
3339 *mipsV:
3340 *vr4100:
3341 *vr5000:
3342 *r3900:
3343 {
3344 unsigned32 instruction = instruction_0;
3345 int destreg = ((instruction >> 6) & 0x0000001F);
3346 int fs = ((instruction >> 11) & 0x0000001F);
3347 int format = ((instruction >> 21) & 0x00000007);
3348 {
3349 if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word)))
3350 SignalException(ReservedInstruction,instruction);
3351 else
3352 StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word));
3353 }
3354 }
3355
3356
3357 010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32::DIV.fmt
3358 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
3359 *mipsI:
3360 *mipsII:
3361 *mipsIII:
3362 *mipsIV:
3363 *mipsV:
3364 *vr4100:
3365 *vr5000:
3366 *r3900:
3367 {
3368 unsigned32 instruction = instruction_0;
3369 int destreg = ((instruction >> 6) & 0x0000001F);
3370 int fs = ((instruction >> 11) & 0x0000001F);
3371 int ft = ((instruction >> 16) & 0x0000001F);
3372 int format = ((instruction >> 21) & 0x00000007);
3373 {
3374 if ((format != fmt_single) && (format != fmt_double))
3375 SignalException(ReservedInstruction,instruction);
3376 else
3377 StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));
3378 }
3379 }
3380
3381
3382 // DMFC1
3383 // DMTC1
3384 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64::DMxC1
3385 "dm%s<X>c1 r<RT>, f<FS>"
3386 *mipsIII:
3387 {
3388 if (X)
3389 {
3390 if (SizeFGR() == 64)
3391 PENDING_FILL((FS + FGRIDX),GPR[RT]);
3392 else if ((FS & 0x1) == 0)
3393 {
3394 PENDING_FILL(((FS + 1) + FGRIDX),VH4_8(GPR[RT]));
3395 PENDING_FILL((FS + FGRIDX),VL4_8(GPR[RT]));
3396 }
3397 }
3398 else
3399 {
3400 if (SizeFGR() == 64)
3401 PENDING_FILL(RT,FGR[FS]);
3402 else if ((FS & 0x1) == 0)
3403 PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
3404 else
3405 {
3406 if (STATE_VERBOSE_P(SD))
3407 sim_io_eprintf (SD,
3408 "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n",
3409 (long) CIA);
3410 PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
3411 }
3412 }
3413 }
3414 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64::DMxC1
3415 "dm%s<X>c1 r<RT>, f<FS>"
3416 *mipsIV:
3417 *mipsV:
3418 *vr4100:
3419 *vr5000:
3420 *r3900:
3421 {
3422 if (X)
3423 {
3424 if (SizeFGR() == 64)
3425 StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
3426 else if ((FS & 0x1) == 0)
3427 StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
3428 }
3429 else
3430 {
3431 if (SizeFGR() == 64)
3432 GPR[RT] = FGR[FS];
3433 else if ((FS & 0x1) == 0)
3434 GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
3435 else
3436 {
3437 if (STATE_VERBOSE_P(SD))
3438 sim_io_eprintf (SD,
3439 "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n",
3440 (long) CIA);
3441 GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
3442 }
3443 }
3444 }
3445
3446
3447 010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64::FLOOR.L.fmt
3448 "floor.l.%s<FMT> f<FD>, f<FS>"
3449 *mipsIII:
3450 *mipsIV:
3451 *mipsV:
3452 *vr4100:
3453 *vr5000:
3454 *r3900:
3455 {
3456 unsigned32 instruction = instruction_0;
3457 int destreg = ((instruction >> 6) & 0x0000001F);
3458 int fs = ((instruction >> 11) & 0x0000001F);
3459 int format = ((instruction >> 21) & 0x00000007);
3460 {
3461 if ((format != fmt_single) && (format != fmt_double))
3462 SignalException(ReservedInstruction,instruction);
3463 else
3464 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long));
3465 }
3466 }
3467
3468
3469 010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32::FLOOR.W.fmt
3470 "floor.w.%s<FMT> f<FD>, f<FS>"
3471 *mipsII:
3472 *mipsIII:
3473 *mipsIV:
3474 *mipsV:
3475 *vr4100:
3476 *vr5000:
3477 *r3900:
3478 {
3479 unsigned32 instruction = instruction_0;
3480 int destreg = ((instruction >> 6) & 0x0000001F);
3481 int fs = ((instruction >> 11) & 0x0000001F);
3482 int format = ((instruction >> 21) & 0x00000007);
3483 {
3484 if ((format != fmt_single) && (format != fmt_double))
3485 SignalException(ReservedInstruction,instruction);
3486 else
3487 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word));
3488 }
3489 }
3490
3491
3492 110101,5.BASE,5.FT,16.OFFSET:COP1:64::LDC1
3493 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
3494 *mipsI:
3495 *mipsII:
3496 *mipsIII:
3497 *mipsIV:
3498 *mipsV:
3499 *vr4100:
3500 *vr5000:
3501 *r3900:
3502 {
3503 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
3504 }
3505
3506
3507 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64::LDXC1
3508 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
3509 *mipsIV:
3510 *mipsV:
3511 *vr5000:
3512 {
3513 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
3514 }
3515
3516
3517
3518 110001,5.BASE,5.FT,16.OFFSET:COP1:32::LWC1
3519 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
3520 *mipsI:
3521 *mipsII:
3522 *mipsIII:
3523 *mipsIV:
3524 *mipsV:
3525 *vr4100:
3526 *vr5000:
3527 *r3900:
3528 {
3529 COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
3530 }
3531
3532
3533 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32::LWXC1
3534 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
3535 *mipsIV:
3536 *mipsV:
3537 *vr5000:
3538 {
3539 COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
3540 }
3541
3542
3543
3544 //
3545 // FIXME: Not correct for mips*
3546 //
3547 010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D
3548 "madd.d f<FD>, f<FR>, f<FS>, f<FT>"
3549 *mipsIV:
3550 *mipsV:
3551 *vr5000:
3552 {
3553 unsigned32 instruction = instruction_0;
3554 int destreg = ((instruction >> 6) & 0x0000001F);
3555 int fs = ((instruction >> 11) & 0x0000001F);
3556 int ft = ((instruction >> 16) & 0x0000001F);
3557 int fr = ((instruction >> 21) & 0x0000001F);
3558 {
3559 StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
3560 }
3561 }
3562
3563
3564 010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S
3565 "madd.s f<FD>, f<FR>, f<FS>, f<FT>"
3566 *mipsIV:
3567 *mipsV:
3568 *vr5000:
3569 {
3570 unsigned32 instruction = instruction_0;
3571 int destreg = ((instruction >> 6) & 0x0000001F);
3572 int fs = ((instruction >> 11) & 0x0000001F);
3573 int ft = ((instruction >> 16) & 0x0000001F);
3574 int fr = ((instruction >> 21) & 0x0000001F);
3575 {
3576 StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
3577 }
3578 }
3579
3580
3581 // MFC1
3582 // MTC1
3583 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32::MxC1
3584 "m%s<X>c1 r<RT>, f<FS>"
3585 *mipsI:
3586 *mipsII:
3587 *mipsIII:
3588 {
3589 if (X)
3590 { /*MTC1*/
3591 if (SizeFGR() == 64)
3592 {
3593 if (STATE_VERBOSE_P(SD))
3594 sim_io_eprintf (SD,
3595 "Warning: PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n",
3596 (long) CIA);
3597 PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
3598 }
3599 else
3600 PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT]));
3601 }
3602 else /*MFC1*/
3603 PENDING_FILL (RT, SIGNEXTEND(FGR[FS],32));
3604 }
3605 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32::MxC1
3606 "m%s<X>c1 r<RT>, f<FS>"
3607 *mipsIV:
3608 *mipsV:
3609 *vr4100:
3610 *vr5000:
3611 *r3900:
3612 {
3613 int fs = FS;
3614 if (X)
3615 /*MTC1*/
3616 StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
3617 else /*MFC1*/
3618 GPR[RT] = SIGNEXTEND(FGR[FS],32);
3619 }
3620
3621
3622 010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32::MOV.fmt
3623 "mov.%s<FMT> f<FD>, f<FS>"
3624 *mipsI:
3625 *mipsII:
3626 *mipsIII:
3627 *mipsIV:
3628 *mipsV:
3629 *vr4100:
3630 *vr5000:
3631 *r3900:
3632 {
3633 unsigned32 instruction = instruction_0;
3634 int destreg = ((instruction >> 6) & 0x0000001F);
3635 int fs = ((instruction >> 11) & 0x0000001F);
3636 int format = ((instruction >> 21) & 0x00000007);
3637 {
3638 StoreFPR(destreg,format,ValueFPR(fs,format));
3639 }
3640 }
3641
3642
3643 // MOVF
3644 // MOVT
3645 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32::MOVtf
3646 "mov%s<TF> r<RD>, r<RS>, <CC>"
3647 *mipsIV:
3648 *mipsV:
3649 *vr5000:
3650 {
3651 if (GETFCC(CC) == TF)
3652 GPR[RD] = GPR[RS];
3653 }
3654
3655
3656 // MOVF.fmt
3657 // MOVT.fmt
3658 010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32::MOVtf.fmt
3659 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
3660 *mipsIV:
3661 *mipsV:
3662 *vr5000:
3663 {
3664 unsigned32 instruction = instruction_0;
3665 int format = ((instruction >> 21) & 0x00000007);
3666 {
3667 if (GETFCC(CC) == TF)
3668 StoreFPR (FD, format, ValueFPR (FS, format));
3669 else
3670 StoreFPR (FD, format, ValueFPR (FD, format));
3671 }
3672 }
3673
3674
3675 010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32::MOVN.fmt
3676 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
3677 *mipsIV:
3678 *mipsV:
3679 *vr5000:
3680 {
3681 if (GPR[RT] != 0)
3682 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
3683 else
3684 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
3685 }
3686
3687
3688 // MOVT see MOVtf
3689
3690
3691 // MOVT.fmt see MOVtf.fmt
3692
3693
3694
3695 010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32::MOVZ.fmt
3696 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
3697 *mipsIV:
3698 *mipsV:
3699 *vr5000:
3700 {
3701 if (GPR[RT] == 0)
3702 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
3703 else
3704 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
3705 }
3706
3707
3708 // MSUB.fmt
3709 010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32::MSUB.D
3710 "msub.d f<FD>, f<FR>, f<FS>, f<FT>"
3711 *mipsIV:
3712 *mipsV:
3713 *vr5000:
3714 {
3715 unsigned32 instruction = instruction_0;
3716 int destreg = ((instruction >> 6) & 0x0000001F);
3717 int fs = ((instruction >> 11) & 0x0000001F);
3718 int ft = ((instruction >> 16) & 0x0000001F);
3719 int fr = ((instruction >> 21) & 0x0000001F);
3720 {
3721 StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
3722 }
3723 }
3724
3725
3726 // MSUB.fmt
3727 010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32::MSUB.S
3728 "msub.s f<FD>, f<FR>, f<FS>, f<FT>"
3729 *mipsIV:
3730 *mipsV:
3731 *vr5000:
3732 {
3733 unsigned32 instruction = instruction_0;
3734 int destreg = ((instruction >> 6) & 0x0000001F);
3735 int fs = ((instruction >> 11) & 0x0000001F);
3736 int ft = ((instruction >> 16) & 0x0000001F);
3737 int fr = ((instruction >> 21) & 0x0000001F);
3738 {
3739 StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
3740 }
3741 }
3742
3743
3744 // MTC1 see MxC1
3745
3746
3747 010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32::MUL.fmt
3748 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
3749 *mipsI:
3750 *mipsII:
3751 *mipsIII:
3752 *mipsIV:
3753 *mipsV:
3754 *vr4100:
3755 *vr5000:
3756 *r3900:
3757 {
3758 unsigned32 instruction = instruction_0;
3759 int destreg = ((instruction >> 6) & 0x0000001F);
3760 int fs = ((instruction >> 11) & 0x0000001F);
3761 int ft = ((instruction >> 16) & 0x0000001F);
3762 int format = ((instruction >> 21) & 0x00000007);
3763 {
3764 if ((format != fmt_single) && (format != fmt_double))
3765 SignalException(ReservedInstruction,instruction);
3766 else
3767 StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));
3768 }
3769 }
3770
3771
3772 010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32::NEG.fmt
3773 "neg.%s<FMT> f<FD>, f<FS>"
3774 *mipsI:
3775 *mipsII:
3776 *mipsIII:
3777 *mipsIV:
3778 *mipsV:
3779 *vr4100:
3780 *vr5000:
3781 *r3900:
3782 {
3783 unsigned32 instruction = instruction_0;
3784 int destreg = ((instruction >> 6) & 0x0000001F);
3785 int fs = ((instruction >> 11) & 0x0000001F);
3786 int format = ((instruction >> 21) & 0x00000007);
3787 {
3788 if ((format != fmt_single) && (format != fmt_double))
3789 SignalException(ReservedInstruction,instruction);
3790 else
3791 StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));
3792 }
3793 }
3794
3795
3796 // NMADD.fmt
3797 010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32::NMADD.D
3798 "nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
3799 *mipsIV:
3800 *mipsV:
3801 *vr5000:
3802 {
3803 unsigned32 instruction = instruction_0;
3804 int destreg = ((instruction >> 6) & 0x0000001F);
3805 int fs = ((instruction >> 11) & 0x0000001F);
3806 int ft = ((instruction >> 16) & 0x0000001F);
3807 int fr = ((instruction >> 21) & 0x0000001F);
3808 {
3809 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));
3810 }
3811 }
3812
3813
3814 // NMADD.fmt
3815 010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32::NMADD.S
3816 "nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
3817 *mipsIV:
3818 *mipsV:
3819 *vr5000:
3820 {
3821 unsigned32 instruction = instruction_0;
3822 int destreg = ((instruction >> 6) & 0x0000001F);
3823 int fs = ((instruction >> 11) & 0x0000001F);
3824 int ft = ((instruction >> 16) & 0x0000001F);
3825 int fr = ((instruction >> 21) & 0x0000001F);
3826 {
3827 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));
3828 }
3829 }
3830
3831
3832 // NMSUB.fmt
3833 010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32::NMSUB.D
3834 "nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
3835 *mipsIV:
3836 *mipsV:
3837 *vr5000:
3838 {
3839 unsigned32 instruction = instruction_0;
3840 int destreg = ((instruction >> 6) & 0x0000001F);
3841 int fs = ((instruction >> 11) & 0x0000001F);
3842 int ft = ((instruction >> 16) & 0x0000001F);
3843 int fr = ((instruction >> 21) & 0x0000001F);
3844 {
3845 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));
3846 }
3847 }
3848
3849
3850 // NMSUB.fmt
3851 010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32::NMSUB.S
3852 "nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
3853 *mipsIV:
3854 *mipsV:
3855 *vr5000:
3856 {
3857 unsigned32 instruction = instruction_0;
3858 int destreg = ((instruction >> 6) & 0x0000001F);
3859 int fs = ((instruction >> 11) & 0x0000001F);
3860 int ft = ((instruction >> 16) & 0x0000001F);
3861 int fr = ((instruction >> 21) & 0x0000001F);
3862 {
3863 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));
3864 }
3865 }
3866
3867
3868 010011,5.BASE,5.INDEX,5.HINT,00000001111:COP1X:32::PREFX
3869 "prefx <HINT>, r<INDEX>(r<BASE>)"
3870 *mipsIV:
3871 *mipsV:
3872 *vr5000:
3873 {
3874 unsigned32 instruction = instruction_0;
3875 int fs = ((instruction >> 11) & 0x0000001F);
3876 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
3877 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
3878 {
3879 address_word vaddr = ((unsigned64)op1 + (unsigned64)op2);
3880 address_word paddr;
3881 int uncached;
3882 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
3883 Prefetch(uncached,paddr,vaddr,isDATA,fs);
3884 }
3885 }
3886
3887 010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32::RECIP.fmt
3888 "recip.%s<FMT> f<FD>, f<FS>"
3889 *mipsIV:
3890 *mipsV:
3891 *vr5000:
3892 {
3893 unsigned32 instruction = instruction_0;
3894 int destreg = ((instruction >> 6) & 0x0000001F);
3895 int fs = ((instruction >> 11) & 0x0000001F);
3896 int format = ((instruction >> 21) & 0x00000007);
3897 {
3898 if ((format != fmt_single) && (format != fmt_double))
3899 SignalException(ReservedInstruction,instruction);
3900 else
3901 StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));
3902 }
3903 }
3904
3905
3906 010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64::ROUND.L.fmt
3907 "round.l.%s<FMT> f<FD>, f<FS>"
3908 *mipsIII:
3909 *mipsIV:
3910 *mipsV:
3911 *vr4100:
3912 *vr5000:
3913 *r3900:
3914 {
3915 unsigned32 instruction = instruction_0;
3916 int destreg = ((instruction >> 6) & 0x0000001F);
3917 int fs = ((instruction >> 11) & 0x0000001F);
3918 int format = ((instruction >> 21) & 0x00000007);
3919 {
3920 if ((format != fmt_single) && (format != fmt_double))
3921 SignalException(ReservedInstruction,instruction);
3922 else
3923 StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long));
3924 }
3925 }
3926
3927
3928 010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32::ROUND.W.fmt
3929 "round.w.%s<FMT> f<FD>, f<FS>"
3930 *mipsII:
3931 *mipsIII:
3932 *mipsIV:
3933 *mipsV:
3934 *vr4100:
3935 *vr5000:
3936 *r3900:
3937 {
3938 unsigned32 instruction = instruction_0;
3939 int destreg = ((instruction >> 6) & 0x0000001F);
3940 int fs = ((instruction >> 11) & 0x0000001F);
3941 int format = ((instruction >> 21) & 0x00000007);
3942 {
3943 if ((format != fmt_single) && (format != fmt_double))
3944 SignalException(ReservedInstruction,instruction);
3945 else
3946 StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word));
3947 }
3948 }
3949
3950
3951 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32::RSQRT.fmt
3952 *mipsIV:
3953 *mipsV:
3954 "rsqrt.%s<FMT> f<FD>, f<FS>"
3955 *vr5000:
3956 {
3957 unsigned32 instruction = instruction_0;
3958 int destreg = ((instruction >> 6) & 0x0000001F);
3959 int fs = ((instruction >> 11) & 0x0000001F);
3960 int format = ((instruction >> 21) & 0x00000007);
3961 {
3962 if ((format != fmt_single) && (format != fmt_double))
3963 SignalException(ReservedInstruction,instruction);
3964 else
3965 StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format),format));
3966 }
3967 }
3968
3969
3970 111101,5.BASE,5.FT,16.OFFSET:COP1:64::SDC1
3971 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
3972 *mipsI:
3973 *mipsII:
3974 *mipsIII:
3975 *mipsIV:
3976 *mipsV:
3977 *vr4100:
3978 *vr5000:
3979 *r3900:
3980 {
3981 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
3982 }
3983
3984
3985 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64::SDXC1
3986 "ldxc1 f<FS>, r<INDEX>(r<BASE>)"
3987 *mipsIV:
3988 *mipsV:
3989 *vr5000:
3990 {
3991 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
3992 }
3993
3994
3995 010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32::SQRT.fmt
3996 "sqrt.%s<FMT> f<FD>, f<FS>"
3997 *mipsII:
3998 *mipsIII:
3999 *mipsIV:
4000 *mipsV:
4001 *vr4100:
4002 *vr5000:
4003 *r3900:
4004 {
4005 unsigned32 instruction = instruction_0;
4006 int destreg = ((instruction >> 6) & 0x0000001F);
4007 int fs = ((instruction >> 11) & 0x0000001F);
4008 int format = ((instruction >> 21) & 0x00000007);
4009 {
4010 if ((format != fmt_single) && (format != fmt_double))
4011 SignalException(ReservedInstruction,instruction);
4012 else
4013 StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format)));
4014 }
4015 }
4016
4017
4018 010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32::SUB.fmt
4019 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
4020 *mipsI:
4021 *mipsII:
4022 *mipsIII:
4023 *mipsIV:
4024 *mipsV:
4025 *vr4100:
4026 *vr5000:
4027 *r3900:
4028 {
4029 unsigned32 instruction = instruction_0;
4030 int destreg = ((instruction >> 6) & 0x0000001F);
4031 int fs = ((instruction >> 11) & 0x0000001F);
4032 int ft = ((instruction >> 16) & 0x0000001F);
4033 int format = ((instruction >> 21) & 0x00000007);
4034 {
4035 if ((format != fmt_single) && (format != fmt_double))
4036 SignalException(ReservedInstruction,instruction);
4037 else
4038 StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));
4039 }
4040 }
4041
4042
4043
4044 111001,5.BASE,5.FT,16.OFFSET:COP1:32::SWC1
4045 "swc1 f<FT>, <OFFSET>(r<BASE>)"
4046 *mipsI:
4047 *mipsII:
4048 *mipsIII:
4049 *mipsIV:
4050 *mipsV:
4051 *vr4100:
4052 *vr5000:
4053 *r3900:
4054 {
4055 unsigned32 instruction = instruction_0;
4056 signed_word offset = EXTEND16 (OFFSET);
4057 int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
4058 signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
4059 {
4060 address_word vaddr = ((uword64)op1 + offset);
4061 address_word paddr;
4062 int uncached;
4063 if ((vaddr & 3) != 0)
4064 {
4065 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
4066 }
4067 else
4068 {
4069 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4070 {
4071 uword64 memval = 0;
4072 uword64 memval1 = 0;
4073 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4074 address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
4075 address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
4076 unsigned int byte;
4077 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4078 byte = ((vaddr & mask) ^ bigendiancpu);
4079 memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte));
4080 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4081 }
4082 }
4083 }
4084 }
4085
4086
4087 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32::SWXC1
4088 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
4089 *mipsIV:
4090 *mipsV:
4091 *vr5000:
4092 {
4093 unsigned32 instruction = instruction_0;
4094 int fs = ((instruction >> 11) & 0x0000001F);
4095 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
4096 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
4097 {
4098 address_word vaddr = ((unsigned64)op1 + op2);
4099 address_word paddr;
4100 int uncached;
4101 if ((vaddr & 3) != 0)
4102 {
4103 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
4104 }
4105 else
4106 {
4107 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4108 {
4109 unsigned64 memval = 0;
4110 unsigned64 memval1 = 0;
4111 unsigned64 mask = 0x7;
4112 unsigned int byte;
4113 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
4114 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
4115 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
4116 {
4117 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4118 }
4119 }
4120 }
4121 }
4122 }
4123
4124
4125 010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64::TRUNC.L.fmt
4126 "trunc.l.%s<FMT> f<FD>, f<FS>"
4127 *mipsIII:
4128 *mipsIV:
4129 *mipsV:
4130 *vr4100:
4131 *vr5000:
4132 *r3900:
4133 {
4134 unsigned32 instruction = instruction_0;
4135 int destreg = ((instruction >> 6) & 0x0000001F);
4136 int fs = ((instruction >> 11) & 0x0000001F);
4137 int format = ((instruction >> 21) & 0x00000007);
4138 {
4139 if ((format != fmt_single) && (format != fmt_double))
4140 SignalException(ReservedInstruction,instruction);
4141 else
4142 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long));
4143 }
4144 }
4145
4146
4147 010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32::TRUNC.W
4148 "trunc.w.%s<FMT> f<FD>, f<FS>"
4149 *mipsII:
4150 *mipsIII:
4151 *mipsIV:
4152 *mipsV:
4153 *vr4100:
4154 *vr5000:
4155 *r3900:
4156 {
4157 unsigned32 instruction = instruction_0;
4158 int destreg = ((instruction >> 6) & 0x0000001F);
4159 int fs = ((instruction >> 11) & 0x0000001F);
4160 int format = ((instruction >> 21) & 0x00000007);
4161 {
4162 if ((format != fmt_single) && (format != fmt_double))
4163 SignalException(ReservedInstruction,instruction);
4164 else
4165 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word));
4166 }
4167 }
4168
4169 \f
4170 //
4171 // MIPS Architecture:
4172 //
4173 // System Control Instruction Set (COP0)
4174 //
4175
4176
4177 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4178 "bc0f <OFFSET>"
4179 *mipsI:
4180 *mipsII:
4181 *mipsIII:
4182 *mipsIV:
4183 *mipsV:
4184 *vr4100:
4185 *vr5000:
4186
4187 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4188 "bc0f <OFFSET>"
4189 // stub needed for eCos as tx39 hardware bug workaround
4190 *r3900:
4191 {
4192 /* do nothing */
4193 }
4194
4195
4196 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
4197 "bc0fl <OFFSET>"
4198 *mipsI:
4199 *mipsII:
4200 *mipsIII:
4201 *mipsIV:
4202 *mipsV:
4203 *vr4100:
4204 *vr5000:
4205
4206
4207 010000,01000,00001,16.OFFSET:COP0:32::BC0T
4208 "bc0t <OFFSET>"
4209 *mipsI:
4210 *mipsII:
4211 *mipsIII:
4212 *mipsIV:
4213 *mipsV:
4214 *vr4100:
4215
4216
4217 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
4218 "bc0tl <OFFSET>"
4219 *mipsI:
4220 *mipsII:
4221 *mipsIII:
4222 *mipsIV:
4223 *mipsV:
4224 *vr4100:
4225 *vr5000:
4226
4227
4228 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
4229 *mipsIII:
4230 *mipsIV:
4231 *mipsV:
4232 *vr4100:
4233 *vr5000:
4234 *r3900:
4235 {
4236 unsigned32 instruction = instruction_0;
4237 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
4238 int hint = ((instruction >> 16) & 0x0000001F);
4239 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
4240 {
4241 address_word vaddr = (op1 + offset);
4242 address_word paddr;
4243 int uncached;
4244 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
4245 CacheOp(hint,vaddr,paddr,instruction);
4246 }
4247 }
4248
4249
4250 010000,1,0000000000000000000,111001:COP0:32::DI
4251 "di"
4252 *mipsI:
4253 *mipsII:
4254 *mipsIII:
4255 *mipsIV:
4256 *mipsV:
4257 *vr4100:
4258 *vr5000:
4259
4260
4261 010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
4262 "dmfc0 r<RT>, r<RD>"
4263 *mipsIII:
4264 *mipsIV:
4265 *mipsV:
4266 {
4267 DecodeCoproc (instruction_0);
4268 }
4269
4270
4271 010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
4272 "dmtc0 r<RT>, r<RD>"
4273 *mipsIII:
4274 *mipsIV:
4275 *mipsV:
4276 {
4277 DecodeCoproc (instruction_0);
4278 }
4279
4280
4281 010000,1,0000000000000000000,111000:COP0:32::EI
4282 "ei"
4283 *mipsI:
4284 *mipsII:
4285 *mipsIII:
4286 *mipsIV:
4287 *mipsV:
4288 *vr4100:
4289 *vr5000:
4290
4291
4292 010000,1,0000000000000000000,011000:COP0:32::ERET
4293 "eret"
4294 *mipsIII:
4295 *mipsIV:
4296 *mipsV:
4297 *vr4100:
4298 *vr5000:
4299 {
4300 if (SR & status_ERL)
4301 {
4302 /* Oops, not yet available */
4303 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
4304 NIA = EPC;
4305 SR &= ~status_ERL;
4306 }
4307 else
4308 {
4309 NIA = EPC;
4310 SR &= ~status_EXL;
4311 }
4312 }
4313
4314
4315 010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
4316 "mfc0 r<RT>, r<RD> # <REGX>"
4317 *mipsI:
4318 *mipsII:
4319 *mipsIII:
4320 *mipsIV:
4321 *mipsV:
4322 *vr4100:
4323 *vr5000:
4324 *r3900:
4325 {
4326 TRACE_ALU_INPUT0 ();
4327 DecodeCoproc (instruction_0);
4328 TRACE_ALU_RESULT (GPR[RT]);
4329 }
4330
4331 010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
4332 "mtc0 r<RT>, r<RD> # <REGX>"
4333 *mipsI:
4334 *mipsII:
4335 *mipsIII:
4336 *mipsIV:
4337 *mipsV:
4338 *vr4100:
4339 *vr5000:
4340 *r3900:
4341 {
4342 DecodeCoproc (instruction_0);
4343 }
4344
4345
4346 010000,1,0000000000000000000,010000:COP0:32::RFE
4347 "rfe"
4348 *mipsI:
4349 *mipsII:
4350 *mipsIII:
4351 *mipsIV:
4352 *mipsV:
4353 *vr4100:
4354 *vr5000:
4355 *r3900:
4356 {
4357 DecodeCoproc (instruction_0);
4358 }
4359
4360
4361 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
4362 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
4363 *mipsI:
4364 *mipsII:
4365 *mipsIII:
4366 *mipsIV:
4367 *mipsV:
4368 *vr4100:
4369 *r3900:
4370 {
4371 DecodeCoproc (instruction_0);
4372 }
4373
4374
4375
4376 010000,1,0000000000000000000,001000:COP0:32::TLBP
4377 "tlbp"
4378 *mipsI:
4379 *mipsII:
4380 *mipsIII:
4381 *mipsIV:
4382 *mipsV:
4383 *vr4100:
4384 *vr5000:
4385
4386
4387 010000,1,0000000000000000000,000001:COP0:32::TLBR
4388 "tlbr"
4389 *mipsI:
4390 *mipsII:
4391 *mipsIII:
4392 *mipsIV:
4393 *mipsV:
4394 *vr4100:
4395 *vr5000:
4396
4397
4398 010000,1,0000000000000000000,000010:COP0:32::TLBWI
4399 "tlbwi"
4400 *mipsI:
4401 *mipsII:
4402 *mipsIII:
4403 *mipsIV:
4404 *mipsV:
4405 *vr4100:
4406 *vr5000:
4407
4408
4409 010000,1,0000000000000000000,000110:COP0:32::TLBWR
4410 "tlbwr"
4411 *mipsI:
4412 *mipsII:
4413 *mipsIII:
4414 *mipsIV:
4415 *mipsV:
4416 *vr4100:
4417 *vr5000:
4418
4419 \f
4420 :include:::m16.igen
4421 :include:::tx.igen
4422 :include:::vr.igen
4423 \f
This page took 0.115056 seconds and 5 git commands to generate.