1// -*- C -*-
2//
3//    <insn> ::=
4//        <insn-word> { "+" <insn-word> }
5//        ":" <format-name>
6//        ":" <filter-flags>
7//        ":" <options>
8//        ":" <name>
9//        <nl>
10//        { <insn-model> }
11//        { <insn-mnemonic> }
12//        <code-block>
13//
14
15
16// IGEN config - mips16
17// :option:16::insn-bit-size:16
18// :option:16::hi-bit-nr:15
19:option:16::insn-specifying-widths:true
20:option:16::gen-delayed-branch:false
21
22// IGEN config - mips32/64..
23// :option:32::insn-bit-size:32
24// :option:32::hi-bit-nr:31
25:option:32::insn-specifying-widths:true
26:option:32::gen-delayed-branch:false
27
28
29// Generate separate simulators for each target
30// :option:::multi-sim:true
31
32
33// Models known by this simulator are defined below.
34//
35// When placing models in the instruction descriptions, please place
36// them one per line, in the order given here.
37
38//  MIPS ISAs:
39//
40//  Instructions and related functions for these models are included in
41//  this file.
42:model:::mipsI:mips3000:
43:model:::mipsII:mips6000:
44:model:::mipsIII:mips4000:
45:model:::mipsIV:mips8000:
46:model:::mipsV:mipsisaV:
47:model:::mips32:mipsisa32:
48:model:::mips64:mipsisa64:
49
50//  Vendor ISAs:
51//
52//  Standard MIPS ISA instructions used for these models are listed here,
53//  as are functions needed by those standard instructions.  Instructions
54//  which are model-dependent and which are not in the standard MIPS ISAs
55//  (or which pre-date or use different encodings than the standard
56//  instructions) are (for the most part) in separate .igen files.
57:model:::vr4100:mips4100:		// vr.igen
58:model:::vr4120:mips4120:
59:model:::vr5000:mips5000:
60:model:::vr5400:mips5400:
61:model:::vr5500:mips5500:
62:model:::r3900:mips3900:		// tx.igen
63
64//  MIPS Application Specific Extensions (ASEs)
65//
66//  Instructions for the ASEs are in separate .igen files.
67//  ASEs add instructions on to a base ISA.
68:model:::mips16:mips16:			// m16.igen (and m16.dc)
69:model:::mips3d:mips3d:			// mips3d.igen
70:model:::mdmx:mdmx:			// mdmx.igen
71
72//  Vendor Extensions
73//
74//  Instructions specific to these extensions are in separate .igen files.
75//  Extensions add instructions on to a base ISA.
76:model:::sb1:sb1:			// sb1.igen
77
78
79// Pseudo instructions known by IGEN
80:internal::::illegal:
81{
82  SignalException (ReservedInstruction, 0);
83}
84
85
86// Pseudo instructions known by interp.c
87// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
88000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
89"rsvd <OP>"
90{
91  SignalException (ReservedInstruction, instruction_0);
92}
93
94
95
96// Helper:
97//
98// Simulate a 32 bit delayslot instruction
99//
100
101:function:::address_word:delayslot32:address_word target
102{
103  instruction_word delay_insn;
104  sim_events_slip (SD, 1);
105  DSPC = CIA;
106  CIA = CIA + 4; /* NOTE not mips16 */
107  STATE |= simDELAYSLOT;
108  delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
109  ENGINE_ISSUE_PREFIX_HOOK();
110  idecode_issue (CPU_, delay_insn, (CIA));
111  STATE &= ~simDELAYSLOT;
112  return target;
113}
114
115:function:::address_word:nullify_next_insn32:
116{
117  sim_events_slip (SD, 1);
118  dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
119  return CIA + 8;
120}
121
122
123// Helper:
124//
125// Calculate an effective address given a base and an offset.
126//
127
128:function:::address_word:loadstore_ea:address_word base, address_word offset
129*mipsI:
130*mipsII:
131*mipsIII:
132*mipsIV:
133*mipsV:
134*mips32:
135*vr4100:
136*vr5000:
137*r3900:
138{
139  return base + offset;
140}
141
142:function:::address_word:loadstore_ea:address_word base, address_word offset
143*mips64:
144{
145#if 0 /* XXX FIXME: enable this only after some additional testing.  */
146  /* If in user mode and UX is not set, use 32-bit compatibility effective
147     address computations as defined in the MIPS64 Architecture for
148     Programmers Volume III, Revision 0.95, section 4.9.  */
149  if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX))
150      == (ksu_user << status_KSU_shift))
151    return (address_word)((signed32)base + (signed32)offset);
152#endif
153  return base + offset;
154}
155
156
157// Helper:
158//
159// Check that a 32-bit register value is properly sign-extended.
160// (See NotWordValue in ISA spec.)
161//
162
163:function:::int:not_word_value:unsigned_word value
164*mipsI:
165*mipsII:
166*mipsIII:
167*mipsIV:
168*mipsV:
169*vr4100:
170*vr5000:
171*r3900:
172{
173  /* For historical simulator compatibility (until documentation is
174     found that makes these operations unpredictable on some of these
175     architectures), this check never returns true.  */
176  return 0;
177}
178
179:function:::int:not_word_value:unsigned_word value
180*mips32:
181{
182  /* On MIPS32, since registers are 32-bits, there's no check to be done.  */
183  return 0;
184}
185
186:function:::int:not_word_value:unsigned_word value
187*mips64:
188{
189  return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0));
190}
191
192
193// Helper:
194//
195// Handle UNPREDICTABLE operation behaviour.  The goal here is to prevent
196// theoretically portable code which invokes non-portable behaviour from
197// running with no indication of the portability issue.
198// (See definition of UNPREDICTABLE in ISA spec.)
199//
200
201:function:::void:unpredictable:
202*mipsI:
203*mipsII:
204*mipsIII:
205*mipsIV:
206*mipsV:
207*vr4100:
208*vr5000:
209*r3900:
210{
211}
212
213:function:::void:unpredictable:
214*mips32:
215*mips64:
216{
217  unpredictable_action (CPU, CIA);
218}
219
220
221// Helpers:
222//
223// Check that an access to a HI/LO register meets timing requirements
224//
225// In all MIPS ISAs,
226//
227//	OP {HI and LO} followed by MT{LO or HI} (and not MT{HI or LO})
228//	makes subsequent MF{HI or LO} UNPREDICTABLE. (1)
229//
230// The following restrictions exist for MIPS I - MIPS III:
231//
232//	MF{HI or LO} followed by MT{HI or LO} w/ less than 2 instructions
233//	in between makes MF UNPREDICTABLE. (2)
234//
235//	MF{HI or LO} followed by OP {HI and LO} w/ less than 2 instructions
236//	in between makes MF UNPREDICTABLE. (3)
237//
238// On the r3900, restriction (2) is not present, and restriction (3) is not
239// present for multiplication.
240//
241// Unfortunately, there seems to be some confusion about whether the last
242// two restrictions should apply to "MIPS IV" as well.  One edition of
243// the MIPS IV ISA says they do, but references in later ISA documents
244// suggest they don't.
245//
246// In reality, some MIPS IV parts, such as the VR5000 and VR5400, do have
247// these restrictions, while others, like the VR5500, don't.  To accomodate
248// such differences, the MIPS IV and MIPS V version of these helper functions
249// use auxillary routines to determine whether the restriction applies.
250
251// check_mf_cycles:
252//
253// Helper used by check_mt_hilo, check_mult_hilo, and check_div_hilo
254// to check for restrictions (2) and (3) above.
255//
256:function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
257{
258  if (history->mf.timestamp + 3 > time)
259    {
260      sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
261			itable[MY_INDEX].name,
262			new, (long) CIA,
263			(long) history->mf.cia);
264      return 0;
265    }
266  return 1;
267}
268
269
270// check_mt_hilo:
271//
272// Check for restriction (2) above (for ISAs/processors that have it),
273// and record timestamps for restriction (1) above.
274//
275:function:::int:check_mt_hilo:hilo_history *history
276*mipsI:
277*mipsII:
278*mipsIII:
279*vr4100:
280*vr5000:
281{
282  signed64 time = sim_events_time (SD);
283  int ok = check_mf_cycles (SD_, history, time, "MT");
284  history->mt.timestamp = time;
285  history->mt.cia = CIA;
286  return ok;
287}
288
289:function:::int:check_mt_hilo:hilo_history *history
290*mipsIV:
291*mipsV:
292{
293  signed64 time = sim_events_time (SD);
294  int ok = (! MIPS_MACH_HAS_MT_HILO_HAZARD (SD)
295	    || check_mf_cycles (SD_, history, time, "MT"));
296  history->mt.timestamp = time;
297  history->mt.cia = CIA;
298  return ok;
299}
300
301:function:::int:check_mt_hilo:hilo_history *history
302*mips32:
303*mips64:
304*r3900:
305{
306  signed64 time = sim_events_time (SD);
307  history->mt.timestamp = time;
308  history->mt.cia = CIA;
309  return 1;
310}
311
312
313// check_mf_hilo:
314//
315// Check for restriction (1) above, and record timestamps for
316// restriction (2) and (3) above.
317//
318:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
319*mipsI:
320*mipsII:
321*mipsIII:
322*mipsIV:
323*mipsV:
324*mips32:
325*mips64:
326*vr4100:
327*vr5000:
328*r3900:
329{
330  signed64 time = sim_events_time (SD);
331  int ok = 1;
332  if (peer != NULL
333      && peer->mt.timestamp > history->op.timestamp
334      && history->mt.timestamp < history->op.timestamp
335      && ! (history->mf.timestamp > history->op.timestamp
336	    && history->mf.timestamp < peer->mt.timestamp)
337      && ! (peer->mf.timestamp > history->op.timestamp
338	    && peer->mf.timestamp < peer->mt.timestamp))
339    {
340      /* The peer has been written to since the last OP yet we have
341         not */
342      sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
343			itable[MY_INDEX].name,
344			(long) CIA,
345			(long) history->op.cia,
346			(long) peer->mt.cia);
347      ok = 0;
348    }
349  history->mf.timestamp = time;
350  history->mf.cia = CIA;
351  return ok;
352}
353
354
355
356// check_mult_hilo:
357//
358// Check for restriction (3) above (for ISAs/processors that have it)
359// for MULT ops, and record timestamps for restriction (1) above.
360//
361:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
362*mipsI:
363*mipsII:
364*mipsIII:
365*vr4100:
366*vr5000:
367{
368  signed64 time = sim_events_time (SD);
369  int ok = (check_mf_cycles (SD_, hi, time, "OP")
370	    && check_mf_cycles (SD_, lo, time, "OP"));
371  hi->op.timestamp = time;
372  lo->op.timestamp = time;
373  hi->op.cia = CIA;
374  lo->op.cia = CIA;
375  return ok;
376}
377
378:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
379*mipsIV:
380*mipsV:
381{
382  signed64 time = sim_events_time (SD);
383  int ok = (! MIPS_MACH_HAS_MULT_HILO_HAZARD (SD)
384	    || (check_mf_cycles (SD_, hi, time, "OP")
385	        && check_mf_cycles (SD_, lo, time, "OP")));
386  hi->op.timestamp = time;
387  lo->op.timestamp = time;
388  hi->op.cia = CIA;
389  lo->op.cia = CIA;
390  return ok;
391}
392
393:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
394*mips32:
395*mips64:
396*r3900:
397{
398  /* FIXME: could record the fact that a stall occured if we want */
399  signed64 time = sim_events_time (SD);
400  hi->op.timestamp = time;
401  lo->op.timestamp = time;
402  hi->op.cia = CIA;
403  lo->op.cia = CIA;
404  return 1;
405}
406
407
408// check_div_hilo:
409//
410// Check for restriction (3) above (for ISAs/processors that have it)
411// for DIV ops, and record timestamps for restriction (1) above.
412//
413:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
414*mipsI:
415*mipsII:
416*mipsIII:
417*vr4100:
418*vr5000:
419*r3900:
420{
421  signed64 time = sim_events_time (SD);
422  int ok = (check_mf_cycles (SD_, hi, time, "OP")
423	    && check_mf_cycles (SD_, lo, time, "OP"));
424  hi->op.timestamp = time;
425  lo->op.timestamp = time;
426  hi->op.cia = CIA;
427  lo->op.cia = CIA;
428  return ok;
429}
430
431:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
432*mipsIV:
433*mipsV:
434{
435  signed64 time = sim_events_time (SD);
436  int ok = (! MIPS_MACH_HAS_DIV_HILO_HAZARD (SD)
437	    || (check_mf_cycles (SD_, hi, time, "OP")
438	        && check_mf_cycles (SD_, lo, time, "OP")));
439  hi->op.timestamp = time;
440  lo->op.timestamp = time;
441  hi->op.cia = CIA;
442  lo->op.cia = CIA;
443  return ok;
444}
445
446:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
447*mips32:
448*mips64:
449{
450  signed64 time = sim_events_time (SD);
451  hi->op.timestamp = time;
452  lo->op.timestamp = time;
453  hi->op.cia = CIA;
454  lo->op.cia = CIA;
455  return 1;
456}
457
458
459// Helper:
460//
461// Check that the 64-bit instruction can currently be used, and signal
462// a ReservedInstruction exception if not.
463//
464
465:function:::void:check_u64:instruction_word insn
466*mipsIII:
467*mipsIV:
468*mipsV:
469*vr4100:
470*vr5000:
471{
472  // The check should be similar to mips64 for any with PX/UX bit equivalents.
473}
474
475:function:::void:check_u64:instruction_word insn
476*mips64:
477{
478#if 0 /* XXX FIXME: enable this only after some additional testing.  */
479  if (UserMode && (SR & (status_UX|status_PX)) == 0)
480    SignalException (ReservedInstruction, insn);
481#endif
482}
483
484
485
486//
487// MIPS Architecture:
488//
489//        CPU Instruction Set (mipsI - mipsV, mips32, mips64)
490//
491
492
493
494000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
495"add r<RD>, r<RS>, r<RT>"
496*mipsI:
497*mipsII:
498*mipsIII:
499*mipsIV:
500*mipsV:
501*mips32:
502*mips64:
503*vr4100:
504*vr5000:
505*r3900:
506{
507  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
508    Unpredictable ();
509  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
510  {
511    ALU32_BEGIN (GPR[RS]);
512    ALU32_ADD (GPR[RT]);
513    ALU32_END (GPR[RD]);   /* This checks for overflow.  */
514  }
515  TRACE_ALU_RESULT (GPR[RD]);
516}
517
518
519
520001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
521"addi r<RT>, r<RS>, <IMMEDIATE>"
522*mipsI:
523*mipsII:
524*mipsIII:
525*mipsIV:
526*mipsV:
527*mips32:
528*mips64:
529*vr4100:
530*vr5000:
531*r3900:
532{
533  if (NotWordValue (GPR[RS]))
534    Unpredictable ();
535  TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
536  {
537    ALU32_BEGIN (GPR[RS]);
538    ALU32_ADD (EXTEND16 (IMMEDIATE));
539    ALU32_END (GPR[RT]);   /* This checks for overflow.  */
540  }
541  TRACE_ALU_RESULT (GPR[RT]);
542}
543
544
545
546:function:::void:do_addiu:int rs, int rt, unsigned16 immediate
547{
548  if (NotWordValue (GPR[rs]))
549    Unpredictable ();
550  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
551  GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
552  TRACE_ALU_RESULT (GPR[rt]);
553}
554
555001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
556"addiu r<RT>, r<RS>, <IMMEDIATE>"
557*mipsI:
558*mipsII:
559*mipsIII:
560*mipsIV:
561*mipsV:
562*mips32:
563*mips64:
564*vr4100:
565*vr5000:
566*r3900:
567{
568  do_addiu (SD_, RS, RT, IMMEDIATE);
569}
570
571
572
573:function:::void:do_addu:int rs, int rt, int rd
574{
575  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
576    Unpredictable ();
577  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
578  GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
579  TRACE_ALU_RESULT (GPR[rd]);
580}
581
582000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
583"addu r<RD>, r<RS>, r<RT>"
584*mipsI:
585*mipsII:
586*mipsIII:
587*mipsIV:
588*mipsV:
589*mips32:
590*mips64:
591*vr4100:
592*vr5000:
593*r3900:
594{
595  do_addu (SD_, RS, RT, RD);
596}
597
598
599
600:function:::void:do_and:int rs, int rt, int rd
601{
602  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
603  GPR[rd] = GPR[rs] & GPR[rt];
604  TRACE_ALU_RESULT (GPR[rd]);
605}
606
607000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
608"and r<RD>, r<RS>, r<RT>"
609*mipsI:
610*mipsII:
611*mipsIII:
612*mipsIV:
613*mipsV:
614*mips32:
615*mips64:
616*vr4100:
617*vr5000:
618*r3900:
619{
620  do_and (SD_, RS, RT, RD);
621}
622
623
624
625001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
626"andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
627*mipsI:
628*mipsII:
629*mipsIII:
630*mipsIV:
631*mipsV:
632*mips32:
633*mips64:
634*vr4100:
635*vr5000:
636*r3900:
637{
638  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
639  GPR[RT] = GPR[RS] & IMMEDIATE;
640  TRACE_ALU_RESULT (GPR[RT]);
641}
642
643
644
645000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
646"beq r<RS>, r<RT>, <OFFSET>"
647*mipsI:
648*mipsII:
649*mipsIII:
650*mipsIV:
651*mipsV:
652*mips32:
653*mips64:
654*vr4100:
655*vr5000:
656*r3900:
657{
658  address_word offset = EXTEND16 (OFFSET) << 2;
659  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
660    {
661      DELAY_SLOT (NIA + offset);
662    }
663}
664
665
666
667010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
668"beql r<RS>, r<RT>, <OFFSET>"
669*mipsII:
670*mipsIII:
671*mipsIV:
672*mipsV:
673*mips32:
674*mips64:
675*vr4100:
676*vr5000:
677*r3900:
678{
679  address_word offset = EXTEND16 (OFFSET) << 2;
680  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
681    {
682      DELAY_SLOT (NIA + offset);
683    }
684  else
685    NULLIFY_NEXT_INSTRUCTION ();
686}
687
688
689
690000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
691"bgez r<RS>, <OFFSET>"
692*mipsI:
693*mipsII:
694*mipsIII:
695*mipsIV:
696*mipsV:
697*mips32:
698*mips64:
699*vr4100:
700*vr5000:
701*r3900:
702{
703  address_word offset = EXTEND16 (OFFSET) << 2;
704  if ((signed_word) GPR[RS] >= 0)
705    {
706      DELAY_SLOT (NIA + offset);
707    }
708}
709
710
711
712000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
713"bgezal r<RS>, <OFFSET>"
714*mipsI:
715*mipsII:
716*mipsIII:
717*mipsIV:
718*mipsV:
719*mips32:
720*mips64:
721*vr4100:
722*vr5000:
723*r3900:
724{
725  address_word offset = EXTEND16 (OFFSET) << 2;
726  if (RS == 31)
727    Unpredictable ();
728  RA = (CIA + 8);
729  if ((signed_word) GPR[RS] >= 0)
730    {
731      DELAY_SLOT (NIA + offset);
732    }
733}
734
735
736
737000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
738"bgezall r<RS>, <OFFSET>"
739*mipsII:
740*mipsIII:
741*mipsIV:
742*mipsV:
743*mips32:
744*mips64:
745*vr4100:
746*vr5000:
747*r3900:
748{
749  address_word offset = EXTEND16 (OFFSET) << 2;
750  if (RS == 31)
751    Unpredictable ();
752  RA = (CIA + 8);
753  /* NOTE: The branch occurs AFTER the next instruction has been
754     executed */
755  if ((signed_word) GPR[RS] >= 0)
756    {
757      DELAY_SLOT (NIA + offset);
758    }
759  else
760    NULLIFY_NEXT_INSTRUCTION ();
761}
762
763
764
765000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
766"bgezl r<RS>, <OFFSET>"
767*mipsII:
768*mipsIII:
769*mipsIV:
770*mipsV:
771*mips32:
772*mips64:
773*vr4100:
774*vr5000:
775*r3900:
776{
777  address_word offset = EXTEND16 (OFFSET) << 2;
778  if ((signed_word) GPR[RS] >= 0)
779    {
780      DELAY_SLOT (NIA + offset);
781    }
782  else
783    NULLIFY_NEXT_INSTRUCTION ();
784}
785
786
787
788000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
789"bgtz r<RS>, <OFFSET>"
790*mipsI:
791*mipsII:
792*mipsIII:
793*mipsIV:
794*mipsV:
795*mips32:
796*mips64:
797*vr4100:
798*vr5000:
799*r3900:
800{
801  address_word offset = EXTEND16 (OFFSET) << 2;
802  if ((signed_word) GPR[RS] > 0)
803    {
804      DELAY_SLOT (NIA + offset);
805    }
806}
807
808
809
810010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
811"bgtzl r<RS>, <OFFSET>"
812*mipsII:
813*mipsIII:
814*mipsIV:
815*mipsV:
816*mips32:
817*mips64:
818*vr4100:
819*vr5000:
820*r3900:
821{
822  address_word offset = EXTEND16 (OFFSET) << 2;
823  /* NOTE: The branch occurs AFTER the next instruction has been
824     executed */
825  if ((signed_word) GPR[RS] > 0)
826    {
827      DELAY_SLOT (NIA + offset);
828    }
829  else
830    NULLIFY_NEXT_INSTRUCTION ();
831}
832
833
834
835000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
836"blez r<RS>, <OFFSET>"
837*mipsI:
838*mipsII:
839*mipsIII:
840*mipsIV:
841*mipsV:
842*mips32:
843*mips64:
844*vr4100:
845*vr5000:
846*r3900:
847{
848  address_word offset = EXTEND16 (OFFSET) << 2;
849  /* NOTE: The branch occurs AFTER the next instruction has been
850     executed */
851  if ((signed_word) GPR[RS] <= 0)
852    {
853      DELAY_SLOT (NIA + offset);
854    }
855}
856
857
858
859010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
860"bgezl r<RS>, <OFFSET>"
861*mipsII:
862*mipsIII:
863*mipsIV:
864*mipsV:
865*mips32:
866*mips64:
867*vr4100:
868*vr5000:
869*r3900:
870{
871  address_word offset = EXTEND16 (OFFSET) << 2;
872  if ((signed_word) GPR[RS] <= 0)
873    {
874      DELAY_SLOT (NIA + offset);
875    }
876  else
877    NULLIFY_NEXT_INSTRUCTION ();
878}
879
880
881
882000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
883"bltz r<RS>, <OFFSET>"
884*mipsI:
885*mipsII:
886*mipsIII:
887*mipsIV:
888*mipsV:
889*mips32:
890*mips64:
891*vr4100:
892*vr5000:
893*r3900:
894{
895  address_word offset = EXTEND16 (OFFSET) << 2;
896  if ((signed_word) GPR[RS] < 0)
897    {
898      DELAY_SLOT (NIA + offset);
899    }
900}
901
902
903
904000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
905"bltzal r<RS>, <OFFSET>"
906*mipsI:
907*mipsII:
908*mipsIII:
909*mipsIV:
910*mipsV:
911*mips32:
912*mips64:
913*vr4100:
914*vr5000:
915*r3900:
916{
917  address_word offset = EXTEND16 (OFFSET) << 2;
918  if (RS == 31)
919    Unpredictable ();
920  RA = (CIA + 8);
921  /* NOTE: The branch occurs AFTER the next instruction has been
922     executed */
923  if ((signed_word) GPR[RS] < 0)
924    {
925      DELAY_SLOT (NIA + offset);
926    }
927}
928
929
930
931000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
932"bltzall r<RS>, <OFFSET>"
933*mipsII:
934*mipsIII:
935*mipsIV:
936*mipsV:
937*mips32:
938*mips64:
939*vr4100:
940*vr5000:
941*r3900:
942{
943  address_word offset = EXTEND16 (OFFSET) << 2;
944  if (RS == 31)
945    Unpredictable ();
946  RA = (CIA + 8);
947  if ((signed_word) GPR[RS] < 0)
948    {
949      DELAY_SLOT (NIA + offset);
950    }
951  else
952    NULLIFY_NEXT_INSTRUCTION ();
953}
954
955
956
957000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
958"bltzl r<RS>, <OFFSET>"
959*mipsII:
960*mipsIII:
961*mipsIV:
962*mipsV:
963*mips32:
964*mips64:
965*vr4100:
966*vr5000:
967*r3900:
968{
969  address_word offset = EXTEND16 (OFFSET) << 2;
970  /* NOTE: The branch occurs AFTER the next instruction has been
971     executed */
972  if ((signed_word) GPR[RS] < 0)
973    {
974      DELAY_SLOT (NIA + offset);
975    }
976  else
977    NULLIFY_NEXT_INSTRUCTION ();
978}
979
980
981
982000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
983"bne r<RS>, r<RT>, <OFFSET>"
984*mipsI:
985*mipsII:
986*mipsIII:
987*mipsIV:
988*mipsV:
989*mips32:
990*mips64:
991*vr4100:
992*vr5000:
993*r3900:
994{
995  address_word offset = EXTEND16 (OFFSET) << 2;
996  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
997    {
998      DELAY_SLOT (NIA + offset);
999    }
1000}
1001
1002
1003
1004010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
1005"bnel r<RS>, r<RT>, <OFFSET>"
1006*mipsII:
1007*mipsIII:
1008*mipsIV:
1009*mipsV:
1010*mips32:
1011*mips64:
1012*vr4100:
1013*vr5000:
1014*r3900:
1015{
1016  address_word offset = EXTEND16 (OFFSET) << 2;
1017  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
1018    {
1019      DELAY_SLOT (NIA + offset);
1020    }
1021  else
1022    NULLIFY_NEXT_INSTRUCTION ();
1023}
1024
1025
1026
1027000000,20.CODE,001101:SPECIAL:32::BREAK
1028"break %#lx<CODE>"
1029*mipsI:
1030*mipsII:
1031*mipsIII:
1032*mipsIV:
1033*mipsV:
1034*mips32:
1035*mips64:
1036*vr4100:
1037*vr5000:
1038*r3900:
1039{
1040  /* Check for some break instruction which are reserved for use by the simulator.  */
1041  unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
1042  if (break_code == (HALT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
1043      break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
1044    {
1045      sim_engine_halt (SD, CPU, NULL, cia,
1046                       sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
1047    }
1048  else if (break_code == (BREAKPOINT_INSTRUCTION  & HALT_INSTRUCTION_MASK) ||
1049           break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
1050    {
1051      if (STATE & simDELAYSLOT)
1052        PC = cia - 4; /* reference the branch instruction */
1053      else
1054        PC = cia;
1055      SignalException (BreakPoint, instruction_0);
1056    }
1057
1058  else
1059    {
1060      /* If we get this far, we're not an instruction reserved by the sim.  Raise
1061	 the exception. */
1062      SignalException (BreakPoint, instruction_0);
1063    }
1064}
1065
1066
1067
1068011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO
1069"clo r<RD>, r<RS>"
1070*mips32:
1071*mips64:
1072*vr5500:
1073{
1074  unsigned32 temp = GPR[RS];
1075  unsigned32 i, mask;
1076  if (RT != RD)
1077    Unpredictable ();
1078  if (NotWordValue (GPR[RS]))
1079    Unpredictable ();
1080  TRACE_ALU_INPUT1 (GPR[RS]);
1081  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
1082    {
1083      if ((temp & mask) == 0)
1084	break;
1085      mask >>= 1;
1086    }
1087  GPR[RD] = EXTEND32 (i);
1088  TRACE_ALU_RESULT (GPR[RD]);
1089}
1090
1091
1092
1093011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ
1094"clz r<RD>, r<RS>"
1095*mips32:
1096*mips64:
1097*vr5500:
1098{
1099  unsigned32 temp = GPR[RS];
1100  unsigned32 i, mask;
1101  if (RT != RD)
1102    Unpredictable ();
1103  if (NotWordValue (GPR[RS]))
1104    Unpredictable ();
1105  TRACE_ALU_INPUT1 (GPR[RS]);
1106  for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
1107    {
1108      if ((temp & mask) != 0)
1109	break;
1110      mask >>= 1;
1111    }
1112  GPR[RD] = EXTEND32 (i);
1113  TRACE_ALU_RESULT (GPR[RD]);
1114}
1115
1116
1117
1118000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
1119"dadd r<RD>, r<RS>, r<RT>"
1120*mipsIII:
1121*mipsIV:
1122*mipsV:
1123*mips64:
1124*vr4100:
1125*vr5000:
1126{
1127  check_u64 (SD_, instruction_0);
1128  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1129  {
1130    ALU64_BEGIN (GPR[RS]);
1131    ALU64_ADD (GPR[RT]);
1132    ALU64_END (GPR[RD]);   /* This checks for overflow.  */
1133  }
1134  TRACE_ALU_RESULT (GPR[RD]);
1135}
1136
1137
1138
1139011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
1140"daddi r<RT>, r<RS>, <IMMEDIATE>"
1141*mipsIII:
1142*mipsIV:
1143*mipsV:
1144*mips64:
1145*vr4100:
1146*vr5000:
1147{
1148  check_u64 (SD_, instruction_0);
1149  TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
1150  {
1151    ALU64_BEGIN (GPR[RS]);
1152    ALU64_ADD (EXTEND16 (IMMEDIATE));
1153    ALU64_END (GPR[RT]);   /* This checks for overflow.  */
1154  }
1155  TRACE_ALU_RESULT (GPR[RT]);
1156}
1157
1158
1159
1160:function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
1161{
1162  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
1163  GPR[rt] = GPR[rs] + EXTEND16 (immediate);
1164  TRACE_ALU_RESULT (GPR[rt]);
1165}
1166
1167011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
1168"daddiu r<RT>, r<RS>, <IMMEDIATE>"
1169*mipsIII:
1170*mipsIV:
1171*mipsV:
1172*mips64:
1173*vr4100:
1174*vr5000:
1175{
1176  check_u64 (SD_, instruction_0);
1177  do_daddiu (SD_, RS, RT, IMMEDIATE);
1178}
1179
1180
1181
1182:function:::void:do_daddu:int rs, int rt, int rd
1183{
1184  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1185  GPR[rd] = GPR[rs] + GPR[rt];
1186  TRACE_ALU_RESULT (GPR[rd]);
1187}
1188
1189000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
1190"daddu r<RD>, r<RS>, r<RT>"
1191*mipsIII:
1192*mipsIV:
1193*mipsV:
1194*mips64:
1195*vr4100:
1196*vr5000:
1197{
1198  check_u64 (SD_, instruction_0);
1199  do_daddu (SD_, RS, RT, RD);
1200}
1201
1202
1203
1204011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
1205"dclo r<RD>, r<RS>"
1206*mips64:
1207*vr5500:
1208{
1209  unsigned64 temp = GPR[RS];
1210  unsigned32 i;
1211  unsigned64 mask;
1212  check_u64 (SD_, instruction_0);
1213  if (RT != RD)
1214    Unpredictable ();
1215  TRACE_ALU_INPUT1 (GPR[RS]);
1216  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
1217    {
1218      if ((temp & mask) == 0)
1219	break;
1220      mask >>= 1;
1221    }
1222  GPR[RD] = EXTEND32 (i);
1223  TRACE_ALU_RESULT (GPR[RD]);
1224}
1225
1226
1227
1228011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
1229"dclz r<RD>, r<RS>"
1230*mips64:
1231*vr5500:
1232{
1233  unsigned64 temp = GPR[RS];
1234  unsigned32 i;
1235  unsigned64 mask;
1236  check_u64 (SD_, instruction_0);
1237  if (RT != RD)
1238    Unpredictable ();
1239  TRACE_ALU_INPUT1 (GPR[RS]);
1240  for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
1241    {
1242      if ((temp & mask) != 0)
1243	break;
1244      mask >>= 1;
1245    }
1246  GPR[RD] = EXTEND32 (i);
1247  TRACE_ALU_RESULT (GPR[RD]);
1248}
1249
1250
1251
1252:function:::void:do_ddiv:int rs, int rt
1253{
1254  check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1255  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1256  {
1257    signed64 n = GPR[rs];
1258    signed64 d = GPR[rt];
1259    signed64 hi;
1260    signed64 lo;
1261    if (d == 0)
1262      {
1263	lo = SIGNED64 (0x8000000000000000);
1264	hi = 0;
1265      }
1266    else if (d == -1 && n == SIGNED64 (0x8000000000000000))
1267      {
1268	lo = SIGNED64 (0x8000000000000000);
1269	hi = 0;
1270      }
1271    else
1272      {
1273	lo = (n / d);
1274	hi = (n % d);
1275      }
1276    HI = hi;
1277    LO = lo;
1278  }
1279  TRACE_ALU_RESULT2 (HI, LO);
1280}
1281
1282000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
1283"ddiv r<RS>, r<RT>"
1284*mipsIII:
1285*mipsIV:
1286*mipsV:
1287*mips64:
1288*vr4100:
1289*vr5000:
1290{
1291  check_u64 (SD_, instruction_0);
1292  do_ddiv (SD_, RS, RT);
1293}
1294
1295
1296
1297:function:::void:do_ddivu:int rs, int rt
1298{
1299  check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1300  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1301  {
1302    unsigned64 n = GPR[rs];
1303    unsigned64 d = GPR[rt];
1304    unsigned64 hi;
1305    unsigned64 lo;
1306    if (d == 0)
1307      {
1308	lo = SIGNED64 (0x8000000000000000);
1309	hi = 0;
1310      }
1311    else
1312      {
1313	lo = (n / d);
1314	hi = (n % d);
1315      }
1316    HI = hi;
1317    LO = lo;
1318  }
1319  TRACE_ALU_RESULT2 (HI, LO);
1320}
1321
1322000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
1323"ddivu r<RS>, r<RT>"
1324*mipsIII:
1325*mipsIV:
1326*mipsV:
1327*mips64:
1328*vr4100:
1329*vr5000:
1330{
1331  check_u64 (SD_, instruction_0);
1332  do_ddivu (SD_, RS, RT);
1333}
1334
1335
1336
1337:function:::void:do_div:int rs, int rt
1338{
1339  check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1340  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1341  {
1342    signed32 n = GPR[rs];
1343    signed32 d = GPR[rt];
1344    if (d == 0)
1345      {
1346	LO = EXTEND32 (0x80000000);
1347	HI = EXTEND32 (0);
1348      }
1349    else if (n == SIGNED32 (0x80000000) && d == -1)
1350      {
1351	LO = EXTEND32 (0x80000000);
1352	HI = EXTEND32 (0);
1353      }
1354    else
1355      {
1356	LO = EXTEND32 (n / d);
1357	HI = EXTEND32 (n % d);
1358      }
1359  }
1360  TRACE_ALU_RESULT2 (HI, LO);
1361}
1362
1363000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
1364"div r<RS>, r<RT>"
1365*mipsI:
1366*mipsII:
1367*mipsIII:
1368*mipsIV:
1369*mipsV:
1370*mips32:
1371*mips64:
1372*vr4100:
1373*vr5000:
1374*r3900:
1375{
1376  do_div (SD_, RS, RT);
1377}
1378
1379
1380
1381:function:::void:do_divu:int rs, int rt
1382{
1383  check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1384  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1385  {
1386    unsigned32 n = GPR[rs];
1387    unsigned32 d = GPR[rt];
1388    if (d == 0)
1389      {
1390	LO = EXTEND32 (0x80000000);
1391	HI = EXTEND32 (0);
1392      }
1393    else
1394      {
1395	LO = EXTEND32 (n / d);
1396	HI = EXTEND32 (n % d);
1397      }
1398  }
1399  TRACE_ALU_RESULT2 (HI, LO);
1400}
1401
1402000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
1403"divu r<RS>, r<RT>"
1404*mipsI:
1405*mipsII:
1406*mipsIII:
1407*mipsIV:
1408*mipsV:
1409*mips32:
1410*mips64:
1411*vr4100:
1412*vr5000:
1413*r3900:
1414{
1415  do_divu (SD_, RS, RT);
1416}
1417
1418
1419
1420:function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
1421{
1422  unsigned64 lo;
1423  unsigned64 hi;
1424  unsigned64 m00;
1425  unsigned64 m01;
1426  unsigned64 m10;
1427  unsigned64 m11;
1428  unsigned64 mid;
1429  int sign;
1430  unsigned64 op1 = GPR[rs];
1431  unsigned64 op2 = GPR[rt];
1432  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1433  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1434  /* make signed multiply unsigned */
1435  sign = 0;
1436  if (signed_p)
1437    {
1438      if ((signed64) op1 < 0)
1439	{
1440	  op1 = - op1;
1441	  ++sign;
1442	}
1443      if ((signed64) op2 < 0)
1444	{
1445	  op2 = - op2;
1446	  ++sign;
1447	}
1448    }
1449  /* multiply out the 4 sub products */
1450  m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
1451  m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
1452  m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
1453  m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
1454  /* add the products */
1455  mid = ((unsigned64) VH4_8 (m00)
1456	 + (unsigned64) VL4_8 (m10)
1457	 + (unsigned64) VL4_8 (m01));
1458  lo = U8_4 (mid, m00);
1459  hi = (m11
1460	+ (unsigned64) VH4_8 (mid)
1461	+ (unsigned64) VH4_8 (m01)
1462	+ (unsigned64) VH4_8 (m10));
1463  /* fix the sign */
1464  if (sign & 1)
1465    {
1466      lo = -lo;
1467      if (lo == 0)
1468	hi = -hi;
1469      else
1470	hi = -hi - 1;
1471    }
1472  /* save the result HI/LO (and a gpr) */
1473  LO = lo;
1474  HI = hi;
1475  if (rd != 0)
1476    GPR[rd] = lo;
1477  TRACE_ALU_RESULT2 (HI, LO);
1478}
1479
1480:function:::void:do_dmult:int rs, int rt, int rd
1481{
1482  do_dmultx (SD_, rs, rt, rd, 1);
1483}
1484
1485000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
1486"dmult r<RS>, r<RT>"
1487*mipsIII:
1488*mipsIV:
1489*mipsV:
1490*mips64:
1491*vr4100:
1492{
1493  check_u64 (SD_, instruction_0);
1494  do_dmult (SD_, RS, RT, 0);
1495}
1496
1497000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
1498"dmult r<RS>, r<RT>":RD == 0
1499"dmult r<RD>, r<RS>, r<RT>"
1500*vr5000:
1501{
1502  check_u64 (SD_, instruction_0);
1503  do_dmult (SD_, RS, RT, RD);
1504}
1505
1506
1507
1508:function:::void:do_dmultu:int rs, int rt, int rd
1509{
1510  do_dmultx (SD_, rs, rt, rd, 0);
1511}
1512
1513000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
1514"dmultu r<RS>, r<RT>"
1515*mipsIII:
1516*mipsIV:
1517*mipsV:
1518*mips64:
1519*vr4100:
1520{
1521  check_u64 (SD_, instruction_0);
1522  do_dmultu (SD_, RS, RT, 0);
1523}
1524
1525000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
1526"dmultu r<RD>, r<RS>, r<RT>":RD == 0
1527"dmultu r<RS>, r<RT>"
1528*vr5000:
1529{
1530  check_u64 (SD_, instruction_0);
1531  do_dmultu (SD_, RS, RT, RD);
1532}
1533
1534:function:::void:do_dsll:int rt, int rd, int shift
1535{
1536  TRACE_ALU_INPUT2 (GPR[rt], shift);
1537  GPR[rd] = GPR[rt] << shift;
1538  TRACE_ALU_RESULT (GPR[rd]);
1539}
1540
1541000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
1542"dsll r<RD>, r<RT>, <SHIFT>"
1543*mipsIII:
1544*mipsIV:
1545*mipsV:
1546*mips64:
1547*vr4100:
1548*vr5000:
1549{
1550  check_u64 (SD_, instruction_0);
1551  do_dsll (SD_, RT, RD, SHIFT);
1552}
1553
1554
1555000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
1556"dsll32 r<RD>, r<RT>, <SHIFT>"
1557*mipsIII:
1558*mipsIV:
1559*mipsV:
1560*mips64:
1561*vr4100:
1562*vr5000:
1563{
1564  int s = 32 + SHIFT;
1565  check_u64 (SD_, instruction_0);
1566  TRACE_ALU_INPUT2 (GPR[RT], s);
1567  GPR[RD] = GPR[RT] << s;
1568  TRACE_ALU_RESULT (GPR[RD]);
1569}
1570
1571:function:::void:do_dsllv:int rs, int rt, int rd
1572{
1573  int s = MASKED64 (GPR[rs], 5, 0);
1574  TRACE_ALU_INPUT2 (GPR[rt], s);
1575  GPR[rd] = GPR[rt] << s;
1576  TRACE_ALU_RESULT (GPR[rd]);
1577}
1578
1579000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
1580"dsllv r<RD>, r<RT>, r<RS>"
1581*mipsIII:
1582*mipsIV:
1583*mipsV:
1584*mips64:
1585*vr4100:
1586*vr5000:
1587{
1588  check_u64 (SD_, instruction_0);
1589  do_dsllv (SD_, RS, RT, RD);
1590}
1591
1592:function:::void:do_dsra:int rt, int rd, int shift
1593{
1594  TRACE_ALU_INPUT2 (GPR[rt], shift);
1595  GPR[rd] = ((signed64) GPR[rt]) >> shift;
1596  TRACE_ALU_RESULT (GPR[rd]);
1597}
1598
1599
1600000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
1601"dsra r<RD>, r<RT>, <SHIFT>"
1602*mipsIII:
1603*mipsIV:
1604*mipsV:
1605*mips64:
1606*vr4100:
1607*vr5000:
1608{
1609  check_u64 (SD_, instruction_0);
1610  do_dsra (SD_, RT, RD, SHIFT);
1611}
1612
1613
1614000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
1615"dsra32 r<RD>, r<RT>, <SHIFT>"
1616*mipsIII:
1617*mipsIV:
1618*mipsV:
1619*mips64:
1620*vr4100:
1621*vr5000:
1622{
1623  int s = 32 + SHIFT;
1624  check_u64 (SD_, instruction_0);
1625  TRACE_ALU_INPUT2 (GPR[RT], s);
1626  GPR[RD] = ((signed64) GPR[RT]) >> s;
1627  TRACE_ALU_RESULT (GPR[RD]);
1628}
1629
1630
1631:function:::void:do_dsrav:int rs, int rt, int rd
1632{
1633  int s = MASKED64 (GPR[rs], 5, 0);
1634  TRACE_ALU_INPUT2 (GPR[rt], s);
1635  GPR[rd] = ((signed64) GPR[rt]) >> s;
1636  TRACE_ALU_RESULT (GPR[rd]);
1637}
1638
1639000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
1640"dsrav r<RD>, r<RT>, r<RS>"
1641*mipsIII:
1642*mipsIV:
1643*mipsV:
1644*mips64:
1645*vr4100:
1646*vr5000:
1647{
1648  check_u64 (SD_, instruction_0);
1649  do_dsrav (SD_, RS, RT, RD);
1650}
1651
1652:function:::void:do_dsrl:int rt, int rd, int shift
1653{
1654  TRACE_ALU_INPUT2 (GPR[rt], shift);
1655  GPR[rd] = (unsigned64) GPR[rt] >> shift;
1656  TRACE_ALU_RESULT (GPR[rd]);
1657}
1658
1659
1660000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
1661"dsrl r<RD>, r<RT>, <SHIFT>"
1662*mipsIII:
1663*mipsIV:
1664*mipsV:
1665*mips64:
1666*vr4100:
1667*vr5000:
1668{
1669  check_u64 (SD_, instruction_0);
1670  do_dsrl (SD_, RT, RD, SHIFT);
1671}
1672
1673
1674000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
1675"dsrl32 r<RD>, r<RT>, <SHIFT>"
1676*mipsIII:
1677*mipsIV:
1678*mipsV:
1679*mips64:
1680*vr4100:
1681*vr5000:
1682{
1683  int s = 32 + SHIFT;
1684  check_u64 (SD_, instruction_0);
1685  TRACE_ALU_INPUT2 (GPR[RT], s);
1686  GPR[RD] = (unsigned64) GPR[RT] >> s;
1687  TRACE_ALU_RESULT (GPR[RD]);
1688}
1689
1690
1691:function:::void:do_dsrlv:int rs, int rt, int rd
1692{
1693  int s = MASKED64 (GPR[rs], 5, 0);
1694  TRACE_ALU_INPUT2 (GPR[rt], s);
1695  GPR[rd] = (unsigned64) GPR[rt] >> s;
1696  TRACE_ALU_RESULT (GPR[rd]);
1697}
1698
1699
1700
1701000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
1702"dsrlv r<RD>, r<RT>, r<RS>"
1703*mipsIII:
1704*mipsIV:
1705*mipsV:
1706*mips64:
1707*vr4100:
1708*vr5000:
1709{
1710  check_u64 (SD_, instruction_0);
1711  do_dsrlv (SD_, RS, RT, RD);
1712}
1713
1714
1715000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
1716"dsub r<RD>, r<RS>, r<RT>"
1717*mipsIII:
1718*mipsIV:
1719*mipsV:
1720*mips64:
1721*vr4100:
1722*vr5000:
1723{
1724  check_u64 (SD_, instruction_0);
1725  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1726  {
1727    ALU64_BEGIN (GPR[RS]);
1728    ALU64_SUB (GPR[RT]);
1729    ALU64_END (GPR[RD]);   /* This checks for overflow.  */
1730  }
1731  TRACE_ALU_RESULT (GPR[RD]);
1732}
1733
1734
1735:function:::void:do_dsubu:int rs, int rt, int rd
1736{
1737  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1738  GPR[rd] = GPR[rs] - GPR[rt];
1739  TRACE_ALU_RESULT (GPR[rd]);
1740}
1741
1742000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
1743"dsubu r<RD>, r<RS>, r<RT>"
1744*mipsIII:
1745*mipsIV:
1746*mipsV:
1747*mips64:
1748*vr4100:
1749*vr5000:
1750{
1751  check_u64 (SD_, instruction_0);
1752  do_dsubu (SD_, RS, RT, RD);
1753}
1754
1755
1756000010,26.INSTR_INDEX:NORMAL:32::J
1757"j <INSTR_INDEX>"
1758*mipsI:
1759*mipsII:
1760*mipsIII:
1761*mipsIV:
1762*mipsV:
1763*mips32:
1764*mips64:
1765*vr4100:
1766*vr5000:
1767*r3900:
1768{
1769  /* NOTE: The region used is that of the delay slot NIA and NOT the
1770     current instruction */
1771  address_word region = (NIA & MASK (63, 28));
1772  DELAY_SLOT (region | (INSTR_INDEX << 2));
1773}
1774
1775
1776000011,26.INSTR_INDEX:NORMAL:32::JAL
1777"jal <INSTR_INDEX>"
1778*mipsI:
1779*mipsII:
1780*mipsIII:
1781*mipsIV:
1782*mipsV:
1783*mips32:
1784*mips64:
1785*vr4100:
1786*vr5000:
1787*r3900:
1788{
1789  /* NOTE: The region used is that of the delay slot and NOT the
1790     current instruction */
1791  address_word region = (NIA & MASK (63, 28));
1792  GPR[31] = CIA + 8;
1793  DELAY_SLOT (region | (INSTR_INDEX << 2));
1794}
1795
1796000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
1797"jalr r<RS>":RD == 31
1798"jalr r<RD>, r<RS>"
1799*mipsI:
1800*mipsII:
1801*mipsIII:
1802*mipsIV:
1803*mipsV:
1804*mips32:
1805*mips64:
1806*vr4100:
1807*vr5000:
1808*r3900:
1809{
1810  address_word temp = GPR[RS];
1811  GPR[RD] = CIA + 8;
1812  DELAY_SLOT (temp);
1813}
1814
1815
1816000000,5.RS,000000000000000,001000:SPECIAL:32::JR
1817"jr r<RS>"
1818*mipsI:
1819*mipsII:
1820*mipsIII:
1821*mipsIV:
1822*mipsV:
1823*mips32:
1824*mips64:
1825*vr4100:
1826*vr5000:
1827*r3900:
1828{
1829  DELAY_SLOT (GPR[RS]);
1830}
1831
1832
1833:function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
1834{
1835  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1836  address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
1837  address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
1838  unsigned int byte;
1839  address_word paddr;
1840  int uncached;
1841  unsigned64 memval;
1842  address_word vaddr;
1843
1844  vaddr = loadstore_ea (SD_, base, offset);
1845  if ((vaddr & access) != 0)
1846    {
1847      SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
1848    }
1849  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1850  paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1851  LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
1852  byte = ((vaddr & mask) ^ bigendiancpu);
1853  return (memval >> (8 * byte));
1854}
1855
1856:function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
1857{
1858  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1859  address_word reverseendian = (ReverseEndian ? -1 : 0);
1860  address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1861  unsigned int byte;
1862  unsigned int word;
1863  address_word paddr;
1864  int uncached;
1865  unsigned64 memval;
1866  address_word vaddr;
1867  int nr_lhs_bits;
1868  int nr_rhs_bits;
1869  unsigned_word lhs_mask;
1870  unsigned_word temp;
1871
1872  vaddr = loadstore_ea (SD_, base, offset);
1873  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1874  paddr = (paddr ^ (reverseendian & mask));
1875  if (BigEndianMem == 0)
1876    paddr = paddr & ~access;
1877
1878  /* compute where within the word/mem we are */
1879  byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
1880  word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
1881  nr_lhs_bits = 8 * byte + 8;
1882  nr_rhs_bits = 8 * access - 8 * byte;
1883  /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
1884
1885  /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
1886	   (long) ((unsigned64) vaddr >> 32), (long) vaddr,
1887	   (long) ((unsigned64) paddr >> 32), (long) paddr,
1888	   word, byte, nr_lhs_bits, nr_rhs_bits); */
1889
1890  LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
1891  if (word == 0)
1892    {
1893      /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
1894      temp = (memval << nr_rhs_bits);
1895    }
1896  else
1897    {
1898      /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
1899      temp = (memval >> nr_lhs_bits);
1900    }
1901  lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
1902  rt = (rt & ~lhs_mask) | (temp & lhs_mask);
1903
1904  /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
1905	   (long) ((unsigned64) memval >> 32), (long) memval,
1906	   (long) ((unsigned64) temp >> 32), (long) temp,
1907	   (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
1908	   (long) (rt >> 32), (long) rt); */
1909  return rt;
1910}
1911
1912:function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
1913{
1914  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1915  address_word reverseendian = (ReverseEndian ? -1 : 0);
1916  address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1917  unsigned int byte;
1918  address_word paddr;
1919  int uncached;
1920  unsigned64 memval;
1921  address_word vaddr;
1922
1923  vaddr = loadstore_ea (SD_, base, offset);
1924  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1925  /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
1926  paddr = (paddr ^ (reverseendian & mask));
1927  if (BigEndianMem != 0)
1928    paddr = paddr & ~access;
1929  byte = ((vaddr & mask) ^ (bigendiancpu & mask));
1930  /* NOTE: SPEC is wrong, had `byte' not `access - byte'.  See SW. */
1931  LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
1932  /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
1933     (long) paddr, byte, (long) paddr, (long) memval); */
1934  {
1935    unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
1936    rt &= ~screen;
1937    rt |= (memval >> (8 * byte)) & screen;
1938  }
1939  return rt;
1940}
1941
1942
1943100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
1944"lb r<RT>, <OFFSET>(r<BASE>)"
1945*mipsI:
1946*mipsII:
1947*mipsIII:
1948*mipsIV:
1949*mipsV:
1950*mips32:
1951*mips64:
1952*vr4100:
1953*vr5000:
1954*r3900:
1955{
1956  GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
1957}
1958
1959
1960100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
1961"lbu r<RT>, <OFFSET>(r<BASE>)"
1962*mipsI:
1963*mipsII:
1964*mipsIII:
1965*mipsIV:
1966*mipsV:
1967*mips32:
1968*mips64:
1969*vr4100:
1970*vr5000:
1971*r3900:
1972{
1973  GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
1974}
1975
1976
1977110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
1978"ld r<RT>, <OFFSET>(r<BASE>)"
1979*mipsIII:
1980*mipsIV:
1981*mipsV:
1982*mips64:
1983*vr4100:
1984*vr5000:
1985{
1986  check_u64 (SD_, instruction_0);
1987  GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1988}
1989
1990
19911101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
1992"ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1993*mipsII:
1994*mipsIII:
1995*mipsIV:
1996*mipsV:
1997*mips32:
1998*mips64:
1999*vr4100:
2000*vr5000:
2001*r3900:
2002{
2003  COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
2004}
2005
2006
2007
2008
2009011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
2010"ldl r<RT>, <OFFSET>(r<BASE>)"
2011*mipsIII:
2012*mipsIV:
2013*mipsV:
2014*mips64:
2015*vr4100:
2016*vr5000:
2017{
2018  check_u64 (SD_, instruction_0);
2019  GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2020}
2021
2022
2023011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
2024"ldr r<RT>, <OFFSET>(r<BASE>)"
2025*mipsIII:
2026*mipsIV:
2027*mipsV:
2028*mips64:
2029*vr4100:
2030*vr5000:
2031{
2032  check_u64 (SD_, instruction_0);
2033  GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2034}
2035
2036
2037100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
2038"lh r<RT>, <OFFSET>(r<BASE>)"
2039*mipsI:
2040*mipsII:
2041*mipsIII:
2042*mipsIV:
2043*mipsV:
2044*mips32:
2045*mips64:
2046*vr4100:
2047*vr5000:
2048*r3900:
2049{
2050  GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
2051}
2052
2053
2054100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
2055"lhu r<RT>, <OFFSET>(r<BASE>)"
2056*mipsI:
2057*mipsII:
2058*mipsIII:
2059*mipsIV:
2060*mipsV:
2061*mips32:
2062*mips64:
2063*vr4100:
2064*vr5000:
2065*r3900:
2066{
2067  GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
2068}
2069
2070
2071110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
2072"ll r<RT>, <OFFSET>(r<BASE>)"
2073*mipsII:
2074*mipsIII:
2075*mipsIV:
2076*mipsV:
2077*mips32:
2078*mips64:
2079*vr4100:
2080*vr5000:
2081{
2082  address_word base = GPR[BASE];
2083  address_word offset = EXTEND16 (OFFSET);
2084  {
2085    address_word vaddr = loadstore_ea (SD_, base, offset);
2086    address_word paddr;
2087    int uncached;
2088    if ((vaddr & 3) != 0)
2089      {
2090        SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
2091      }
2092    else
2093      {
2094	if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2095	  {
2096	    unsigned64 memval = 0;
2097	    unsigned64 memval1 = 0;
2098	    unsigned64 mask = 0x7;
2099	    unsigned int shift = 2;
2100	    unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
2101	    unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
2102	    unsigned int byte;
2103	    paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
2104	    LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
2105	    byte = ((vaddr & mask) ^ (bigend << shift));
2106	    GPR[RT] = EXTEND32 (memval >> (8 * byte));
2107	    LLBIT = 1;
2108	  }
2109      }
2110  }
2111}
2112
2113
2114110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
2115"lld r<RT>, <OFFSET>(r<BASE>)"
2116*mipsIII:
2117*mipsIV:
2118*mipsV:
2119*mips64:
2120*vr4100:
2121*vr5000:
2122{
2123  address_word base = GPR[BASE];
2124  address_word offset = EXTEND16 (OFFSET);
2125  check_u64 (SD_, instruction_0);
2126  {
2127    address_word vaddr = loadstore_ea (SD_, base, offset);
2128    address_word paddr;
2129    int uncached;
2130    if ((vaddr & 7) != 0)
2131      {
2132	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
2133      }
2134    else
2135      {
2136	if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2137	  {
2138	    unsigned64 memval = 0;
2139	    unsigned64 memval1 = 0;
2140	    LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
2141	    GPR[RT] = memval;
2142	    LLBIT = 1;
2143	  }
2144      }
2145  }
2146}
2147
2148
2149001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
2150"lui r<RT>, %#lx<IMMEDIATE>"
2151*mipsI:
2152*mipsII:
2153*mipsIII:
2154*mipsIV:
2155*mipsV:
2156*mips32:
2157*mips64:
2158*vr4100:
2159*vr5000:
2160*r3900:
2161{
2162  TRACE_ALU_INPUT1 (IMMEDIATE);
2163  GPR[RT] = EXTEND32 (IMMEDIATE << 16);
2164  TRACE_ALU_RESULT (GPR[RT]);
2165}
2166
2167
2168100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
2169"lw r<RT>, <OFFSET>(r<BASE>)"
2170*mipsI:
2171*mipsII:
2172*mipsIII:
2173*mipsIV:
2174*mipsV:
2175*mips32:
2176*mips64:
2177*vr4100:
2178*vr5000:
2179*r3900:
2180{
2181  GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
2182}
2183
2184
21851100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
2186"lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2187*mipsI:
2188*mipsII:
2189*mipsIII:
2190*mipsIV:
2191*mipsV:
2192*mips32:
2193*mips64:
2194*vr4100:
2195*vr5000:
2196*r3900:
2197{
2198  COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
2199}
2200
2201
2202100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
2203"lwl r<RT>, <OFFSET>(r<BASE>)"
2204*mipsI:
2205*mipsII:
2206*mipsIII:
2207*mipsIV:
2208*mipsV:
2209*mips32:
2210*mips64:
2211*vr4100:
2212*vr5000:
2213*r3900:
2214{
2215  GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
2216}
2217
2218
2219100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
2220"lwr r<RT>, <OFFSET>(r<BASE>)"
2221*mipsI:
2222*mipsII:
2223*mipsIII:
2224*mipsIV:
2225*mipsV:
2226*mips32:
2227*mips64:
2228*vr4100:
2229*vr5000:
2230*r3900:
2231{
2232  GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
2233}
2234
2235
2236100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU
2237"lwu r<RT>, <OFFSET>(r<BASE>)"
2238*mipsIII:
2239*mipsIV:
2240*mipsV:
2241*mips64:
2242*vr4100:
2243*vr5000:
2244{
2245  check_u64 (SD_, instruction_0);
2246  GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
2247}
2248
2249
2250
2251011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD
2252"madd r<RS>, r<RT>"
2253*mips32:
2254*mips64:
2255*vr5500:
2256{
2257  signed64 temp;
2258  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2259  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
2260    Unpredictable ();
2261  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2262  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2263          + ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
2264  LO = EXTEND32 (temp);
2265  HI = EXTEND32 (VH4_8 (temp));
2266  TRACE_ALU_RESULT2 (HI, LO);
2267}
2268
2269
2270
2271011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU
2272"maddu r<RS>, r<RT>"
2273*mips32:
2274*mips64:
2275*vr5500:
2276{
2277  unsigned64 temp;
2278  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2279  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
2280    Unpredictable ();
2281  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2282  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2283          + ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
2284  LO = EXTEND32 (temp);
2285  HI = EXTEND32 (VH4_8 (temp));
2286  TRACE_ALU_RESULT2 (HI, LO);
2287}
2288
2289
2290:function:::void:do_mfhi:int rd
2291{
2292  check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
2293  TRACE_ALU_INPUT1 (HI);
2294  GPR[rd] = HI;
2295  TRACE_ALU_RESULT (GPR[rd]);
2296}
2297
2298000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
2299"mfhi r<RD>"
2300*mipsI:
2301*mipsII:
2302*mipsIII:
2303*mipsIV:
2304*mipsV:
2305*mips32:
2306*mips64:
2307*vr4100:
2308*vr5000:
2309*r3900:
2310{
2311  do_mfhi (SD_, RD);
2312}
2313
2314
2315
2316:function:::void:do_mflo:int rd
2317{
2318  check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
2319  TRACE_ALU_INPUT1 (LO);
2320  GPR[rd] = LO;
2321  TRACE_ALU_RESULT (GPR[rd]);
2322}
2323
2324000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
2325"mflo r<RD>"
2326*mipsI:
2327*mipsII:
2328*mipsIII:
2329*mipsIV:
2330*mipsV:
2331*mips32:
2332*mips64:
2333*vr4100:
2334*vr5000:
2335*r3900:
2336{
2337  do_mflo (SD_, RD);
2338}
2339
2340
2341
2342000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
2343"movn r<RD>, r<RS>, r<RT>"
2344*mipsIV:
2345*mipsV:
2346*mips32:
2347*mips64:
2348*vr5000:
2349{
2350  if (GPR[RT] != 0)
2351    {
2352      GPR[RD] = GPR[RS];
2353      TRACE_ALU_RESULT (GPR[RD]);
2354    }
2355}
2356
2357
2358
2359000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
2360"movz r<RD>, r<RS>, r<RT>"
2361*mipsIV:
2362*mipsV:
2363*mips32:
2364*mips64:
2365*vr5000:
2366{
2367  if (GPR[RT] == 0)
2368    {
2369      GPR[RD] = GPR[RS];
2370      TRACE_ALU_RESULT (GPR[RD]);
2371    }
2372}
2373
2374
2375
2376011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB
2377"msub r<RS>, r<RT>"
2378*mips32:
2379*mips64:
2380*vr5500:
2381{
2382  signed64 temp;
2383  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2384  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
2385    Unpredictable ();
2386  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2387  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2388          - ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
2389  LO = EXTEND32 (temp);
2390  HI = EXTEND32 (VH4_8 (temp));
2391  TRACE_ALU_RESULT2 (HI, LO);
2392}
2393
2394
2395
2396011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU
2397"msubu r<RS>, r<RT>"
2398*mips32:
2399*mips64:
2400*vr5500:
2401{
2402  unsigned64 temp;
2403  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2404  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
2405    Unpredictable ();
2406  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2407  temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
2408          - ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
2409  LO = EXTEND32 (temp);
2410  HI = EXTEND32 (VH4_8 (temp));
2411  TRACE_ALU_RESULT2 (HI, LO);
2412}
2413
2414
2415
2416000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
2417"mthi r<RS>"
2418*mipsI:
2419*mipsII:
2420*mipsIII:
2421*mipsIV:
2422*mipsV:
2423*mips32:
2424*mips64:
2425*vr4100:
2426*vr5000:
2427*r3900:
2428{
2429  check_mt_hilo (SD_, HIHISTORY);
2430  HI = GPR[RS];
2431}
2432
2433
2434
2435000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
2436"mtlo r<RS>"
2437*mipsI:
2438*mipsII:
2439*mipsIII:
2440*mipsIV:
2441*mipsV:
2442*mips32:
2443*mips64:
2444*vr4100:
2445*vr5000:
2446*r3900:
2447{
2448  check_mt_hilo (SD_, LOHISTORY);
2449  LO = GPR[RS];
2450}
2451
2452
2453
2454011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL
2455"mul r<RD>, r<RS>, r<RT>"
2456*mips32:
2457*mips64:
2458*vr5500:
2459{
2460  signed64 prod;
2461  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
2462    Unpredictable ();
2463  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2464  prod = (((signed64)(signed32) GPR[RS])
2465          * ((signed64)(signed32) GPR[RT]));
2466  GPR[RD] = EXTEND32 (VL4_8 (prod));
2467  TRACE_ALU_RESULT (GPR[RD]);
2468}
2469
2470
2471
2472:function:::void:do_mult:int rs, int rt, int rd
2473{
2474  signed64 prod;
2475  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2476  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
2477    Unpredictable ();
2478  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2479  prod = (((signed64)(signed32) GPR[rs])
2480	  * ((signed64)(signed32) GPR[rt]));
2481  LO = EXTEND32 (VL4_8 (prod));
2482  HI = EXTEND32 (VH4_8 (prod));
2483  if (rd != 0)
2484    GPR[rd] = LO;
2485  TRACE_ALU_RESULT2 (HI, LO);
2486}
2487
2488000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
2489"mult r<RS>, r<RT>"
2490*mipsI:
2491*mipsII:
2492*mipsIII:
2493*mipsIV:
2494*mipsV:
2495*mips32:
2496*mips64:
2497*vr4100:
2498{
2499  do_mult (SD_, RS, RT, 0);
2500}
2501
2502
2503000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
2504"mult r<RS>, r<RT>":RD == 0
2505"mult r<RD>, r<RS>, r<RT>"
2506*vr5000:
2507*r3900:
2508{
2509  do_mult (SD_, RS, RT, RD);
2510}
2511
2512
2513:function:::void:do_multu:int rs, int rt, int rd
2514{
2515  unsigned64 prod;
2516  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2517  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
2518    Unpredictable ();
2519  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2520  prod = (((unsigned64)(unsigned32) GPR[rs])
2521	  * ((unsigned64)(unsigned32) GPR[rt]));
2522  LO = EXTEND32 (VL4_8 (prod));
2523  HI = EXTEND32 (VH4_8 (prod));
2524  if (rd != 0)
2525    GPR[rd] = LO;
2526  TRACE_ALU_RESULT2 (HI, LO);
2527}
2528
2529000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
2530"multu r<RS>, r<RT>"
2531*mipsI:
2532*mipsII:
2533*mipsIII:
2534*mipsIV:
2535*mipsV:
2536*mips32:
2537*mips64:
2538*vr4100:
2539{
2540  do_multu (SD_, RS, RT, 0);
2541}
2542
2543000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
2544"multu r<RS>, r<RT>":RD == 0
2545"multu r<RD>, r<RS>, r<RT>"
2546*vr5000:
2547*r3900:
2548{
2549  do_multu (SD_, RS, RT, RD);
2550}
2551
2552
2553:function:::void:do_nor:int rs, int rt, int rd
2554{
2555  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2556  GPR[rd] = ~ (GPR[rs] | GPR[rt]);
2557  TRACE_ALU_RESULT (GPR[rd]);
2558}
2559
2560000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
2561"nor r<RD>, r<RS>, r<RT>"
2562*mipsI:
2563*mipsII:
2564*mipsIII:
2565*mipsIV:
2566*mipsV:
2567*mips32:
2568*mips64:
2569*vr4100:
2570*vr5000:
2571*r3900:
2572{
2573  do_nor (SD_, RS, RT, RD);
2574}
2575
2576
2577:function:::void:do_or:int rs, int rt, int rd
2578{
2579  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2580  GPR[rd] = (GPR[rs] | GPR[rt]);
2581  TRACE_ALU_RESULT (GPR[rd]);
2582}
2583
2584000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
2585"or r<RD>, r<RS>, r<RT>"
2586*mipsI:
2587*mipsII:
2588*mipsIII:
2589*mipsIV:
2590*mipsV:
2591*mips32:
2592*mips64:
2593*vr4100:
2594*vr5000:
2595*r3900:
2596{
2597  do_or (SD_, RS, RT, RD);
2598}
2599
2600
2601
2602:function:::void:do_ori:int rs, int rt, unsigned immediate
2603{
2604  TRACE_ALU_INPUT2 (GPR[rs], immediate);
2605  GPR[rt] = (GPR[rs] | immediate);
2606  TRACE_ALU_RESULT (GPR[rt]);
2607}
2608
2609001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
2610"ori r<RT>, r<RS>, %#lx<IMMEDIATE>"
2611*mipsI:
2612*mipsII:
2613*mipsIII:
2614*mipsIV:
2615*mipsV:
2616*mips32:
2617*mips64:
2618*vr4100:
2619*vr5000:
2620*r3900:
2621{
2622  do_ori (SD_, RS, RT, IMMEDIATE);
2623}
2624
2625
2626110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF
2627"pref <HINT>, <OFFSET>(r<BASE>)"
2628*mipsIV:
2629*mipsV:
2630*mips32:
2631*mips64:
2632*vr5000:
2633{
2634  address_word base = GPR[BASE];
2635  address_word offset = EXTEND16 (OFFSET);
2636  {
2637    address_word vaddr = loadstore_ea (SD_, base, offset);
2638    address_word paddr;
2639    int uncached;
2640    {
2641      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2642	Prefetch(uncached,paddr,vaddr,isDATA,HINT);
2643    }
2644  }
2645}
2646
2647
2648:function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
2649{
2650  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2651  address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
2652  address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
2653  unsigned int byte;
2654  address_word paddr;
2655  int uncached;
2656  unsigned64 memval;
2657  address_word vaddr;
2658
2659  vaddr = loadstore_ea (SD_, base, offset);
2660  if ((vaddr & access) != 0)
2661    {
2662      SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
2663    }
2664  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2665  paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
2666  byte = ((vaddr & mask) ^ bigendiancpu);
2667  memval = (word << (8 * byte));
2668  StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
2669}
2670
2671:function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
2672{
2673  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2674  address_word reverseendian = (ReverseEndian ? -1 : 0);
2675  address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2676  unsigned int byte;
2677  unsigned int word;
2678  address_word paddr;
2679  int uncached;
2680  unsigned64 memval;
2681  address_word vaddr;
2682  int nr_lhs_bits;
2683  int nr_rhs_bits;
2684
2685  vaddr = loadstore_ea (SD_, base, offset);
2686  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2687  paddr = (paddr ^ (reverseendian & mask));
2688  if (BigEndianMem == 0)
2689    paddr = paddr & ~access;
2690
2691  /* compute where within the word/mem we are */
2692  byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
2693  word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
2694  nr_lhs_bits = 8 * byte + 8;
2695  nr_rhs_bits = 8 * access - 8 * byte;
2696  /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
2697  /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
2698	   (long) ((unsigned64) vaddr >> 32), (long) vaddr,
2699	   (long) ((unsigned64) paddr >> 32), (long) paddr,
2700	   word, byte, nr_lhs_bits, nr_rhs_bits); */
2701
2702  if (word == 0)
2703    {
2704      memval = (rt >> nr_rhs_bits);
2705    }
2706  else
2707    {
2708      memval = (rt << nr_lhs_bits);
2709    }
2710  /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
2711	   (long) ((unsigned64) rt >> 32), (long) rt,
2712	   (long) ((unsigned64) memval >> 32), (long) memval); */
2713  StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
2714}
2715
2716:function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
2717{
2718  address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2719  address_word reverseendian = (ReverseEndian ? -1 : 0);
2720  address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2721  unsigned int byte;
2722  address_word paddr;
2723  int uncached;
2724  unsigned64 memval;
2725  address_word vaddr;
2726
2727  vaddr = loadstore_ea (SD_, base, offset);
2728  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2729  paddr = (paddr ^ (reverseendian & mask));
2730  if (BigEndianMem != 0)
2731    paddr &= ~access;
2732  byte = ((vaddr & mask) ^ (bigendiancpu & mask));
2733  memval = (rt << (byte * 8));
2734  StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
2735}
2736
2737
2738101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
2739"sb r<RT>, <OFFSET>(r<BASE>)"
2740*mipsI:
2741*mipsII:
2742*mipsIII:
2743*mipsIV:
2744*mipsV:
2745*mips32:
2746*mips64:
2747*vr4100:
2748*vr5000:
2749*r3900:
2750{
2751  do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2752}
2753
2754
2755111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
2756"sc r<RT>, <OFFSET>(r<BASE>)"
2757*mipsII:
2758*mipsIII:
2759*mipsIV:
2760*mipsV:
2761*mips32:
2762*mips64:
2763*vr4100:
2764*vr5000:
2765{
2766  unsigned32 instruction = instruction_0;
2767  address_word base = GPR[BASE];
2768  address_word offset = EXTEND16 (OFFSET);
2769  {
2770    address_word vaddr = loadstore_ea (SD_, base, offset);
2771    address_word paddr;
2772    int uncached;
2773    if ((vaddr & 3) != 0)
2774      {
2775	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
2776      }
2777    else
2778      {
2779	if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2780	  {
2781	    unsigned64 memval = 0;
2782	    unsigned64 memval1 = 0;
2783	    unsigned64 mask = 0x7;
2784	    unsigned int byte;
2785	    paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
2786	    byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
2787	    memval = ((unsigned64) GPR[RT] << (8 * byte));
2788	    if (LLBIT)
2789	      {
2790		StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
2791	      }
2792	    GPR[RT] = LLBIT;
2793	  }
2794      }
2795  }
2796}
2797
2798
2799111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
2800"scd r<RT>, <OFFSET>(r<BASE>)"
2801*mipsIII:
2802*mipsIV:
2803*mipsV:
2804*mips64:
2805*vr4100:
2806*vr5000:
2807{
2808  address_word base = GPR[BASE];
2809  address_word offset = EXTEND16 (OFFSET);
2810  check_u64 (SD_, instruction_0);
2811  {
2812    address_word vaddr = loadstore_ea (SD_, base, offset);
2813    address_word paddr;
2814    int uncached;
2815    if ((vaddr & 7) != 0)
2816      {
2817	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
2818      }
2819    else
2820      {
2821	if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2822	  {
2823	    unsigned64 memval = 0;
2824	    unsigned64 memval1 = 0;
2825	    memval = GPR[RT];
2826	    if (LLBIT)
2827	      {
2828		StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
2829	      }
2830	    GPR[RT] = LLBIT;
2831	  }
2832      }
2833  }
2834}
2835
2836
2837111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
2838"sd r<RT>, <OFFSET>(r<BASE>)"
2839*mipsIII:
2840*mipsIV:
2841*mipsV:
2842*mips64:
2843*vr4100:
2844*vr5000:
2845{
2846  check_u64 (SD_, instruction_0);
2847  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2848}
2849
2850
28511111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
2852"sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2853*mipsII:
2854*mipsIII:
2855*mipsIV:
2856*mipsV:
2857*mips32:
2858*mips64:
2859*vr4100:
2860*vr5000:
2861{
2862  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
2863}
2864
2865
2866101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
2867"sdl r<RT>, <OFFSET>(r<BASE>)"
2868*mipsIII:
2869*mipsIV:
2870*mipsV:
2871*mips64:
2872*vr4100:
2873*vr5000:
2874{
2875  check_u64 (SD_, instruction_0);
2876  do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2877}
2878
2879
2880101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
2881"sdr r<RT>, <OFFSET>(r<BASE>)"
2882*mipsIII:
2883*mipsIV:
2884*mipsV:
2885*mips64:
2886*vr4100:
2887*vr5000:
2888{
2889  check_u64 (SD_, instruction_0);
2890  do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2891}
2892
2893
2894101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
2895"sh r<RT>, <OFFSET>(r<BASE>)"
2896*mipsI:
2897*mipsII:
2898*mipsIII:
2899*mipsIV:
2900*mipsV:
2901*mips32:
2902*mips64:
2903*vr4100:
2904*vr5000:
2905*r3900:
2906{
2907  do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2908}
2909
2910
2911:function:::void:do_sll:int rt, int rd, int shift
2912{
2913  unsigned32 temp = (GPR[rt] << shift);
2914  TRACE_ALU_INPUT2 (GPR[rt], shift);
2915  GPR[rd] = EXTEND32 (temp);
2916  TRACE_ALU_RESULT (GPR[rd]);
2917}
2918
2919000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa
2920"nop":RD == 0 && RT == 0 && SHIFT == 0
2921"sll r<RD>, r<RT>, <SHIFT>"
2922*mipsI:
2923*mipsII:
2924*mipsIII:
2925*mipsIV:
2926*mipsV:
2927*vr4100:
2928*vr5000:
2929*r3900:
2930{
2931  /* Skip shift for NOP, so that there won't be lots of extraneous
2932     trace output.  */
2933  if (RD != 0 || RT != 0 || SHIFT != 0)
2934    do_sll (SD_, RT, RD, SHIFT);
2935}
2936
2937000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb
2938"nop":RD == 0 && RT == 0 && SHIFT == 0
2939"ssnop":RD == 0 && RT == 0 && SHIFT == 1
2940"sll r<RD>, r<RT>, <SHIFT>"
2941*mips32:
2942*mips64:
2943{
2944  /* Skip shift for NOP and SSNOP, so that there won't be lots of
2945     extraneous trace output.  */
2946  if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1))
2947    do_sll (SD_, RT, RD, SHIFT);
2948}
2949
2950
2951:function:::void:do_sllv:int rs, int rt, int rd
2952{
2953  int s = MASKED (GPR[rs], 4, 0);
2954  unsigned32 temp = (GPR[rt] << s);
2955  TRACE_ALU_INPUT2 (GPR[rt], s);
2956  GPR[rd] = EXTEND32 (temp);
2957  TRACE_ALU_RESULT (GPR[rd]);
2958}
2959
2960000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
2961"sllv r<RD>, r<RT>, r<RS>"
2962*mipsI:
2963*mipsII:
2964*mipsIII:
2965*mipsIV:
2966*mipsV:
2967*mips32:
2968*mips64:
2969*vr4100:
2970*vr5000:
2971*r3900:
2972{
2973  do_sllv (SD_, RS, RT, RD);
2974}
2975
2976
2977:function:::void:do_slt:int rs, int rt, int rd
2978{
2979  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2980  GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
2981  TRACE_ALU_RESULT (GPR[rd]);
2982}
2983
2984000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
2985"slt r<RD>, r<RS>, r<RT>"
2986*mipsI:
2987*mipsII:
2988*mipsIII:
2989*mipsIV:
2990*mipsV:
2991*mips32:
2992*mips64:
2993*vr4100:
2994*vr5000:
2995*r3900:
2996{
2997  do_slt (SD_, RS, RT, RD);
2998}
2999
3000
3001:function:::void:do_slti:int rs, int rt, unsigned16 immediate
3002{
3003  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
3004  GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
3005  TRACE_ALU_RESULT (GPR[rt]);
3006}
3007
3008001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
3009"slti r<RT>, r<RS>, <IMMEDIATE>"
3010*mipsI:
3011*mipsII:
3012*mipsIII:
3013*mipsIV:
3014*mipsV:
3015*mips32:
3016*mips64:
3017*vr4100:
3018*vr5000:
3019*r3900:
3020{
3021  do_slti (SD_, RS, RT, IMMEDIATE);
3022}
3023
3024
3025:function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
3026{
3027  TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
3028  GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
3029  TRACE_ALU_RESULT (GPR[rt]);
3030}
3031
3032001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
3033"sltiu r<RT>, r<RS>, <IMMEDIATE>"
3034*mipsI:
3035*mipsII:
3036*mipsIII:
3037*mipsIV:
3038*mipsV:
3039*mips32:
3040*mips64:
3041*vr4100:
3042*vr5000:
3043*r3900:
3044{
3045  do_sltiu (SD_, RS, RT, IMMEDIATE);
3046}
3047
3048
3049
3050:function:::void:do_sltu:int rs, int rt, int rd
3051{
3052  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3053  GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
3054  TRACE_ALU_RESULT (GPR[rd]);
3055}
3056
3057000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
3058"sltu r<RD>, r<RS>, r<RT>"
3059*mipsI:
3060*mipsII:
3061*mipsIII:
3062*mipsIV:
3063*mipsV:
3064*mips32:
3065*mips64:
3066*vr4100:
3067*vr5000:
3068*r3900:
3069{
3070  do_sltu (SD_, RS, RT, RD);
3071}
3072
3073
3074:function:::void:do_sra:int rt, int rd, int shift
3075{
3076  signed32 temp = (signed32) GPR[rt] >> shift;
3077  if (NotWordValue (GPR[rt]))
3078    Unpredictable ();
3079  TRACE_ALU_INPUT2 (GPR[rt], shift);
3080  GPR[rd] = EXTEND32 (temp);
3081  TRACE_ALU_RESULT (GPR[rd]);
3082}
3083
3084000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
3085"sra r<RD>, r<RT>, <SHIFT>"
3086*mipsI:
3087*mipsII:
3088*mipsIII:
3089*mipsIV:
3090*mipsV:
3091*mips32:
3092*mips64:
3093*vr4100:
3094*vr5000:
3095*r3900:
3096{
3097  do_sra (SD_, RT, RD, SHIFT);
3098}
3099
3100
3101
3102:function:::void:do_srav:int rs, int rt, int rd
3103{
3104  int s = MASKED (GPR[rs], 4, 0);
3105  signed32 temp = (signed32) GPR[rt] >> s;
3106  if (NotWordValue (GPR[rt]))
3107    Unpredictable ();
3108  TRACE_ALU_INPUT2 (GPR[rt], s);
3109  GPR[rd] = EXTEND32 (temp);
3110  TRACE_ALU_RESULT (GPR[rd]);
3111}
3112
3113000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
3114"srav r<RD>, r<RT>, r<RS>"
3115*mipsI:
3116*mipsII:
3117*mipsIII:
3118*mipsIV:
3119*mipsV:
3120*mips32:
3121*mips64:
3122*vr4100:
3123*vr5000:
3124*r3900:
3125{
3126  do_srav (SD_, RS, RT, RD);
3127}
3128
3129
3130
3131:function:::void:do_srl:int rt, int rd, int shift
3132{
3133  unsigned32 temp = (unsigned32) GPR[rt] >> shift;
3134  if (NotWordValue (GPR[rt]))
3135    Unpredictable ();
3136  TRACE_ALU_INPUT2 (GPR[rt], shift);
3137  GPR[rd] = EXTEND32 (temp);
3138  TRACE_ALU_RESULT (GPR[rd]);
3139}
3140
3141000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
3142"srl r<RD>, r<RT>, <SHIFT>"
3143*mipsI:
3144*mipsII:
3145*mipsIII:
3146*mipsIV:
3147*mipsV:
3148*mips32:
3149*mips64:
3150*vr4100:
3151*vr5000:
3152*r3900:
3153{
3154  do_srl (SD_, RT, RD, SHIFT);
3155}
3156
3157
3158:function:::void:do_srlv:int rs, int rt, int rd
3159{
3160  int s = MASKED (GPR[rs], 4, 0);
3161  unsigned32 temp = (unsigned32) GPR[rt] >> s;
3162  if (NotWordValue (GPR[rt]))
3163    Unpredictable ();
3164  TRACE_ALU_INPUT2 (GPR[rt], s);
3165  GPR[rd] = EXTEND32 (temp);
3166  TRACE_ALU_RESULT (GPR[rd]);
3167}
3168
3169000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
3170"srlv r<RD>, r<RT>, r<RS>"
3171*mipsI:
3172*mipsII:
3173*mipsIII:
3174*mipsIV:
3175*mipsV:
3176*mips32:
3177*mips64:
3178*vr4100:
3179*vr5000:
3180*r3900:
3181{
3182  do_srlv (SD_, RS, RT, RD);
3183}
3184
3185
3186000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
3187"sub r<RD>, r<RS>, r<RT>"
3188*mipsI:
3189*mipsII:
3190*mipsIII:
3191*mipsIV:
3192*mipsV:
3193*mips32:
3194*mips64:
3195*vr4100:
3196*vr5000:
3197*r3900:
3198{
3199  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
3200    Unpredictable ();
3201  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
3202  {
3203    ALU32_BEGIN (GPR[RS]);
3204    ALU32_SUB (GPR[RT]);
3205    ALU32_END (GPR[RD]);   /* This checks for overflow.  */
3206  }
3207  TRACE_ALU_RESULT (GPR[RD]);
3208}
3209
3210
3211:function:::void:do_subu:int rs, int rt, int rd
3212{
3213  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3214    Unpredictable ();
3215  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3216  GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
3217  TRACE_ALU_RESULT (GPR[rd]);
3218}
3219
3220000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
3221"subu r<RD>, r<RS>, r<RT>"
3222*mipsI:
3223*mipsII:
3224*mipsIII:
3225*mipsIV:
3226*mipsV:
3227*mips32:
3228*mips64:
3229*vr4100:
3230*vr5000:
3231*r3900:
3232{
3233  do_subu (SD_, RS, RT, RD);
3234}
3235
3236
3237101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
3238"sw r<RT>, <OFFSET>(r<BASE>)"
3239*mipsI:
3240*mipsII:
3241*mipsIII:
3242*mipsIV:
3243*mipsV:
3244*mips32:
3245*mips64:
3246*vr4100:
3247*r3900:
3248*vr5000:
3249{
3250  do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3251}
3252
3253
32541110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
3255"swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3256*mipsI:
3257*mipsII:
3258*mipsIII:
3259*mipsIV:
3260*mipsV:
3261*mips32:
3262*mips64:
3263*vr4100:
3264*vr5000:
3265*r3900:
3266{
3267  do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
3268}
3269
3270
3271101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
3272"swl r<RT>, <OFFSET>(r<BASE>)"
3273*mipsI:
3274*mipsII:
3275*mipsIII:
3276*mipsIV:
3277*mipsV:
3278*mips32:
3279*mips64:
3280*vr4100:
3281*vr5000:
3282*r3900:
3283{
3284  do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3285}
3286
3287
3288101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
3289"swr r<RT>, <OFFSET>(r<BASE>)"
3290*mipsI:
3291*mipsII:
3292*mipsIII:
3293*mipsIV:
3294*mipsV:
3295*mips32:
3296*mips64:
3297*vr4100:
3298*vr5000:
3299*r3900:
3300{
3301  do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3302}
3303
3304
3305000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
3306"sync":STYPE == 0
3307"sync <STYPE>"
3308*mipsII:
3309*mipsIII:
3310*mipsIV:
3311*mipsV:
3312*mips32:
3313*mips64:
3314*vr4100:
3315*vr5000:
3316*r3900:
3317{
3318  SyncOperation (STYPE);
3319}
3320
3321
3322000000,20.CODE,001100:SPECIAL:32::SYSCALL
3323"syscall %#lx<CODE>"
3324*mipsI:
3325*mipsII:
3326*mipsIII:
3327*mipsIV:
3328*mipsV:
3329*mips32:
3330*mips64:
3331*vr4100:
3332*vr5000:
3333*r3900:
3334{
3335  SignalException (SystemCall, instruction_0);
3336}
3337
3338
3339000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
3340"teq r<RS>, r<RT>"
3341*mipsII:
3342*mipsIII:
3343*mipsIV:
3344*mipsV:
3345*mips32:
3346*mips64:
3347*vr4100:
3348*vr5000:
3349{
3350  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
3351    SignalException (Trap, instruction_0);
3352}
3353
3354
3355000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
3356"teqi r<RS>, <IMMEDIATE>"
3357*mipsII:
3358*mipsIII:
3359*mipsIV:
3360*mipsV:
3361*mips32:
3362*mips64:
3363*vr4100:
3364*vr5000:
3365{
3366  if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
3367    SignalException (Trap, instruction_0);
3368}
3369
3370
3371000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
3372"tge r<RS>, r<RT>"
3373*mipsII:
3374*mipsIII:
3375*mipsIV:
3376*mipsV:
3377*mips32:
3378*mips64:
3379*vr4100:
3380*vr5000:
3381{
3382  if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
3383    SignalException (Trap, instruction_0);
3384}
3385
3386
3387000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
3388"tgei r<RS>, <IMMEDIATE>"
3389*mipsII:
3390*mipsIII:
3391*mipsIV:
3392*mipsV:
3393*mips32:
3394*mips64:
3395*vr4100:
3396*vr5000:
3397{
3398  if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
3399    SignalException (Trap, instruction_0);
3400}
3401
3402
3403000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
3404"tgeiu r<RS>, <IMMEDIATE>"
3405*mipsII:
3406*mipsIII:
3407*mipsIV:
3408*mipsV:
3409*mips32:
3410*mips64:
3411*vr4100:
3412*vr5000:
3413{
3414  if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
3415    SignalException (Trap, instruction_0);
3416}
3417
3418
3419000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
3420"tgeu r<RS>, r<RT>"
3421*mipsII:
3422*mipsIII:
3423*mipsIV:
3424*mipsV:
3425*mips32:
3426*mips64:
3427*vr4100:
3428*vr5000:
3429{
3430  if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
3431    SignalException (Trap, instruction_0);
3432}
3433
3434
3435000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
3436"tlt r<RS>, r<RT>"
3437*mipsII:
3438*mipsIII:
3439*mipsIV:
3440*mipsV:
3441*mips32:
3442*mips64:
3443*vr4100:
3444*vr5000:
3445{
3446  if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
3447    SignalException (Trap, instruction_0);
3448}
3449
3450
3451000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
3452"tlti r<RS>, <IMMEDIATE>"
3453*mipsII:
3454*mipsIII:
3455*mipsIV:
3456*mipsV:
3457*mips32:
3458*mips64:
3459*vr4100:
3460*vr5000:
3461{
3462  if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
3463    SignalException (Trap, instruction_0);
3464}
3465
3466
3467000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
3468"tltiu r<RS>, <IMMEDIATE>"
3469*mipsII:
3470*mipsIII:
3471*mipsIV:
3472*mipsV:
3473*mips32:
3474*mips64:
3475*vr4100:
3476*vr5000:
3477{
3478  if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
3479    SignalException (Trap, instruction_0);
3480}
3481
3482
3483000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
3484"tltu r<RS>, r<RT>"
3485*mipsII:
3486*mipsIII:
3487*mipsIV:
3488*mipsV:
3489*mips32:
3490*mips64:
3491*vr4100:
3492*vr5000:
3493{
3494  if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
3495    SignalException (Trap, instruction_0);
3496}
3497
3498
3499000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
3500"tne r<RS>, r<RT>"
3501*mipsII:
3502*mipsIII:
3503*mipsIV:
3504*mipsV:
3505*mips32:
3506*mips64:
3507*vr4100:
3508*vr5000:
3509{
3510  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
3511    SignalException (Trap, instruction_0);
3512}
3513
3514
3515000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
3516"tnei r<RS>, <IMMEDIATE>"
3517*mipsII:
3518*mipsIII:
3519*mipsIV:
3520*mipsV:
3521*mips32:
3522*mips64:
3523*vr4100:
3524*vr5000:
3525{
3526  if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
3527    SignalException (Trap, instruction_0);
3528}
3529
3530
3531:function:::void:do_xor:int rs, int rt, int rd
3532{
3533  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3534  GPR[rd] = GPR[rs] ^ GPR[rt];
3535  TRACE_ALU_RESULT (GPR[rd]);
3536}
3537
3538000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
3539"xor r<RD>, r<RS>, r<RT>"
3540*mipsI:
3541*mipsII:
3542*mipsIII:
3543*mipsIV:
3544*mipsV:
3545*mips32:
3546*mips64:
3547*vr4100:
3548*vr5000:
3549*r3900:
3550{
3551  do_xor (SD_, RS, RT, RD);
3552}
3553
3554
3555:function:::void:do_xori:int rs, int rt, unsigned16 immediate
3556{
3557  TRACE_ALU_INPUT2 (GPR[rs], immediate);
3558  GPR[rt] = GPR[rs] ^ immediate;
3559  TRACE_ALU_RESULT (GPR[rt]);
3560}
3561
3562001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
3563"xori r<RT>, r<RS>, %#lx<IMMEDIATE>"
3564*mipsI:
3565*mipsII:
3566*mipsIII:
3567*mipsIV:
3568*mipsV:
3569*mips32:
3570*mips64:
3571*vr4100:
3572*vr5000:
3573*r3900:
3574{
3575  do_xori (SD_, RS, RT, IMMEDIATE);
3576}
3577
3578
3579//
3580// MIPS Architecture:
3581//
3582//        FPU Instruction Set (COP1 & COP1X)
3583//
3584
3585
3586:%s::::FMT:int fmt
3587{
3588  switch (fmt)
3589    {
3590    case fmt_single: return "s";
3591    case fmt_double: return "d";
3592    case fmt_word: return "w";
3593    case fmt_long: return "l";
3594    case fmt_ps: return "ps";
3595    default: return "?";
3596    }
3597}
3598
3599:%s::::TF:int tf
3600{
3601  if (tf)
3602    return "t";
3603  else
3604    return "f";
3605}
3606
3607:%s::::ND:int nd
3608{
3609  if (nd)
3610    return "l";
3611  else
3612    return "";
3613}
3614
3615:%s::::COND:int cond
3616{
3617  switch (cond)
3618    {
3619    case 00: return "f";
3620    case 01: return "un";
3621    case 02: return "eq";
3622    case 03: return "ueq";
3623    case 04: return "olt";
3624    case 05: return "ult";
3625    case 06: return "ole";
3626    case 07: return "ule";
3627    case 010: return "sf";
3628    case 011: return "ngle";
3629    case 012: return "seq";
3630    case 013: return "ngl";
3631    case 014: return "lt";
3632    case 015: return "nge";
3633    case 016: return "le";
3634    case 017: return "ngt";
3635    default: return "?";
3636    }
3637}
3638
3639
3640// Helpers:
3641//
3642// Check that the given FPU format is usable, and signal a
3643// ReservedInstruction exception if not.
3644//
3645
3646// check_fmt_p checks that the format is single, double, or paired single.
3647:function:::void:check_fmt_p:int fmt, instruction_word insn
3648*mipsI:
3649*mipsII:
3650*mipsIII:
3651*mipsIV:
3652*mips32:
3653*vr4100:
3654*vr5000:
3655*r3900:
3656{
3657  /* None of these ISAs support Paired Single, so just fall back to
3658     the single/double check.  */
3659  if ((fmt != fmt_single) && (fmt != fmt_double))
3660    SignalException (ReservedInstruction, insn);
3661}
3662
3663:function:::void:check_fmt_p:int fmt, instruction_word insn
3664*mipsV:
3665*mips64:
3666{
3667  if ((fmt != fmt_single) && (fmt != fmt_double)
3668      && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
3669    SignalException (ReservedInstruction, insn);
3670}
3671
3672
3673// Helper:
3674//
3675// Check that the FPU is currently usable, and signal a CoProcessorUnusable
3676// exception if not.
3677//
3678
3679:function:::void:check_fpu:
3680*mipsI:
3681*mipsII:
3682*mipsIII:
3683*mipsIV:
3684*mipsV:
3685*mips32:
3686*mips64:
3687*vr4100:
3688*vr5000:
3689*r3900:
3690{
3691  if (! COP_Usable (1))
3692    SignalExceptionCoProcessorUnusable (1);
3693}
3694
3695
3696// Helper:
3697//
3698// Load a double word FP value using 2 32-bit memory cycles a la MIPS II
3699// or MIPS32.  do_load cannot be used instead because it returns an
3700// unsigned_word, which is limited to the size of the machine's registers.
3701//
3702
3703:function:::unsigned64:do_load_double:address_word base, address_word offset
3704*mipsII:
3705*mips32:
3706{
3707  int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
3708  address_word vaddr;
3709  address_word paddr;
3710  int uncached;
3711  unsigned64 memval;
3712  unsigned64 v;
3713
3714  vaddr = loadstore_ea (SD_, base, offset);
3715  if ((vaddr & AccessLength_DOUBLEWORD) != 0)
3716    {
3717      SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
3718		       AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
3719		       sim_core_unaligned_signal);
3720    }
3721  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
3722		      isREAL);
3723  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr,
3724	      isDATA, isREAL);
3725  v = (unsigned64)memval;
3726  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4,
3727	      isDATA, isREAL);
3728  return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
3729}
3730
3731
3732// Helper:
3733//
3734// Store a double word FP value using 2 32-bit memory cycles a la MIPS II
3735// or MIPS32.  do_load cannot be used instead because it returns an
3736// unsigned_word, which is limited to the size of the machine's registers.
3737//
3738
3739:function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
3740*mipsII:
3741*mips32:
3742{
3743  int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
3744  address_word vaddr;
3745  address_word paddr;
3746  int uncached;
3747  unsigned64 memval;
3748
3749  vaddr = loadstore_ea (SD_, base, offset);
3750  if ((vaddr & AccessLength_DOUBLEWORD) != 0)
3751    {
3752      SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
3753		       AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
3754		       sim_core_unaligned_signal);
3755    }
3756  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET,
3757		      isREAL);
3758  memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
3759  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
3760	       isREAL);
3761  memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
3762  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4,
3763	       isREAL);
3764}
3765
3766
3767010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
3768"abs.%s<FMT> f<FD>, f<FS>"
3769*mipsI:
3770*mipsII:
3771*mipsIII:
3772*mipsIV:
3773*mipsV:
3774*mips32:
3775*mips64:
3776*vr4100:
3777*vr5000:
3778*r3900:
3779{
3780  int fmt = FMT;
3781  check_fpu (SD_);
3782  check_fmt_p (SD_, fmt, instruction_0);
3783  StoreFPR (FD, fmt, AbsoluteValue (ValueFPR (FS, fmt), fmt));
3784}
3785
3786
3787
3788010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
3789"add.%s<FMT> f<FD>, f<FS>, f<FT>"
3790*mipsI:
3791*mipsII:
3792*mipsIII:
3793*mipsIV:
3794*mipsV:
3795*mips32:
3796*mips64:
3797*vr4100:
3798*vr5000:
3799*r3900:
3800{
3801  int fmt = FMT;
3802  check_fpu (SD_);
3803  check_fmt_p (SD_, fmt, instruction_0);
3804  StoreFPR (FD, fmt, Add (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
3805}
3806
3807
3808010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:64,f::ALNV.PS
3809"alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
3810*mipsV:
3811*mips64:
3812{
3813  unsigned64 fs;
3814  unsigned64 ft;
3815  unsigned64 fd;
3816  check_fpu (SD_);
3817  check_u64 (SD_, instruction_0);
3818  fs = ValueFPR (FS, fmt_ps);
3819  if ((GPR[RS] & 0x3) != 0)
3820    Unpredictable ();
3821  if ((GPR[RS] & 0x4) == 0)
3822    fd = fs;
3823  else
3824    {
3825      ft = ValueFPR (FT, fmt_ps);
3826      if (BigEndianCPU)
3827	fd = PackPS (PSLower (fs), PSUpper (ft));
3828      else
3829	fd = PackPS (PSLower (ft), PSUpper (fs));
3830    }
3831  StoreFPR (FD, fmt_ps, fd);
3832}
3833
3834
3835// BC1F
3836// BC1FL
3837// BC1T
3838// BC1TL
3839
3840010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
3841"bc1%s<TF>%s<ND> <OFFSET>"
3842*mipsI:
3843*mipsII:
3844*mipsIII:
3845{
3846  check_fpu (SD_);
3847  TRACE_BRANCH_INPUT (PREVCOC1());
3848  if (PREVCOC1() == TF)
3849    {
3850      address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3851      TRACE_BRANCH_RESULT (dest);
3852      DELAY_SLOT (dest);
3853    }
3854  else if (ND)
3855    {
3856      TRACE_BRANCH_RESULT (0);
3857      NULLIFY_NEXT_INSTRUCTION ();
3858    }
3859  else
3860    {
3861      TRACE_BRANCH_RESULT (NIA);
3862    }
3863}
3864
3865010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
3866"bc1%s<TF>%s<ND> <OFFSET>":CC == 0
3867"bc1%s<TF>%s<ND> <CC>, <OFFSET>"
3868*mipsIV:
3869*mipsV:
3870*mips32:
3871*mips64:
3872#*vr4100:
3873*vr5000:
3874*r3900:
3875{
3876  check_fpu (SD_);
3877  if (GETFCC(CC) == TF)
3878    {
3879      address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3880      DELAY_SLOT (dest);
3881    }
3882  else if (ND)
3883    {
3884      NULLIFY_NEXT_INSTRUCTION ();
3885    }
3886}
3887
3888
3889010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta
3890"c.%s<COND>.%s<FMT> f<FS>, f<FT>"
3891*mipsI:
3892*mipsII:
3893*mipsIII:
3894{
3895  int fmt = FMT;
3896  check_fpu (SD_);
3897  Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0);
3898  TRACE_ALU_RESULT (ValueFCR (31));
3899}
3900
3901010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb
3902"c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
3903"c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
3904*mipsIV:
3905*mipsV:
3906*mips32:
3907*mips64:
3908*vr4100:
3909*vr5000:
3910*r3900:
3911{
3912  int fmt = FMT;
3913  check_fpu (SD_);
3914  check_fmt_p (SD_, fmt, instruction_0);
3915  Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, CC);
3916  TRACE_ALU_RESULT (ValueFCR (31));
3917}
3918
3919
3920010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001010:COP1:64,f::CEIL.L.fmt
3921"ceil.l.%s<FMT> f<FD>, f<FS>"
3922*mipsIII:
3923*mipsIV:
3924*mipsV:
3925*mips64:
3926*vr4100:
3927*vr5000:
3928*r3900:
3929{
3930  int fmt = FMT;
3931  check_fpu (SD_);
3932  StoreFPR (FD, fmt_long, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
3933	    fmt_long));
3934}
3935
3936
3937010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
3938"ceil.w.%s<FMT> f<FD>, f<FS>"
3939*mipsII:
3940*mipsIII:
3941*mipsIV:
3942*mipsV:
3943*mips32:
3944*mips64:
3945*vr4100:
3946*vr5000:
3947*r3900:
3948{
3949  int fmt = FMT;
3950  check_fpu (SD_);
3951  StoreFPR (FD, fmt_word, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
3952	    fmt_word));
3953}
3954
3955
3956010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a
3957"cfc1 r<RT>, f<FS>"
3958*mipsI:
3959*mipsII:
3960*mipsIII:
3961{
3962  check_fpu (SD_);
3963  if (FS == 0)
3964    PENDING_FILL (RT, EXTEND32 (FCR0));
3965  else if (FS == 31)
3966    PENDING_FILL (RT, EXTEND32 (FCR31));
3967  /* else NOP */
3968}
3969
3970010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b
3971"cfc1 r<RT>, f<FS>"
3972*mipsIV:
3973*vr4100:
3974*vr5000:
3975*r3900:
3976{
3977  check_fpu (SD_);
3978  if (FS == 0 || FS == 31)
3979    {
3980      unsigned_word  fcr = ValueFCR (FS);
3981      TRACE_ALU_INPUT1 (fcr);
3982      GPR[RT] = fcr;
3983    }
3984  /* else NOP */
3985  TRACE_ALU_RESULT (GPR[RT]);
3986}
3987
3988010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c
3989"cfc1 r<RT>, f<FS>"
3990*mipsV:
3991*mips32:
3992*mips64:
3993{
3994  check_fpu (SD_);
3995  if (FS == 0 || FS == 25 || FS == 26 || FS == 28 || FS == 31)
3996    {
3997      unsigned_word  fcr = ValueFCR (FS);
3998      TRACE_ALU_INPUT1 (fcr);
3999      GPR[RT] = fcr;
4000    }
4001  /* else NOP */
4002  TRACE_ALU_RESULT (GPR[RT]);
4003}
4004
4005010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
4006"ctc1 r<RT>, f<FS>"
4007*mipsI:
4008*mipsII:
4009*mipsIII:
4010{
4011  check_fpu (SD_);
4012  if (FS == 31)
4013    PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT]));
4014  /* else NOP */
4015}
4016
4017010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b
4018"ctc1 r<RT>, f<FS>"
4019*mipsIV:
4020*vr4100:
4021*vr5000:
4022*r3900:
4023{
4024  check_fpu (SD_);
4025  TRACE_ALU_INPUT1 (GPR[RT]);
4026  if (FS == 31)
4027    StoreFCR (FS, GPR[RT]);
4028  /* else NOP */
4029}
4030
4031010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c
4032"ctc1 r<RT>, f<FS>"
4033*mipsV:
4034*mips32:
4035*mips64:
4036{
4037  check_fpu (SD_);
4038  TRACE_ALU_INPUT1 (GPR[RT]);
4039  if (FS == 25 || FS == 26 || FS == 28 || FS == 31)
4040      StoreFCR (FS, GPR[RT]);
4041  /* else NOP */
4042}
4043
4044
4045//
4046// FIXME: Does not correctly differentiate between mips*
4047//
4048010001,10,3.FMT!1!2!3!6!7,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt
4049"cvt.d.%s<FMT> f<FD>, f<FS>"
4050*mipsI:
4051*mipsII:
4052*mipsIII:
4053*mipsIV:
4054*mipsV:
4055*mips32:
4056*mips64:
4057*vr4100:
4058*vr5000:
4059*r3900:
4060{
4061  int fmt = FMT;
4062  check_fpu (SD_);
4063  if ((fmt == fmt_double) | 0)
4064    SignalException (ReservedInstruction, instruction_0);
4065  StoreFPR (FD, fmt_double, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
4066	    fmt_double));
4067}
4068
4069
4070010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100101:COP1:64,f::CVT.L.fmt
4071"cvt.l.%s<FMT> f<FD>, f<FS>"
4072*mipsIII:
4073*mipsIV:
4074*mipsV:
4075*mips64:
4076*vr4100:
4077*vr5000:
4078*r3900:
4079{
4080  int fmt = FMT;
4081  check_fpu (SD_);
4082  if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
4083    SignalException (ReservedInstruction, instruction_0);
4084  StoreFPR (FD, fmt_long, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
4085	    fmt_long));
4086}
4087
4088
4089010001,10,000,5.FT,5.FS,5.FD,100110:COP1:64,f::CVT.PS.S
4090"cvt.ps.s f<FD>, f<FS>, f<FT>"
4091*mipsV:
4092*mips64:
4093{
4094  check_fpu (SD_);
4095  check_u64 (SD_, instruction_0);
4096  StoreFPR (FD, fmt_ps, PackPS (ValueFPR (FS, fmt_single),
4097				ValueFPR (FT, fmt_single)));
4098}
4099
4100
4101//
4102// FIXME: Does not correctly differentiate between mips*
4103//
4104010001,10,3.FMT!0!2!3!6!7,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
4105"cvt.s.%s<FMT> f<FD>, f<FS>"
4106*mipsI:
4107*mipsII:
4108*mipsIII:
4109*mipsIV:
4110*mipsV:
4111*mips32:
4112*mips64:
4113*vr4100:
4114*vr5000:
4115*r3900:
4116{
4117  int fmt = FMT;
4118  check_fpu (SD_);
4119  if ((fmt == fmt_single) | 0)
4120    SignalException (ReservedInstruction, instruction_0);
4121  StoreFPR (FD, fmt_single, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
4122	    fmt_single));
4123}
4124
4125
4126010001,10,110,00000,5.FS,5.FD,101000:COP1:64,f::CVT.S.PL
4127"cvt.s.pl f<FD>, f<FS>"
4128*mipsV:
4129*mips64:
4130{
4131  check_fpu (SD_);
4132  check_u64 (SD_, instruction_0);
4133  StoreFPR (FD, fmt_single, PSLower (ValueFPR (FS, fmt_ps)));
4134}
4135
4136
4137010001,10,110,00000,5.FS,5.FD,100000:COP1:64,f::CVT.S.PU
4138"cvt.s.pu f<FD>, f<FS>"
4139*mipsV:
4140*mips64:
4141{
4142  check_fpu (SD_);
4143  check_u64 (SD_, instruction_0);
4144  StoreFPR (FD, fmt_single, PSUpper (ValueFPR (FS, fmt_ps)));
4145}
4146
4147
4148010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
4149"cvt.w.%s<FMT> f<FD>, f<FS>"
4150*mipsI:
4151*mipsII:
4152*mipsIII:
4153*mipsIV:
4154*mipsV:
4155*mips32:
4156*mips64:
4157*vr4100:
4158*vr5000:
4159*r3900:
4160{
4161  int fmt = FMT;
4162  check_fpu (SD_);
4163  if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
4164    SignalException (ReservedInstruction, instruction_0);
4165  StoreFPR (FD, fmt_word, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
4166	    fmt_word));
4167}
4168
4169
4170010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt
4171"div.%s<FMT> f<FD>, f<FS>, f<FT>"
4172*mipsI:
4173*mipsII:
4174*mipsIII:
4175*mipsIV:
4176*mipsV:
4177*mips32:
4178*mips64:
4179*vr4100:
4180*vr5000:
4181*r3900:
4182{
4183  int fmt = FMT;
4184  check_fpu (SD_);
4185  StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
4186}
4187
4188
4189010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a
4190"dmfc1 r<RT>, f<FS>"
4191*mipsIII:
4192{
4193  unsigned64 v;
4194  check_fpu (SD_);
4195  check_u64 (SD_, instruction_0);
4196  if (SizeFGR () == 64)
4197    v = FGR[FS];
4198  else if ((FS & 0x1) == 0)
4199    v = SET64HI (FGR[FS+1]) | FGR[FS];
4200  else
4201    v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
4202  PENDING_FILL (RT, v);
4203  TRACE_ALU_RESULT (v);
4204}
4205
4206010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b
4207"dmfc1 r<RT>, f<FS>"
4208*mipsIV:
4209*mipsV:
4210*mips64:
4211*vr4100:
4212*vr5000:
4213*r3900:
4214{
4215  check_fpu (SD_);
4216  check_u64 (SD_, instruction_0);
4217  if (SizeFGR () == 64)
4218    GPR[RT] = FGR[FS];
4219  else if ((FS & 0x1) == 0)
4220    GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
4221  else
4222    GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
4223  TRACE_ALU_RESULT (GPR[RT]);
4224}
4225
4226
4227010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a
4228"dmtc1 r<RT>, f<FS>"
4229*mipsIII:
4230{
4231  unsigned64 v;
4232  check_fpu (SD_);
4233  check_u64 (SD_, instruction_0);
4234  if (SizeFGR () == 64)
4235    PENDING_FILL ((FS + FGR_BASE), GPR[RT]);
4236  else if ((FS & 0x1) == 0)
4237    {
4238      PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT]));
4239      PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
4240    }
4241  else
4242    Unpredictable ();
4243  TRACE_FP_RESULT (GPR[RT]);
4244}
4245
4246010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b
4247"dmtc1 r<RT>, f<FS>"
4248*mipsIV:
4249*mipsV:
4250*mips64:
4251*vr4100:
4252*vr5000:
4253*r3900:
4254{
4255  check_fpu (SD_);
4256  check_u64 (SD_, instruction_0);
4257  if (SizeFGR () == 64)
4258    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
4259  else if ((FS & 0x1) == 0)
4260    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
4261  else
4262    Unpredictable ();
4263}
4264
4265
4266010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001011:COP1:64,f::FLOOR.L.fmt
4267"floor.l.%s<FMT> f<FD>, f<FS>"
4268*mipsIII:
4269*mipsIV:
4270*mipsV:
4271*mips64:
4272*vr4100:
4273*vr5000:
4274*r3900:
4275{
4276  int fmt = FMT;
4277  check_fpu (SD_);
4278  StoreFPR (FD, fmt_long, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
4279	    fmt_long));
4280}
4281
4282
4283010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt
4284"floor.w.%s<FMT> f<FD>, f<FS>"
4285*mipsII:
4286*mipsIII:
4287*mipsIV:
4288*mipsV:
4289*mips32:
4290*mips64:
4291*vr4100:
4292*vr5000:
4293*r3900:
4294{
4295  int fmt = FMT;
4296  check_fpu (SD_);
4297  StoreFPR (FD, fmt_word, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
4298	    fmt_word));
4299}
4300
4301
4302110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
4303"ldc1 f<FT>, <OFFSET>(r<BASE>)"
4304*mipsII:
4305*mips32:
4306{
4307  check_fpu (SD_);
4308  COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
4309}
4310
4311
4312110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
4313"ldc1 f<FT>, <OFFSET>(r<BASE>)"
4314*mipsIII:
4315*mipsIV:
4316*mipsV:
4317*mips64:
4318*vr4100:
4319*vr5000:
4320*r3900:
4321{
4322  check_fpu (SD_);
4323  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
4324}
4325
4326
4327010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1
4328"ldxc1 f<FD>, r<INDEX>(r<BASE>)"
4329*mipsIV:
4330*mipsV:
4331*mips64:
4332*vr5000:
4333{
4334  check_fpu (SD_);
4335  check_u64 (SD_, instruction_0);
4336  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
4337}
4338
4339
4340010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64,f::LUXC1
4341"luxc1 f<FD>, r<INDEX>(r<BASE>)"
4342*mipsV:
4343*mips64:
4344{
4345  address_word base = GPR[BASE];
4346  address_word index = GPR[INDEX];
4347  address_word vaddr = base + index;
4348  check_fpu (SD_);
4349  check_u64 (SD_, instruction_0);
4350  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
4351  if ((vaddr & 0x7) != 0)
4352    index -= (vaddr & 0x7);
4353  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
4354}
4355
4356
4357110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1
4358"lwc1 f<FT>, <OFFSET>(r<BASE>)"
4359*mipsI:
4360*mipsII:
4361*mipsIII:
4362*mipsIV:
4363*mipsV:
4364*mips32:
4365*mips64:
4366*vr4100:
4367*vr5000:
4368*r3900:
4369{
4370  check_fpu (SD_);
4371  COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
4372}
4373
4374
4375010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:64,f::LWXC1
4376"lwxc1 f<FD>, r<INDEX>(r<BASE>)"
4377*mipsIV:
4378*mipsV:
4379*mips64:
4380*vr5000:
4381{
4382  check_fpu (SD_);
4383  check_u64 (SD_, instruction_0);
4384  COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
4385}
4386
4387
4388
4389010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT!2!3!4!5!7:COP1X:64,f::MADD.fmt
4390"madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
4391*mipsIV:
4392*mipsV:
4393*mips64:
4394*vr5000:
4395{
4396  int fmt = FMT;
4397  check_fpu (SD_);
4398  check_u64 (SD_, instruction_0);
4399  check_fmt_p (SD_, fmt, instruction_0);
4400  StoreFPR (FD, fmt, MultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
4401				  ValueFPR (FR, fmt), fmt));
4402}
4403
4404
4405010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a
4406"mfc1 r<RT>, f<FS>"
4407*mipsI:
4408*mipsII:
4409*mipsIII:
4410{
4411  unsigned64 v;
4412  check_fpu (SD_);
4413  v = EXTEND32 (FGR[FS]);
4414  PENDING_FILL (RT, v);
4415  TRACE_ALU_RESULT (v);
4416}
4417
4418010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b
4419"mfc1 r<RT>, f<FS>"
4420*mipsIV:
4421*mipsV:
4422*mips32:
4423*mips64:
4424*vr4100:
4425*vr5000:
4426*r3900:
4427{
4428  check_fpu (SD_);
4429  GPR[RT] = EXTEND32 (FGR[FS]);
4430  TRACE_ALU_RESULT (GPR[RT]);
4431}
4432
4433
4434010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt
4435"mov.%s<FMT> f<FD>, f<FS>"
4436*mipsI:
4437*mipsII:
4438*mipsIII:
4439*mipsIV:
4440*mipsV:
4441*mips32:
4442*mips64:
4443*vr4100:
4444*vr5000:
4445*r3900:
4446{
4447  int fmt = FMT;
4448  check_fpu (SD_);
4449  check_fmt_p (SD_, fmt, instruction_0);
4450  StoreFPR (FD, fmt, ValueFPR (FS, fmt));
4451}
4452
4453
4454// MOVF
4455// MOVT
4456000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf
4457"mov%s<TF> r<RD>, r<RS>, <CC>"
4458*mipsIV:
4459*mipsV:
4460*mips32:
4461*mips64:
4462*vr5000:
4463{
4464  check_fpu (SD_);
4465  if (GETFCC(CC) == TF)
4466    GPR[RD] = GPR[RS];
4467}
4468
4469
4470// MOVF.fmt
4471// MOVT.fmt
4472010001,10,3.FMT!2!3!4!5!7,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt
4473"mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
4474*mipsIV:
4475*mipsV:
4476*mips32:
4477*mips64:
4478*vr5000:
4479{
4480  int fmt = FMT;
4481  check_fpu (SD_);
4482  if (fmt != fmt_ps)
4483    {
4484      if (GETFCC(CC) == TF)
4485	StoreFPR (FD, fmt, ValueFPR (FS, fmt));
4486      else
4487	StoreFPR (FD, fmt, ValueFPR (FD, fmt));   /* set fmt */
4488    }
4489  else
4490    {
4491      unsigned64 fd;
4492      fd = PackPS (PSUpper (ValueFPR ((GETFCC (CC+1) == TF) ? FS : FD,
4493				      fmt_ps)),
4494		   PSLower (ValueFPR ((GETFCC (CC+0) == TF) ? FS : FD,
4495				      fmt_ps)));
4496      StoreFPR (FD, fmt_ps, fd);
4497    }
4498}
4499
4500
4501010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt
4502"movn.%s<FMT> f<FD>, f<FS>, r<RT>"
4503*mipsIV:
4504*mipsV:
4505*mips32:
4506*mips64:
4507*vr5000:
4508{
4509  check_fpu (SD_);
4510  if (GPR[RT] != 0)
4511    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
4512  else
4513    StoreFPR (FD, FMT, ValueFPR (FD, FMT));
4514}
4515
4516
4517// MOVT see MOVtf
4518
4519
4520// MOVT.fmt see MOVtf.fmt
4521
4522
4523
4524010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt
4525"movz.%s<FMT> f<FD>, f<FS>, r<RT>"
4526*mipsIV:
4527*mipsV:
4528*mips32:
4529*mips64:
4530*vr5000:
4531{
4532  check_fpu (SD_);
4533  if (GPR[RT] == 0)
4534    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
4535  else
4536    StoreFPR (FD, FMT, ValueFPR (FD, FMT));
4537}
4538
4539
4540010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT!2!3!4!5!7:COP1X:64,f::MSUB.fmt
4541"msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
4542*mipsIV:
4543*mipsV:
4544*mips64:
4545*vr5000:
4546{
4547  int fmt = FMT;
4548  check_fpu (SD_);
4549  check_u64 (SD_, instruction_0);
4550  check_fmt_p (SD_, fmt, instruction_0);
4551  StoreFPR (FD, fmt, MultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
4552				  ValueFPR (FR, fmt), fmt));
4553}
4554
4555
4556010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a
4557"mtc1 r<RT>, f<FS>"
4558*mipsI:
4559*mipsII:
4560*mipsIII:
4561{
4562  check_fpu (SD_);
4563  if (SizeFGR () == 64)
4564    PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT])));
4565  else
4566    PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
4567  TRACE_FP_RESULT (GPR[RT]);
4568}
4569
4570010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b
4571"mtc1 r<RT>, f<FS>"
4572*mipsIV:
4573*mipsV:
4574*mips32:
4575*mips64:
4576*vr4100:
4577*vr5000:
4578*r3900:
4579{
4580  check_fpu (SD_);
4581  StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
4582}
4583
4584
4585010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
4586"mul.%s<FMT> f<FD>, f<FS>, f<FT>"
4587*mipsI:
4588*mipsII:
4589*mipsIII:
4590*mipsIV:
4591*mipsV:
4592*mips32:
4593*mips64:
4594*vr4100:
4595*vr5000:
4596*r3900:
4597{
4598  int fmt = FMT;
4599  check_fpu (SD_);
4600  check_fmt_p (SD_, fmt, instruction_0);
4601  StoreFPR (FD, fmt, Multiply (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
4602}
4603
4604
4605010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt
4606"neg.%s<FMT> f<FD>, f<FS>"
4607*mipsI:
4608*mipsII:
4609*mipsIII:
4610*mipsIV:
4611*mipsV:
4612*mips32:
4613*mips64:
4614*vr4100:
4615*vr5000:
4616*r3900:
4617{
4618  int fmt = FMT;
4619  check_fpu (SD_);
4620  check_fmt_p (SD_, fmt, instruction_0);
4621  StoreFPR (FD, fmt, Negate (ValueFPR (FS, fmt), fmt));
4622}
4623
4624
4625010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT!2!3!4!5!7:COP1X:64,f::NMADD.fmt
4626"nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
4627*mipsIV:
4628*mipsV:
4629*mips64:
4630*vr5000:
4631{
4632  int fmt = FMT;
4633  check_fpu (SD_);
4634  check_u64 (SD_, instruction_0);
4635  check_fmt_p (SD_, fmt, instruction_0);
4636  StoreFPR (FD, fmt, NegMultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
4637				     ValueFPR (FR, fmt), fmt));
4638}
4639
4640
4641010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT!2!3!4!5!7:COP1X:64,f::NMSUB.fmt
4642"nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
4643*mipsIV:
4644*mipsV:
4645*mips64:
4646*vr5000:
4647{
4648  int fmt = FMT;
4649  check_fpu (SD_);
4650  check_u64 (SD_, instruction_0);
4651  check_fmt_p (SD_, fmt, instruction_0);
4652  StoreFPR (FD, fmt, NegMultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
4653				     ValueFPR (FR, fmt), fmt));
4654}
4655
4656
4657010001,10,110,5.FT,5.FS,5.FD,101100:COP1:64,f::PLL.PS
4658"pll.ps f<FD>, f<FS>, f<FT>"
4659*mipsV:
4660*mips64:
4661{
4662  check_fpu (SD_);
4663  check_u64 (SD_, instruction_0);
4664  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
4665				PSLower (ValueFPR (FT, fmt_ps))));
4666}
4667
4668
4669010001,10,110,5.FT,5.FS,5.FD,101101:COP1:64,f::PLU.PS
4670"plu.ps f<FD>, f<FS>, f<FT>"
4671*mipsV:
4672*mips64:
4673{
4674  check_fpu (SD_);
4675  check_u64 (SD_, instruction_0);
4676  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
4677				PSUpper (ValueFPR (FT, fmt_ps))));
4678}
4679
4680
4681010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:64::PREFX
4682"prefx <HINT>, r<INDEX>(r<BASE>)"
4683*mipsIV:
4684*mipsV:
4685*mips64:
4686*vr5000:
4687{
4688  address_word base = GPR[BASE];
4689  address_word index = GPR[INDEX];
4690  {
4691    address_word vaddr = loadstore_ea (SD_, base, index);
4692    address_word paddr;
4693    int uncached;
4694    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
4695      Prefetch(uncached,paddr,vaddr,isDATA,HINT);
4696  }
4697}
4698
4699
4700010001,10,110,5.FT,5.FS,5.FD,101110:COP1:64,f::PUL.PS
4701"pul.ps f<FD>, f<FS>, f<FT>"
4702*mipsV:
4703*mips64:
4704{
4705  check_fpu (SD_);
4706  check_u64 (SD_, instruction_0);
4707  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
4708				PSLower (ValueFPR (FT, fmt_ps))));
4709}
4710
4711
4712010001,10,110,5.FT,5.FS,5.FD,101111:COP1:64,f::PUU.PS
4713"puu.ps f<FD>, f<FS>, f<FT>"
4714*mipsV:
4715*mips64:
4716{
4717  check_fpu (SD_);
4718  check_u64 (SD_, instruction_0);
4719  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
4720				PSUpper (ValueFPR (FT, fmt_ps))));
4721}
4722
4723
4724010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
4725"recip.%s<FMT> f<FD>, f<FS>"
4726*mipsIV:
4727*mipsV:
4728*mips64:
4729*vr5000:
4730{
4731  int fmt = FMT;
4732  check_fpu (SD_);
4733  StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt));
4734}
4735
4736
4737010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001000:COP1:64,f::ROUND.L.fmt
4738"round.l.%s<FMT> f<FD>, f<FS>"
4739*mipsIII:
4740*mipsIV:
4741*mipsV:
4742*mips64:
4743*vr4100:
4744*vr5000:
4745*r3900:
4746{
4747  int fmt = FMT;
4748  check_fpu (SD_);
4749  StoreFPR (FD, fmt_long, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
4750	    fmt_long));
4751}
4752
4753
4754010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt
4755"round.w.%s<FMT> f<FD>, f<FS>"
4756*mipsII:
4757*mipsIII:
4758*mipsIV:
4759*mipsV:
4760*mips32:
4761*mips64:
4762*vr4100:
4763*vr5000:
4764*r3900:
4765{
4766  int fmt = FMT;
4767  check_fpu (SD_);
4768  StoreFPR (FD, fmt_word, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
4769	    fmt_word));
4770}
4771
4772
4773010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
4774"rsqrt.%s<FMT> f<FD>, f<FS>"
4775*mipsIV:
4776*mipsV:
4777*mips64:
4778*vr5000:
4779{
4780  int fmt = FMT;
4781  check_fpu (SD_);
4782  StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt));
4783}
4784
4785
4786111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
4787"sdc1 f<FT>, <OFFSET>(r<BASE>)"
4788*mipsII:
4789*mips32:
4790{
4791  check_fpu (SD_);
4792  do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
4793}
4794
4795
4796111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
4797"sdc1 f<FT>, <OFFSET>(r<BASE>)"
4798*mipsIII:
4799*mipsIV:
4800*mipsV:
4801*mips64:
4802*vr4100:
4803*vr5000:
4804*r3900:
4805{
4806  check_fpu (SD_);
4807  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
4808}
4809
4810
4811010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1
4812"sdxc1 f<FS>, r<INDEX>(r<BASE>)"
4813*mipsIV:
4814*mipsV:
4815*mips64:
4816*vr5000:
4817{
4818  check_fpu (SD_);
4819  check_u64 (SD_, instruction_0);
4820  do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
4821}
4822
4823
4824010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64,f::SUXC1
4825"suxc1 f<FS>, r<INDEX>(r<BASE>)"
4826*mipsV:
4827*mips64:
4828{
4829  unsigned64 v;
4830  address_word base = GPR[BASE];
4831  address_word index = GPR[INDEX];
4832  address_word vaddr = base + index;
4833  check_fpu (SD_);
4834  check_u64 (SD_, instruction_0);
4835  /* Arrange for the bottom 3 bits of (base + index) to be 0.  */
4836  if ((vaddr & 0x7) != 0)
4837    index -= (vaddr & 0x7);
4838  do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, FS));
4839}
4840
4841
4842010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt
4843"sqrt.%s<FMT> f<FD>, f<FS>"
4844*mipsII:
4845*mipsIII:
4846*mipsIV:
4847*mipsV:
4848*mips32:
4849*mips64:
4850*vr4100:
4851*vr5000:
4852*r3900:
4853{
4854  int fmt = FMT;
4855  check_fpu (SD_);
4856  StoreFPR (FD, fmt,  (SquareRoot (ValueFPR (FS, fmt), fmt)));
4857}
4858
4859
4860010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt
4861"sub.%s<FMT> f<FD>, f<FS>, f<FT>"
4862*mipsI:
4863*mipsII:
4864*mipsIII:
4865*mipsIV:
4866*mipsV:
4867*mips32:
4868*mips64:
4869*vr4100:
4870*vr5000:
4871*r3900:
4872{
4873  int fmt = FMT;
4874  check_fpu (SD_);
4875  check_fmt_p (SD_, fmt, instruction_0);
4876  StoreFPR (FD, fmt, Sub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
4877}
4878
4879
4880
4881111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1
4882"swc1 f<FT>, <OFFSET>(r<BASE>)"
4883*mipsI:
4884*mipsII:
4885*mipsIII:
4886*mipsIV:
4887*mipsV:
4888*mips32:
4889*mips64:
4890*vr4100:
4891*vr5000:
4892*r3900:
4893{
4894  address_word base = GPR[BASE];
4895  address_word offset = EXTEND16 (OFFSET);
4896  check_fpu (SD_);
4897  {
4898    address_word vaddr = loadstore_ea (SD_, base, offset);
4899    address_word paddr;
4900    int uncached;
4901    if ((vaddr & 3) != 0)
4902      {
4903	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
4904      }
4905    else
4906      {
4907	if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4908	  {
4909	    uword64 memval = 0;
4910	    uword64 memval1 = 0;
4911	    uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4912	    address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
4913	    address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
4914	    unsigned int byte;
4915	    paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4916	    byte = ((vaddr & mask) ^ bigendiancpu);
4917	    memval = (((uword64)COP_SW(((instruction_0 >> 26) & 0x3),FT)) << (8 * byte));
4918	    StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4919	  }
4920      }
4921  }
4922}
4923
4924
4925010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1
4926"swxc1 f<FS>, r<INDEX>(r<BASE>)"
4927*mipsIV:
4928*mipsV:
4929*mips64:
4930*vr5000:
4931{
4932
4933  address_word base = GPR[BASE];
4934  address_word index = GPR[INDEX];
4935  check_fpu (SD_);
4936  check_u64 (SD_, instruction_0);
4937  {
4938   address_word vaddr = loadstore_ea (SD_, base, index);
4939   address_word paddr;
4940   int uncached;
4941   if ((vaddr & 3) != 0)
4942     {
4943       SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
4944     }
4945   else
4946   {
4947    if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4948    {
4949     unsigned64 memval = 0;
4950     unsigned64 memval1 = 0;
4951     unsigned64 mask = 0x7;
4952     unsigned int byte;
4953     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
4954     byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
4955     memval = (((unsigned64)COP_SW(1,FS)) << (8 * byte));
4956      {
4957       StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4958      }
4959    }
4960   }
4961  }
4962}
4963
4964
4965010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001001:COP1:64,f::TRUNC.L.fmt
4966"trunc.l.%s<FMT> f<FD>, f<FS>"
4967*mipsIII:
4968*mipsIV:
4969*mipsV:
4970*mips64:
4971*vr4100:
4972*vr5000:
4973*r3900:
4974{
4975  int fmt = FMT;
4976  check_fpu (SD_);
4977  StoreFPR (FD, fmt_long, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
4978	    fmt_long));
4979}
4980
4981
4982010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W
4983"trunc.w.%s<FMT> f<FD>, f<FS>"
4984*mipsII:
4985*mipsIII:
4986*mipsIV:
4987*mipsV:
4988*mips32:
4989*mips64:
4990*vr4100:
4991*vr5000:
4992*r3900:
4993{
4994  int fmt = FMT;
4995  check_fpu (SD_);
4996  StoreFPR (FD, fmt_word, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
4997	    fmt_word));
4998}
4999
5000
5001//
5002// MIPS Architecture:
5003//
5004//        System Control Instruction Set (COP0)
5005//
5006
5007
5008010000,01000,00000,16.OFFSET:COP0:32::BC0F
5009"bc0f <OFFSET>"
5010*mipsI:
5011*mipsII:
5012*mipsIII:
5013*mipsIV:
5014*mipsV:
5015*mips32:
5016*mips64:
5017*vr4100:
5018*vr5000:
5019
5020010000,01000,00000,16.OFFSET:COP0:32::BC0F
5021"bc0f <OFFSET>"
5022// stub needed for eCos as tx39 hardware bug workaround
5023*r3900:
5024{
5025  /* do nothing */
5026}
5027
5028
5029010000,01000,00010,16.OFFSET:COP0:32::BC0FL
5030"bc0fl <OFFSET>"
5031*mipsI:
5032*mipsII:
5033*mipsIII:
5034*mipsIV:
5035*mipsV:
5036*mips32:
5037*mips64:
5038*vr4100:
5039*vr5000:
5040
5041
5042010000,01000,00001,16.OFFSET:COP0:32::BC0T
5043"bc0t <OFFSET>"
5044*mipsI:
5045*mipsII:
5046*mipsIII:
5047*mipsIV:
5048*mipsV:
5049*mips32:
5050*mips64:
5051*vr4100:
5052
5053
5054010000,01000,00011,16.OFFSET:COP0:32::BC0TL
5055"bc0tl <OFFSET>"
5056*mipsI:
5057*mipsII:
5058*mipsIII:
5059*mipsIV:
5060*mipsV:
5061*mips32:
5062*mips64:
5063*vr4100:
5064*vr5000:
5065
5066
5067101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
5068"cache <OP>, <OFFSET>(r<BASE>)"
5069*mipsIII:
5070*mipsIV:
5071*mipsV:
5072*mips32:
5073*mips64:
5074*vr4100:
5075*vr5000:
5076*r3900:
5077{
5078  address_word base = GPR[BASE];
5079  address_word offset = EXTEND16 (OFFSET);
5080  {
5081    address_word vaddr = loadstore_ea (SD_, base, offset);
5082    address_word paddr;
5083    int uncached;
5084    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
5085      CacheOp(OP,vaddr,paddr,instruction_0);
5086  }
5087}
5088
5089
5090010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
5091"dmfc0 r<RT>, r<RD>"
5092*mipsIII:
5093*mipsIV:
5094*mipsV:
5095*mips64:
5096{
5097  check_u64 (SD_, instruction_0);
5098  DecodeCoproc (instruction_0);
5099}
5100
5101
5102010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
5103"dmtc0 r<RT>, r<RD>"
5104*mipsIII:
5105*mipsIV:
5106*mipsV:
5107*mips64:
5108{
5109  check_u64 (SD_, instruction_0);
5110  DecodeCoproc (instruction_0);
5111}
5112
5113
5114010000,1,0000000000000000000,011000:COP0:32::ERET
5115"eret"
5116*mipsIII:
5117*mipsIV:
5118*mipsV:
5119*mips32:
5120*mips64:
5121*vr4100:
5122*vr5000:
5123{
5124  if (SR & status_ERL)
5125    {
5126      /* Oops, not yet available */
5127      sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
5128      NIA = EPC;
5129      SR &= ~status_ERL;
5130    }
5131  else
5132    {
5133      NIA = EPC;
5134      SR &= ~status_EXL;
5135    }
5136}
5137
5138
5139010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
5140"mfc0 r<RT>, r<RD> # <REGX>"
5141*mipsI:
5142*mipsII:
5143*mipsIII:
5144*mipsIV:
5145*mipsV:
5146*mips32:
5147*mips64:
5148*vr4100:
5149*vr5000:
5150*r3900:
5151{
5152  TRACE_ALU_INPUT0 ();
5153  DecodeCoproc (instruction_0);
5154  TRACE_ALU_RESULT (GPR[RT]);
5155}
5156
5157010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
5158"mtc0 r<RT>, r<RD> # <REGX>"
5159*mipsI:
5160*mipsII:
5161*mipsIII:
5162*mipsIV:
5163*mipsV:
5164*mips32:
5165*mips64:
5166*vr4100:
5167*vr5000:
5168*r3900:
5169{
5170  DecodeCoproc (instruction_0);
5171}
5172
5173
5174010000,1,0000000000000000000,010000:COP0:32::RFE
5175"rfe"
5176*mipsI:
5177*mipsII:
5178*mipsIII:
5179*mipsIV:
5180*mipsV:
5181*vr4100:
5182*vr5000:
5183*r3900:
5184{
5185  DecodeCoproc (instruction_0);
5186}
5187
5188
51890100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
5190"cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
5191*mipsI:
5192*mipsII:
5193*mipsIII:
5194*mipsIV:
5195*mipsV:
5196*mips32:
5197*mips64:
5198*vr4100:
5199*r3900:
5200{
5201  DecodeCoproc (instruction_0);
5202}
5203
5204
5205
5206010000,1,0000000000000000000,001000:COP0:32::TLBP
5207"tlbp"
5208*mipsI:
5209*mipsII:
5210*mipsIII:
5211*mipsIV:
5212*mipsV:
5213*mips32:
5214*mips64:
5215*vr4100:
5216*vr5000:
5217
5218
5219010000,1,0000000000000000000,000001:COP0:32::TLBR
5220"tlbr"
5221*mipsI:
5222*mipsII:
5223*mipsIII:
5224*mipsIV:
5225*mipsV:
5226*mips32:
5227*mips64:
5228*vr4100:
5229*vr5000:
5230
5231
5232010000,1,0000000000000000000,000010:COP0:32::TLBWI
5233"tlbwi"
5234*mipsI:
5235*mipsII:
5236*mipsIII:
5237*mipsIV:
5238*mipsV:
5239*mips32:
5240*mips64:
5241*vr4100:
5242*vr5000:
5243
5244
5245010000,1,0000000000000000000,000110:COP0:32::TLBWR
5246"tlbwr"
5247*mipsI:
5248*mipsII:
5249*mipsIII:
5250*mipsIV:
5251*mipsV:
5252*mips32:
5253*mips64:
5254*vr4100:
5255*vr5000:
5256
5257
5258:include:::m16.igen
5259:include:::mdmx.igen
5260:include:::mips3d.igen
5261:include:::sb1.igen
5262:include:::tx.igen
5263:include:::vr.igen
5264
5265