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