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