3 // In mips.igen, the semantics for many of the instructions were created
4 // using code generated by gencode. Those semantic segments could be
8 // <insn-word> { "+" <insn-word> }
15 // { <insn-mnemonic> }
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
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
33 // Generate separate simulators for each target
34 // :option:::multi-sim:true
37 // Models known by this simulator are defined below.
39 // When placing models in the instruction descriptions, please place
40 // them one per line, in the order given here.
44 // Instructions and related functions for these models are included in
46 :model:::mipsI:mips3000:
47 :model:::mipsII:mips6000:
48 :model:::mipsIII:mips4000:
49 :model:::mipsIV:mips8000:
50 :model:::mipsV:mipsisaV:
54 // Standard MIPS ISA instructions used for these models are listed here,
55 // as are functions needed by those standard instructions. Instructions
56 // which are model-dependent and which are not in the standard MIPS ISAs
57 // (or which pre-date or use different encodings than the standard
58 // instructions) are (for the most part) in separate .igen files.
59 :model:::vr4100:mips4100: // vr.igen
60 :model:::vr5000:mips5000:
61 :model:::r3900:mips3900: // tx.igen
63 // MIPS Application Specific Extensions (ASEs)
65 // Instructions for the ASEs are in separate .igen files.
66 :model:::mips16:mips16: // m16.igen (and m16.dc)
69 // Pseudo instructions known by IGEN
72 SignalException (ReservedInstruction, 0);
76 // Pseudo instructions known by interp.c
77 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
78 000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
81 SignalException (ReservedInstruction, instruction_0);
88 // Simulate a 32 bit delayslot instruction
91 :function:::address_word:delayslot32:address_word target
93 instruction_word delay_insn;
94 sim_events_slip (SD, 1);
96 CIA = CIA + 4; /* NOTE not mips16 */
97 STATE |= simDELAYSLOT;
98 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
99 ENGINE_ISSUE_PREFIX_HOOK();
100 idecode_issue (CPU_, delay_insn, (CIA));
101 STATE &= ~simDELAYSLOT;
105 :function:::address_word:nullify_next_insn32:
107 sim_events_slip (SD, 1);
108 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
114 // Check that an access to a HI/LO register meets timing requirements
116 // The following requirements exist:
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}.
124 :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
126 if (history->mf.timestamp + 3 > time)
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,
131 (long) history->mf.cia);
137 :function:::int:check_mt_hilo:hilo_history *history
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;
153 :function:::int:check_mt_hilo:hilo_history *history
156 signed64 time = sim_events_time (SD);
157 history->mt.timestamp = time;
158 history->mt.cia = CIA;
163 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
173 signed64 time = sim_events_time (SD);
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))
183 /* The peer has been written to since the last OP yet we have
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,
188 (long) history->op.cia,
189 (long) peer->mt.cia);
192 history->mf.timestamp = time;
193 history->mf.cia = CIA;
199 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
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;
218 // The r3900 mult and multu insns _can_ be exectuted immediatly after
220 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
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;
233 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
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;
256 // Check that the 64-bit instruction can currently be used, and signal
257 // an ReservedInstruction exception if not.
260 :function:::void:check_u64:instruction_word insn
267 // On mips64, if UserMode check SR:PX & SR:UX bits.
268 // The check should be similar to mips64 for any with PX/UX bit equivalents.
274 // MIPS Architecture:
276 // CPU Instruction Set (mipsI - mipsV)
281 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
282 "add r<RD>, r<RS>, r<RT>"
292 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
294 ALU32_BEGIN (GPR[RS]);
296 ALU32_END (GPR[RD]); /* This checks for overflow. */
298 TRACE_ALU_RESULT (GPR[RD]);
303 001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
304 "addi r<RT>, r<RS>, <IMMEDIATE>"
314 TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
316 ALU32_BEGIN (GPR[RS]);
317 ALU32_ADD (EXTEND16 (IMMEDIATE));
318 ALU32_END (GPR[RT]); /* This checks for overflow. */
320 TRACE_ALU_RESULT (GPR[RT]);
325 :function:::void:do_addiu:int rs, int rt, unsigned16 immediate
327 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
328 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
329 TRACE_ALU_RESULT (GPR[rt]);
332 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
333 "addiu r<RT>, r<RS>, <IMMEDIATE>"
343 do_addiu (SD_, RS, RT, IMMEDIATE);
348 :function:::void:do_addu:int rs, int rt, int rd
350 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
351 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
352 TRACE_ALU_RESULT (GPR[rd]);
355 000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
356 "addu r<RD>, r<RS>, r<RT>"
366 do_addu (SD_, RS, RT, RD);
371 :function:::void:do_and:int rs, int rt, int rd
373 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
374 GPR[rd] = GPR[rs] & GPR[rt];
375 TRACE_ALU_RESULT (GPR[rd]);
378 000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
379 "and r<RD>, r<RS>, r<RT>"
389 do_and (SD_, RS, RT, RD);
394 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
395 "and r<RT>, r<RS>, <IMMEDIATE>"
405 TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
406 GPR[RT] = GPR[RS] & IMMEDIATE;
407 TRACE_ALU_RESULT (GPR[RT]);
412 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
413 "beq r<RS>, r<RT>, <OFFSET>"
423 address_word offset = EXTEND16 (OFFSET) << 2;
425 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
427 mark_branch_bug (NIA+offset);
428 DELAY_SLOT (NIA + offset);
434 010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
435 "beql r<RS>, r<RT>, <OFFSET>"
444 address_word offset = EXTEND16 (OFFSET) << 2;
446 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
448 mark_branch_bug (NIA+offset);
449 DELAY_SLOT (NIA + offset);
452 NULLIFY_NEXT_INSTRUCTION ();
457 000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
458 "bgez r<RS>, <OFFSET>"
468 address_word offset = EXTEND16 (OFFSET) << 2;
470 if ((signed_word) GPR[RS] >= 0)
472 mark_branch_bug (NIA+offset);
473 DELAY_SLOT (NIA + offset);
479 000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
480 "bgezal r<RS>, <OFFSET>"
490 address_word offset = EXTEND16 (OFFSET) << 2;
493 if ((signed_word) GPR[RS] >= 0)
495 mark_branch_bug (NIA+offset);
496 DELAY_SLOT (NIA + offset);
502 000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
503 "bgezall r<RS>, <OFFSET>"
512 address_word offset = EXTEND16 (OFFSET) << 2;
515 /* NOTE: The branch occurs AFTER the next instruction has been
517 if ((signed_word) GPR[RS] >= 0)
519 mark_branch_bug (NIA+offset);
520 DELAY_SLOT (NIA + offset);
523 NULLIFY_NEXT_INSTRUCTION ();
528 000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
529 "bgezl r<RS>, <OFFSET>"
538 address_word offset = EXTEND16 (OFFSET) << 2;
540 if ((signed_word) GPR[RS] >= 0)
542 mark_branch_bug (NIA+offset);
543 DELAY_SLOT (NIA + offset);
546 NULLIFY_NEXT_INSTRUCTION ();
551 000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
552 "bgtz r<RS>, <OFFSET>"
562 address_word offset = EXTEND16 (OFFSET) << 2;
564 if ((signed_word) GPR[RS] > 0)
566 mark_branch_bug (NIA+offset);
567 DELAY_SLOT (NIA + offset);
573 010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
574 "bgtzl r<RS>, <OFFSET>"
583 address_word offset = EXTEND16 (OFFSET) << 2;
585 /* NOTE: The branch occurs AFTER the next instruction has been
587 if ((signed_word) GPR[RS] > 0)
589 mark_branch_bug (NIA+offset);
590 DELAY_SLOT (NIA + offset);
593 NULLIFY_NEXT_INSTRUCTION ();
598 000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
599 "blez r<RS>, <OFFSET>"
609 address_word offset = EXTEND16 (OFFSET) << 2;
611 /* NOTE: The branch occurs AFTER the next instruction has been
613 if ((signed_word) GPR[RS] <= 0)
615 mark_branch_bug (NIA+offset);
616 DELAY_SLOT (NIA + offset);
622 010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
623 "bgezl r<RS>, <OFFSET>"
632 address_word offset = EXTEND16 (OFFSET) << 2;
634 if ((signed_word) GPR[RS] <= 0)
636 mark_branch_bug (NIA+offset);
637 DELAY_SLOT (NIA + offset);
640 NULLIFY_NEXT_INSTRUCTION ();
645 000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
646 "bltz r<RS>, <OFFSET>"
656 address_word offset = EXTEND16 (OFFSET) << 2;
658 if ((signed_word) GPR[RS] < 0)
660 mark_branch_bug (NIA+offset);
661 DELAY_SLOT (NIA + offset);
667 000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
668 "bltzal r<RS>, <OFFSET>"
678 address_word offset = EXTEND16 (OFFSET) << 2;
681 /* NOTE: The branch occurs AFTER the next instruction has been
683 if ((signed_word) GPR[RS] < 0)
685 mark_branch_bug (NIA+offset);
686 DELAY_SLOT (NIA + offset);
692 000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
693 "bltzall r<RS>, <OFFSET>"
702 address_word offset = EXTEND16 (OFFSET) << 2;
705 if ((signed_word) GPR[RS] < 0)
707 mark_branch_bug (NIA+offset);
708 DELAY_SLOT (NIA + offset);
711 NULLIFY_NEXT_INSTRUCTION ();
716 000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
717 "bltzl r<RS>, <OFFSET>"
726 address_word offset = EXTEND16 (OFFSET) << 2;
728 /* NOTE: The branch occurs AFTER the next instruction has been
730 if ((signed_word) GPR[RS] < 0)
732 mark_branch_bug (NIA+offset);
733 DELAY_SLOT (NIA + offset);
736 NULLIFY_NEXT_INSTRUCTION ();
741 000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
742 "bne r<RS>, r<RT>, <OFFSET>"
752 address_word offset = EXTEND16 (OFFSET) << 2;
754 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
756 mark_branch_bug (NIA+offset);
757 DELAY_SLOT (NIA + offset);
763 010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
764 "bnel r<RS>, r<RT>, <OFFSET>"
773 address_word offset = EXTEND16 (OFFSET) << 2;
775 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
777 mark_branch_bug (NIA+offset);
778 DELAY_SLOT (NIA + offset);
781 NULLIFY_NEXT_INSTRUCTION ();
786 000000,20.CODE,001101:SPECIAL:32::BREAK
797 /* Check for some break instruction which are reserved for use by the simulator. */
798 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
799 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
800 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
802 sim_engine_halt (SD, CPU, NULL, cia,
803 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
805 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
806 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
808 if (STATE & simDELAYSLOT)
809 PC = cia - 4; /* reference the branch instruction */
812 SignalException(BreakPoint, instruction_0);
817 /* If we get this far, we're not an instruction reserved by the sim. Raise
819 SignalException(BreakPoint, instruction_0);
825 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
826 "dadd r<RD>, r<RS>, r<RT>"
833 check_u64 (SD_, instruction_0);
834 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
836 ALU64_BEGIN (GPR[RS]);
838 ALU64_END (GPR[RD]); /* This checks for overflow. */
840 TRACE_ALU_RESULT (GPR[RD]);
845 011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
846 "daddi r<RT>, r<RS>, <IMMEDIATE>"
853 check_u64 (SD_, instruction_0);
854 TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
856 ALU64_BEGIN (GPR[RS]);
857 ALU64_ADD (EXTEND16 (IMMEDIATE));
858 ALU64_END (GPR[RT]); /* This checks for overflow. */
860 TRACE_ALU_RESULT (GPR[RT]);
865 :function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
867 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
868 GPR[rt] = GPR[rs] + EXTEND16 (immediate);
869 TRACE_ALU_RESULT (GPR[rt]);
872 011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
873 "daddiu r<RT>, r<RS>, <IMMEDIATE>"
880 check_u64 (SD_, instruction_0);
881 do_daddiu (SD_, RS, RT, IMMEDIATE);
886 :function:::void:do_daddu:int rs, int rt, int rd
888 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
889 GPR[rd] = GPR[rs] + GPR[rt];
890 TRACE_ALU_RESULT (GPR[rd]);
893 000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
894 "daddu r<RD>, r<RS>, r<RT>"
901 check_u64 (SD_, instruction_0);
902 do_daddu (SD_, RS, RT, RD);
907 :function:::void:do_ddiv:int rs, int rt
909 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
910 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
912 signed64 n = GPR[rs];
913 signed64 d = GPR[rt];
918 lo = SIGNED64 (0x8000000000000000);
921 else if (d == -1 && n == SIGNED64 (0x8000000000000000))
923 lo = SIGNED64 (0x8000000000000000);
934 TRACE_ALU_RESULT2 (HI, LO);
937 000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
945 check_u64 (SD_, instruction_0);
946 do_ddiv (SD_, RS, RT);
951 :function:::void:do_ddivu:int rs, int rt
953 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
954 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
956 unsigned64 n = GPR[rs];
957 unsigned64 d = GPR[rt];
962 lo = SIGNED64 (0x8000000000000000);
973 TRACE_ALU_RESULT2 (HI, LO);
976 000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
984 check_u64 (SD_, instruction_0);
985 do_ddivu (SD_, RS, RT);
990 :function:::void:do_div:int rs, int rt
992 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
993 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
995 signed32 n = GPR[rs];
996 signed32 d = GPR[rt];
999 LO = EXTEND32 (0x80000000);
1002 else if (n == SIGNED32 (0x80000000) && d == -1)
1004 LO = EXTEND32 (0x80000000);
1009 LO = EXTEND32 (n / d);
1010 HI = EXTEND32 (n % d);
1013 TRACE_ALU_RESULT2 (HI, LO);
1016 000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
1027 do_div (SD_, RS, RT);
1032 :function:::void:do_divu:int rs, int rt
1034 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
1035 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1037 unsigned32 n = GPR[rs];
1038 unsigned32 d = GPR[rt];
1041 LO = EXTEND32 (0x80000000);
1046 LO = EXTEND32 (n / d);
1047 HI = EXTEND32 (n % d);
1050 TRACE_ALU_RESULT2 (HI, LO);
1053 000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
1064 do_divu (SD_, RS, RT);
1069 :function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
1079 unsigned64 op1 = GPR[rs];
1080 unsigned64 op2 = GPR[rt];
1081 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1082 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1083 /* make signed multiply unsigned */
1098 /* multiply out the 4 sub products */
1099 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
1100 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
1101 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
1102 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
1103 /* add the products */
1104 mid = ((unsigned64) VH4_8 (m00)
1105 + (unsigned64) VL4_8 (m10)
1106 + (unsigned64) VL4_8 (m01));
1107 lo = U8_4 (mid, m00);
1109 + (unsigned64) VH4_8 (mid)
1110 + (unsigned64) VH4_8 (m01)
1111 + (unsigned64) VH4_8 (m10));
1121 /* save the result HI/LO (and a gpr) */
1126 TRACE_ALU_RESULT2 (HI, LO);
1129 :function:::void:do_dmult:int rs, int rt, int rd
1131 do_dmultx (SD_, rs, rt, rd, 1);
1134 000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
1135 "dmult r<RS>, r<RT>"
1141 check_u64 (SD_, instruction_0);
1142 do_dmult (SD_, RS, RT, 0);
1145 000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
1146 "dmult r<RS>, r<RT>":RD == 0
1147 "dmult r<RD>, r<RS>, r<RT>"
1150 check_u64 (SD_, instruction_0);
1151 do_dmult (SD_, RS, RT, RD);
1156 :function:::void:do_dmultu:int rs, int rt, int rd
1158 do_dmultx (SD_, rs, rt, rd, 0);
1161 000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
1162 "dmultu r<RS>, r<RT>"
1168 check_u64 (SD_, instruction_0);
1169 do_dmultu (SD_, RS, RT, 0);
1172 000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
1173 "dmultu r<RD>, r<RS>, r<RT>":RD == 0
1174 "dmultu r<RS>, r<RT>"
1177 check_u64 (SD_, instruction_0);
1178 do_dmultu (SD_, RS, RT, RD);
1181 :function:::void:do_dsll:int rt, int rd, int shift
1183 GPR[rd] = GPR[rt] << shift;
1186 :function:::void:do_dsllv:int rs, int rt, int rd
1188 int s = MASKED64 (GPR[rs], 5, 0);
1189 GPR[rd] = GPR[rt] << s;
1193 000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
1194 "dsll r<RD>, r<RT>, <SHIFT>"
1201 check_u64 (SD_, instruction_0);
1202 do_dsll (SD_, RT, RD, SHIFT);
1206 000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
1207 "dsll32 r<RD>, r<RT>, <SHIFT>"
1215 check_u64 (SD_, instruction_0);
1216 GPR[RD] = GPR[RT] << s;
1219 000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
1220 "dsllv r<RD>, r<RT>, r<RS>"
1227 check_u64 (SD_, instruction_0);
1228 do_dsllv (SD_, RS, RT, RD);
1231 :function:::void:do_dsra:int rt, int rd, int shift
1233 GPR[rd] = ((signed64) GPR[rt]) >> shift;
1237 000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
1238 "dsra r<RD>, r<RT>, <SHIFT>"
1245 check_u64 (SD_, instruction_0);
1246 do_dsra (SD_, RT, RD, SHIFT);
1250 000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
1251 "dsra32 r<RT>, r<RD>, <SHIFT>"
1259 check_u64 (SD_, instruction_0);
1260 GPR[RD] = ((signed64) GPR[RT]) >> s;
1264 :function:::void:do_dsrav:int rs, int rt, int rd
1266 int s = MASKED64 (GPR[rs], 5, 0);
1267 TRACE_ALU_INPUT2 (GPR[rt], s);
1268 GPR[rd] = ((signed64) GPR[rt]) >> s;
1269 TRACE_ALU_RESULT (GPR[rd]);
1272 000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
1273 "dsrav r<RT>, r<RD>, r<RS>"
1280 check_u64 (SD_, instruction_0);
1281 do_dsrav (SD_, RS, RT, RD);
1284 :function:::void:do_dsrl:int rt, int rd, int shift
1286 GPR[rd] = (unsigned64) GPR[rt] >> shift;
1290 000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
1291 "dsrl r<RD>, r<RT>, <SHIFT>"
1298 check_u64 (SD_, instruction_0);
1299 do_dsrl (SD_, RT, RD, SHIFT);
1303 000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
1304 "dsrl32 r<RD>, r<RT>, <SHIFT>"
1312 check_u64 (SD_, instruction_0);
1313 GPR[RD] = (unsigned64) GPR[RT] >> s;
1317 :function:::void:do_dsrlv:int rs, int rt, int rd
1319 int s = MASKED64 (GPR[rs], 5, 0);
1320 GPR[rd] = (unsigned64) GPR[rt] >> s;
1325 000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
1326 "dsrlv r<RD>, r<RT>, r<RS>"
1333 check_u64 (SD_, instruction_0);
1334 do_dsrlv (SD_, RS, RT, RD);
1338 000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
1339 "dsub r<RD>, r<RS>, r<RT>"
1346 check_u64 (SD_, instruction_0);
1347 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1349 ALU64_BEGIN (GPR[RS]);
1350 ALU64_SUB (GPR[RT]);
1351 ALU64_END (GPR[RD]); /* This checks for overflow. */
1353 TRACE_ALU_RESULT (GPR[RD]);
1357 :function:::void:do_dsubu:int rs, int rt, int rd
1359 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1360 GPR[rd] = GPR[rs] - GPR[rt];
1361 TRACE_ALU_RESULT (GPR[rd]);
1364 000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
1365 "dsubu r<RD>, r<RS>, r<RT>"
1372 check_u64 (SD_, instruction_0);
1373 do_dsubu (SD_, RS, RT, RD);
1377 000010,26.INSTR_INDEX:NORMAL:32::J
1388 /* NOTE: The region used is that of the delay slot NIA and NOT the
1389 current instruction */
1390 address_word region = (NIA & MASK (63, 28));
1391 DELAY_SLOT (region | (INSTR_INDEX << 2));
1395 000011,26.INSTR_INDEX:NORMAL:32::JAL
1406 /* NOTE: The region used is that of the delay slot and NOT the
1407 current instruction */
1408 address_word region = (NIA & MASK (63, 28));
1410 DELAY_SLOT (region | (INSTR_INDEX << 2));
1413 000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
1414 "jalr r<RS>":RD == 31
1425 address_word temp = GPR[RS];
1431 000000,5.RS,000000000000000,001000:SPECIAL:32::JR
1442 DELAY_SLOT (GPR[RS]);
1446 :function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
1448 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1449 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
1450 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
1457 vaddr = base + offset;
1458 if ((vaddr & access) != 0)
1460 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
1462 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1463 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1464 LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
1465 byte = ((vaddr & mask) ^ bigendiancpu);
1466 return (memval >> (8 * byte));
1469 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
1471 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1472 address_word reverseendian = (ReverseEndian ? -1 : 0);
1473 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1482 unsigned_word lhs_mask;
1485 vaddr = base + offset;
1486 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1487 paddr = (paddr ^ (reverseendian & mask));
1488 if (BigEndianMem == 0)
1489 paddr = paddr & ~access;
1491 /* compute where within the word/mem we are */
1492 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
1493 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
1494 nr_lhs_bits = 8 * byte + 8;
1495 nr_rhs_bits = 8 * access - 8 * byte;
1496 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
1498 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
1499 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
1500 (long) ((unsigned64) paddr >> 32), (long) paddr,
1501 word, byte, nr_lhs_bits, nr_rhs_bits); */
1503 LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
1506 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
1507 temp = (memval << nr_rhs_bits);
1511 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
1512 temp = (memval >> nr_lhs_bits);
1514 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
1515 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
1517 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
1518 (long) ((unsigned64) memval >> 32), (long) memval,
1519 (long) ((unsigned64) temp >> 32), (long) temp,
1520 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
1521 (long) (rt >> 32), (long) rt); */
1525 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
1527 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1528 address_word reverseendian = (ReverseEndian ? -1 : 0);
1529 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
1536 vaddr = base + offset;
1537 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
1538 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
1539 paddr = (paddr ^ (reverseendian & mask));
1540 if (BigEndianMem != 0)
1541 paddr = paddr & ~access;
1542 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
1543 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
1544 LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
1545 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
1546 (long) paddr, byte, (long) paddr, (long) memval); */
1548 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
1550 rt |= (memval >> (8 * byte)) & screen;
1556 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
1557 "lb r<RT>, <OFFSET>(r<BASE>)"
1567 GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
1571 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
1572 "lbu r<RT>, <OFFSET>(r<BASE>)"
1582 GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
1586 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
1587 "ld r<RT>, <OFFSET>(r<BASE>)"
1594 check_u64 (SD_, instruction_0);
1595 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1599 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
1600 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1609 COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
1615 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
1616 "ldl r<RT>, <OFFSET>(r<BASE>)"
1623 check_u64 (SD_, instruction_0);
1624 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1628 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
1629 "ldr r<RT>, <OFFSET>(r<BASE>)"
1636 check_u64 (SD_, instruction_0);
1637 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
1641 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
1642 "lh r<RT>, <OFFSET>(r<BASE>)"
1652 GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
1656 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
1657 "lhu r<RT>, <OFFSET>(r<BASE>)"
1667 GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
1671 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
1672 "ll r<RT>, <OFFSET>(r<BASE>)"
1680 unsigned32 instruction = instruction_0;
1681 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
1682 int destreg = ((instruction >> 16) & 0x0000001F);
1683 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
1685 address_word vaddr = ((unsigned64)op1 + offset);
1688 if ((vaddr & 3) != 0)
1690 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
1694 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1696 unsigned64 memval = 0;
1697 unsigned64 memval1 = 0;
1698 unsigned64 mask = 0x7;
1699 unsigned int shift = 2;
1700 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
1701 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
1703 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
1704 LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
1705 byte = ((vaddr & mask) ^ (bigend << shift));
1706 GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
1714 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
1715 "lld r<RT>, <OFFSET>(r<BASE>)"
1722 unsigned32 instruction = instruction_0;
1723 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
1724 int destreg = ((instruction >> 16) & 0x0000001F);
1725 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
1726 check_u64 (SD_, instruction_0);
1728 address_word vaddr = ((unsigned64)op1 + offset);
1731 if ((vaddr & 7) != 0)
1733 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
1737 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
1739 unsigned64 memval = 0;
1740 unsigned64 memval1 = 0;
1741 LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
1742 GPR[destreg] = memval;
1750 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
1751 "lui r<RT>, <IMMEDIATE>"
1761 TRACE_ALU_INPUT1 (IMMEDIATE);
1762 GPR[RT] = EXTEND32 (IMMEDIATE << 16);
1763 TRACE_ALU_RESULT (GPR[RT]);
1767 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
1768 "lw r<RT>, <OFFSET>(r<BASE>)"
1778 GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
1782 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
1783 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
1793 COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
1797 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
1798 "lwl r<RT>, <OFFSET>(r<BASE>)"
1808 GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
1812 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
1813 "lwr r<RT>, <OFFSET>(r<BASE>)"
1823 GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
1827 100111,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWU
1828 "lwu r<RT>, <OFFSET>(r<BASE>)"
1835 check_u64 (SD_, instruction_0);
1836 GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
1840 :function:::void:do_mfhi:int rd
1842 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
1843 TRACE_ALU_INPUT1 (HI);
1845 TRACE_ALU_RESULT (GPR[rd]);
1848 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
1864 :function:::void:do_mflo:int rd
1866 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
1867 TRACE_ALU_INPUT1 (LO);
1869 TRACE_ALU_RESULT (GPR[rd]);
1872 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
1888 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
1889 "movn r<RD>, r<RS>, r<RT>"
1900 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
1901 "movz r<RD>, r<RS>, r<RT>"
1912 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
1923 check_mt_hilo (SD_, HIHISTORY);
1929 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
1940 check_mt_hilo (SD_, LOHISTORY);
1946 :function:::void:do_mult:int rs, int rt, int rd
1949 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1950 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1951 prod = (((signed64)(signed32) GPR[rs])
1952 * ((signed64)(signed32) GPR[rt]));
1953 LO = EXTEND32 (VL4_8 (prod));
1954 HI = EXTEND32 (VH4_8 (prod));
1957 TRACE_ALU_RESULT2 (HI, LO);
1960 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
1969 do_mult (SD_, RS, RT, 0);
1973 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
1974 "mult r<RS>, r<RT>":RD == 0
1975 "mult r<RD>, r<RS>, r<RT>"
1979 do_mult (SD_, RS, RT, RD);
1983 :function:::void:do_multu:int rs, int rt, int rd
1986 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1987 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1988 prod = (((unsigned64)(unsigned32) GPR[rs])
1989 * ((unsigned64)(unsigned32) GPR[rt]));
1990 LO = EXTEND32 (VL4_8 (prod));
1991 HI = EXTEND32 (VH4_8 (prod));
1994 TRACE_ALU_RESULT2 (HI, LO);
1997 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
1998 "multu r<RS>, r<RT>"
2006 do_multu (SD_, RS, RT, 0);
2009 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
2010 "multu r<RS>, r<RT>":RD == 0
2011 "multu r<RD>, r<RS>, r<RT>"
2015 do_multu (SD_, RS, RT, RD);
2019 :function:::void:do_nor:int rs, int rt, int rd
2021 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2022 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
2023 TRACE_ALU_RESULT (GPR[rd]);
2026 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
2027 "nor r<RD>, r<RS>, r<RT>"
2037 do_nor (SD_, RS, RT, RD);
2041 :function:::void:do_or:int rs, int rt, int rd
2043 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2044 GPR[rd] = (GPR[rs] | GPR[rt]);
2045 TRACE_ALU_RESULT (GPR[rd]);
2048 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
2049 "or r<RD>, r<RS>, r<RT>"
2059 do_or (SD_, RS, RT, RD);
2064 :function:::void:do_ori:int rs, int rt, unsigned immediate
2066 TRACE_ALU_INPUT2 (GPR[rs], immediate);
2067 GPR[rt] = (GPR[rs] | immediate);
2068 TRACE_ALU_RESULT (GPR[rt]);
2071 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
2072 "ori r<RT>, r<RS>, <IMMEDIATE>"
2082 do_ori (SD_, RS, RT, IMMEDIATE);
2086 110011,5.RS,nnnnn,16.OFFSET:NORMAL:32::PREF
2091 unsigned32 instruction = instruction_0;
2092 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
2093 int hint = ((instruction >> 16) & 0x0000001F);
2094 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
2096 address_word vaddr = ((unsigned64)op1 + offset);
2100 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
2101 Prefetch(uncached,paddr,vaddr,isDATA,hint);
2107 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
2109 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2110 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
2111 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
2118 vaddr = base + offset;
2119 if ((vaddr & access) != 0)
2121 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
2123 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2124 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
2125 byte = ((vaddr & mask) ^ bigendiancpu);
2126 memval = (word << (8 * byte));
2127 StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
2130 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
2132 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2133 address_word reverseendian = (ReverseEndian ? -1 : 0);
2134 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2144 vaddr = base + offset;
2145 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2146 paddr = (paddr ^ (reverseendian & mask));
2147 if (BigEndianMem == 0)
2148 paddr = paddr & ~access;
2150 /* compute where within the word/mem we are */
2151 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
2152 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
2153 nr_lhs_bits = 8 * byte + 8;
2154 nr_rhs_bits = 8 * access - 8 * byte;
2155 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
2156 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
2157 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
2158 (long) ((unsigned64) paddr >> 32), (long) paddr,
2159 word, byte, nr_lhs_bits, nr_rhs_bits); */
2163 memval = (rt >> nr_rhs_bits);
2167 memval = (rt << nr_lhs_bits);
2169 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
2170 (long) ((unsigned64) rt >> 32), (long) rt,
2171 (long) ((unsigned64) memval >> 32), (long) memval); */
2172 StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
2175 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
2177 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
2178 address_word reverseendian = (ReverseEndian ? -1 : 0);
2179 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
2186 vaddr = base + offset;
2187 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
2188 paddr = (paddr ^ (reverseendian & mask));
2189 if (BigEndianMem != 0)
2191 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
2192 memval = (rt << (byte * 8));
2193 StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
2197 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
2198 "sb r<RT>, <OFFSET>(r<BASE>)"
2208 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2212 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
2213 "sc r<RT>, <OFFSET>(r<BASE>)"
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)];
2226 address_word vaddr = ((unsigned64)op1 + offset);
2229 if ((vaddr & 3) != 0)
2231 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
2235 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2237 unsigned64 memval = 0;
2238 unsigned64 memval1 = 0;
2239 unsigned64 mask = 0x7;
2241 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
2242 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
2243 memval = ((unsigned64) op2 << (8 * byte));
2246 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
2248 GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
2255 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
2256 "scd r<RT>, <OFFSET>(r<BASE>)"
2263 unsigned32 instruction = instruction_0;
2264 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
2265 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
2266 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
2267 check_u64 (SD_, instruction_0);
2269 address_word vaddr = ((unsigned64)op1 + offset);
2272 if ((vaddr & 7) != 0)
2274 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
2278 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
2280 unsigned64 memval = 0;
2281 unsigned64 memval1 = 0;
2285 StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
2287 GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
2294 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
2295 "sd r<RT>, <OFFSET>(r<BASE>)"
2302 check_u64 (SD_, instruction_0);
2303 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2307 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
2308 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2316 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
2320 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
2321 "sdl r<RT>, <OFFSET>(r<BASE>)"
2328 check_u64 (SD_, instruction_0);
2329 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2333 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
2334 "sdr r<RT>, <OFFSET>(r<BASE>)"
2341 check_u64 (SD_, instruction_0);
2342 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2346 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
2347 "sh r<RT>, <OFFSET>(r<BASE>)"
2357 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2361 :function:::void:do_sll:int rt, int rd, int shift
2363 unsigned32 temp = (GPR[rt] << shift);
2364 TRACE_ALU_INPUT2 (GPR[rt], shift);
2365 GPR[rd] = EXTEND32 (temp);
2366 TRACE_ALU_RESULT (GPR[rd]);
2369 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLL
2370 "nop":RD == 0 && RT == 0 && SHIFT == 0
2371 "sll r<RD>, r<RT>, <SHIFT>"
2381 /* Skip shift for NOP, so that there won't be lots of extraneous
2383 if (RD != 0 || RT != 0 || SHIFT != 0)
2384 do_sll (SD_, RT, RD, SHIFT);
2388 :function:::void:do_sllv:int rs, int rt, int rd
2390 int s = MASKED (GPR[rs], 4, 0);
2391 unsigned32 temp = (GPR[rt] << s);
2392 TRACE_ALU_INPUT2 (GPR[rt], s);
2393 GPR[rd] = EXTEND32 (temp);
2394 TRACE_ALU_RESULT (GPR[rd]);
2397 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
2398 "sllv r<RD>, r<RT>, r<RS>"
2408 do_sllv (SD_, RS, RT, RD);
2412 :function:::void:do_slt:int rs, int rt, int rd
2414 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2415 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
2416 TRACE_ALU_RESULT (GPR[rd]);
2419 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
2420 "slt r<RD>, r<RS>, r<RT>"
2430 do_slt (SD_, RS, RT, RD);
2434 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
2436 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2437 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
2438 TRACE_ALU_RESULT (GPR[rt]);
2441 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
2442 "slti r<RT>, r<RS>, <IMMEDIATE>"
2452 do_slti (SD_, RS, RT, IMMEDIATE);
2456 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
2458 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2459 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
2460 TRACE_ALU_RESULT (GPR[rt]);
2463 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
2464 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
2474 do_sltiu (SD_, RS, RT, IMMEDIATE);
2479 :function:::void:do_sltu:int rs, int rt, int rd
2481 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2482 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
2483 TRACE_ALU_RESULT (GPR[rd]);
2486 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
2487 "sltu r<RD>, r<RS>, r<RT>"
2497 do_sltu (SD_, RS, RT, RD);
2501 :function:::void:do_sra:int rt, int rd, int shift
2503 signed32 temp = (signed32) GPR[rt] >> shift;
2504 TRACE_ALU_INPUT2 (GPR[rt], shift);
2505 GPR[rd] = EXTEND32 (temp);
2506 TRACE_ALU_RESULT (GPR[rd]);
2509 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
2510 "sra r<RD>, r<RT>, <SHIFT>"
2520 do_sra (SD_, RT, RD, SHIFT);
2525 :function:::void:do_srav:int rs, int rt, int rd
2527 int s = MASKED (GPR[rs], 4, 0);
2528 signed32 temp = (signed32) GPR[rt] >> s;
2529 TRACE_ALU_INPUT2 (GPR[rt], s);
2530 GPR[rd] = EXTEND32 (temp);
2531 TRACE_ALU_RESULT (GPR[rd]);
2534 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
2535 "srav r<RD>, r<RT>, r<RS>"
2545 do_srav (SD_, RS, RT, RD);
2550 :function:::void:do_srl:int rt, int rd, int shift
2552 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
2553 TRACE_ALU_INPUT2 (GPR[rt], shift);
2554 GPR[rd] = EXTEND32 (temp);
2555 TRACE_ALU_RESULT (GPR[rd]);
2558 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
2559 "srl r<RD>, r<RT>, <SHIFT>"
2569 do_srl (SD_, RT, RD, SHIFT);
2573 :function:::void:do_srlv:int rs, int rt, int rd
2575 int s = MASKED (GPR[rs], 4, 0);
2576 unsigned32 temp = (unsigned32) GPR[rt] >> s;
2577 TRACE_ALU_INPUT2 (GPR[rt], s);
2578 GPR[rd] = EXTEND32 (temp);
2579 TRACE_ALU_RESULT (GPR[rd]);
2582 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
2583 "srlv r<RD>, r<RT>, r<RS>"
2593 do_srlv (SD_, RS, RT, RD);
2597 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
2598 "sub r<RD>, r<RS>, r<RT>"
2608 TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
2610 ALU32_BEGIN (GPR[RS]);
2611 ALU32_SUB (GPR[RT]);
2612 ALU32_END (GPR[RD]); /* This checks for overflow. */
2614 TRACE_ALU_RESULT (GPR[RD]);
2618 :function:::void:do_subu:int rs, int rt, int rd
2620 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2621 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
2622 TRACE_ALU_RESULT (GPR[rd]);
2625 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
2626 "subu r<RD>, r<RS>, r<RT>"
2636 do_subu (SD_, RS, RT, RD);
2640 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
2641 "sw r<RT>, <OFFSET>(r<BASE>)"
2651 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2655 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
2656 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
2666 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
2670 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
2671 "swl r<RT>, <OFFSET>(r<BASE>)"
2681 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2685 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
2686 "swr r<RT>, <OFFSET>(r<BASE>)"
2696 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
2700 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
2711 SyncOperation (STYPE);
2715 000000,20.CODE,001100:SPECIAL:32::SYSCALL
2726 SignalException(SystemCall, instruction_0);
2730 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
2739 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
2740 SignalException(Trap, instruction_0);
2744 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
2745 "teqi r<RS>, <IMMEDIATE>"
2753 if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
2754 SignalException(Trap, instruction_0);
2758 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
2767 if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
2768 SignalException(Trap, instruction_0);
2772 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
2773 "tgei r<RS>, <IMMEDIATE>"
2781 if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
2782 SignalException(Trap, instruction_0);
2786 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
2787 "tgeiu r<RS>, <IMMEDIATE>"
2795 if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
2796 SignalException(Trap, instruction_0);
2800 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
2809 if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
2810 SignalException(Trap, instruction_0);
2814 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
2823 if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
2824 SignalException(Trap, instruction_0);
2828 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
2829 "tlti r<RS>, <IMMEDIATE>"
2837 if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
2838 SignalException(Trap, instruction_0);
2842 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
2843 "tltiu r<RS>, <IMMEDIATE>"
2851 if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
2852 SignalException(Trap, instruction_0);
2856 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
2865 if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
2866 SignalException(Trap, instruction_0);
2870 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
2879 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2880 SignalException(Trap, instruction_0);
2884 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
2885 "tne r<RS>, <IMMEDIATE>"
2893 if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
2894 SignalException(Trap, instruction_0);
2898 :function:::void:do_xor:int rs, int rt, int rd
2900 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2901 GPR[rd] = GPR[rs] ^ GPR[rt];
2902 TRACE_ALU_RESULT (GPR[rd]);
2905 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
2906 "xor r<RD>, r<RS>, r<RT>"
2916 do_xor (SD_, RS, RT, RD);
2920 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
2922 TRACE_ALU_INPUT2 (GPR[rs], immediate);
2923 GPR[rt] = GPR[rs] ^ immediate;
2924 TRACE_ALU_RESULT (GPR[rt]);
2927 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
2928 "xori r<RT>, r<RS>, <IMMEDIATE>"
2938 do_xori (SD_, RS, RT, IMMEDIATE);
2943 // MIPS Architecture:
2945 // FPU Instruction Set (COP1 & COP1X)
2953 case fmt_single: return "s";
2954 case fmt_double: return "d";
2955 case fmt_word: return "w";
2956 case fmt_long: return "l";
2957 default: return "?";
2967 default: return "?";
2987 :%s::::COND:int cond
2991 case 00: return "f";
2992 case 01: return "un";
2993 case 02: return "eq";
2994 case 03: return "ueq";
2995 case 04: return "olt";
2996 case 05: return "ult";
2997 case 06: return "ole";
2998 case 07: return "ule";
2999 case 010: return "sf";
3000 case 011: return "ngle";
3001 case 012: return "seq";
3002 case 013: return "ngl";
3003 case 014: return "lt";
3004 case 015: return "nge";
3005 case 016: return "le";
3006 case 017: return "ngt";
3007 default: return "?";
3013 // Check that the FPU is currently usable, and signal a CoProcessorUnusable
3014 // exception if not.
3017 :function:::void:check_fpu:
3027 #if 0 /* XXX FIXME: For now, never treat the FPU as disabled. */
3028 if (! COP_Usable (1))
3029 SignalExceptionCoProcessorUnusable (1);
3034 010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
3035 "abs.%s<FMT> f<FD>, f<FS>"
3045 unsigned32 instruction = instruction_0;
3046 int destreg = ((instruction >> 6) & 0x0000001F);
3047 int fs = ((instruction >> 11) & 0x0000001F);
3048 int format = ((instruction >> 21) & 0x00000007);
3051 if ((format != fmt_single) && (format != fmt_double))
3052 SignalException(ReservedInstruction,instruction);
3054 StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));
3060 010001,10,3.FMT,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
3061 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
3071 unsigned32 instruction = instruction_0;
3072 int destreg = ((instruction >> 6) & 0x0000001F);
3073 int fs = ((instruction >> 11) & 0x0000001F);
3074 int ft = ((instruction >> 16) & 0x0000001F);
3075 int format = ((instruction >> 21) & 0x00000007);
3078 if ((format != fmt_single) && (format != fmt_double))
3079 SignalException(ReservedInstruction, instruction);
3081 StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));
3092 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
3093 "bc1%s<TF>%s<ND> <OFFSET>"
3099 check_branch_bug ();
3100 TRACE_BRANCH_INPUT (PREVCOC1());
3101 if (PREVCOC1() == TF)
3103 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3104 TRACE_BRANCH_RESULT (dest);
3105 mark_branch_bug (dest);
3110 TRACE_BRANCH_RESULT (0);
3111 NULLIFY_NEXT_INSTRUCTION ();
3115 TRACE_BRANCH_RESULT (NIA);
3119 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
3120 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
3121 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
3129 check_branch_bug ();
3130 if (GETFCC(CC) == TF)
3132 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
3133 mark_branch_bug (dest);
3138 NULLIFY_NEXT_INSTRUCTION ();
3151 :function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
3153 if ((fmt != fmt_single) && (fmt != fmt_double))
3154 SignalException (ReservedInstruction, insn);
3161 unsigned64 ofs = ValueFPR (fs, fmt);
3162 unsigned64 oft = ValueFPR (ft, fmt);
3163 if (NaN (ofs, fmt) || NaN (oft, fmt))
3165 if (FCSR & FP_ENABLE (IO))
3167 FCSR |= FP_CAUSE (IO);
3168 SignalExceptionFPE ();
3176 less = Less (ofs, oft, fmt);
3177 equal = Equal (ofs, oft, fmt);
3180 condition = (((cond & (1 << 2)) && less)
3181 || ((cond & (1 << 1)) && equal)
3182 || ((cond & (1 << 0)) && unordered));
3183 SETFCC (cc, condition);
3187 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32::C.cond.fmta
3188 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
3194 do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0);
3197 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32::C.cond.fmtb
3198 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
3199 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
3207 do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0);
3211 010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64::CEIL.L.fmt
3212 "ceil.l.%s<FMT> f<FD>, f<FS>"
3220 unsigned32 instruction = instruction_0;
3221 int destreg = ((instruction >> 6) & 0x0000001F);
3222 int fs = ((instruction >> 11) & 0x0000001F);
3223 int format = ((instruction >> 21) & 0x00000007);
3226 if ((format != fmt_single) && (format != fmt_double))
3227 SignalException(ReservedInstruction,instruction);
3229 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long));
3234 010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32::CEIL.W
3243 unsigned32 instruction = instruction_0;
3244 int destreg = ((instruction >> 6) & 0x0000001F);
3245 int fs = ((instruction >> 11) & 0x0000001F);
3246 int format = ((instruction >> 21) & 0x00000007);
3249 if ((format != fmt_single) && (format != fmt_double))
3250 SignalException(ReservedInstruction,instruction);
3252 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word));
3259 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32::CxC1
3260 "c%s<X>c1 r<RT>, f<FS>"
3269 PENDING_FILL(FCR0IDX,VL4_8(GPR[RT]));
3271 PENDING_FILL(FCR31IDX,VL4_8(GPR[RT]));
3273 PENDING_SCHED(FCSR, FCR31 & (1<<23), 1, 23);
3276 { /* control from */
3278 PENDING_FILL(RT,SIGNEXTEND(FCR0,32));
3280 PENDING_FILL(RT,SIGNEXTEND(FCR31,32));
3284 010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32::CxC1
3285 "c%s<X>c1 r<RT>, f<FS>"
3296 TRACE_ALU_INPUT1 (GPR[RT]);
3299 FCR0 = VL4_8(GPR[RT]);
3300 TRACE_ALU_RESULT (FCR0);
3304 FCR31 = VL4_8(GPR[RT]);
3305 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
3306 TRACE_ALU_RESULT (FCR31);
3310 TRACE_ALU_RESULT0 ();
3315 { /* control from */
3318 TRACE_ALU_INPUT1 (FCR0);
3319 GPR[RT] = SIGNEXTEND (FCR0, 32);
3323 TRACE_ALU_INPUT1 (FCR31);
3324 GPR[RT] = SIGNEXTEND (FCR31, 32);
3326 TRACE_ALU_RESULT (GPR[RT]);
3333 // FIXME: Does not correctly differentiate between mips*
3335 010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32::CVT.D.fmt
3336 "cvt.d.%s<FMT> f<FD>, f<FS>"
3346 unsigned32 instruction = instruction_0;
3347 int destreg = ((instruction >> 6) & 0x0000001F);
3348 int fs = ((instruction >> 11) & 0x0000001F);
3349 int format = ((instruction >> 21) & 0x00000007);
3352 if ((format == fmt_double) | 0)
3353 SignalException(ReservedInstruction,instruction);
3355 StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double));
3360 010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64::CVT.L.fmt
3361 "cvt.l.%s<FMT> f<FD>, f<FS>"
3369 unsigned32 instruction = instruction_0;
3370 int destreg = ((instruction >> 6) & 0x0000001F);
3371 int fs = ((instruction >> 11) & 0x0000001F);
3372 int format = ((instruction >> 21) & 0x00000007);
3375 if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word)))
3376 SignalException(ReservedInstruction,instruction);
3378 StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long));
3384 // FIXME: Does not correctly differentiate between mips*
3386 010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32::CVT.S.fmt
3387 "cvt.s.%s<FMT> f<FD>, f<FS>"
3397 unsigned32 instruction = instruction_0;
3398 int destreg = ((instruction >> 6) & 0x0000001F);
3399 int fs = ((instruction >> 11) & 0x0000001F);
3400 int format = ((instruction >> 21) & 0x00000007);
3403 if ((format == fmt_single) | 0)
3404 SignalException(ReservedInstruction,instruction);
3406 StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single));
3411 010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32::CVT.W.fmt
3412 "cvt.w.%s<FMT> f<FD>, f<FS>"
3422 unsigned32 instruction = instruction_0;
3423 int destreg = ((instruction >> 6) & 0x0000001F);
3424 int fs = ((instruction >> 11) & 0x0000001F);
3425 int format = ((instruction >> 21) & 0x00000007);
3428 if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word)))
3429 SignalException(ReservedInstruction,instruction);
3431 StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word));
3436 010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32::DIV.fmt
3437 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
3447 unsigned32 instruction = instruction_0;
3448 int destreg = ((instruction >> 6) & 0x0000001F);
3449 int fs = ((instruction >> 11) & 0x0000001F);
3450 int ft = ((instruction >> 16) & 0x0000001F);
3451 int format = ((instruction >> 21) & 0x00000007);
3454 if ((format != fmt_single) && (format != fmt_double))
3455 SignalException(ReservedInstruction,instruction);
3457 StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));
3464 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64::DMxC1
3465 "dm%s<X>c1 r<RT>, f<FS>"
3469 check_u64 (SD_, instruction_0);
3472 if (SizeFGR() == 64)
3473 PENDING_FILL((FS + FGRIDX),GPR[RT]);
3474 else if ((FS & 0x1) == 0)
3476 PENDING_FILL(((FS + 1) + FGRIDX),VH4_8(GPR[RT]));
3477 PENDING_FILL((FS + FGRIDX),VL4_8(GPR[RT]));
3482 if (SizeFGR() == 64)
3483 PENDING_FILL(RT,FGR[FS]);
3484 else if ((FS & 0x1) == 0)
3485 PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
3488 if (STATE_VERBOSE_P(SD))
3490 "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n",
3492 PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
3496 010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64::DMxC1
3497 "dm%s<X>c1 r<RT>, f<FS>"
3505 check_u64 (SD_, instruction_0);
3508 if (SizeFGR() == 64)
3509 StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
3510 else if ((FS & 0x1) == 0)
3511 StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
3515 if (SizeFGR() == 64)
3517 else if ((FS & 0x1) == 0)
3518 GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
3521 if (STATE_VERBOSE_P(SD))
3523 "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n",
3525 GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
3531 010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64::FLOOR.L.fmt
3532 "floor.l.%s<FMT> f<FD>, f<FS>"
3540 unsigned32 instruction = instruction_0;
3541 int destreg = ((instruction >> 6) & 0x0000001F);
3542 int fs = ((instruction >> 11) & 0x0000001F);
3543 int format = ((instruction >> 21) & 0x00000007);
3546 if ((format != fmt_single) && (format != fmt_double))
3547 SignalException(ReservedInstruction,instruction);
3549 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long));
3554 010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32::FLOOR.W.fmt
3555 "floor.w.%s<FMT> f<FD>, f<FS>"
3564 unsigned32 instruction = instruction_0;
3565 int destreg = ((instruction >> 6) & 0x0000001F);
3566 int fs = ((instruction >> 11) & 0x0000001F);
3567 int format = ((instruction >> 21) & 0x00000007);
3570 if ((format != fmt_single) && (format != fmt_double))
3571 SignalException(ReservedInstruction,instruction);
3573 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word));
3578 110101,5.BASE,5.FT,16.OFFSET:COP1:64::LDC1
3579 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
3590 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
3594 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64::LDXC1
3595 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
3601 check_u64 (SD_, instruction_0);
3602 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
3607 110001,5.BASE,5.FT,16.OFFSET:COP1:32::LWC1
3608 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
3619 COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
3623 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32::LWXC1
3624 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
3630 check_u64 (SD_, instruction_0);
3631 COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
3637 // FIXME: Not correct for mips*
3639 010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D
3640 "madd.d f<FD>, f<FR>, f<FS>, f<FT>"
3645 unsigned32 instruction = instruction_0;
3646 int destreg = ((instruction >> 6) & 0x0000001F);
3647 int fs = ((instruction >> 11) & 0x0000001F);
3648 int ft = ((instruction >> 16) & 0x0000001F);
3649 int fr = ((instruction >> 21) & 0x0000001F);
3652 StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
3657 010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S
3658 "madd.s f<FD>, f<FR>, f<FS>, f<FT>"
3663 unsigned32 instruction = instruction_0;
3664 int destreg = ((instruction >> 6) & 0x0000001F);
3665 int fs = ((instruction >> 11) & 0x0000001F);
3666 int ft = ((instruction >> 16) & 0x0000001F);
3667 int fr = ((instruction >> 21) & 0x0000001F);
3670 StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
3677 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32::MxC1
3678 "m%s<X>c1 r<RT>, f<FS>"
3686 if (SizeFGR() == 64)
3688 if (STATE_VERBOSE_P(SD))
3690 "Warning: PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n",
3692 PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
3695 PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT]));
3698 PENDING_FILL (RT, SIGNEXTEND(FGR[FS],32));
3700 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32::MxC1
3701 "m%s<X>c1 r<RT>, f<FS>"
3712 StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
3714 GPR[RT] = SIGNEXTEND(FGR[FS],32);
3718 010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32::MOV.fmt
3719 "mov.%s<FMT> f<FD>, f<FS>"
3729 unsigned32 instruction = instruction_0;
3730 int destreg = ((instruction >> 6) & 0x0000001F);
3731 int fs = ((instruction >> 11) & 0x0000001F);
3732 int format = ((instruction >> 21) & 0x00000007);
3735 StoreFPR(destreg,format,ValueFPR(fs,format));
3742 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32::MOVtf
3743 "mov%s<TF> r<RD>, r<RS>, <CC>"
3749 if (GETFCC(CC) == TF)
3756 010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32::MOVtf.fmt
3757 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
3762 unsigned32 instruction = instruction_0;
3763 int format = ((instruction >> 21) & 0x00000007);
3766 if (GETFCC(CC) == TF)
3767 StoreFPR (FD, format, ValueFPR (FS, format));
3769 StoreFPR (FD, format, ValueFPR (FD, format));
3774 010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32::MOVN.fmt
3775 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
3782 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
3784 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
3791 // MOVT.fmt see MOVtf.fmt
3795 010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32::MOVZ.fmt
3796 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
3803 StoreFPR (FD, FMT, ValueFPR (FS, FMT));
3805 StoreFPR (FD, FMT, ValueFPR (FD, FMT));
3810 010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32::MSUB.D
3811 "msub.d f<FD>, f<FR>, f<FS>, f<FT>"
3816 unsigned32 instruction = instruction_0;
3817 int destreg = ((instruction >> 6) & 0x0000001F);
3818 int fs = ((instruction >> 11) & 0x0000001F);
3819 int ft = ((instruction >> 16) & 0x0000001F);
3820 int fr = ((instruction >> 21) & 0x0000001F);
3823 StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
3829 010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32::MSUB.S
3830 "msub.s f<FD>, f<FR>, f<FS>, f<FT>"
3835 unsigned32 instruction = instruction_0;
3836 int destreg = ((instruction >> 6) & 0x0000001F);
3837 int fs = ((instruction >> 11) & 0x0000001F);
3838 int ft = ((instruction >> 16) & 0x0000001F);
3839 int fr = ((instruction >> 21) & 0x0000001F);
3842 StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
3850 010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32::MUL.fmt
3851 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
3861 unsigned32 instruction = instruction_0;
3862 int destreg = ((instruction >> 6) & 0x0000001F);
3863 int fs = ((instruction >> 11) & 0x0000001F);
3864 int ft = ((instruction >> 16) & 0x0000001F);
3865 int format = ((instruction >> 21) & 0x00000007);
3868 if ((format != fmt_single) && (format != fmt_double))
3869 SignalException(ReservedInstruction,instruction);
3871 StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));
3876 010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32::NEG.fmt
3877 "neg.%s<FMT> f<FD>, f<FS>"
3887 unsigned32 instruction = instruction_0;
3888 int destreg = ((instruction >> 6) & 0x0000001F);
3889 int fs = ((instruction >> 11) & 0x0000001F);
3890 int format = ((instruction >> 21) & 0x00000007);
3893 if ((format != fmt_single) && (format != fmt_double))
3894 SignalException(ReservedInstruction,instruction);
3896 StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));
3902 010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32::NMADD.D
3903 "nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
3908 unsigned32 instruction = instruction_0;
3909 int destreg = ((instruction >> 6) & 0x0000001F);
3910 int fs = ((instruction >> 11) & 0x0000001F);
3911 int ft = ((instruction >> 16) & 0x0000001F);
3912 int fr = ((instruction >> 21) & 0x0000001F);
3915 StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
3921 010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32::NMADD.S
3922 "nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
3927 unsigned32 instruction = instruction_0;
3928 int destreg = ((instruction >> 6) & 0x0000001F);
3929 int fs = ((instruction >> 11) & 0x0000001F);
3930 int ft = ((instruction >> 16) & 0x0000001F);
3931 int fr = ((instruction >> 21) & 0x0000001F);
3934 StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
3940 010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32::NMSUB.D
3941 "nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
3946 unsigned32 instruction = instruction_0;
3947 int destreg = ((instruction >> 6) & 0x0000001F);
3948 int fs = ((instruction >> 11) & 0x0000001F);
3949 int ft = ((instruction >> 16) & 0x0000001F);
3950 int fr = ((instruction >> 21) & 0x0000001F);
3953 StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
3959 010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32::NMSUB.S
3960 "nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
3965 unsigned32 instruction = instruction_0;
3966 int destreg = ((instruction >> 6) & 0x0000001F);
3967 int fs = ((instruction >> 11) & 0x0000001F);
3968 int ft = ((instruction >> 16) & 0x0000001F);
3969 int fr = ((instruction >> 21) & 0x0000001F);
3972 StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
3977 010011,5.BASE,5.INDEX,5.HINT,00000001111:COP1X:32::PREFX
3978 "prefx <HINT>, r<INDEX>(r<BASE>)"
3983 unsigned32 instruction = instruction_0;
3984 int fs = ((instruction >> 11) & 0x0000001F);
3985 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
3986 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
3988 address_word vaddr = ((unsigned64)op1 + (unsigned64)op2);
3991 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
3992 Prefetch(uncached,paddr,vaddr,isDATA,fs);
3996 010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32::RECIP.fmt
3997 "recip.%s<FMT> f<FD>, f<FS>"
4002 unsigned32 instruction = instruction_0;
4003 int destreg = ((instruction >> 6) & 0x0000001F);
4004 int fs = ((instruction >> 11) & 0x0000001F);
4005 int format = ((instruction >> 21) & 0x00000007);
4008 if ((format != fmt_single) && (format != fmt_double))
4009 SignalException(ReservedInstruction,instruction);
4011 StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));
4016 010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64::ROUND.L.fmt
4017 "round.l.%s<FMT> f<FD>, f<FS>"
4025 unsigned32 instruction = instruction_0;
4026 int destreg = ((instruction >> 6) & 0x0000001F);
4027 int fs = ((instruction >> 11) & 0x0000001F);
4028 int format = ((instruction >> 21) & 0x00000007);
4031 if ((format != fmt_single) && (format != fmt_double))
4032 SignalException(ReservedInstruction,instruction);
4034 StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long));
4039 010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32::ROUND.W.fmt
4040 "round.w.%s<FMT> f<FD>, f<FS>"
4049 unsigned32 instruction = instruction_0;
4050 int destreg = ((instruction >> 6) & 0x0000001F);
4051 int fs = ((instruction >> 11) & 0x0000001F);
4052 int format = ((instruction >> 21) & 0x00000007);
4055 if ((format != fmt_single) && (format != fmt_double))
4056 SignalException(ReservedInstruction,instruction);
4058 StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word));
4063 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32::RSQRT.fmt
4066 "rsqrt.%s<FMT> f<FD>, f<FS>"
4069 unsigned32 instruction = instruction_0;
4070 int destreg = ((instruction >> 6) & 0x0000001F);
4071 int fs = ((instruction >> 11) & 0x0000001F);
4072 int format = ((instruction >> 21) & 0x00000007);
4075 if ((format != fmt_single) && (format != fmt_double))
4076 SignalException(ReservedInstruction,instruction);
4078 StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format),format));
4083 111101,5.BASE,5.FT,16.OFFSET:COP1:64::SDC1
4084 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
4095 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
4099 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64::SDXC1
4100 "ldxc1 f<FS>, r<INDEX>(r<BASE>)"
4106 check_u64 (SD_, instruction_0);
4107 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
4111 010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32::SQRT.fmt
4112 "sqrt.%s<FMT> f<FD>, f<FS>"
4121 unsigned32 instruction = instruction_0;
4122 int destreg = ((instruction >> 6) & 0x0000001F);
4123 int fs = ((instruction >> 11) & 0x0000001F);
4124 int format = ((instruction >> 21) & 0x00000007);
4127 if ((format != fmt_single) && (format != fmt_double))
4128 SignalException(ReservedInstruction,instruction);
4130 StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format)));
4135 010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32::SUB.fmt
4136 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
4146 unsigned32 instruction = instruction_0;
4147 int destreg = ((instruction >> 6) & 0x0000001F);
4148 int fs = ((instruction >> 11) & 0x0000001F);
4149 int ft = ((instruction >> 16) & 0x0000001F);
4150 int format = ((instruction >> 21) & 0x00000007);
4153 if ((format != fmt_single) && (format != fmt_double))
4154 SignalException(ReservedInstruction,instruction);
4156 StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));
4162 111001,5.BASE,5.FT,16.OFFSET:COP1:32::SWC1
4163 "swc1 f<FT>, <OFFSET>(r<BASE>)"
4173 unsigned32 instruction = instruction_0;
4174 signed_word offset = EXTEND16 (OFFSET);
4175 int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
4176 signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
4179 address_word vaddr = ((uword64)op1 + offset);
4182 if ((vaddr & 3) != 0)
4184 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
4188 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4191 uword64 memval1 = 0;
4192 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4193 address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
4194 address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
4196 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4197 byte = ((vaddr & mask) ^ bigendiancpu);
4198 memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte));
4199 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4206 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32::SWXC1
4207 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
4212 unsigned32 instruction = instruction_0;
4213 int fs = ((instruction >> 11) & 0x0000001F);
4214 signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
4215 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
4217 check_u64 (SD_, instruction_0);
4219 address_word vaddr = ((unsigned64)op1 + op2);
4222 if ((vaddr & 3) != 0)
4224 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
4228 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
4230 unsigned64 memval = 0;
4231 unsigned64 memval1 = 0;
4232 unsigned64 mask = 0x7;
4234 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
4235 byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
4236 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
4238 StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
4246 010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64::TRUNC.L.fmt
4247 "trunc.l.%s<FMT> f<FD>, f<FS>"
4255 unsigned32 instruction = instruction_0;
4256 int destreg = ((instruction >> 6) & 0x0000001F);
4257 int fs = ((instruction >> 11) & 0x0000001F);
4258 int format = ((instruction >> 21) & 0x00000007);
4261 if ((format != fmt_single) && (format != fmt_double))
4262 SignalException(ReservedInstruction,instruction);
4264 StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long));
4269 010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32::TRUNC.W
4270 "trunc.w.%s<FMT> f<FD>, f<FS>"
4279 unsigned32 instruction = instruction_0;
4280 int destreg = ((instruction >> 6) & 0x0000001F);
4281 int fs = ((instruction >> 11) & 0x0000001F);
4282 int format = ((instruction >> 21) & 0x00000007);
4285 if ((format != fmt_single) && (format != fmt_double))
4286 SignalException(ReservedInstruction,instruction);
4288 StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word));
4294 // MIPS Architecture:
4296 // System Control Instruction Set (COP0)
4300 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4310 010000,01000,00000,16.OFFSET:COP0:32::BC0F
4312 // stub needed for eCos as tx39 hardware bug workaround
4319 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
4330 010000,01000,00001,16.OFFSET:COP0:32::BC0T
4340 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
4351 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
4359 unsigned32 instruction = instruction_0;
4360 signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
4361 int hint = ((instruction >> 16) & 0x0000001F);
4362 signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
4364 address_word vaddr = (op1 + offset);
4367 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
4368 CacheOp(hint,vaddr,paddr,instruction);
4373 010000,1,0000000000000000000,111001:COP0:32::DI
4384 010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
4385 "dmfc0 r<RT>, r<RD>"
4390 check_u64 (SD_, instruction_0);
4391 DecodeCoproc (instruction_0);
4395 010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
4396 "dmtc0 r<RT>, r<RD>"
4401 check_u64 (SD_, instruction_0);
4402 DecodeCoproc (instruction_0);
4406 010000,1,0000000000000000000,111000:COP0:32::EI
4417 010000,1,0000000000000000000,011000:COP0:32::ERET
4425 if (SR & status_ERL)
4427 /* Oops, not yet available */
4428 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
4440 010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
4441 "mfc0 r<RT>, r<RD> # <REGX>"
4451 TRACE_ALU_INPUT0 ();
4452 DecodeCoproc (instruction_0);
4453 TRACE_ALU_RESULT (GPR[RT]);
4456 010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
4457 "mtc0 r<RT>, r<RD> # <REGX>"
4467 DecodeCoproc (instruction_0);
4471 010000,1,0000000000000000000,010000:COP0:32::RFE
4482 DecodeCoproc (instruction_0);
4486 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
4487 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
4496 DecodeCoproc (instruction_0);
4501 010000,1,0000000000000000000,001000:COP0:32::TLBP
4512 010000,1,0000000000000000000,000001:COP0:32::TLBR
4523 010000,1,0000000000000000000,000010:COP0:32::TLBWI
4534 010000,1,0000000000000000000,000110:COP0:32::TLBWR