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