1// -*- C -*- 2// 3// <insn> ::= 4// <insn-word> { "+" <insn-word> } 5// ":" <format-name> 6// ":" <filter-flags> 7// ":" <options> 8// ":" <name> 9// <nl> 10// { <insn-model> } 11// { <insn-mnemonic> } 12// <code-block> 13// 14 15 16// IGEN config - mips16 17// :option:16::insn-bit-size:16 18// :option:16::hi-bit-nr:15 19:option:16::insn-specifying-widths:true 20:option:16::gen-delayed-branch:false 21 22// IGEN config - mips32/64.. 23// :option:32::insn-bit-size:32 24// :option:32::hi-bit-nr:31 25:option:32::insn-specifying-widths:true 26:option:32::gen-delayed-branch:false 27 28 29// Generate separate simulators for each target 30// :option:::multi-sim:true 31 32 33// Models known by this simulator are defined below. 34// 35// When placing models in the instruction descriptions, please place 36// them one per line, in the order given here. 37 38// MIPS ISAs: 39// 40// Instructions and related functions for these models are included in 41// this file. 42:model:::mipsI:mips3000: 43:model:::mipsII:mips6000: 44:model:::mipsIII:mips4000: 45:model:::mipsIV:mips8000: 46:model:::mipsV:mipsisaV: 47:model:::mips32:mipsisa32: 48:model:::mips32r2:mipsisa32r2: 49:model:::mips64:mipsisa64: 50:model:::mips64r2:mipsisa64r2: 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 60:model:::vr4120:mips4120: 61:model:::vr5000:mips5000: 62:model:::vr5400:mips5400: 63:model:::vr5500:mips5500: 64:model:::r3900:mips3900: // tx.igen 65 66// MIPS Application Specific Extensions (ASEs) 67// 68// Instructions for the ASEs are in separate .igen files. 69// ASEs add instructions on to a base ISA. 70:model:::mips16:mips16: // m16.igen (and m16.dc) 71:model:::mips16e:mips16e: // m16e.igen 72:model:::mips3d:mips3d: // mips3d.igen 73:model:::mdmx:mdmx: // mdmx.igen 74:model:::dsp:dsp: // dsp.igen 75:model:::dsp2:dsp2: // dsp2.igen 76:model:::smartmips:smartmips: // smartmips.igen 77:model:::micromips32:micromips64: // micromips.igen 78:model:::micromips64:micromips64: // micromips.igen 79:model:::micromipsdsp:micromipsdsp: // micromipsdsp.igen 80 81// Vendor Extensions 82// 83// Instructions specific to these extensions are in separate .igen files. 84// Extensions add instructions on to a base ISA. 85:model:::sb1:sb1: // sb1.igen 86 87 88// Pseudo instructions known by IGEN 89:internal::::illegal: 90{ 91 SignalException (ReservedInstruction, 0); 92} 93 94 95// Pseudo instructions known by interp.c 96// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK 97000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD 98"rsvd <OP>" 99{ 100 SignalException (ReservedInstruction, instruction_0); 101} 102 103 104 105// Helper: 106// 107// Simulate a 32 bit delayslot instruction 108// 109 110:function:::address_word:delayslot32:address_word target 111{ 112 instruction_word delay_insn; 113 sim_events_slip (SD, 1); 114 DSPC = CIA; 115 CIA = CIA + 4; /* NOTE not mips16 */ 116 STATE |= simDELAYSLOT; 117 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */ 118 ENGINE_ISSUE_PREFIX_HOOK(); 119 idecode_issue (CPU_, delay_insn, (CIA)); 120 STATE &= ~simDELAYSLOT; 121 return target; 122} 123 124:function:::address_word:nullify_next_insn32: 125{ 126 sim_events_slip (SD, 1); 127 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction"); 128 return CIA + 8; 129} 130 131 132// Helper: 133// 134// Calculate an effective address given a base and an offset. 135// 136 137:function:::address_word:loadstore_ea:address_word base, address_word offset 138*mipsI: 139*mipsII: 140*mipsIII: 141*mipsIV: 142*mipsV: 143*mips32: 144*mips32r2: 145*vr4100: 146*vr5000: 147*r3900: 148*micromips32: 149{ 150 return base + offset; 151} 152 153:function:::address_word:loadstore_ea:address_word base, address_word offset 154*mips64: 155*mips64r2: 156*micromips64: 157{ 158#if 0 /* XXX FIXME: enable this only after some additional testing. */ 159 /* If in user mode and UX is not set, use 32-bit compatibility effective 160 address computations as defined in the MIPS64 Architecture for 161 Programmers Volume III, Revision 0.95, section 4.9. */ 162 if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX)) 163 == (ksu_user << status_KSU_shift)) 164 return (address_word)((signed32)base + (signed32)offset); 165#endif 166 return base + offset; 167} 168 169 170// Helper: 171// 172// Check that a 32-bit register value is properly sign-extended. 173// (See NotWordValue in ISA spec.) 174// 175 176:function:::int:not_word_value:unsigned_word value 177*mipsI: 178*mipsII: 179*mipsIII: 180*mipsIV: 181*mipsV: 182*vr4100: 183*vr5000: 184*r3900: 185*mips32: 186*mips32r2: 187*mips64: 188*mips64r2: 189*micromips32: 190*micromips64: 191{ 192#if WITH_TARGET_WORD_BITSIZE == 64 193 return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 194#else 195 return 0; 196#endif 197} 198 199// Helper: 200// 201// Handle UNPREDICTABLE operation behaviour. The goal here is to prevent 202// theoretically portable code which invokes non-portable behaviour from 203// running with no indication of the portability issue. 204// (See definition of UNPREDICTABLE in ISA spec.) 205// 206 207:function:::void:unpredictable: 208*mipsI: 209*mipsII: 210*mipsIII: 211*mipsIV: 212*mipsV: 213*vr4100: 214*vr5000: 215*r3900: 216{ 217} 218 219:function:::void:unpredictable: 220*mips32: 221*mips32r2: 222*mips64: 223*mips64r2: 224*micromips32: 225*micromips64: 226{ 227 unpredictable_action (CPU, CIA); 228} 229 230 231// Helpers: 232// 233// Check that an access to a HI/LO register meets timing requirements 234// 235// In all MIPS ISAs, 236// 237// OP {HI and LO} followed by MT{LO or HI} (and not MT{HI or LO}) 238// makes subsequent MF{HI or LO} UNPREDICTABLE. (1) 239// 240// The following restrictions exist for MIPS I - MIPS III: 241// 242// MF{HI or LO} followed by MT{HI or LO} w/ less than 2 instructions 243// in between makes MF UNPREDICTABLE. (2) 244// 245// MF{HI or LO} followed by OP {HI and LO} w/ less than 2 instructions 246// in between makes MF UNPREDICTABLE. (3) 247// 248// On the r3900, restriction (2) is not present, and restriction (3) is not 249// present for multiplication. 250// 251// Unfortunately, there seems to be some confusion about whether the last 252// two restrictions should apply to "MIPS IV" as well. One edition of 253// the MIPS IV ISA says they do, but references in later ISA documents 254// suggest they don't. 255// 256// In reality, some MIPS IV parts, such as the VR5000 and VR5400, do have 257// these restrictions, while others, like the VR5500, don't. To accomodate 258// such differences, the MIPS IV and MIPS V version of these helper functions 259// use auxillary routines to determine whether the restriction applies. 260 261// check_mf_cycles: 262// 263// Helper used by check_mt_hilo, check_mult_hilo, and check_div_hilo 264// to check for restrictions (2) and (3) above. 265// 266:function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new 267{ 268 if (history->mf.timestamp + 3 > time) 269 { 270 sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n", 271 itable[MY_INDEX].name, 272 new, (long) CIA, 273 (long) history->mf.cia); 274 return 0; 275 } 276 return 1; 277} 278 279 280// check_mt_hilo: 281// 282// Check for restriction (2) above (for ISAs/processors that have it), 283// and record timestamps for restriction (1) above. 284// 285:function:::int:check_mt_hilo:hilo_history *history 286*mipsI: 287*mipsII: 288*mipsIII: 289*vr4100: 290*vr5000: 291{ 292 signed64 time = sim_events_time (SD); 293 int ok = check_mf_cycles (SD_, history, time, "MT"); 294 history->mt.timestamp = time; 295 history->mt.cia = CIA; 296 return ok; 297} 298 299:function:::int:check_mt_hilo:hilo_history *history 300*mipsIV: 301*mipsV: 302{ 303 signed64 time = sim_events_time (SD); 304 int ok = (! MIPS_MACH_HAS_MT_HILO_HAZARD (SD) 305 || check_mf_cycles (SD_, history, time, "MT")); 306 history->mt.timestamp = time; 307 history->mt.cia = CIA; 308 return ok; 309} 310 311:function:::int:check_mt_hilo:hilo_history *history 312*mips32: 313*mips32r2: 314*mips64: 315*mips64r2: 316*r3900: 317*micromips32: 318*micromips64: 319{ 320 signed64 time = sim_events_time (SD); 321 history->mt.timestamp = time; 322 history->mt.cia = CIA; 323 return 1; 324} 325 326 327// check_mf_hilo: 328// 329// Check for restriction (1) above, and record timestamps for 330// restriction (2) and (3) above. 331// 332:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer 333*mipsI: 334*mipsII: 335*mipsIII: 336*mipsIV: 337*mipsV: 338*mips32: 339*mips32r2: 340*mips64: 341*mips64r2: 342*vr4100: 343*vr5000: 344*r3900: 345*micromips32: 346*micromips64: 347{ 348 signed64 time = sim_events_time (SD); 349 int ok = 1; 350 if (peer != NULL 351 && peer->mt.timestamp > history->op.timestamp 352 && history->mt.timestamp < history->op.timestamp 353 && ! (history->mf.timestamp > history->op.timestamp 354 && history->mf.timestamp < peer->mt.timestamp) 355 && ! (peer->mf.timestamp > history->op.timestamp 356 && peer->mf.timestamp < peer->mt.timestamp)) 357 { 358 /* The peer has been written to since the last OP yet we have 359 not */ 360 sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n", 361 itable[MY_INDEX].name, 362 (long) CIA, 363 (long) history->op.cia, 364 (long) peer->mt.cia); 365 ok = 0; 366 } 367 history->mf.timestamp = time; 368 history->mf.cia = CIA; 369 return ok; 370} 371 372 373 374// check_mult_hilo: 375// 376// Check for restriction (3) above (for ISAs/processors that have it) 377// for MULT ops, and record timestamps for restriction (1) above. 378// 379:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo 380*mipsI: 381*mipsII: 382*mipsIII: 383*vr4100: 384*vr5000: 385{ 386 signed64 time = sim_events_time (SD); 387 int ok = (check_mf_cycles (SD_, hi, time, "OP") 388 && check_mf_cycles (SD_, lo, time, "OP")); 389 hi->op.timestamp = time; 390 lo->op.timestamp = time; 391 hi->op.cia = CIA; 392 lo->op.cia = CIA; 393 return ok; 394} 395 396:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo 397*mipsIV: 398*mipsV: 399{ 400 signed64 time = sim_events_time (SD); 401 int ok = (! MIPS_MACH_HAS_MULT_HILO_HAZARD (SD) 402 || (check_mf_cycles (SD_, hi, time, "OP") 403 && check_mf_cycles (SD_, lo, time, "OP"))); 404 hi->op.timestamp = time; 405 lo->op.timestamp = time; 406 hi->op.cia = CIA; 407 lo->op.cia = CIA; 408 return ok; 409} 410 411:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo 412*mips32: 413*mips32r2: 414*mips64: 415*mips64r2: 416*r3900: 417*micromips32: 418*micromips64: 419{ 420 /* FIXME: could record the fact that a stall occured if we want */ 421 signed64 time = sim_events_time (SD); 422 hi->op.timestamp = time; 423 lo->op.timestamp = time; 424 hi->op.cia = CIA; 425 lo->op.cia = CIA; 426 return 1; 427} 428 429 430// check_div_hilo: 431// 432// Check for restriction (3) above (for ISAs/processors that have it) 433// for DIV ops, and record timestamps for restriction (1) above. 434// 435:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo 436*mipsI: 437*mipsII: 438*mipsIII: 439*vr4100: 440*vr5000: 441*r3900: 442{ 443 signed64 time = sim_events_time (SD); 444 int ok = (check_mf_cycles (SD_, hi, time, "OP") 445 && check_mf_cycles (SD_, lo, time, "OP")); 446 hi->op.timestamp = time; 447 lo->op.timestamp = time; 448 hi->op.cia = CIA; 449 lo->op.cia = CIA; 450 return ok; 451} 452 453:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo 454*mipsIV: 455*mipsV: 456{ 457 signed64 time = sim_events_time (SD); 458 int ok = (! MIPS_MACH_HAS_DIV_HILO_HAZARD (SD) 459 || (check_mf_cycles (SD_, hi, time, "OP") 460 && check_mf_cycles (SD_, lo, time, "OP"))); 461 hi->op.timestamp = time; 462 lo->op.timestamp = time; 463 hi->op.cia = CIA; 464 lo->op.cia = CIA; 465 return ok; 466} 467 468:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo 469*mips32: 470*mips32r2: 471*mips64: 472*mips64r2: 473*micromips32: 474*micromips64: 475{ 476 signed64 time = sim_events_time (SD); 477 hi->op.timestamp = time; 478 lo->op.timestamp = time; 479 hi->op.cia = CIA; 480 lo->op.cia = CIA; 481 return 1; 482} 483 484 485// Helper: 486// 487// Check that the 64-bit instruction can currently be used, and signal 488// a ReservedInstruction exception if not. 489// 490 491:function:::void:check_u64:instruction_word insn 492*mipsIII: 493*mipsIV: 494*mipsV: 495*vr4100: 496*vr5000: 497*vr5400: 498*vr5500: 499*r3900: 500{ 501 // The check should be similar to mips64 for any with PX/UX bit equivalents. 502} 503 504:function:::void:check_u64:instruction_word insn 505*mips16e: 506*mips64: 507*mips64r2: 508*mips32: 509*mips32r2: 510*micromips64: 511*micromips32: 512{ 513#if 0 /* XXX FIXME: enable this only after some additional testing. */ 514 if (UserMode && (SR & (status_UX|status_PX)) == 0) 515 SignalException (ReservedInstruction, insn); 516#endif 517} 518 519 520 521// 522// MIPS Architecture: 523// 524// CPU Instruction Set (mipsI - mipsV, mips32/r2, mips64/r2) 525// 526 527 528:function:::void:do_add:int rs, int rt, int rd 529{ 530 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 531 Unpredictable (); 532 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 533 { 534 ALU32_BEGIN (GPR[rs]); 535 ALU32_ADD (GPR[rt]); 536 ALU32_END (GPR[rd]); /* This checks for overflow. */ 537 } 538 TRACE_ALU_RESULT (GPR[rd]); 539} 540 541:function:::void:do_addi:int rs, int rt, unsigned16 immediate 542{ 543 if (NotWordValue (GPR[rs])) 544 Unpredictable (); 545 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 546 { 547 ALU32_BEGIN (GPR[rs]); 548 ALU32_ADD (EXTEND16 (immediate)); 549 ALU32_END (GPR[rt]); /* This checks for overflow. */ 550 } 551 TRACE_ALU_RESULT (GPR[rt]); 552} 553 554:function:::void:do_andi:int rs, int rt, unsigned int immediate 555{ 556 TRACE_ALU_INPUT2 (GPR[rs], immediate); 557 GPR[rt] = GPR[rs] & immediate; 558 TRACE_ALU_RESULT (GPR[rt]); 559} 560 561:function:::void:do_dadd:int rd, int rs, int rt 562{ 563 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 564 { 565 ALU64_BEGIN (GPR[rs]); 566 ALU64_ADD (GPR[rt]); 567 ALU64_END (GPR[rd]); /* This checks for overflow. */ 568 } 569 TRACE_ALU_RESULT (GPR[rd]); 570} 571 572:function:::void:do_daddi:int rt, int rs, int immediate 573{ 574 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 575 { 576 ALU64_BEGIN (GPR[rs]); 577 ALU64_ADD (EXTEND16 (immediate)); 578 ALU64_END (GPR[rt]); /* This checks for overflow. */ 579 } 580 TRACE_ALU_RESULT (GPR[rt]); 581} 582 583:function:::void:do_dsll32:int rd, int rt, int shift 584{ 585 int s = 32 + shift; 586 TRACE_ALU_INPUT2 (GPR[rt], s); 587 GPR[rd] = GPR[rt] << s; 588 TRACE_ALU_RESULT (GPR[rd]); 589} 590 591:function:::void:do_dsra32:int rd, int rt, int shift 592{ 593 int s = 32 + shift; 594 TRACE_ALU_INPUT2 (GPR[rt], s); 595 GPR[rd] = ((signed64) GPR[rt]) >> s; 596 TRACE_ALU_RESULT (GPR[rd]); 597} 598 599:function:::void:do_dsrl32:int rd, int rt, int shift 600{ 601 int s = 32 + shift; 602 TRACE_ALU_INPUT2 (GPR[rt], s); 603 GPR[rd] = (unsigned64) GPR[rt] >> s; 604 TRACE_ALU_RESULT (GPR[rd]); 605} 606 607:function:::void:do_dsub:int rd, int rs, int rt 608{ 609 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 610 { 611 ALU64_BEGIN (GPR[rs]); 612 ALU64_SUB (GPR[rt]); 613 ALU64_END (GPR[rd]); /* This checks for overflow. */ 614 } 615 TRACE_ALU_RESULT (GPR[rd]); 616} 617 618:function:::void:do_break:address_word instruction_0 619{ 620 /* Check for some break instruction which are reserved for use by the 621 simulator. */ 622 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK; 623 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) || 624 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK)) 625 { 626 sim_engine_halt (SD, CPU, NULL, cia, 627 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF)); 628 } 629 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) || 630 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK)) 631 { 632 if (STATE & simDELAYSLOT) 633 PC = cia - 4; /* reference the branch instruction */ 634 else 635 PC = cia; 636 SignalException (BreakPoint, instruction_0); 637 } 638 639 else 640 { 641 /* If we get this far, we're not an instruction reserved by the sim. Raise 642 the exception. */ 643 SignalException (BreakPoint, instruction_0); 644 } 645} 646 647:function:::void:do_break16:address_word instruction_0 648{ 649 if (STATE & simDELAYSLOT) 650 PC = cia - 2; /* reference the branch instruction */ 651 else 652 PC = cia; 653 SignalException (BreakPoint, instruction_0); 654} 655 656:function:::void:do_clo:int rd, int rs 657{ 658 unsigned32 temp = GPR[rs]; 659 unsigned32 i, mask; 660 if (NotWordValue (GPR[rs])) 661 Unpredictable (); 662 TRACE_ALU_INPUT1 (GPR[rs]); 663 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i) 664 { 665 if ((temp & mask) == 0) 666 break; 667 mask >>= 1; 668 } 669 GPR[rd] = EXTEND32 (i); 670 TRACE_ALU_RESULT (GPR[rd]); 671} 672 673:function:::void:do_clz:int rd, int rs 674{ 675 unsigned32 temp = GPR[rs]; 676 unsigned32 i, mask; 677 if (NotWordValue (GPR[rs])) 678 Unpredictable (); 679 TRACE_ALU_INPUT1 (GPR[rs]); 680 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i) 681 { 682 if ((temp & mask) != 0) 683 break; 684 mask >>= 1; 685 } 686 GPR[rd] = EXTEND32 (i); 687 TRACE_ALU_RESULT (GPR[rd]); 688} 689 690:function:::void:do_dclo:int rd, int rs 691{ 692 unsigned64 temp = GPR[rs]; 693 unsigned32 i; 694 unsigned64 mask; 695 TRACE_ALU_INPUT1 (GPR[rs]); 696 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i) 697 { 698 if ((temp & mask) == 0) 699 break; 700 mask >>= 1; 701 } 702 GPR[rd] = EXTEND32 (i); 703 TRACE_ALU_RESULT (GPR[rd]); 704} 705 706:function:::void:do_dclz:int rd, int rs 707{ 708 unsigned64 temp = GPR[rs]; 709 unsigned32 i; 710 unsigned64 mask; 711 TRACE_ALU_INPUT1 (GPR[rs]); 712 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i) 713 { 714 if ((temp & mask) != 0) 715 break; 716 mask >>= 1; 717 } 718 GPR[rd] = EXTEND32 (i); 719 TRACE_ALU_RESULT (GPR[rd]); 720} 721 722:function:::void:do_lb:int rt, int offset, int base 723{ 724 GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base], 725 EXTEND16 (offset))); 726} 727 728:function:::void:do_lh:int rt, int offset, int base 729{ 730 GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], 731 EXTEND16 (offset))); 732} 733 734:function:::void:do_lwr:int rt, int offset, int base 735{ 736 GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base], 737 EXTEND16 (offset), GPR[rt])); 738} 739 740:function:::void:do_lwl:int rt, int offset, int base 741{ 742 GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base], 743 EXTEND16 (offset), GPR[rt])); 744} 745 746:function:::void:do_lwc:int num, int rt, int offset, int base 747{ 748 COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base], 749 EXTEND16 (offset))); 750} 751 752:function:::void:do_lw:int rt, int offset, int base 753{ 754 GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], 755 EXTEND16 (offset))); 756} 757 758:function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0 759{ 760 check_u64 (SD_, instruction_0); 761 GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset)); 762} 763 764:function:::void:do_lhu:int rt, int offset, int base 765{ 766 GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset)); 767} 768 769:function:::void:do_ldc:int num, int rt, int offset, int base 770{ 771 COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base], 772 EXTEND16 (offset))); 773} 774 775:function:::void:do_lbu:int rt, int offset, int base 776{ 777 GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset)); 778} 779 780:function:::void:do_ll:int rt, int insn_offset, int basereg 781{ 782 address_word base = GPR[basereg]; 783 address_word offset = EXTEND16 (insn_offset); 784 { 785 address_word vaddr = loadstore_ea (SD_, base, offset); 786 address_word paddr = vaddr; 787 if ((vaddr & 3) != 0) 788 { 789 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, 790 sim_core_unaligned_signal); 791 } 792 else 793 { 794 unsigned64 memval = 0; 795 unsigned64 memval1 = 0; 796 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 797 unsigned int shift = 2; 798 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); 799 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); 800 unsigned int byte; 801 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); 802 LoadMemory (&memval, &memval1, AccessLength_WORD, paddr, vaddr, 803 isDATA, isREAL); 804 byte = ((vaddr & mask) ^ (bigend << shift)); 805 GPR[rt] = EXTEND32 (memval >> (8 * byte)); 806 LLBIT = 1; 807 } 808 } 809} 810 811:function:::void:do_lld:int rt, int roffset, int rbase 812{ 813 address_word base = GPR[rbase]; 814 address_word offset = EXTEND16 (roffset); 815 { 816 address_word vaddr = loadstore_ea (SD_, base, offset); 817 address_word paddr = vaddr; 818 819 if ((vaddr & 7) != 0) 820 { 821 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, 822 sim_core_unaligned_signal); 823 } 824 else 825 { 826 unsigned64 memval = 0; 827 unsigned64 memval1 = 0; 828 LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr, 829 isDATA, isREAL); 830 GPR[rt] = memval; 831 LLBIT = 1; 832 } 833 } 834} 835 836:function:::void:do_lui:int rt, int immediate 837{ 838 TRACE_ALU_INPUT1 (immediate); 839 GPR[rt] = EXTEND32 (immediate << 16); 840 TRACE_ALU_RESULT (GPR[rt]); 841} 842 843:function:::void:do_madd:int rs, int rt 844{ 845 signed64 temp; 846 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 847 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 848 Unpredictable (); 849 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 850 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO)) 851 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs]))); 852 LO = EXTEND32 (temp); 853 HI = EXTEND32 (VH4_8 (temp)); 854 TRACE_ALU_RESULT2 (HI, LO); 855} 856 857:function:::void:do_dsp_madd:int ac, int rs, int rt 858{ 859 signed64 temp; 860 if (ac == 0) 861 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 862 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 863 Unpredictable (); 864 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 865 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac))) 866 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs]))); 867 DSPLO(ac) = EXTEND32 (temp); 868 DSPHI(ac) = EXTEND32 (VH4_8 (temp)); 869 if (ac == 0) 870 TRACE_ALU_RESULT2 (HI, LO); 871} 872 873:function:::void:do_maddu:int rs, int rt 874{ 875 unsigned64 temp; 876 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 877 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 878 Unpredictable (); 879 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 880 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO)) 881 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt]))); 882 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */ 883 LO = EXTEND32 (temp); 884 HI = EXTEND32 (VH4_8 (temp)); 885 TRACE_ALU_RESULT2 (HI, LO); 886} 887 888:function:::void:do_dsp_maddu:int ac, int rs, int rt 889{ 890 unsigned64 temp; 891 if (ac == 0) 892 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 893 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 894 Unpredictable (); 895 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 896 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac))) 897 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt]))); 898 if (ac == 0) 899 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */ 900 DSPLO(ac) = EXTEND32 (temp); 901 DSPHI(ac) = EXTEND32 (VH4_8 (temp)); 902 if (ac == 0) 903 TRACE_ALU_RESULT2 (HI, LO); 904} 905 906:function:::void:do_dsp_mfhi:int ac, int rd 907{ 908 if (ac == 0) 909 do_mfhi (SD_, rd); 910 else 911 GPR[rd] = DSPHI(ac); 912} 913 914:function:::void:do_dsp_mflo:int ac, int rd 915{ 916 if (ac == 0) 917 do_mflo (SD_, rd); 918 else 919 GPR[rd] = DSPLO(ac); 920} 921 922:function:::void:do_movn:int rd, int rs, int rt 923{ 924 if (GPR[rt] != 0) 925 { 926 GPR[rd] = GPR[rs]; 927 TRACE_ALU_RESULT (GPR[rd]); 928 } 929} 930 931:function:::void:do_movz:int rd, int rs, int rt 932{ 933 if (GPR[rt] == 0) 934 { 935 GPR[rd] = GPR[rs]; 936 TRACE_ALU_RESULT (GPR[rd]); 937 } 938} 939 940:function:::void:do_msub:int rs, int rt 941{ 942 signed64 temp; 943 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 944 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 945 Unpredictable (); 946 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 947 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO)) 948 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs]))); 949 LO = EXTEND32 (temp); 950 HI = EXTEND32 (VH4_8 (temp)); 951 TRACE_ALU_RESULT2 (HI, LO); 952} 953 954:function:::void:do_dsp_msub:int ac, int rs, int rt 955{ 956 signed64 temp; 957 if (ac == 0) 958 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 959 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 960 Unpredictable (); 961 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 962 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac))) 963 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs]))); 964 DSPLO(ac) = EXTEND32 (temp); 965 DSPHI(ac) = EXTEND32 (VH4_8 (temp)); 966 if (ac == 0) 967 TRACE_ALU_RESULT2 (HI, LO); 968} 969 970:function:::void:do_msubu:int rs, int rt 971{ 972 unsigned64 temp; 973 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 974 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 975 Unpredictable (); 976 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 977 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO)) 978 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt]))); 979 LO = EXTEND32 (temp); 980 HI = EXTEND32 (VH4_8 (temp)); 981 TRACE_ALU_RESULT2 (HI, LO); 982} 983 984:function:::void:do_dsp_msubu:int ac, int rs, int rt 985{ 986 unsigned64 temp; 987 if (ac == 0) 988 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 989 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 990 Unpredictable (); 991 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 992 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac))) 993 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt]))); 994 DSPLO(ac) = EXTEND32 (temp); 995 DSPHI(ac) = EXTEND32 (VH4_8 (temp)); 996 if (ac == 0) 997 TRACE_ALU_RESULT2 (HI, LO); 998} 999 1000:function:::void:do_mthi:int rs 1001{ 1002 check_mt_hilo (SD_, HIHISTORY); 1003 HI = GPR[rs]; 1004} 1005 1006:function:::void:do_dsp_mthi:int ac, int rs 1007{ 1008 if (ac == 0) 1009 check_mt_hilo (SD_, HIHISTORY); 1010 DSPHI(ac) = GPR[rs]; 1011} 1012 1013:function:::void:do_mtlo:int rs 1014{ 1015 check_mt_hilo (SD_, LOHISTORY); 1016 LO = GPR[rs]; 1017} 1018 1019:function:::void:do_dsp_mtlo:int ac, int rs 1020{ 1021 if (ac == 0) 1022 check_mt_hilo (SD_, LOHISTORY); 1023 DSPLO(ac) = GPR[rs]; 1024} 1025 1026:function:::void:do_mul:int rd, int rs, int rt 1027{ 1028 signed64 prod; 1029 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 1030 Unpredictable (); 1031 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1032 prod = (((signed64)(signed32) GPR[rs]) 1033 * ((signed64)(signed32) GPR[rt])); 1034 GPR[rd] = EXTEND32 (VL4_8 (prod)); 1035 TRACE_ALU_RESULT (GPR[rd]); 1036} 1037 1038:function:::void:do_dsp_mult:int ac, int rs, int rt 1039{ 1040 signed64 prod; 1041 if (ac == 0) 1042 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 1043 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 1044 Unpredictable (); 1045 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1046 prod = ((signed64)(signed32) GPR[rs]) 1047 * ((signed64)(signed32) GPR[rt]); 1048 DSPLO(ac) = EXTEND32 (VL4_8 (prod)); 1049 DSPHI(ac) = EXTEND32 (VH4_8 (prod)); 1050 if (ac == 0) 1051 { 1052 ACX = 0; /* SmartMIPS */ 1053 TRACE_ALU_RESULT2 (HI, LO); 1054 } 1055} 1056 1057:function:::void:do_dsp_multu:int ac, int rs, int rt 1058{ 1059 unsigned64 prod; 1060 if (ac == 0) 1061 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 1062 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 1063 Unpredictable (); 1064 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1065 prod = ((unsigned64)(unsigned32) GPR[rs]) 1066 * ((unsigned64)(unsigned32) GPR[rt]); 1067 DSPLO(ac) = EXTEND32 (VL4_8 (prod)); 1068 DSPHI(ac) = EXTEND32 (VH4_8 (prod)); 1069 if (ac == 0) 1070 TRACE_ALU_RESULT2 (HI, LO); 1071} 1072 1073:function:::void:do_pref:int hint, int insn_offset, int insn_base 1074{ 1075 address_word base = GPR[insn_base]; 1076 address_word offset = EXTEND16 (insn_offset); 1077 { 1078 address_word vaddr = loadstore_ea (SD_, base, offset); 1079 address_word paddr = vaddr; 1080 /* Prefetch (paddr, vaddr, isDATA, hint); */ 1081 } 1082} 1083 1084:function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0 1085{ 1086 unsigned32 instruction = instruction_0; 1087 address_word base = GPR[basereg]; 1088 address_word offset = EXTEND16 (offsetarg); 1089 { 1090 address_word vaddr = loadstore_ea (SD_, base, offset); 1091 address_word paddr = vaddr; 1092 1093 if ((vaddr & 3) != 0) 1094 { 1095 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, 1096 sim_core_unaligned_signal); 1097 } 1098 else 1099 { 1100 unsigned64 memval = 0; 1101 unsigned64 memval1 = 0; 1102 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 1103 address_word reverseendian = 1104 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); 1105 address_word bigendiancpu = 1106 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); 1107 unsigned int byte; 1108 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); 1109 byte = ((vaddr & mask) ^ bigendiancpu); 1110 memval = ((unsigned64) GPR[rt] << (8 * byte)); 1111 if (LLBIT) 1112 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, 1113 isREAL); 1114 GPR[rt] = LLBIT; 1115 } 1116 } 1117} 1118 1119:function:::void:do_scd:int rt, int roffset, int rbase 1120{ 1121 address_word base = GPR[rbase]; 1122 address_word offset = EXTEND16 (roffset); 1123 { 1124 address_word vaddr = loadstore_ea (SD_, base, offset); 1125 address_word paddr = vaddr; 1126 1127 if ((vaddr & 7) != 0) 1128 { 1129 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, 1130 sim_core_unaligned_signal); 1131 } 1132 else 1133 { 1134 unsigned64 memval = 0; 1135 unsigned64 memval1 = 0; 1136 memval = GPR[rt]; 1137 if (LLBIT) 1138 StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr, 1139 isREAL); 1140 GPR[rt] = LLBIT; 1141 } 1142 } 1143} 1144 1145:function:::void:do_sub:int rs, int rt, int rd 1146{ 1147 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 1148 Unpredictable (); 1149 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1150 { 1151 ALU32_BEGIN (GPR[rs]); 1152 ALU32_SUB (GPR[rt]); 1153 ALU32_END (GPR[rd]); /* This checks for overflow. */ 1154 } 1155 TRACE_ALU_RESULT (GPR[rd]); 1156} 1157 1158:function:::void:do_sw:int rt, int offset, int base 1159{ 1160 do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]); 1161} 1162 1163:function:::void:do_teq:int rs, int rt, address_word instruction_0 1164{ 1165 if ((signed_word) GPR[rs] == (signed_word) GPR[rt]) 1166 SignalException (Trap, instruction_0); 1167} 1168 1169:function:::void:do_teqi:int rs, int immediate, address_word instruction_0 1170{ 1171 if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate)) 1172 SignalException (Trap, instruction_0); 1173} 1174 1175:function:::void:do_tge:int rs, int rt, address_word instruction_0 1176{ 1177 if ((signed_word) GPR[rs] >= (signed_word) GPR[rt]) 1178 SignalException (Trap, instruction_0); 1179} 1180 1181:function:::void:do_tgei:int rs, int immediate, address_word instruction_0 1182{ 1183 if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate)) 1184 SignalException (Trap, instruction_0); 1185} 1186 1187:function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0 1188{ 1189 if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate)) 1190 SignalException (Trap, instruction_0); 1191} 1192 1193:function:::void:do_tgeu:int rs ,int rt, address_word instruction_0 1194{ 1195 if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt]) 1196 SignalException (Trap, instruction_0); 1197} 1198 1199:function:::void:do_tlt:int rs, int rt, address_word instruction_0 1200{ 1201 if ((signed_word) GPR[rs] < (signed_word) GPR[rt]) 1202 SignalException (Trap, instruction_0); 1203} 1204 1205:function:::void:do_tlti:int rs, int immediate, address_word instruction_0 1206{ 1207 if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate)) 1208 SignalException (Trap, instruction_0); 1209} 1210 1211:function:::void:do_tltiu:int rs, int immediate, address_word instruction_0 1212{ 1213 if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate)) 1214 SignalException (Trap, instruction_0); 1215} 1216 1217:function:::void:do_tltu:int rs, int rt, address_word instruction_0 1218{ 1219 if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]) 1220 SignalException (Trap, instruction_0); 1221} 1222 1223:function:::void:do_tne:int rs, int rt, address_word instruction_0 1224{ 1225 if ((signed_word) GPR[rs] != (signed_word) GPR[rt]) 1226 SignalException (Trap, instruction_0); 1227} 1228 1229:function:::void:do_tnei:int rs, int immediate, address_word instruction_0 1230{ 1231 if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate)) 1232 SignalException (Trap, instruction_0); 1233} 1234 1235:function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0 1236{ 1237 check_fpu (SD_); 1238 check_fmt_p (SD_, fmt, instruction_0); 1239 StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt)); 1240} 1241 1242:function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0 1243{ 1244 check_fpu (SD_); 1245 check_fmt_p (SD_, fmt, instruction_0); 1246 StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); 1247} 1248 1249:function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0 1250{ 1251 unsigned64 fsx; 1252 unsigned64 ftx; 1253 unsigned64 fdx; 1254 check_fpu (SD_); 1255 check_u64 (SD_, instruction_0); 1256 fsx = ValueFPR (fs, fmt_ps); 1257 if ((GPR[rs] & 0x3) != 0) 1258 Unpredictable (); 1259 if ((GPR[rs] & 0x4) == 0) 1260 fdx = fsx; 1261 else 1262 { 1263 ftx = ValueFPR (ft, fmt_ps); 1264 if (BigEndianCPU) 1265 fdx = PackPS (PSLower (fsx), PSUpper (ftx)); 1266 else 1267 fdx = PackPS (PSLower (ftx), PSUpper (fsx)); 1268 } 1269 StoreFPR (fd, fmt_ps, fdx); 1270} 1271 1272:function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0 1273{ 1274 check_fpu (SD_); 1275 check_fmt_p (SD_, fmt, instruction_0); 1276 Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc); 1277 TRACE_ALU_RESULT (ValueFCR (31)); 1278} 1279 1280:function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0 1281{ 1282 check_fpu (SD_); 1283 check_fmt_p (SD_, fmt, instruction_0); 1284 StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt, 1285 type)); 1286} 1287 1288:function:::void:do_cfc1:int rt, int fs 1289{ 1290 check_fpu (SD_); 1291 if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31) 1292 { 1293 unsigned_word fcr = ValueFCR (fs); 1294 TRACE_ALU_INPUT1 (fcr); 1295 GPR[rt] = fcr; 1296 } 1297 /* else NOP */ 1298 TRACE_ALU_RESULT (GPR[rt]); 1299} 1300 1301:function:::void:do_ctc1:int rt, int fs 1302{ 1303 check_fpu (SD_); 1304 TRACE_ALU_INPUT1 (GPR[rt]); 1305 if (fs == 25 || fs == 26 || fs == 28 || fs == 31) 1306 StoreFCR (fs, GPR[rt]); 1307 /* else NOP */ 1308} 1309 1310:function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0 1311{ 1312 check_fpu (SD_); 1313 if ((fmt == fmt_double) | 0) 1314 SignalException (ReservedInstruction, instruction_0); 1315 StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt, 1316 fmt_double)); 1317} 1318 1319:function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0 1320{ 1321 check_fpu (SD_); 1322 if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word))) 1323 SignalException (ReservedInstruction, instruction_0); 1324 StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt, 1325 fmt_long)); 1326} 1327 1328:function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0 1329{ 1330 check_fpu (SD_); 1331 check_u64 (SD_, instruction_0); 1332 StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single), 1333 ValueFPR (ft, fmt_single))); 1334} 1335 1336:function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0 1337{ 1338 check_fpu (SD_); 1339 if ((fmt == fmt_single) | 0) 1340 SignalException (ReservedInstruction, instruction_0); 1341 StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt, 1342 fmt_single)); 1343} 1344 1345:function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0 1346{ 1347 check_fpu (SD_); 1348 check_u64 (SD_, instruction_0); 1349 StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps))); 1350} 1351 1352:function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0 1353{ 1354 check_fpu (SD_); 1355 check_u64 (SD_, instruction_0); 1356 StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps))); 1357} 1358 1359:function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0 1360{ 1361 check_fpu (SD_); 1362 if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word))) 1363 SignalException (ReservedInstruction, instruction_0); 1364 StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt, 1365 fmt_word)); 1366} 1367 1368:function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0 1369{ 1370 check_fpu (SD_); 1371 StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); 1372} 1373 1374:function:::void:do_dmfc1b:int rt, int fs 1375*mipsIV: 1376*mipsV: 1377*mips64: 1378*mips64r2: 1379*vr4100: 1380*vr5000: 1381*r3900: 1382*micromips64: 1383{ 1384 if (SizeFGR () == 64) 1385 GPR[rt] = FGR[fs]; 1386 else if ((fs & 0x1) == 0) 1387 GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs]; 1388 else 1389 GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; 1390 TRACE_ALU_RESULT (GPR[rt]); 1391} 1392 1393:function:::void:do_dmtc1b:int rt, int fs 1394{ 1395 if (SizeFGR () == 64) 1396 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]); 1397 else if ((fs & 0x1) == 0) 1398 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]); 1399 else 1400 Unpredictable (); 1401} 1402 1403:function:::void:do_floor_fmt:int type, int fmt, int fd, int fs 1404{ 1405 check_fpu (SD_); 1406 StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt, 1407 type)); 1408} 1409 1410:function:::void:do_luxc1_32:int fd, int rindex, int rbase 1411*mips32r2: 1412*micromips32: 1413{ 1414 address_word base = GPR[rbase]; 1415 address_word index = GPR[rindex]; 1416 address_word vaddr = base + index; 1417 check_fpu (SD_); 1418 if (SizeFGR () != 64) 1419 Unpredictable (); 1420 /* Arrange for the bottom 3 bits of (base + index) to be 0. */ 1421 if ((vaddr & 0x7) != 0) 1422 index -= (vaddr & 0x7); 1423 COP_LD (1, fd, do_load_double (SD_, base, index)); 1424} 1425 1426:function:::void:do_luxc1_64:int fd, int rindex, int rbase 1427{ 1428 address_word base = GPR[rbase]; 1429 address_word index = GPR[rindex]; 1430 address_word vaddr = base + index; 1431 if (SizeFGR () != 64) 1432 Unpredictable (); 1433 /* Arrange for the bottom 3 bits of (base + index) to be 0. */ 1434 if ((vaddr & 0x7) != 0) 1435 index -= (vaddr & 0x7); 1436 COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index)); 1437 1438} 1439 1440:function:::void:do_lwc1:int ft, int offset, int base 1441{ 1442 check_fpu (SD_); 1443 COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base], 1444 EXTEND16 (offset))); 1445} 1446 1447:function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0 1448{ 1449 check_fpu (SD_); 1450 check_u64 (SD_, instruction_0); 1451 COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index])); 1452} 1453 1454:function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0 1455{ 1456 check_fpu (SD_); 1457 check_u64 (SD_, instruction_0); 1458 check_fmt_p (SD_, fmt, instruction_0); 1459 StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt), 1460 ValueFPR (fr, fmt), fmt)); 1461} 1462 1463:function:::void:do_mfc1b:int rt, int fs 1464{ 1465 check_fpu (SD_); 1466 GPR[rt] = EXTEND32 (FGR[fs]); 1467 TRACE_ALU_RESULT (GPR[rt]); 1468} 1469 1470:function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0 1471{ 1472 check_fpu (SD_); 1473 check_fmt_p (SD_, fmt, instruction_0); 1474 StoreFPR (fd, fmt, ValueFPR (fs, fmt)); 1475} 1476 1477:function:::void:do_movtf:int tf, int rd, int rs, int cc 1478{ 1479 check_fpu (SD_); 1480 if (GETFCC(cc) == tf) 1481 GPR[rd] = GPR[rs]; 1482} 1483 1484:function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc 1485{ 1486 check_fpu (SD_); 1487 if (fmt != fmt_ps) 1488 { 1489 if (GETFCC(cc) == tf) 1490 StoreFPR (fd, fmt, ValueFPR (fs, fmt)); 1491 else 1492 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); /* set fmt */ 1493 } 1494 else 1495 { 1496 unsigned64 fdx; 1497 fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd, 1498 fmt_ps)), 1499 PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd, 1500 fmt_ps))); 1501 StoreFPR (fd, fmt_ps, fdx); 1502 } 1503} 1504 1505:function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt 1506{ 1507 check_fpu (SD_); 1508 if (GPR[rt] != 0) 1509 StoreFPR (fd, fmt, ValueFPR (fs, fmt)); 1510 else 1511 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); 1512} 1513 1514:function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt 1515{ 1516 check_fpu (SD_); 1517 if (GPR[rt] == 0) 1518 StoreFPR (fd, fmt, ValueFPR (fs, fmt)); 1519 else 1520 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); 1521} 1522 1523:function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0 1524{ 1525 check_fpu (SD_); 1526 check_u64 (SD_, instruction_0); 1527 check_fmt_p (SD_, fmt, instruction_0); 1528 StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), 1529 ValueFPR (fr, fmt), fmt)); 1530} 1531 1532:function:::void:do_mtc1b:int rt, int fs 1533{ 1534 check_fpu (SD_); 1535 StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt])); 1536} 1537 1538:function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0 1539{ 1540 check_fpu (SD_); 1541 check_fmt_p (SD_, fmt, instruction_0); 1542 StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); 1543} 1544 1545:function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0 1546{ 1547 check_fpu (SD_); 1548 check_fmt_p (SD_, fmt, instruction_0); 1549 StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt)); 1550} 1551 1552:function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0 1553{ 1554 check_fpu (SD_); 1555 check_u64 (SD_, instruction_0); 1556 check_fmt_p (SD_, fmt, instruction_0); 1557 StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt), 1558 ValueFPR (fr, fmt), fmt)); 1559} 1560 1561:function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0 1562{ 1563 check_fpu (SD_); 1564 check_u64 (SD_, instruction_0); 1565 check_fmt_p (SD_, fmt, instruction_0); 1566 StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), 1567 ValueFPR (fr, fmt), fmt)); 1568} 1569 1570:function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0 1571{ 1572 check_fpu (SD_); 1573 check_u64 (SD_, instruction_0); 1574 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)), 1575 PSLower (ValueFPR (ft, fmt_ps)))); 1576} 1577 1578:function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0 1579{ 1580 check_fpu (SD_); 1581 check_u64 (SD_, instruction_0); 1582 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)), 1583 PSUpper (ValueFPR (ft, fmt_ps)))); 1584} 1585 1586:function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0 1587{ 1588 check_fpu (SD_); 1589 check_u64 (SD_, instruction_0); 1590 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)), 1591 PSLower (ValueFPR (ft, fmt_ps)))); 1592} 1593 1594:function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0 1595{ 1596 check_fpu (SD_); 1597 check_u64 (SD_, instruction_0); 1598 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)), 1599 PSUpper (ValueFPR (ft, fmt_ps)))); 1600} 1601 1602:function:::void:do_recip_fmt:int fmt, int fd, int fs 1603{ 1604 check_fpu (SD_); 1605 StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt)); 1606} 1607 1608:function:::void:do_round_fmt:int type, int fmt, int fd, int fs 1609{ 1610 check_fpu (SD_); 1611 StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt, 1612 type)); 1613} 1614 1615:function:::void:do_rsqrt_fmt:int fmt, int fd, int fs 1616{ 1617 check_fpu (SD_); 1618 StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt)); 1619} 1620 1621:function:::void:do_prefx:int hint, int rindex, int rbase 1622{ 1623 address_word base = GPR[rbase]; 1624 address_word index = GPR[rindex]; 1625 { 1626 address_word vaddr = loadstore_ea (SD_, base, index); 1627 address_word paddr = vaddr; 1628 /* Prefetch (paddr, vaddr, isDATA, hint); */ 1629 } 1630} 1631 1632:function:::void:do_sdc1:int ft, int offset, int base 1633*mipsII: 1634*mips32: 1635*mips32r2: 1636*micromips32: 1637{ 1638 check_fpu (SD_); 1639 do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft)); 1640} 1641 1642:function:::void:do_suxc1_32:int fs, int rindex, int rbase 1643*mips32r2: 1644*micromips32: 1645{ 1646 address_word base = GPR[rbase]; 1647 address_word index = GPR[rindex]; 1648 address_word vaddr = base + index; 1649 check_fpu (SD_); 1650 if (SizeFGR () != 64) 1651 Unpredictable (); 1652 /* Arrange for the bottom 3 bits of (base + index) to be 0. */ 1653 if ((vaddr & 0x7) != 0) 1654 index -= (vaddr & 0x7); 1655 do_store_double (SD_, base, index, COP_SD (1, fs)); 1656} 1657 1658:function:::void:do_suxc1_64:int fs, int rindex, int rbase 1659{ 1660 address_word base = GPR[rbase]; 1661 address_word index = GPR[rindex]; 1662 address_word vaddr = base + index; 1663 if (SizeFGR () != 64) 1664 Unpredictable (); 1665 /* Arrange for the bottom 3 bits of (base + index) to be 0. */ 1666 if ((vaddr & 0x7) != 0) 1667 index -= (vaddr & 0x7); 1668 do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs)); 1669} 1670 1671:function:::void:do_sqrt_fmt:int fmt, int fd, int fs 1672{ 1673 check_fpu (SD_); 1674 StoreFPR (fd, fmt, (SquareRoot (ValueFPR (fs, fmt), fmt))); 1675} 1676 1677:function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0 1678{ 1679 check_fpu (SD_); 1680 check_fmt_p (SD_, fmt, instruction_0); 1681 StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); 1682} 1683 1684:function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0 1685{ 1686 address_word base = GPR[rbase]; 1687 address_word offset = EXTEND16 (roffset); 1688 check_fpu (SD_); 1689 { 1690 address_word vaddr = loadstore_ea (SD_, base, offset); 1691 address_word paddr = vaddr; 1692 1693 if ((vaddr & 3) != 0) 1694 { 1695 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, 1696 write_transfer, sim_core_unaligned_signal); 1697 } 1698 else 1699 { 1700 uword64 memval = 0; 1701 uword64 memval1 = 0; 1702 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 1703 address_word reverseendian = 1704 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); 1705 address_word bigendiancpu = 1706 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); 1707 unsigned int byte; 1708 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); 1709 byte = ((vaddr & mask) ^ bigendiancpu); 1710 memval = (((uword64)COP_SW(1, ft)) << (8 * byte)); 1711 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL); 1712 } 1713 } 1714} 1715 1716:function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0 1717{ 1718 address_word base = GPR[rbase]; 1719 address_word index = GPR[rindex]; 1720 check_fpu (SD_); 1721 check_u64 (SD_, instruction_0); 1722 { 1723 address_word vaddr = loadstore_ea (SD_, base, index); 1724 address_word paddr = vaddr; 1725 1726 if ((vaddr & 3) != 0) 1727 { 1728 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, 1729 sim_core_unaligned_signal); 1730 } 1731 else 1732 { 1733 unsigned64 memval = 0; 1734 unsigned64 memval1 = 0; 1735 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 1736 address_word reverseendian = 1737 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); 1738 address_word bigendiancpu = 1739 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); 1740 unsigned int byte; 1741 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); 1742 byte = ((vaddr & mask) ^ bigendiancpu); 1743 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte)); 1744 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, 1745 isREAL); 1746 } 1747 } 1748} 1749 1750:function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs 1751{ 1752 check_fpu (SD_); 1753 StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt, 1754 type)); 1755} 1756 1757000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD 1758"add r<RD>, r<RS>, r<RT>" 1759*mipsI: 1760*mipsII: 1761*mipsIII: 1762*mipsIV: 1763*mipsV: 1764*mips32: 1765*mips32r2: 1766*mips64: 1767*mips64r2: 1768*vr4100: 1769*vr5000: 1770*r3900: 1771{ 1772 do_add (SD_, RS, RT, RD); 1773} 1774 1775 1776 1777001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI 1778"addi r<RT>, r<RS>, <IMMEDIATE>" 1779*mipsI: 1780*mipsII: 1781*mipsIII: 1782*mipsIV: 1783*mipsV: 1784*mips32: 1785*mips32r2: 1786*mips64: 1787*mips64r2: 1788*vr4100: 1789*vr5000: 1790*r3900: 1791{ 1792 do_addi (SD_, RS, RT, IMMEDIATE); 1793} 1794 1795 1796 1797:function:::void:do_addiu:int rs, int rt, unsigned16 immediate 1798{ 1799 if (NotWordValue (GPR[rs])) 1800 Unpredictable (); 1801 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 1802 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate)); 1803 TRACE_ALU_RESULT (GPR[rt]); 1804} 1805 1806001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU 1807"addiu r<RT>, r<RS>, <IMMEDIATE>" 1808*mipsI: 1809*mipsII: 1810*mipsIII: 1811*mipsIV: 1812*mipsV: 1813*mips32: 1814*mips32r2: 1815*mips64: 1816*mips64r2: 1817*vr4100: 1818*vr5000: 1819*r3900: 1820{ 1821 do_addiu (SD_, RS, RT, IMMEDIATE); 1822} 1823 1824 1825 1826:function:::void:do_addu:int rs, int rt, int rd 1827{ 1828 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 1829 Unpredictable (); 1830 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1831 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]); 1832 TRACE_ALU_RESULT (GPR[rd]); 1833} 1834 1835000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU 1836"addu r<RD>, r<RS>, r<RT>" 1837*mipsI: 1838*mipsII: 1839*mipsIII: 1840*mipsIV: 1841*mipsV: 1842*mips32: 1843*mips32r2: 1844*mips64: 1845*mips64r2: 1846*vr4100: 1847*vr5000: 1848*r3900: 1849{ 1850 do_addu (SD_, RS, RT, RD); 1851} 1852 1853 1854 1855:function:::void:do_and:int rs, int rt, int rd 1856{ 1857 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 1858 GPR[rd] = GPR[rs] & GPR[rt]; 1859 TRACE_ALU_RESULT (GPR[rd]); 1860} 1861 1862000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND 1863"and r<RD>, r<RS>, r<RT>" 1864*mipsI: 1865*mipsII: 1866*mipsIII: 1867*mipsIV: 1868*mipsV: 1869*mips32: 1870*mips32r2: 1871*mips64: 1872*mips64r2: 1873*vr4100: 1874*vr5000: 1875*r3900: 1876{ 1877 do_and (SD_, RS, RT, RD); 1878} 1879 1880 1881 1882001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI 1883"andi r<RT>, r<RS>, %#lx<IMMEDIATE>" 1884*mipsI: 1885*mipsII: 1886*mipsIII: 1887*mipsIV: 1888*mipsV: 1889*mips32: 1890*mips32r2: 1891*mips64: 1892*mips64r2: 1893*vr4100: 1894*vr5000: 1895*r3900: 1896{ 1897 do_andi (SD_,RS, RT, IMMEDIATE); 1898} 1899 1900 1901 1902000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ 1903"beq r<RS>, r<RT>, <OFFSET>" 1904*mipsI: 1905*mipsII: 1906*mipsIII: 1907*mipsIV: 1908*mipsV: 1909*mips32: 1910*mips32r2: 1911*mips64: 1912*mips64r2: 1913*vr4100: 1914*vr5000: 1915*r3900: 1916{ 1917 address_word offset = EXTEND16 (OFFSET) << 2; 1918 if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) 1919 { 1920 DELAY_SLOT (NIA + offset); 1921 } 1922} 1923 1924 1925 1926010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL 1927"beql r<RS>, r<RT>, <OFFSET>" 1928*mipsII: 1929*mipsIII: 1930*mipsIV: 1931*mipsV: 1932*mips32: 1933*mips32r2: 1934*mips64: 1935*mips64r2: 1936*vr4100: 1937*vr5000: 1938*r3900: 1939{ 1940 address_word offset = EXTEND16 (OFFSET) << 2; 1941 if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) 1942 { 1943 DELAY_SLOT (NIA + offset); 1944 } 1945 else 1946 NULLIFY_NEXT_INSTRUCTION (); 1947} 1948 1949 1950 1951000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ 1952"bgez r<RS>, <OFFSET>" 1953*mipsI: 1954*mipsII: 1955*mipsIII: 1956*mipsIV: 1957*mipsV: 1958*mips32: 1959*mips32r2: 1960*mips64: 1961*mips64r2: 1962*vr4100: 1963*vr5000: 1964*r3900: 1965{ 1966 address_word offset = EXTEND16 (OFFSET) << 2; 1967 if ((signed_word) GPR[RS] >= 0) 1968 { 1969 DELAY_SLOT (NIA + offset); 1970 } 1971} 1972 1973 1974 1975000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL 1976"bgezal r<RS>, <OFFSET>" 1977*mipsI: 1978*mipsII: 1979*mipsIII: 1980*mipsIV: 1981*mipsV: 1982*mips32: 1983*mips32r2: 1984*mips64: 1985*mips64r2: 1986*vr4100: 1987*vr5000: 1988*r3900: 1989{ 1990 address_word offset = EXTEND16 (OFFSET) << 2; 1991 if (RS == 31) 1992 Unpredictable (); 1993 RA = (CIA + 8); 1994 if ((signed_word) GPR[RS] >= 0) 1995 { 1996 DELAY_SLOT (NIA + offset); 1997 } 1998} 1999 2000 2001 2002000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL 2003"bgezall r<RS>, <OFFSET>" 2004*mipsII: 2005*mipsIII: 2006*mipsIV: 2007*mipsV: 2008*mips32: 2009*mips32r2: 2010*mips64: 2011*mips64r2: 2012*vr4100: 2013*vr5000: 2014*r3900: 2015{ 2016 address_word offset = EXTEND16 (OFFSET) << 2; 2017 if (RS == 31) 2018 Unpredictable (); 2019 RA = (CIA + 8); 2020 /* NOTE: The branch occurs AFTER the next instruction has been 2021 executed */ 2022 if ((signed_word) GPR[RS] >= 0) 2023 { 2024 DELAY_SLOT (NIA + offset); 2025 } 2026 else 2027 NULLIFY_NEXT_INSTRUCTION (); 2028} 2029 2030 2031 2032000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL 2033"bgezl r<RS>, <OFFSET>" 2034*mipsII: 2035*mipsIII: 2036*mipsIV: 2037*mipsV: 2038*mips32: 2039*mips32r2: 2040*mips64: 2041*mips64r2: 2042*vr4100: 2043*vr5000: 2044*r3900: 2045{ 2046 address_word offset = EXTEND16 (OFFSET) << 2; 2047 if ((signed_word) GPR[RS] >= 0) 2048 { 2049 DELAY_SLOT (NIA + offset); 2050 } 2051 else 2052 NULLIFY_NEXT_INSTRUCTION (); 2053} 2054 2055 2056 2057000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ 2058"bgtz r<RS>, <OFFSET>" 2059*mipsI: 2060*mipsII: 2061*mipsIII: 2062*mipsIV: 2063*mipsV: 2064*mips32: 2065*mips32r2: 2066*mips64: 2067*mips64r2: 2068*vr4100: 2069*vr5000: 2070*r3900: 2071{ 2072 address_word offset = EXTEND16 (OFFSET) << 2; 2073 if ((signed_word) GPR[RS] > 0) 2074 { 2075 DELAY_SLOT (NIA + offset); 2076 } 2077} 2078 2079 2080 2081010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL 2082"bgtzl r<RS>, <OFFSET>" 2083*mipsII: 2084*mipsIII: 2085*mipsIV: 2086*mipsV: 2087*mips32: 2088*mips32r2: 2089*mips64: 2090*mips64r2: 2091*vr4100: 2092*vr5000: 2093*r3900: 2094{ 2095 address_word offset = EXTEND16 (OFFSET) << 2; 2096 /* NOTE: The branch occurs AFTER the next instruction has been 2097 executed */ 2098 if ((signed_word) GPR[RS] > 0) 2099 { 2100 DELAY_SLOT (NIA + offset); 2101 } 2102 else 2103 NULLIFY_NEXT_INSTRUCTION (); 2104} 2105 2106 2107 2108000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ 2109"blez r<RS>, <OFFSET>" 2110*mipsI: 2111*mipsII: 2112*mipsIII: 2113*mipsIV: 2114*mipsV: 2115*mips32: 2116*mips32r2: 2117*mips64: 2118*mips64r2: 2119*vr4100: 2120*vr5000: 2121*r3900: 2122{ 2123 address_word offset = EXTEND16 (OFFSET) << 2; 2124 /* NOTE: The branch occurs AFTER the next instruction has been 2125 executed */ 2126 if ((signed_word) GPR[RS] <= 0) 2127 { 2128 DELAY_SLOT (NIA + offset); 2129 } 2130} 2131 2132 2133 2134010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL 2135"bgezl r<RS>, <OFFSET>" 2136*mipsII: 2137*mipsIII: 2138*mipsIV: 2139*mipsV: 2140*mips32: 2141*mips32r2: 2142*mips64: 2143*mips64r2: 2144*vr4100: 2145*vr5000: 2146*r3900: 2147{ 2148 address_word offset = EXTEND16 (OFFSET) << 2; 2149 if ((signed_word) GPR[RS] <= 0) 2150 { 2151 DELAY_SLOT (NIA + offset); 2152 } 2153 else 2154 NULLIFY_NEXT_INSTRUCTION (); 2155} 2156 2157 2158 2159000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ 2160"bltz r<RS>, <OFFSET>" 2161*mipsI: 2162*mipsII: 2163*mipsIII: 2164*mipsIV: 2165*mipsV: 2166*mips32: 2167*mips32r2: 2168*mips64: 2169*mips64r2: 2170*vr4100: 2171*vr5000: 2172*r3900: 2173{ 2174 address_word offset = EXTEND16 (OFFSET) << 2; 2175 if ((signed_word) GPR[RS] < 0) 2176 { 2177 DELAY_SLOT (NIA + offset); 2178 } 2179} 2180 2181 2182 2183000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL 2184"bltzal r<RS>, <OFFSET>" 2185*mipsI: 2186*mipsII: 2187*mipsIII: 2188*mipsIV: 2189*mipsV: 2190*mips32: 2191*mips32r2: 2192*mips64: 2193*mips64r2: 2194*vr4100: 2195*vr5000: 2196*r3900: 2197{ 2198 address_word offset = EXTEND16 (OFFSET) << 2; 2199 if (RS == 31) 2200 Unpredictable (); 2201 RA = (CIA + 8); 2202 /* NOTE: The branch occurs AFTER the next instruction has been 2203 executed */ 2204 if ((signed_word) GPR[RS] < 0) 2205 { 2206 DELAY_SLOT (NIA + offset); 2207 } 2208} 2209 2210 2211 2212000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL 2213"bltzall r<RS>, <OFFSET>" 2214*mipsII: 2215*mipsIII: 2216*mipsIV: 2217*mipsV: 2218*mips32: 2219*mips32r2: 2220*mips64: 2221*mips64r2: 2222*vr4100: 2223*vr5000: 2224*r3900: 2225{ 2226 address_word offset = EXTEND16 (OFFSET) << 2; 2227 if (RS == 31) 2228 Unpredictable (); 2229 RA = (CIA + 8); 2230 if ((signed_word) GPR[RS] < 0) 2231 { 2232 DELAY_SLOT (NIA + offset); 2233 } 2234 else 2235 NULLIFY_NEXT_INSTRUCTION (); 2236} 2237 2238 2239 2240000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL 2241"bltzl r<RS>, <OFFSET>" 2242*mipsII: 2243*mipsIII: 2244*mipsIV: 2245*mipsV: 2246*mips32: 2247*mips32r2: 2248*mips64: 2249*mips64r2: 2250*vr4100: 2251*vr5000: 2252*r3900: 2253{ 2254 address_word offset = EXTEND16 (OFFSET) << 2; 2255 /* NOTE: The branch occurs AFTER the next instruction has been 2256 executed */ 2257 if ((signed_word) GPR[RS] < 0) 2258 { 2259 DELAY_SLOT (NIA + offset); 2260 } 2261 else 2262 NULLIFY_NEXT_INSTRUCTION (); 2263} 2264 2265 2266 2267000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE 2268"bne r<RS>, r<RT>, <OFFSET>" 2269*mipsI: 2270*mipsII: 2271*mipsIII: 2272*mipsIV: 2273*mipsV: 2274*mips32: 2275*mips32r2: 2276*mips64: 2277*mips64r2: 2278*vr4100: 2279*vr5000: 2280*r3900: 2281{ 2282 address_word offset = EXTEND16 (OFFSET) << 2; 2283 if ((signed_word) GPR[RS] != (signed_word) GPR[RT]) 2284 { 2285 DELAY_SLOT (NIA + offset); 2286 } 2287} 2288 2289 2290 2291010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL 2292"bnel r<RS>, r<RT>, <OFFSET>" 2293*mipsII: 2294*mipsIII: 2295*mipsIV: 2296*mipsV: 2297*mips32: 2298*mips32r2: 2299*mips64: 2300*mips64r2: 2301*vr4100: 2302*vr5000: 2303*r3900: 2304{ 2305 address_word offset = EXTEND16 (OFFSET) << 2; 2306 if ((signed_word) GPR[RS] != (signed_word) GPR[RT]) 2307 { 2308 DELAY_SLOT (NIA + offset); 2309 } 2310 else 2311 NULLIFY_NEXT_INSTRUCTION (); 2312} 2313 2314 2315 2316000000,20.CODE,001101:SPECIAL:32::BREAK 2317"break %#lx<CODE>" 2318*mipsI: 2319*mipsII: 2320*mipsIII: 2321*mipsIV: 2322*mipsV: 2323*mips32: 2324*mips32r2: 2325*mips64: 2326*mips64r2: 2327*vr4100: 2328*vr5000: 2329*r3900: 2330{ 2331 do_break (SD_, instruction_0); 2332} 2333 2334 2335 2336011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO 2337"clo r<RD>, r<RS>" 2338*mips32: 2339*mips32r2: 2340*mips64: 2341*mips64r2: 2342*vr5500: 2343{ 2344 if (RT != RD) 2345 Unpredictable (); 2346 do_clo (SD_, RD, RS); 2347} 2348 2349 2350 2351011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ 2352"clz r<RD>, r<RS>" 2353*mips32: 2354*mips32r2: 2355*mips64: 2356*mips64r2: 2357*vr5500: 2358{ 2359 if (RT != RD) 2360 Unpredictable (); 2361 do_clz (SD_, RD, RS); 2362} 2363 2364 2365 2366000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD 2367"dadd r<RD>, r<RS>, r<RT>" 2368*mipsIII: 2369*mipsIV: 2370*mipsV: 2371*mips64: 2372*mips64r2: 2373*vr4100: 2374*vr5000: 2375{ 2376 check_u64 (SD_, instruction_0); 2377 do_dadd (SD_, RD, RS, RT); 2378} 2379 2380 2381 2382011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI 2383"daddi r<RT>, r<RS>, <IMMEDIATE>" 2384*mipsIII: 2385*mipsIV: 2386*mipsV: 2387*mips64: 2388*mips64r2: 2389*vr4100: 2390*vr5000: 2391{ 2392 check_u64 (SD_, instruction_0); 2393 do_daddi (SD_, RT, RS, IMMEDIATE); 2394} 2395 2396 2397 2398:function:::void:do_daddiu:int rs, int rt, unsigned16 immediate 2399{ 2400 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 2401 GPR[rt] = GPR[rs] + EXTEND16 (immediate); 2402 TRACE_ALU_RESULT (GPR[rt]); 2403} 2404 2405011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU 2406"daddiu r<RT>, r<RS>, <IMMEDIATE>" 2407*mipsIII: 2408*mipsIV: 2409*mipsV: 2410*mips64: 2411*mips64r2: 2412*vr4100: 2413*vr5000: 2414{ 2415 check_u64 (SD_, instruction_0); 2416 do_daddiu (SD_, RS, RT, IMMEDIATE); 2417} 2418 2419 2420 2421:function:::void:do_daddu:int rs, int rt, int rd 2422{ 2423 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2424 GPR[rd] = GPR[rs] + GPR[rt]; 2425 TRACE_ALU_RESULT (GPR[rd]); 2426} 2427 2428000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU 2429"daddu r<RD>, r<RS>, r<RT>" 2430*mipsIII: 2431*mipsIV: 2432*mipsV: 2433*mips64: 2434*mips64r2: 2435*vr4100: 2436*vr5000: 2437{ 2438 check_u64 (SD_, instruction_0); 2439 do_daddu (SD_, RS, RT, RD); 2440} 2441 2442 2443 2444011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO 2445"dclo r<RD>, r<RS>" 2446*mips64: 2447*mips64r2: 2448*vr5500: 2449{ 2450 if (RT != RD) 2451 Unpredictable (); 2452 check_u64 (SD_, instruction_0); 2453 do_dclo (SD_, RD, RS); 2454} 2455 2456 2457 2458011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ 2459"dclz r<RD>, r<RS>" 2460*mips64: 2461*mips64r2: 2462*vr5500: 2463{ 2464 if (RT != RD) 2465 Unpredictable (); 2466 check_u64 (SD_, instruction_0); 2467 do_dclz (SD_, RD, RS); 2468} 2469 2470 2471 2472:function:::void:do_ddiv:int rs, int rt 2473{ 2474 check_div_hilo (SD_, HIHISTORY, LOHISTORY); 2475 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2476 { 2477 signed64 n = GPR[rs]; 2478 signed64 d = GPR[rt]; 2479 signed64 hi; 2480 signed64 lo; 2481 if (d == 0) 2482 { 2483 lo = SIGNED64 (0x8000000000000000); 2484 hi = 0; 2485 } 2486 else if (d == -1 && n == SIGNED64 (0x8000000000000000)) 2487 { 2488 lo = SIGNED64 (0x8000000000000000); 2489 hi = 0; 2490 } 2491 else 2492 { 2493 lo = (n / d); 2494 hi = (n % d); 2495 } 2496 HI = hi; 2497 LO = lo; 2498 } 2499 TRACE_ALU_RESULT2 (HI, LO); 2500} 2501 2502000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV 2503"ddiv r<RS>, r<RT>" 2504*mipsIII: 2505*mipsIV: 2506*mipsV: 2507*mips64: 2508*mips64r2: 2509*vr4100: 2510*vr5000: 2511{ 2512 check_u64 (SD_, instruction_0); 2513 do_ddiv (SD_, RS, RT); 2514} 2515 2516 2517 2518:function:::void:do_ddivu:int rs, int rt 2519{ 2520 check_div_hilo (SD_, HIHISTORY, LOHISTORY); 2521 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2522 { 2523 unsigned64 n = GPR[rs]; 2524 unsigned64 d = GPR[rt]; 2525 unsigned64 hi; 2526 unsigned64 lo; 2527 if (d == 0) 2528 { 2529 lo = SIGNED64 (0x8000000000000000); 2530 hi = 0; 2531 } 2532 else 2533 { 2534 lo = (n / d); 2535 hi = (n % d); 2536 } 2537 HI = hi; 2538 LO = lo; 2539 } 2540 TRACE_ALU_RESULT2 (HI, LO); 2541} 2542 2543000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU 2544"ddivu r<RS>, r<RT>" 2545*mipsIII: 2546*mipsIV: 2547*mipsV: 2548*mips64: 2549*mips64r2: 2550*vr4100: 2551*vr5000: 2552{ 2553 check_u64 (SD_, instruction_0); 2554 do_ddivu (SD_, RS, RT); 2555} 2556 2557:function:::void:do_div:int rs, int rt 2558{ 2559 check_div_hilo (SD_, HIHISTORY, LOHISTORY); 2560 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2561 { 2562 signed32 n = GPR[rs]; 2563 signed32 d = GPR[rt]; 2564 if (d == 0) 2565 { 2566 LO = EXTEND32 (0x80000000); 2567 HI = EXTEND32 (0); 2568 } 2569 else if (n == SIGNED32 (0x80000000) && d == -1) 2570 { 2571 LO = EXTEND32 (0x80000000); 2572 HI = EXTEND32 (0); 2573 } 2574 else 2575 { 2576 LO = EXTEND32 (n / d); 2577 HI = EXTEND32 (n % d); 2578 } 2579 } 2580 TRACE_ALU_RESULT2 (HI, LO); 2581} 2582 2583000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV 2584"div r<RS>, r<RT>" 2585*mipsI: 2586*mipsII: 2587*mipsIII: 2588*mipsIV: 2589*mipsV: 2590*mips32: 2591*mips32r2: 2592*mips64: 2593*mips64r2: 2594*vr4100: 2595*vr5000: 2596*r3900: 2597{ 2598 do_div (SD_, RS, RT); 2599} 2600 2601 2602 2603:function:::void:do_divu:int rs, int rt 2604{ 2605 check_div_hilo (SD_, HIHISTORY, LOHISTORY); 2606 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2607 { 2608 unsigned32 n = GPR[rs]; 2609 unsigned32 d = GPR[rt]; 2610 if (d == 0) 2611 { 2612 LO = EXTEND32 (0x80000000); 2613 HI = EXTEND32 (0); 2614 } 2615 else 2616 { 2617 LO = EXTEND32 (n / d); 2618 HI = EXTEND32 (n % d); 2619 } 2620 } 2621 TRACE_ALU_RESULT2 (HI, LO); 2622} 2623 2624000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU 2625"divu r<RS>, r<RT>" 2626*mipsI: 2627*mipsII: 2628*mipsIII: 2629*mipsIV: 2630*mipsV: 2631*mips32: 2632*mips32r2: 2633*mips64: 2634*mips64r2: 2635*vr4100: 2636*vr5000: 2637*r3900: 2638{ 2639 do_divu (SD_, RS, RT); 2640} 2641 2642 2643:function:::void:do_dmultx:int rs, int rt, int rd, int signed_p 2644{ 2645 unsigned64 lo; 2646 unsigned64 hi; 2647 unsigned64 m00; 2648 unsigned64 m01; 2649 unsigned64 m10; 2650 unsigned64 m11; 2651 unsigned64 mid; 2652 int sign; 2653 unsigned64 op1 = GPR[rs]; 2654 unsigned64 op2 = GPR[rt]; 2655 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 2656 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 2657 /* make signed multiply unsigned */ 2658 sign = 0; 2659 if (signed_p) 2660 { 2661 if ((signed64) op1 < 0) 2662 { 2663 op1 = - op1; 2664 ++sign; 2665 } 2666 if ((signed64) op2 < 0) 2667 { 2668 op2 = - op2; 2669 ++sign; 2670 } 2671 } 2672 /* multiply out the 4 sub products */ 2673 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2)); 2674 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2)); 2675 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2)); 2676 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2)); 2677 /* add the products */ 2678 mid = ((unsigned64) VH4_8 (m00) 2679 + (unsigned64) VL4_8 (m10) 2680 + (unsigned64) VL4_8 (m01)); 2681 lo = U8_4 (mid, m00); 2682 hi = (m11 2683 + (unsigned64) VH4_8 (mid) 2684 + (unsigned64) VH4_8 (m01) 2685 + (unsigned64) VH4_8 (m10)); 2686 /* fix the sign */ 2687 if (sign & 1) 2688 { 2689 lo = -lo; 2690 if (lo == 0) 2691 hi = -hi; 2692 else 2693 hi = -hi - 1; 2694 } 2695 /* save the result HI/LO (and a gpr) */ 2696 LO = lo; 2697 HI = hi; 2698 if (rd != 0) 2699 GPR[rd] = lo; 2700 TRACE_ALU_RESULT2 (HI, LO); 2701} 2702 2703:function:::void:do_dmult:int rs, int rt, int rd 2704{ 2705 do_dmultx (SD_, rs, rt, rd, 1); 2706} 2707 2708000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT 2709"dmult r<RS>, r<RT>" 2710*mipsIII: 2711*mipsIV: 2712*mipsV: 2713*mips64: 2714*mips64r2: 2715*vr4100: 2716{ 2717 check_u64 (SD_, instruction_0); 2718 do_dmult (SD_, RS, RT, 0); 2719} 2720 2721000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT 2722"dmult r<RS>, r<RT>":RD == 0 2723"dmult r<RD>, r<RS>, r<RT>" 2724*vr5000: 2725{ 2726 check_u64 (SD_, instruction_0); 2727 do_dmult (SD_, RS, RT, RD); 2728} 2729 2730 2731 2732:function:::void:do_dmultu:int rs, int rt, int rd 2733{ 2734 do_dmultx (SD_, rs, rt, rd, 0); 2735} 2736 2737000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU 2738"dmultu r<RS>, r<RT>" 2739*mipsIII: 2740*mipsIV: 2741*mipsV: 2742*mips64: 2743*mips64r2: 2744*vr4100: 2745{ 2746 check_u64 (SD_, instruction_0); 2747 do_dmultu (SD_, RS, RT, 0); 2748} 2749 2750000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU 2751"dmultu r<RD>, r<RS>, r<RT>":RD == 0 2752"dmultu r<RS>, r<RT>" 2753*vr5000: 2754{ 2755 check_u64 (SD_, instruction_0); 2756 do_dmultu (SD_, RS, RT, RD); 2757} 2758 2759 2760:function:::unsigned64:do_dror:unsigned64 x,unsigned64 y 2761{ 2762 unsigned64 result; 2763 2764 y &= 63; 2765 TRACE_ALU_INPUT2 (x, y); 2766 result = ROTR64 (x, y); 2767 TRACE_ALU_RESULT (result); 2768 return result; 2769} 2770 2771000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR 2772"dror r<RD>, r<RT>, <SHIFT>" 2773*mips64r2: 2774*vr5400: 2775*vr5500: 2776{ 2777 check_u64 (SD_, instruction_0); 2778 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT); 2779} 2780 2781000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32 2782"dror32 r<RD>, r<RT>, <SHIFT>" 2783*mips64r2: 2784*vr5400: 2785*vr5500: 2786{ 2787 check_u64 (SD_, instruction_0); 2788 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32); 2789} 2790 2791000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV 2792"drorv r<RD>, r<RT>, r<RS>" 2793*mips64r2: 2794*vr5400: 2795*vr5500: 2796{ 2797 check_u64 (SD_, instruction_0); 2798 GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]); 2799} 2800 2801 2802:function:::void:do_dsll:int rt, int rd, int shift 2803{ 2804 TRACE_ALU_INPUT2 (GPR[rt], shift); 2805 GPR[rd] = GPR[rt] << shift; 2806 TRACE_ALU_RESULT (GPR[rd]); 2807} 2808 2809000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL 2810"dsll r<RD>, r<RT>, <SHIFT>" 2811*mipsIII: 2812*mipsIV: 2813*mipsV: 2814*mips64: 2815*mips64r2: 2816*vr4100: 2817*vr5000: 2818{ 2819 check_u64 (SD_, instruction_0); 2820 do_dsll (SD_, RT, RD, SHIFT); 2821} 2822 2823 2824000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32 2825"dsll32 r<RD>, r<RT>, <SHIFT>" 2826*mipsIII: 2827*mipsIV: 2828*mipsV: 2829*mips64: 2830*mips64r2: 2831*vr4100: 2832*vr5000: 2833{ 2834 check_u64 (SD_, instruction_0); 2835 do_dsll32 (SD_, RD, RT, SHIFT); 2836} 2837 2838:function:::void:do_dsllv:int rs, int rt, int rd 2839{ 2840 int s = MASKED64 (GPR[rs], 5, 0); 2841 TRACE_ALU_INPUT2 (GPR[rt], s); 2842 GPR[rd] = GPR[rt] << s; 2843 TRACE_ALU_RESULT (GPR[rd]); 2844} 2845 2846000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV 2847"dsllv r<RD>, r<RT>, r<RS>" 2848*mipsIII: 2849*mipsIV: 2850*mipsV: 2851*mips64: 2852*mips64r2: 2853*vr4100: 2854*vr5000: 2855{ 2856 check_u64 (SD_, instruction_0); 2857 do_dsllv (SD_, RS, RT, RD); 2858} 2859 2860:function:::void:do_dsra:int rt, int rd, int shift 2861{ 2862 TRACE_ALU_INPUT2 (GPR[rt], shift); 2863 GPR[rd] = ((signed64) GPR[rt]) >> shift; 2864 TRACE_ALU_RESULT (GPR[rd]); 2865} 2866 2867 2868000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA 2869"dsra r<RD>, r<RT>, <SHIFT>" 2870*mipsIII: 2871*mipsIV: 2872*mipsV: 2873*mips64: 2874*mips64r2: 2875*vr4100: 2876*vr5000: 2877{ 2878 check_u64 (SD_, instruction_0); 2879 do_dsra (SD_, RT, RD, SHIFT); 2880} 2881 2882 2883000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32 2884"dsra32 r<RD>, r<RT>, <SHIFT>" 2885*mipsIII: 2886*mipsIV: 2887*mipsV: 2888*mips64: 2889*mips64r2: 2890*vr4100: 2891*vr5000: 2892{ 2893 check_u64 (SD_, instruction_0); 2894 do_dsra32 (SD_, RD, RT, SHIFT); 2895} 2896 2897 2898:function:::void:do_dsrav:int rs, int rt, int rd 2899{ 2900 int s = MASKED64 (GPR[rs], 5, 0); 2901 TRACE_ALU_INPUT2 (GPR[rt], s); 2902 GPR[rd] = ((signed64) GPR[rt]) >> s; 2903 TRACE_ALU_RESULT (GPR[rd]); 2904} 2905 2906000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV 2907"dsrav r<RD>, r<RT>, r<RS>" 2908*mipsIII: 2909*mipsIV: 2910*mipsV: 2911*mips64: 2912*mips64r2: 2913*vr4100: 2914*vr5000: 2915{ 2916 check_u64 (SD_, instruction_0); 2917 do_dsrav (SD_, RS, RT, RD); 2918} 2919 2920:function:::void:do_dsrl:int rt, int rd, int shift 2921{ 2922 TRACE_ALU_INPUT2 (GPR[rt], shift); 2923 GPR[rd] = (unsigned64) GPR[rt] >> shift; 2924 TRACE_ALU_RESULT (GPR[rd]); 2925} 2926 2927 2928000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL 2929"dsrl r<RD>, r<RT>, <SHIFT>" 2930*mipsIII: 2931*mipsIV: 2932*mipsV: 2933*mips64: 2934*mips64r2: 2935*vr4100: 2936*vr5000: 2937{ 2938 check_u64 (SD_, instruction_0); 2939 do_dsrl (SD_, RT, RD, SHIFT); 2940} 2941 2942 2943000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32 2944"dsrl32 r<RD>, r<RT>, <SHIFT>" 2945*mipsIII: 2946*mipsIV: 2947*mipsV: 2948*mips64: 2949*mips64r2: 2950*vr4100: 2951*vr5000: 2952{ 2953 check_u64 (SD_, instruction_0); 2954 do_dsrl32 (SD_, RD, RT, SHIFT); 2955} 2956 2957 2958:function:::void:do_dsrlv:int rs, int rt, int rd 2959{ 2960 int s = MASKED64 (GPR[rs], 5, 0); 2961 TRACE_ALU_INPUT2 (GPR[rt], s); 2962 GPR[rd] = (unsigned64) GPR[rt] >> s; 2963 TRACE_ALU_RESULT (GPR[rd]); 2964} 2965 2966 2967 2968000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV 2969"dsrlv r<RD>, r<RT>, r<RS>" 2970*mipsIII: 2971*mipsIV: 2972*mipsV: 2973*mips64: 2974*mips64r2: 2975*vr4100: 2976*vr5000: 2977{ 2978 check_u64 (SD_, instruction_0); 2979 do_dsrlv (SD_, RS, RT, RD); 2980} 2981 2982 2983000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB 2984"dsub r<RD>, r<RS>, r<RT>" 2985*mipsIII: 2986*mipsIV: 2987*mipsV: 2988*mips64: 2989*mips64r2: 2990*vr4100: 2991*vr5000: 2992{ 2993 check_u64 (SD_, instruction_0); 2994 do_dsub (SD_, RD, RS, RT); 2995} 2996 2997 2998:function:::void:do_dsubu:int rs, int rt, int rd 2999{ 3000 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 3001 GPR[rd] = GPR[rs] - GPR[rt]; 3002 TRACE_ALU_RESULT (GPR[rd]); 3003} 3004 3005000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU 3006"dsubu r<RD>, r<RS>, r<RT>" 3007*mipsIII: 3008*mipsIV: 3009*mipsV: 3010*mips64: 3011*mips64r2: 3012*vr4100: 3013*vr5000: 3014{ 3015 check_u64 (SD_, instruction_0); 3016 do_dsubu (SD_, RS, RT, RD); 3017} 3018 3019 3020000010,26.INSTR_INDEX:NORMAL:32::J 3021"j <INSTR_INDEX>" 3022*mipsI: 3023*mipsII: 3024*mipsIII: 3025*mipsIV: 3026*mipsV: 3027*mips32: 3028*mips32r2: 3029*mips64: 3030*mips64r2: 3031*vr4100: 3032*vr5000: 3033*r3900: 3034{ 3035 /* NOTE: The region used is that of the delay slot NIA and NOT the 3036 current instruction */ 3037 address_word region = (NIA & MASK (63, 28)); 3038 DELAY_SLOT (region | (INSTR_INDEX << 2)); 3039} 3040 3041 3042000011,26.INSTR_INDEX:NORMAL:32::JAL 3043"jal <INSTR_INDEX>" 3044*mipsI: 3045*mipsII: 3046*mipsIII: 3047*mipsIV: 3048*mipsV: 3049*mips32: 3050*mips32r2: 3051*mips64: 3052*mips64r2: 3053*vr4100: 3054*vr5000: 3055*r3900: 3056{ 3057 /* NOTE: The region used is that of the delay slot and NOT the 3058 current instruction */ 3059 address_word region = (NIA & MASK (63, 28)); 3060 GPR[31] = CIA + 8; 3061 DELAY_SLOT (region | (INSTR_INDEX << 2)); 3062} 3063 3064000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR 3065"jalr r<RS>":RD == 31 3066"jalr r<RD>, r<RS>" 3067*mipsI: 3068*mipsII: 3069*mipsIII: 3070*mipsIV: 3071*mipsV: 3072*mips32: 3073*mips32r2: 3074*mips64: 3075*mips64r2: 3076*vr4100: 3077*vr5000: 3078*r3900: 3079{ 3080 address_word temp = GPR[RS]; 3081 GPR[RD] = CIA + 8; 3082 DELAY_SLOT (temp); 3083} 3084 3085000000,5.RS,00000,5.RD,10000,001001:SPECIAL:32::JALR_HB 3086"jalr.hb r<RS>":RD == 31 3087"jalr.hb r<RD>, r<RS>" 3088*mips32r2: 3089*mips64r2: 3090{ 3091 address_word temp = GPR[RS]; 3092 GPR[RD] = CIA + 8; 3093 DELAY_SLOT (temp); 3094} 3095 3096000000,5.RS,0000000000,00000,001000:SPECIAL:32::JR 3097"jr r<RS>" 3098*mipsI: 3099*mipsII: 3100*mipsIII: 3101*mipsIV: 3102*mipsV: 3103*mips32: 3104*mips32r2: 3105*mips64: 3106*mips64r2: 3107*vr4100: 3108*vr5000: 3109*r3900: 3110{ 3111 DELAY_SLOT (GPR[RS]); 3112} 3113 3114000000,5.RS,0000000000,10000,001000:SPECIAL:32::JR_HB 3115"jr.hb r<RS>" 3116*mips32r2: 3117*mips64r2: 3118{ 3119 DELAY_SLOT (GPR[RS]); 3120} 3121 3122:function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset 3123{ 3124 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 3125 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0); 3126 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); 3127 unsigned int byte; 3128 address_word paddr; 3129 unsigned64 memval; 3130 address_word vaddr; 3131 3132 paddr = vaddr = loadstore_ea (SD_, base, offset); 3133 if ((vaddr & access) != 0) 3134 { 3135 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal); 3136 } 3137 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); 3138 LoadMemory (&memval, NULL, access, paddr, vaddr, isDATA, isREAL); 3139 byte = ((vaddr & mask) ^ bigendiancpu); 3140 return (memval >> (8 * byte)); 3141} 3142 3143:function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt 3144{ 3145 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 3146 address_word reverseendian = (ReverseEndian ? -1 : 0); 3147 address_word bigendiancpu = (BigEndianCPU ? -1 : 0); 3148 unsigned int byte; 3149 unsigned int word; 3150 address_word paddr; 3151 unsigned64 memval; 3152 address_word vaddr; 3153 int nr_lhs_bits; 3154 int nr_rhs_bits; 3155 unsigned_word lhs_mask; 3156 unsigned_word temp; 3157 3158 paddr = vaddr = loadstore_ea (SD_, base, offset); 3159 paddr = (paddr ^ (reverseendian & mask)); 3160 if (BigEndianMem == 0) 3161 paddr = paddr & ~access; 3162 3163 /* compute where within the word/mem we are */ 3164 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */ 3165 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */ 3166 nr_lhs_bits = 8 * byte + 8; 3167 nr_rhs_bits = 8 * access - 8 * byte; 3168 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */ 3169 3170 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n", 3171 (long) ((unsigned64) vaddr >> 32), (long) vaddr, 3172 (long) ((unsigned64) paddr >> 32), (long) paddr, 3173 word, byte, nr_lhs_bits, nr_rhs_bits); */ 3174 3175 LoadMemory (&memval, NULL, byte, paddr, vaddr, isDATA, isREAL); 3176 if (word == 0) 3177 { 3178 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */ 3179 temp = (memval << nr_rhs_bits); 3180 } 3181 else 3182 { 3183 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */ 3184 temp = (memval >> nr_lhs_bits); 3185 } 3186 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits); 3187 rt = (rt & ~lhs_mask) | (temp & lhs_mask); 3188 3189 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n", 3190 (long) ((unsigned64) memval >> 32), (long) memval, 3191 (long) ((unsigned64) temp >> 32), (long) temp, 3192 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask, 3193 (long) (rt >> 32), (long) rt); */ 3194 return rt; 3195} 3196 3197:function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt 3198{ 3199 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 3200 address_word reverseendian = (ReverseEndian ? -1 : 0); 3201 address_word bigendiancpu = (BigEndianCPU ? -1 : 0); 3202 unsigned int byte; 3203 address_word paddr; 3204 unsigned64 memval; 3205 address_word vaddr; 3206 3207 paddr = vaddr = loadstore_ea (SD_, base, offset); 3208 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */ 3209 paddr = (paddr ^ (reverseendian & mask)); 3210 if (BigEndianMem != 0) 3211 paddr = paddr & ~access; 3212 byte = ((vaddr & mask) ^ (bigendiancpu & mask)); 3213 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */ 3214 LoadMemory (&memval, NULL, access - (access & byte), paddr, vaddr, isDATA, isREAL); 3215 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n", 3216 (long) paddr, byte, (long) paddr, (long) memval); */ 3217 { 3218 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0); 3219 rt &= ~screen; 3220 rt |= (memval >> (8 * byte)) & screen; 3221 } 3222 return rt; 3223} 3224 3225 3226100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB 3227"lb r<RT>, <OFFSET>(r<BASE>)" 3228*mipsI: 3229*mipsII: 3230*mipsIII: 3231*mipsIV: 3232*mipsV: 3233*mips32: 3234*mips32r2: 3235*mips64: 3236*mips64r2: 3237*vr4100: 3238*vr5000: 3239*r3900: 3240{ 3241 do_lb (SD_,RT,OFFSET,BASE); 3242} 3243 3244 3245100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU 3246"lbu r<RT>, <OFFSET>(r<BASE>)" 3247*mipsI: 3248*mipsII: 3249*mipsIII: 3250*mipsIV: 3251*mipsV: 3252*mips32: 3253*mips32r2: 3254*mips64: 3255*mips64r2: 3256*vr4100: 3257*vr5000: 3258*r3900: 3259{ 3260 do_lbu (SD_, RT,OFFSET,BASE); 3261} 3262 3263 3264110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD 3265"ld r<RT>, <OFFSET>(r<BASE>)" 3266*mipsIII: 3267*mipsIV: 3268*mipsV: 3269*mips64: 3270*mips64r2: 3271*vr4100: 3272*vr5000: 3273{ 3274 check_u64 (SD_, instruction_0); 3275 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET))); 3276} 3277 3278 32791101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz 3280"ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)" 3281*mipsII: 3282*mipsIII: 3283*mipsIV: 3284*mipsV: 3285*mips32: 3286*mips32r2: 3287*mips64: 3288*mips64r2: 3289*vr4100: 3290*vr5000: 3291*r3900: 3292{ 3293 do_ldc (SD_, ZZ, RT, OFFSET, BASE); 3294} 3295 3296 3297 3298 3299011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL 3300"ldl r<RT>, <OFFSET>(r<BASE>)" 3301*mipsIII: 3302*mipsIV: 3303*mipsV: 3304*mips64: 3305*mips64r2: 3306*vr4100: 3307*vr5000: 3308{ 3309 check_u64 (SD_, instruction_0); 3310 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 3311} 3312 3313 3314011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR 3315"ldr r<RT>, <OFFSET>(r<BASE>)" 3316*mipsIII: 3317*mipsIV: 3318*mipsV: 3319*mips64: 3320*mips64r2: 3321*vr4100: 3322*vr5000: 3323{ 3324 check_u64 (SD_, instruction_0); 3325 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 3326} 3327 3328 3329100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH 3330"lh r<RT>, <OFFSET>(r<BASE>)" 3331*mipsI: 3332*mipsII: 3333*mipsIII: 3334*mipsIV: 3335*mipsV: 3336*mips32: 3337*mips32r2: 3338*mips64: 3339*mips64r2: 3340*vr4100: 3341*vr5000: 3342*r3900: 3343{ 3344 do_lh (SD_,RT,OFFSET,BASE); 3345} 3346 3347 3348100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU 3349"lhu r<RT>, <OFFSET>(r<BASE>)" 3350*mipsI: 3351*mipsII: 3352*mipsIII: 3353*mipsIV: 3354*mipsV: 3355*mips32: 3356*mips32r2: 3357*mips64: 3358*mips64r2: 3359*vr4100: 3360*vr5000: 3361*r3900: 3362{ 3363 do_lhu (SD_,RT,OFFSET,BASE); 3364} 3365 3366 3367110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL 3368"ll r<RT>, <OFFSET>(r<BASE>)" 3369*mipsII: 3370*mipsIII: 3371*mipsIV: 3372*mipsV: 3373*mips32: 3374*mips32r2: 3375*mips64: 3376*mips64r2: 3377*vr4100: 3378*vr5000: 3379{ 3380 do_ll (SD_, RT, OFFSET, BASE); 3381} 3382 3383 3384110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD 3385"lld r<RT>, <OFFSET>(r<BASE>)" 3386*mipsIII: 3387*mipsIV: 3388*mipsV: 3389*mips64: 3390*mips64r2: 3391*vr4100: 3392*vr5000: 3393{ 3394 check_u64 (SD_, instruction_0); 3395 do_lld (SD_, RT, OFFSET, BASE); 3396} 3397 3398 3399001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI 3400"lui r<RT>, %#lx<IMMEDIATE>" 3401*mipsI: 3402*mipsII: 3403*mipsIII: 3404*mipsIV: 3405*mipsV: 3406*mips32: 3407*mips32r2: 3408*mips64: 3409*mips64r2: 3410*vr4100: 3411*vr5000: 3412*r3900: 3413{ 3414 do_lui (SD_, RT, IMMEDIATE); 3415} 3416 3417 3418100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW 3419"lw r<RT>, <OFFSET>(r<BASE>)" 3420*mipsI: 3421*mipsII: 3422*mipsIII: 3423*mipsIV: 3424*mipsV: 3425*mips32: 3426*mips32r2: 3427*mips64: 3428*mips64r2: 3429*vr4100: 3430*vr5000: 3431*r3900: 3432{ 3433 do_lw (SD_,RT,OFFSET,BASE); 3434} 3435 3436 34371100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz 3438"lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)" 3439*mipsI: 3440*mipsII: 3441*mipsIII: 3442*mipsIV: 3443*mipsV: 3444*mips32: 3445*mips32r2: 3446*mips64: 3447*mips64r2: 3448*vr4100: 3449*vr5000: 3450*r3900: 3451{ 3452 do_lwc (SD_, ZZ, RT, OFFSET, BASE); 3453} 3454 3455 3456100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL 3457"lwl r<RT>, <OFFSET>(r<BASE>)" 3458*mipsI: 3459*mipsII: 3460*mipsIII: 3461*mipsIV: 3462*mipsV: 3463*mips32: 3464*mips32r2: 3465*mips64: 3466*mips64r2: 3467*vr4100: 3468*vr5000: 3469*r3900: 3470{ 3471 do_lwl (SD_, RT, OFFSET, BASE); 3472} 3473 3474 3475100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR 3476"lwr r<RT>, <OFFSET>(r<BASE>)" 3477*mipsI: 3478*mipsII: 3479*mipsIII: 3480*mipsIV: 3481*mipsV: 3482*mips32: 3483*mips32r2: 3484*mips64: 3485*mips64r2: 3486*vr4100: 3487*vr5000: 3488*r3900: 3489{ 3490 do_lwr (SD_, RT, OFFSET, BASE); 3491} 3492 3493 3494100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU 3495"lwu r<RT>, <OFFSET>(r<BASE>)" 3496*mipsIII: 3497*mipsIV: 3498*mipsV: 3499*mips64: 3500*mips64r2: 3501*vr4100: 3502*vr5000: 3503{ 3504 do_lwu (SD_, RT, OFFSET, BASE, instruction_0); 3505} 3506 3507 3508 3509011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD 3510"madd r<RS>, r<RT>" 3511*mips32: 3512*mips64: 3513*vr5500: 3514{ 3515 do_madd (SD_, RS, RT); 3516} 3517 3518 3519011100,5.RS,5.RT,000,2.AC,00000,000000:SPECIAL2:32::MADD 3520"madd r<RS>, r<RT>":AC == 0 3521"madd ac<AC>, r<RS>, r<RT>" 3522*mips32r2: 3523*mips64r2: 3524*dsp2: 3525{ 3526 do_dsp_madd (SD_, AC, RS, RT); 3527} 3528 3529 3530011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU 3531"maddu r<RS>, r<RT>" 3532*mips32: 3533*mips64: 3534*vr5500: 3535{ 3536 do_maddu (SD_, RS, RT); 3537} 3538 3539 3540011100,5.RS,5.RT,000,2.AC,00000,000001:SPECIAL2:32::MADDU 3541"maddu r<RS>, r<RT>":AC == 0 3542"maddu ac<AC>, r<RS>, r<RT>" 3543*mips32r2: 3544*mips64r2: 3545*dsp2: 3546{ 3547 do_dsp_maddu (SD_, AC, RS, RT); 3548} 3549 3550 3551:function:::void:do_mfhi:int rd 3552{ 3553 check_mf_hilo (SD_, HIHISTORY, LOHISTORY); 3554 TRACE_ALU_INPUT1 (HI); 3555 GPR[rd] = HI; 3556 TRACE_ALU_RESULT (GPR[rd]); 3557} 3558 3559000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI 3560"mfhi r<RD>" 3561*mipsI: 3562*mipsII: 3563*mipsIII: 3564*mipsIV: 3565*mipsV: 3566*vr4100: 3567*vr5000: 3568*r3900: 3569*mips32: 3570*mips64: 3571{ 3572 do_mfhi (SD_, RD); 3573} 3574 3575 3576000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHI 3577"mfhi r<RD>":AC == 0 3578"mfhi r<RD>, ac<AC>" 3579*mips32r2: 3580*mips64r2: 3581*dsp: 3582{ 3583 do_dsp_mfhi (SD_, AC, RD); 3584} 3585 3586 3587:function:::void:do_mflo:int rd 3588{ 3589 check_mf_hilo (SD_, LOHISTORY, HIHISTORY); 3590 TRACE_ALU_INPUT1 (LO); 3591 GPR[rd] = LO; 3592 TRACE_ALU_RESULT (GPR[rd]); 3593} 3594 3595000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO 3596"mflo r<RD>" 3597*mipsI: 3598*mipsII: 3599*mipsIII: 3600*mipsIV: 3601*mipsV: 3602*vr4100: 3603*vr5000: 3604*r3900: 3605*mips32: 3606*mips64: 3607{ 3608 do_mflo (SD_, RD); 3609} 3610 3611 3612000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLO 3613"mflo r<RD>":AC == 0 3614"mflo r<RD>, ac<AC>" 3615*mips32r2: 3616*mips64r2: 3617*dsp: 3618{ 3619 do_dsp_mflo (SD_, AC, RD); 3620} 3621 3622 3623000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN 3624"movn r<RD>, r<RS>, r<RT>" 3625*mipsIV: 3626*mipsV: 3627*mips32: 3628*mips32r2: 3629*mips64: 3630*mips64r2: 3631*vr5000: 3632{ 3633 do_movn (SD_, RD, RS, RT); 3634} 3635 3636 3637 3638000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ 3639"movz r<RD>, r<RS>, r<RT>" 3640*mipsIV: 3641*mipsV: 3642*mips32: 3643*mips32r2: 3644*mips64: 3645*mips64r2: 3646*vr5000: 3647{ 3648 do_movz (SD_, RD, RS, RT); 3649} 3650 3651 3652 3653011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB 3654"msub r<RS>, r<RT>" 3655*mips32: 3656*mips64: 3657*vr5500: 3658{ 3659 do_msub (SD_, RS, RT); 3660} 3661 3662 3663011100,5.RS,5.RT,000,2.AC,00000,000100:SPECIAL2:32::MSUB 3664"msub r<RS>, r<RT>":AC == 0 3665"msub ac<AC>, r<RS>, r<RT>" 3666*mips32r2: 3667*mips64r2: 3668*dsp2: 3669{ 3670 do_dsp_msub (SD_, AC, RS, RT); 3671} 3672 3673 3674011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU 3675"msubu r<RS>, r<RT>" 3676*mips32: 3677*mips64: 3678*vr5500: 3679{ 3680 do_msubu (SD_, RS, RT); 3681} 3682 3683 3684011100,5.RS,5.RT,000,2.AC,00000,000101:SPECIAL2:32::MSUBU 3685"msubu r<RS>, r<RT>":AC == 0 3686"msubu ac<AC>, r<RS>, r<RT>" 3687*mips32r2: 3688*mips64r2: 3689*dsp2: 3690{ 3691 do_dsp_msubu (SD_, AC, RS, RT); 3692} 3693 3694 3695000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI 3696"mthi r<RS>" 3697*mipsI: 3698*mipsII: 3699*mipsIII: 3700*mipsIV: 3701*mipsV: 3702*vr4100: 3703*vr5000: 3704*r3900: 3705*mips32: 3706*mips64: 3707{ 3708 do_mthi (SD_, RS); 3709} 3710 3711 3712000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHI 3713"mthi r<RS>":AC == 0 3714"mthi r<RS>, ac<AC>" 3715*mips32r2: 3716*mips64r2: 3717*dsp: 3718{ 3719 do_dsp_mthi (SD_, AC, RS); 3720} 3721 3722 3723000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO 3724"mtlo r<RS>" 3725*mipsI: 3726*mipsII: 3727*mipsIII: 3728*mipsIV: 3729*mipsV: 3730*vr4100: 3731*vr5000: 3732*r3900: 3733*mips32: 3734*mips64: 3735{ 3736 do_mtlo (SD_, RS); 3737} 3738 3739 3740000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLO 3741"mtlo r<RS>":AC == 0 3742"mtlo r<RS>, ac<AC>" 3743*mips32r2: 3744*mips64r2: 3745*dsp: 3746{ 3747 do_dsp_mtlo (SD_, AC, RS); 3748} 3749 3750 3751011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL 3752"mul r<RD>, r<RS>, r<RT>" 3753*mips32: 3754*mips32r2: 3755*mips64: 3756*mips64r2: 3757*vr5500: 3758{ 3759 do_mul (SD_, RD, RS, RT); 3760} 3761 3762 3763 3764:function:::void:do_mult:int rs, int rt, int rd 3765{ 3766 signed64 prod; 3767 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 3768 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 3769 Unpredictable (); 3770 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 3771 prod = (((signed64)(signed32) GPR[rs]) 3772 * ((signed64)(signed32) GPR[rt])); 3773 LO = EXTEND32 (VL4_8 (prod)); 3774 HI = EXTEND32 (VH4_8 (prod)); 3775 ACX = 0; /* SmartMIPS */ 3776 if (rd != 0) 3777 GPR[rd] = LO; 3778 TRACE_ALU_RESULT2 (HI, LO); 3779} 3780 3781000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT 3782"mult r<RS>, r<RT>" 3783*mipsI: 3784*mipsII: 3785*mipsIII: 3786*mipsIV: 3787*mipsV: 3788*mips32: 3789*mips64: 3790*vr4100: 3791{ 3792 do_mult (SD_, RS, RT, 0); 3793} 3794 3795 3796000000,5.RS,5.RT,000,2.AC,00000,011000:SPECIAL:32::MULT 3797"mult r<RS>, r<RT>":AC == 0 3798"mult ac<AC>, r<RS>, r<RT>" 3799*mips32r2: 3800*mips64r2: 3801*dsp2: 3802{ 3803 do_dsp_mult (SD_, AC, RS, RT); 3804} 3805 3806 3807000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT 3808"mult r<RS>, r<RT>":RD == 0 3809"mult r<RD>, r<RS>, r<RT>" 3810*vr5000: 3811*r3900: 3812{ 3813 do_mult (SD_, RS, RT, RD); 3814} 3815 3816 3817:function:::void:do_multu:int rs, int rt, int rd 3818{ 3819 unsigned64 prod; 3820 check_mult_hilo (SD_, HIHISTORY, LOHISTORY); 3821 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 3822 Unpredictable (); 3823 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 3824 prod = (((unsigned64)(unsigned32) GPR[rs]) 3825 * ((unsigned64)(unsigned32) GPR[rt])); 3826 LO = EXTEND32 (VL4_8 (prod)); 3827 HI = EXTEND32 (VH4_8 (prod)); 3828 if (rd != 0) 3829 GPR[rd] = LO; 3830 TRACE_ALU_RESULT2 (HI, LO); 3831} 3832 3833000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU 3834"multu r<RS>, r<RT>" 3835*mipsI: 3836*mipsII: 3837*mipsIII: 3838*mipsIV: 3839*mipsV: 3840*mips32: 3841*mips64: 3842*vr4100: 3843{ 3844 do_multu (SD_, RS, RT, 0); 3845} 3846 3847 3848000000,5.RS,5.RT,000,2.AC,00000,011001:SPECIAL:32::MULTU 3849"multu r<RS>, r<RT>":AC == 0 3850"multu r<RS>, r<RT>" 3851*mips32r2: 3852*mips64r2: 3853*dsp2: 3854{ 3855 do_dsp_multu (SD_, AC, RS, RT); 3856} 3857 3858 3859000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU 3860"multu r<RS>, r<RT>":RD == 0 3861"multu r<RD>, r<RS>, r<RT>" 3862*vr5000: 3863*r3900: 3864{ 3865 do_multu (SD_, RS, RT, RD); 3866} 3867 3868 3869:function:::void:do_nor:int rs, int rt, int rd 3870{ 3871 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 3872 GPR[rd] = ~ (GPR[rs] | GPR[rt]); 3873 TRACE_ALU_RESULT (GPR[rd]); 3874} 3875 3876000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR 3877"nor r<RD>, r<RS>, r<RT>" 3878*mipsI: 3879*mipsII: 3880*mipsIII: 3881*mipsIV: 3882*mipsV: 3883*mips32: 3884*mips32r2: 3885*mips64: 3886*mips64r2: 3887*vr4100: 3888*vr5000: 3889*r3900: 3890{ 3891 do_nor (SD_, RS, RT, RD); 3892} 3893 3894 3895:function:::void:do_or:int rs, int rt, int rd 3896{ 3897 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 3898 GPR[rd] = (GPR[rs] | GPR[rt]); 3899 TRACE_ALU_RESULT (GPR[rd]); 3900} 3901 3902000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR 3903"or r<RD>, r<RS>, r<RT>" 3904*mipsI: 3905*mipsII: 3906*mipsIII: 3907*mipsIV: 3908*mipsV: 3909*mips32: 3910*mips32r2: 3911*mips64: 3912*mips64r2: 3913*vr4100: 3914*vr5000: 3915*r3900: 3916{ 3917 do_or (SD_, RS, RT, RD); 3918} 3919 3920 3921 3922:function:::void:do_ori:int rs, int rt, unsigned immediate 3923{ 3924 TRACE_ALU_INPUT2 (GPR[rs], immediate); 3925 GPR[rt] = (GPR[rs] | immediate); 3926 TRACE_ALU_RESULT (GPR[rt]); 3927} 3928 3929001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI 3930"ori r<RT>, r<RS>, %#lx<IMMEDIATE>" 3931*mipsI: 3932*mipsII: 3933*mipsIII: 3934*mipsIV: 3935*mipsV: 3936*mips32: 3937*mips32r2: 3938*mips64: 3939*mips64r2: 3940*vr4100: 3941*vr5000: 3942*r3900: 3943{ 3944 do_ori (SD_, RS, RT, IMMEDIATE); 3945} 3946 3947 3948110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF 3949"pref <HINT>, <OFFSET>(r<BASE>)" 3950*mipsIV: 3951*mipsV: 3952*mips32: 3953*mips32r2: 3954*mips64: 3955*mips64r2: 3956*vr5000: 3957{ 3958 do_pref (SD_, HINT, OFFSET, BASE); 3959} 3960 3961 3962:function:::unsigned64:do_ror:unsigned32 x,unsigned32 y 3963{ 3964 unsigned64 result; 3965 3966 y &= 31; 3967 TRACE_ALU_INPUT2 (x, y); 3968 result = EXTEND32 (ROTR32 (x, y)); 3969 TRACE_ALU_RESULT (result); 3970 return result; 3971} 3972 3973000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR 3974"ror r<RD>, r<RT>, <SHIFT>" 3975*mips32r2: 3976*mips64r2: 3977*smartmips: 3978*vr5400: 3979*vr5500: 3980{ 3981 GPR[RD] = do_ror (SD_, GPR[RT], SHIFT); 3982} 3983 3984000000,5.RS,5.RT,5.RD,00001,000110::32::RORV 3985"rorv r<RD>, r<RT>, r<RS>" 3986*mips32r2: 3987*mips64r2: 3988*smartmips: 3989*vr5400: 3990*vr5500: 3991{ 3992 GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]); 3993} 3994 3995 3996:function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word 3997{ 3998 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 3999 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0); 4000 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); 4001 unsigned int byte; 4002 address_word paddr; 4003 unsigned64 memval; 4004 address_word vaddr; 4005 4006 paddr = vaddr = loadstore_ea (SD_, base, offset); 4007 if ((vaddr & access) != 0) 4008 { 4009 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal); 4010 } 4011 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); 4012 byte = ((vaddr & mask) ^ bigendiancpu); 4013 memval = (word << (8 * byte)); 4014 StoreMemory (access, memval, 0, paddr, vaddr, isREAL); 4015} 4016 4017:function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt 4018{ 4019 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 4020 address_word reverseendian = (ReverseEndian ? -1 : 0); 4021 address_word bigendiancpu = (BigEndianCPU ? -1 : 0); 4022 unsigned int byte; 4023 unsigned int word; 4024 address_word paddr; 4025 unsigned64 memval; 4026 address_word vaddr; 4027 int nr_lhs_bits; 4028 int nr_rhs_bits; 4029 4030 paddr = vaddr = loadstore_ea (SD_, base, offset); 4031 paddr = (paddr ^ (reverseendian & mask)); 4032 if (BigEndianMem == 0) 4033 paddr = paddr & ~access; 4034 4035 /* compute where within the word/mem we are */ 4036 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */ 4037 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */ 4038 nr_lhs_bits = 8 * byte + 8; 4039 nr_rhs_bits = 8 * access - 8 * byte; 4040 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */ 4041 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n", 4042 (long) ((unsigned64) vaddr >> 32), (long) vaddr, 4043 (long) ((unsigned64) paddr >> 32), (long) paddr, 4044 word, byte, nr_lhs_bits, nr_rhs_bits); */ 4045 4046 if (word == 0) 4047 { 4048 memval = (rt >> nr_rhs_bits); 4049 } 4050 else 4051 { 4052 memval = (rt << nr_lhs_bits); 4053 } 4054 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n", 4055 (long) ((unsigned64) rt >> 32), (long) rt, 4056 (long) ((unsigned64) memval >> 32), (long) memval); */ 4057 StoreMemory (byte, memval, 0, paddr, vaddr, isREAL); 4058} 4059 4060:function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt 4061{ 4062 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); 4063 address_word reverseendian = (ReverseEndian ? -1 : 0); 4064 address_word bigendiancpu = (BigEndianCPU ? -1 : 0); 4065 unsigned int byte; 4066 address_word paddr; 4067 unsigned64 memval; 4068 address_word vaddr; 4069 4070 paddr = vaddr = loadstore_ea (SD_, base, offset); 4071 paddr = (paddr ^ (reverseendian & mask)); 4072 if (BigEndianMem != 0) 4073 paddr &= ~access; 4074 byte = ((vaddr & mask) ^ (bigendiancpu & mask)); 4075 memval = (rt << (byte * 8)); 4076 StoreMemory (access - (access & byte), memval, 0, paddr, vaddr, isREAL); 4077} 4078 4079 4080101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB 4081"sb r<RT>, <OFFSET>(r<BASE>)" 4082*mipsI: 4083*mipsII: 4084*mipsIII: 4085*mipsIV: 4086*mipsV: 4087*mips32: 4088*mips32r2: 4089*mips64: 4090*mips64r2: 4091*vr4100: 4092*vr5000: 4093*r3900: 4094{ 4095 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4096} 4097 4098 4099111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC 4100"sc r<RT>, <OFFSET>(r<BASE>)" 4101*mipsII: 4102*mipsIII: 4103*mipsIV: 4104*mipsV: 4105*mips32: 4106*mips32r2: 4107*mips64: 4108*mips64r2: 4109*vr4100: 4110*vr5000: 4111{ 4112 do_sc (SD_, RT, OFFSET, BASE, instruction_0); 4113} 4114 4115 4116111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD 4117"scd r<RT>, <OFFSET>(r<BASE>)" 4118*mipsIII: 4119*mipsIV: 4120*mipsV: 4121*mips64: 4122*mips64r2: 4123*vr4100: 4124*vr5000: 4125{ 4126 check_u64 (SD_, instruction_0); 4127 do_scd (SD_, RT, OFFSET, BASE); 4128} 4129 4130 4131111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD 4132"sd r<RT>, <OFFSET>(r<BASE>)" 4133*mipsIII: 4134*mipsIV: 4135*mipsV: 4136*mips64: 4137*mips64r2: 4138*vr4100: 4139*vr5000: 4140{ 4141 check_u64 (SD_, instruction_0); 4142 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4143} 4144 4145 41461111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz 4147"sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)" 4148*mipsII: 4149*mipsIII: 4150*mipsIV: 4151*mipsV: 4152*mips32: 4153*mips32r2: 4154*mips64: 4155*mips64r2: 4156*vr4100: 4157*vr5000: 4158{ 4159 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT)); 4160} 4161 4162 4163101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL 4164"sdl r<RT>, <OFFSET>(r<BASE>)" 4165*mipsIII: 4166*mipsIV: 4167*mipsV: 4168*mips64: 4169*mips64r2: 4170*vr4100: 4171*vr5000: 4172{ 4173 check_u64 (SD_, instruction_0); 4174 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4175} 4176 4177 4178101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR 4179"sdr r<RT>, <OFFSET>(r<BASE>)" 4180*mipsIII: 4181*mipsIV: 4182*mipsV: 4183*mips64: 4184*mips64r2: 4185*vr4100: 4186*vr5000: 4187{ 4188 check_u64 (SD_, instruction_0); 4189 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4190} 4191 4192 4193 4194101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH 4195"sh r<RT>, <OFFSET>(r<BASE>)" 4196*mipsI: 4197*mipsII: 4198*mipsIII: 4199*mipsIV: 4200*mipsV: 4201*mips32: 4202*mips32r2: 4203*mips64: 4204*mips64r2: 4205*vr4100: 4206*vr5000: 4207*r3900: 4208{ 4209 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4210} 4211 4212 4213:function:::void:do_sll:int rt, int rd, int shift 4214{ 4215 unsigned32 temp = (GPR[rt] << shift); 4216 TRACE_ALU_INPUT2 (GPR[rt], shift); 4217 GPR[rd] = EXTEND32 (temp); 4218 TRACE_ALU_RESULT (GPR[rd]); 4219} 4220 4221000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa 4222"nop":RD == 0 && RT == 0 && SHIFT == 0 4223"sll r<RD>, r<RT>, <SHIFT>" 4224*mipsI: 4225*mipsII: 4226*mipsIII: 4227*mipsIV: 4228*mipsV: 4229*vr4100: 4230*vr5000: 4231*r3900: 4232{ 4233 /* Skip shift for NOP, so that there won't be lots of extraneous 4234 trace output. */ 4235 if (RD != 0 || RT != 0 || SHIFT != 0) 4236 do_sll (SD_, RT, RD, SHIFT); 4237} 4238 4239000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb 4240"nop":RD == 0 && RT == 0 && SHIFT == 0 4241"ssnop":RD == 0 && RT == 0 && SHIFT == 1 4242"sll r<RD>, r<RT>, <SHIFT>" 4243*mips32: 4244*mips32r2: 4245*mips64: 4246*mips64r2: 4247{ 4248 /* Skip shift for NOP and SSNOP, so that there won't be lots of 4249 extraneous trace output. */ 4250 if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1)) 4251 do_sll (SD_, RT, RD, SHIFT); 4252} 4253 4254 4255:function:::void:do_sllv:int rs, int rt, int rd 4256{ 4257 int s = MASKED (GPR[rs], 4, 0); 4258 unsigned32 temp = (GPR[rt] << s); 4259 TRACE_ALU_INPUT2 (GPR[rt], s); 4260 GPR[rd] = EXTEND32 (temp); 4261 TRACE_ALU_RESULT (GPR[rd]); 4262} 4263 4264000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV 4265"sllv r<RD>, r<RT>, r<RS>" 4266*mipsI: 4267*mipsII: 4268*mipsIII: 4269*mipsIV: 4270*mipsV: 4271*mips32: 4272*mips32r2: 4273*mips64: 4274*mips64r2: 4275*vr4100: 4276*vr5000: 4277*r3900: 4278{ 4279 do_sllv (SD_, RS, RT, RD); 4280} 4281 4282 4283:function:::void:do_slt:int rs, int rt, int rd 4284{ 4285 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 4286 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]); 4287 TRACE_ALU_RESULT (GPR[rd]); 4288} 4289 4290000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT 4291"slt r<RD>, r<RS>, r<RT>" 4292*mipsI: 4293*mipsII: 4294*mipsIII: 4295*mipsIV: 4296*mipsV: 4297*mips32: 4298*mips32r2: 4299*mips64: 4300*mips64r2: 4301*vr4100: 4302*vr5000: 4303*r3900: 4304{ 4305 do_slt (SD_, RS, RT, RD); 4306} 4307 4308 4309:function:::void:do_slti:int rs, int rt, unsigned16 immediate 4310{ 4311 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 4312 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate)); 4313 TRACE_ALU_RESULT (GPR[rt]); 4314} 4315 4316001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI 4317"slti r<RT>, r<RS>, <IMMEDIATE>" 4318*mipsI: 4319*mipsII: 4320*mipsIII: 4321*mipsIV: 4322*mipsV: 4323*mips32: 4324*mips32r2: 4325*mips64: 4326*mips64r2: 4327*vr4100: 4328*vr5000: 4329*r3900: 4330{ 4331 do_slti (SD_, RS, RT, IMMEDIATE); 4332} 4333 4334 4335:function:::void:do_sltiu:int rs, int rt, unsigned16 immediate 4336{ 4337 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); 4338 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate)); 4339 TRACE_ALU_RESULT (GPR[rt]); 4340} 4341 4342001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU 4343"sltiu r<RT>, r<RS>, <IMMEDIATE>" 4344*mipsI: 4345*mipsII: 4346*mipsIII: 4347*mipsIV: 4348*mipsV: 4349*mips32: 4350*mips32r2: 4351*mips64: 4352*mips64r2: 4353*vr4100: 4354*vr5000: 4355*r3900: 4356{ 4357 do_sltiu (SD_, RS, RT, IMMEDIATE); 4358} 4359 4360 4361 4362:function:::void:do_sltu:int rs, int rt, int rd 4363{ 4364 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 4365 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]); 4366 TRACE_ALU_RESULT (GPR[rd]); 4367} 4368 4369000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU 4370"sltu r<RD>, r<RS>, r<RT>" 4371*mipsI: 4372*mipsII: 4373*mipsIII: 4374*mipsIV: 4375*mipsV: 4376*mips32: 4377*mips32r2: 4378*mips64: 4379*mips64r2: 4380*vr4100: 4381*vr5000: 4382*r3900: 4383{ 4384 do_sltu (SD_, RS, RT, RD); 4385} 4386 4387 4388:function:::void:do_sra:int rt, int rd, int shift 4389{ 4390 signed32 temp = (signed32) GPR[rt] >> shift; 4391 if (NotWordValue (GPR[rt])) 4392 Unpredictable (); 4393 TRACE_ALU_INPUT2 (GPR[rt], shift); 4394 GPR[rd] = EXTEND32 (temp); 4395 TRACE_ALU_RESULT (GPR[rd]); 4396} 4397 4398000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA 4399"sra r<RD>, r<RT>, <SHIFT>" 4400*mipsI: 4401*mipsII: 4402*mipsIII: 4403*mipsIV: 4404*mipsV: 4405*mips32: 4406*mips32r2: 4407*mips64: 4408*mips64r2: 4409*vr4100: 4410*vr5000: 4411*r3900: 4412{ 4413 do_sra (SD_, RT, RD, SHIFT); 4414} 4415 4416 4417 4418:function:::void:do_srav:int rs, int rt, int rd 4419{ 4420 int s = MASKED (GPR[rs], 4, 0); 4421 signed32 temp = (signed32) GPR[rt] >> s; 4422 if (NotWordValue (GPR[rt])) 4423 Unpredictable (); 4424 TRACE_ALU_INPUT2 (GPR[rt], s); 4425 GPR[rd] = EXTEND32 (temp); 4426 TRACE_ALU_RESULT (GPR[rd]); 4427} 4428 4429000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV 4430"srav r<RD>, r<RT>, r<RS>" 4431*mipsI: 4432*mipsII: 4433*mipsIII: 4434*mipsIV: 4435*mipsV: 4436*mips32: 4437*mips32r2: 4438*mips64: 4439*mips64r2: 4440*vr4100: 4441*vr5000: 4442*r3900: 4443{ 4444 do_srav (SD_, RS, RT, RD); 4445} 4446 4447 4448 4449:function:::void:do_srl:int rt, int rd, int shift 4450{ 4451 unsigned32 temp = (unsigned32) GPR[rt] >> shift; 4452 if (NotWordValue (GPR[rt])) 4453 Unpredictable (); 4454 TRACE_ALU_INPUT2 (GPR[rt], shift); 4455 GPR[rd] = EXTEND32 (temp); 4456 TRACE_ALU_RESULT (GPR[rd]); 4457} 4458 4459000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL 4460"srl r<RD>, r<RT>, <SHIFT>" 4461*mipsI: 4462*mipsII: 4463*mipsIII: 4464*mipsIV: 4465*mipsV: 4466*mips32: 4467*mips32r2: 4468*mips64: 4469*mips64r2: 4470*vr4100: 4471*vr5000: 4472*r3900: 4473{ 4474 do_srl (SD_, RT, RD, SHIFT); 4475} 4476 4477 4478:function:::void:do_srlv:int rs, int rt, int rd 4479{ 4480 int s = MASKED (GPR[rs], 4, 0); 4481 unsigned32 temp = (unsigned32) GPR[rt] >> s; 4482 if (NotWordValue (GPR[rt])) 4483 Unpredictable (); 4484 TRACE_ALU_INPUT2 (GPR[rt], s); 4485 GPR[rd] = EXTEND32 (temp); 4486 TRACE_ALU_RESULT (GPR[rd]); 4487} 4488 4489000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV 4490"srlv r<RD>, r<RT>, r<RS>" 4491*mipsI: 4492*mipsII: 4493*mipsIII: 4494*mipsIV: 4495*mipsV: 4496*mips32: 4497*mips32r2: 4498*mips64: 4499*mips64r2: 4500*vr4100: 4501*vr5000: 4502*r3900: 4503{ 4504 do_srlv (SD_, RS, RT, RD); 4505} 4506 4507 4508000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB 4509"sub r<RD>, r<RS>, r<RT>" 4510*mipsI: 4511*mipsII: 4512*mipsIII: 4513*mipsIV: 4514*mipsV: 4515*mips32: 4516*mips32r2: 4517*mips64: 4518*mips64r2: 4519*vr4100: 4520*vr5000: 4521*r3900: 4522{ 4523 do_sub (SD_, RD, RS, RT); 4524} 4525 4526 4527:function:::void:do_subu:int rs, int rt, int rd 4528{ 4529 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) 4530 Unpredictable (); 4531 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 4532 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]); 4533 TRACE_ALU_RESULT (GPR[rd]); 4534} 4535 4536000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU 4537"subu r<RD>, r<RS>, r<RT>" 4538*mipsI: 4539*mipsII: 4540*mipsIII: 4541*mipsIV: 4542*mipsV: 4543*mips32: 4544*mips32r2: 4545*mips64: 4546*mips64r2: 4547*vr4100: 4548*vr5000: 4549*r3900: 4550{ 4551 do_subu (SD_, RS, RT, RD); 4552} 4553 4554 4555101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW 4556"sw r<RT>, <OFFSET>(r<BASE>)" 4557*mipsI: 4558*mipsII: 4559*mipsIII: 4560*mipsIV: 4561*mipsV: 4562*mips32: 4563*mips32r2: 4564*mips64: 4565*mips64r2: 4566*vr4100: 4567*r3900: 4568*vr5000: 4569{ 4570 do_sw (SD_, RT, OFFSET, BASE); 4571} 4572 4573 45741110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz 4575"swc<ZZ> r<RT>, <OFFSET>(r<BASE>)" 4576*mipsI: 4577*mipsII: 4578*mipsIII: 4579*mipsIV: 4580*mipsV: 4581*mips32: 4582*mips32r2: 4583*mips64: 4584*mips64r2: 4585*vr4100: 4586*vr5000: 4587*r3900: 4588{ 4589 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT)); 4590} 4591 4592 4593101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL 4594"swl r<RT>, <OFFSET>(r<BASE>)" 4595*mipsI: 4596*mipsII: 4597*mipsIII: 4598*mipsIV: 4599*mipsV: 4600*mips32: 4601*mips32r2: 4602*mips64: 4603*mips64r2: 4604*vr4100: 4605*vr5000: 4606*r3900: 4607{ 4608 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4609} 4610 4611 4612101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR 4613"swr r<RT>, <OFFSET>(r<BASE>)" 4614*mipsI: 4615*mipsII: 4616*mipsIII: 4617*mipsIV: 4618*mipsV: 4619*mips32: 4620*mips32r2: 4621*mips64: 4622*mips64r2: 4623*vr4100: 4624*vr5000: 4625*r3900: 4626{ 4627 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]); 4628} 4629 4630 4631000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC 4632"sync":STYPE == 0 4633"sync <STYPE>" 4634*mipsII: 4635*mipsIII: 4636*mipsIV: 4637*mipsV: 4638*mips32: 4639*mips32r2: 4640*mips64: 4641*mips64r2: 4642*vr4100: 4643*vr5000: 4644*r3900: 4645{ 4646 SyncOperation (STYPE); 4647} 4648 4649 4650000000,20.CODE,001100:SPECIAL:32::SYSCALL 4651"syscall %#lx<CODE>" 4652*mipsI: 4653*mipsII: 4654*mipsIII: 4655*mipsIV: 4656*mipsV: 4657*mips32: 4658*mips32r2: 4659*mips64: 4660*mips64r2: 4661*vr4100: 4662*vr5000: 4663*r3900: 4664{ 4665 SignalException (SystemCall, instruction_0); 4666} 4667 4668 4669000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ 4670"teq r<RS>, r<RT>" 4671*mipsII: 4672*mipsIII: 4673*mipsIV: 4674*mipsV: 4675*mips32: 4676*mips32r2: 4677*mips64: 4678*mips64r2: 4679*vr4100: 4680*vr5000: 4681{ 4682 do_teq (SD_, RS, RT, instruction_0); 4683} 4684 4685 4686000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI 4687"teqi r<RS>, <IMMEDIATE>" 4688*mipsII: 4689*mipsIII: 4690*mipsIV: 4691*mipsV: 4692*mips32: 4693*mips32r2: 4694*mips64: 4695*mips64r2: 4696*vr4100: 4697*vr5000: 4698{ 4699 do_teqi (SD_, RS, IMMEDIATE, instruction_0); 4700} 4701 4702 4703000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE 4704"tge r<RS>, r<RT>" 4705*mipsII: 4706*mipsIII: 4707*mipsIV: 4708*mipsV: 4709*mips32: 4710*mips32r2: 4711*mips64: 4712*mips64r2: 4713*vr4100: 4714*vr5000: 4715{ 4716 do_tge (SD_, RS, RT, instruction_0); 4717} 4718 4719 4720000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI 4721"tgei r<RS>, <IMMEDIATE>" 4722*mipsII: 4723*mipsIII: 4724*mipsIV: 4725*mipsV: 4726*mips32: 4727*mips32r2: 4728*mips64: 4729*mips64r2: 4730*vr4100: 4731*vr5000: 4732{ 4733 do_tgei (SD_, RS, IMMEDIATE, instruction_0); 4734} 4735 4736 4737000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU 4738"tgeiu r<RS>, <IMMEDIATE>" 4739*mipsII: 4740*mipsIII: 4741*mipsIV: 4742*mipsV: 4743*mips32: 4744*mips32r2: 4745*mips64: 4746*mips64r2: 4747*vr4100: 4748*vr5000: 4749{ 4750 do_tgeiu (SD_, RS, IMMEDIATE, instruction_0); 4751} 4752 4753 4754000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU 4755"tgeu r<RS>, r<RT>" 4756*mipsII: 4757*mipsIII: 4758*mipsIV: 4759*mipsV: 4760*mips32: 4761*mips32r2: 4762*mips64: 4763*mips64r2: 4764*vr4100: 4765*vr5000: 4766{ 4767 do_tgeu (SD_, RS, RT, instruction_0); 4768} 4769 4770 4771000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT 4772"tlt r<RS>, r<RT>" 4773*mipsII: 4774*mipsIII: 4775*mipsIV: 4776*mipsV: 4777*mips32: 4778*mips32r2: 4779*mips64: 4780*mips64r2: 4781*vr4100: 4782*vr5000: 4783{ 4784 do_tlt (SD_, RS, RT, instruction_0); 4785} 4786 4787 4788000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI 4789"tlti r<RS>, <IMMEDIATE>" 4790*mipsII: 4791*mipsIII: 4792*mipsIV: 4793*mipsV: 4794*mips32: 4795*mips32r2: 4796*mips64: 4797*mips64r2: 4798*vr4100: 4799*vr5000: 4800{ 4801 do_tlti (SD_, RS, IMMEDIATE, instruction_0); 4802} 4803 4804 4805000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU 4806"tltiu r<RS>, <IMMEDIATE>" 4807*mipsII: 4808*mipsIII: 4809*mipsIV: 4810*mipsV: 4811*mips32: 4812*mips32r2: 4813*mips64: 4814*mips64r2: 4815*vr4100: 4816*vr5000: 4817{ 4818 do_tltiu (SD_, RS, IMMEDIATE, instruction_0); 4819} 4820 4821 4822000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU 4823"tltu r<RS>, r<RT>" 4824*mipsII: 4825*mipsIII: 4826*mipsIV: 4827*mipsV: 4828*mips32: 4829*mips32r2: 4830*mips64: 4831*mips64r2: 4832*vr4100: 4833*vr5000: 4834{ 4835 do_tltu (SD_, RS, RT, instruction_0); 4836} 4837 4838 4839000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE 4840"tne r<RS>, r<RT>" 4841*mipsII: 4842*mipsIII: 4843*mipsIV: 4844*mipsV: 4845*mips32: 4846*mips32r2: 4847*mips64: 4848*mips64r2: 4849*vr4100: 4850*vr5000: 4851{ 4852 do_tne (SD_, RS, RT, instruction_0); 4853} 4854 4855 4856000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI 4857"tnei r<RS>, <IMMEDIATE>" 4858*mipsII: 4859*mipsIII: 4860*mipsIV: 4861*mipsV: 4862*mips32: 4863*mips32r2: 4864*mips64: 4865*mips64r2: 4866*vr4100: 4867*vr5000: 4868{ 4869 do_tnei (SD_, RS, IMMEDIATE, instruction_0); 4870} 4871 4872 4873:function:::void:do_xor:int rs, int rt, int rd 4874{ 4875 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); 4876 GPR[rd] = GPR[rs] ^ GPR[rt]; 4877 TRACE_ALU_RESULT (GPR[rd]); 4878} 4879 4880000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR 4881"xor r<RD>, r<RS>, r<RT>" 4882*mipsI: 4883*mipsII: 4884*mipsIII: 4885*mipsIV: 4886*mipsV: 4887*mips32: 4888*mips32r2: 4889*mips64: 4890*mips64r2: 4891*vr4100: 4892*vr5000: 4893*r3900: 4894{ 4895 do_xor (SD_, RS, RT, RD); 4896} 4897 4898 4899:function:::void:do_xori:int rs, int rt, unsigned16 immediate 4900{ 4901 TRACE_ALU_INPUT2 (GPR[rs], immediate); 4902 GPR[rt] = GPR[rs] ^ immediate; 4903 TRACE_ALU_RESULT (GPR[rt]); 4904} 4905 4906001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI 4907"xori r<RT>, r<RS>, %#lx<IMMEDIATE>" 4908*mipsI: 4909*mipsII: 4910*mipsIII: 4911*mipsIV: 4912*mipsV: 4913*mips32: 4914*mips32r2: 4915*mips64: 4916*mips64r2: 4917*vr4100: 4918*vr5000: 4919*r3900: 4920{ 4921 do_xori (SD_, RS, RT, IMMEDIATE); 4922} 4923 4924 4925// 4926// MIPS Architecture: 4927// 4928// FPU Instruction Set (COP1 & COP1X) 4929// 4930 4931 4932:%s::::FMT:int fmt 4933{ 4934 switch (fmt) 4935 { 4936 case fmt_single: return "s"; 4937 case fmt_double: return "d"; 4938 case fmt_word: return "w"; 4939 case fmt_long: return "l"; 4940 case fmt_ps: return "ps"; 4941 default: return "?"; 4942 } 4943} 4944 4945:%s::::TF:int tf 4946{ 4947 if (tf) 4948 return "t"; 4949 else 4950 return "f"; 4951} 4952 4953:%s::::ND:int nd 4954{ 4955 if (nd) 4956 return "l"; 4957 else 4958 return ""; 4959} 4960 4961:%s::::COND:int cond 4962{ 4963 switch (cond) 4964 { 4965 case 00: return "f"; 4966 case 01: return "un"; 4967 case 02: return "eq"; 4968 case 03: return "ueq"; 4969 case 04: return "olt"; 4970 case 05: return "ult"; 4971 case 06: return "ole"; 4972 case 07: return "ule"; 4973 case 010: return "sf"; 4974 case 011: return "ngle"; 4975 case 012: return "seq"; 4976 case 013: return "ngl"; 4977 case 014: return "lt"; 4978 case 015: return "nge"; 4979 case 016: return "le"; 4980 case 017: return "ngt"; 4981 default: return "?"; 4982 } 4983} 4984 4985 4986// Helpers: 4987// 4988// Check that the given FPU format is usable, and signal a 4989// ReservedInstruction exception if not. 4990// 4991 4992// check_fmt_p checks that the format is single, double, or paired single. 4993:function:::void:check_fmt_p:int fmt, instruction_word insn 4994*mipsI: 4995*mipsII: 4996*mipsIII: 4997*mipsIV: 4998*mips32: 4999*vr4100: 5000*vr5000: 5001*r3900: 5002{ 5003 /* None of these ISAs support Paired Single, so just fall back to 5004 the single/double check. */ 5005 if ((fmt != fmt_single) && (fmt != fmt_double)) 5006 SignalException (ReservedInstruction, insn); 5007} 5008 5009:function:::void:check_fmt_p:int fmt, instruction_word insn 5010*mips32r2: 5011*micromips32: 5012{ 5013 if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps)) 5014 SignalException (ReservedInstruction, insn); 5015} 5016 5017:function:::void:check_fmt_p:int fmt, instruction_word insn 5018*mipsV: 5019*mips64: 5020*mips64r2: 5021*micromips64: 5022{ 5023 if ((fmt != fmt_single) && (fmt != fmt_double) 5024 && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0))) 5025 SignalException (ReservedInstruction, insn); 5026} 5027 5028 5029// Helper: 5030// 5031// Check that the FPU is currently usable, and signal a CoProcessorUnusable 5032// exception if not. 5033// 5034 5035:function:::void:check_fpu: 5036*mipsI: 5037*mipsII: 5038*mipsIII: 5039*mipsIV: 5040*mipsV: 5041*mips32: 5042*mips32r2: 5043*mips64: 5044*mips64r2: 5045*vr4100: 5046*vr5000: 5047*r3900: 5048*micromips32: 5049*micromips64: 5050{ 5051 if (! COP_Usable (1)) 5052 SignalExceptionCoProcessorUnusable (1); 5053} 5054 5055 5056// Helper: 5057// 5058// Load a double word FP value using 2 32-bit memory cycles a la MIPS II 5059// or MIPS32. do_load cannot be used instead because it returns an 5060// unsigned_word, which is limited to the size of the machine's registers. 5061// 5062 5063:function:::unsigned64:do_load_double:address_word base, address_word offset 5064*mipsII: 5065*mips32: 5066*mips32r2: 5067*micromips32: 5068{ 5069 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); 5070 address_word vaddr; 5071 address_word paddr; 5072 unsigned64 memval; 5073 unsigned64 v; 5074 5075 paddr = vaddr = loadstore_ea (SD_, base, offset); 5076 if ((vaddr & AccessLength_DOUBLEWORD) != 0) 5077 { 5078 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, 5079 AccessLength_DOUBLEWORD + 1, vaddr, read_transfer, 5080 sim_core_unaligned_signal); 5081 } 5082 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, isREAL); 5083 v = (unsigned64)memval; 5084 LoadMemory (&memval, NULL, AccessLength_WORD, paddr + 4, vaddr + 4, isDATA, 5085 isREAL); 5086 return (bigendian ? ((v << 32) | memval) : (v | (memval << 32))); 5087} 5088 5089 5090// Helper: 5091// 5092// Store a double word FP value using 2 32-bit memory cycles a la MIPS II 5093// or MIPS32. do_load cannot be used instead because it returns an 5094// unsigned_word, which is limited to the size of the machine's registers. 5095// 5096 5097:function:::void:do_store_double:address_word base, address_word offset, unsigned64 v 5098*mipsII: 5099*mips32: 5100*mips32r2: 5101*micromips32: 5102{ 5103 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); 5104 address_word vaddr; 5105 address_word paddr; 5106 unsigned64 memval; 5107 5108 paddr = vaddr = loadstore_ea (SD_, base, offset); 5109 if ((vaddr & AccessLength_DOUBLEWORD) != 0) 5110 { 5111 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, 5112 AccessLength_DOUBLEWORD + 1, vaddr, write_transfer, 5113 sim_core_unaligned_signal); 5114 } 5115 memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF)); 5116 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, isREAL); 5117 memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32)); 5118 StoreMemory (AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, isREAL); 5119} 5120 5121 5122010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt 5123"abs.%s<FMT> f<FD>, f<FS>" 5124*mipsI: 5125*mipsII: 5126*mipsIII: 5127*mipsIV: 5128*mipsV: 5129*mips32: 5130*mips32r2: 5131*mips64: 5132*mips64r2: 5133*vr4100: 5134*vr5000: 5135*r3900: 5136{ 5137 do_abs_fmt (SD_, FMT, FD, FS, instruction_0); 5138} 5139 5140 5141 5142010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt 5143"add.%s<FMT> f<FD>, f<FS>, f<FT>" 5144*mipsI: 5145*mipsII: 5146*mipsIII: 5147*mipsIV: 5148*mipsV: 5149*mips32: 5150*mips32r2: 5151*mips64: 5152*mips64r2: 5153*vr4100: 5154*vr5000: 5155*r3900: 5156{ 5157 do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0); 5158} 5159 5160 5161010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:32,f::ALNV.PS 5162"alnv.ps f<FD>, f<FS>, f<FT>, r<RS>" 5163*mipsV: 5164*mips32r2: 5165*mips64: 5166*mips64r2: 5167{ 5168 do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0); 5169} 5170 5171 5172// BC1F 5173// BC1FL 5174// BC1T 5175// BC1TL 5176 5177010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a 5178"bc1%s<TF>%s<ND> <OFFSET>" 5179*mipsI: 5180*mipsII: 5181*mipsIII: 5182{ 5183 check_fpu (SD_); 5184 TRACE_BRANCH_INPUT (PREVCOC1()); 5185 if (PREVCOC1() == TF) 5186 { 5187 address_word dest = NIA + (EXTEND16 (OFFSET) << 2); 5188 TRACE_BRANCH_RESULT (dest); 5189 DELAY_SLOT (dest); 5190 } 5191 else if (ND) 5192 { 5193 TRACE_BRANCH_RESULT (0); 5194 NULLIFY_NEXT_INSTRUCTION (); 5195 } 5196 else 5197 { 5198 TRACE_BRANCH_RESULT (NIA); 5199 } 5200} 5201 5202010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b 5203"bc1%s<TF>%s<ND> <OFFSET>":CC == 0 5204"bc1%s<TF>%s<ND> <CC>, <OFFSET>" 5205*mipsIV: 5206*mipsV: 5207*mips32: 5208*mips32r2: 5209*mips64: 5210*mips64r2: 5211#*vr4100: 5212*vr5000: 5213*r3900: 5214{ 5215 check_fpu (SD_); 5216 if (GETFCC(CC) == TF) 5217 { 5218 address_word dest = NIA + (EXTEND16 (OFFSET) << 2); 5219 DELAY_SLOT (dest); 5220 } 5221 else if (ND) 5222 { 5223 NULLIFY_NEXT_INSTRUCTION (); 5224 } 5225} 5226 5227 5228010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta 5229"c.%s<COND>.%s<FMT> f<FS>, f<FT>" 5230*mipsI: 5231*mipsII: 5232*mipsIII: 5233{ 5234 int fmt = FMT; 5235 check_fpu (SD_); 5236 Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0); 5237 TRACE_ALU_RESULT (ValueFCR (31)); 5238} 5239 5240010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb 5241"c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0 5242"c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>" 5243*mipsIV: 5244*mipsV: 5245*mips32: 5246*mips32r2: 5247*mips64: 5248*mips64r2: 5249*vr4100: 5250*vr5000: 5251*r3900: 5252{ 5253 do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0); 5254} 5255 5256 5257010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001010:COP1:32,f::CEIL.L.fmt 5258"ceil.l.%s<FMT> f<FD>, f<FS>" 5259*mipsIII: 5260*mipsIV: 5261*mipsV: 5262*mips32r2: 5263*mips64: 5264*mips64r2: 5265*vr4100: 5266*vr5000: 5267*r3900: 5268{ 5269 do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0); 5270} 5271 5272 5273010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W 5274"ceil.w.%s<FMT> f<FD>, f<FS>" 5275*mipsII: 5276*mipsIII: 5277*mipsIV: 5278*mipsV: 5279*mips32: 5280*mips32r2: 5281*mips64: 5282*mips64r2: 5283*vr4100: 5284*vr5000: 5285*r3900: 5286{ 5287 do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0); 5288} 5289 5290 5291010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a 5292"cfc1 r<RT>, f<FS>" 5293*mipsI: 5294*mipsII: 5295*mipsIII: 5296{ 5297 check_fpu (SD_); 5298 if (FS == 0) 5299 PENDING_FILL (RT, EXTEND32 (FCR0)); 5300 else if (FS == 31) 5301 PENDING_FILL (RT, EXTEND32 (FCR31)); 5302 /* else NOP */ 5303} 5304 5305010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b 5306"cfc1 r<RT>, f<FS>" 5307*mipsIV: 5308*vr4100: 5309*vr5000: 5310*r3900: 5311{ 5312 check_fpu (SD_); 5313 if (FS == 0 || FS == 31) 5314 { 5315 unsigned_word fcr = ValueFCR (FS); 5316 TRACE_ALU_INPUT1 (fcr); 5317 GPR[RT] = fcr; 5318 } 5319 /* else NOP */ 5320 TRACE_ALU_RESULT (GPR[RT]); 5321} 5322 5323010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c 5324"cfc1 r<RT>, f<FS>" 5325*mipsV: 5326*mips32: 5327*mips32r2: 5328*mips64: 5329*mips64r2: 5330{ 5331 do_cfc1 (SD_, RT, FS); 5332} 5333 5334010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a 5335"ctc1 r<RT>, f<FS>" 5336*mipsI: 5337*mipsII: 5338*mipsIII: 5339{ 5340 check_fpu (SD_); 5341 if (FS == 31) 5342 PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT])); 5343 /* else NOP */ 5344} 5345 5346010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b 5347"ctc1 r<RT>, f<FS>" 5348*mipsIV: 5349*vr4100: 5350*vr5000: 5351*r3900: 5352{ 5353 check_fpu (SD_); 5354 TRACE_ALU_INPUT1 (GPR[RT]); 5355 if (FS == 31) 5356 StoreFCR (FS, GPR[RT]); 5357 /* else NOP */ 5358} 5359 5360010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c 5361"ctc1 r<RT>, f<FS>" 5362*mipsV: 5363*mips32: 5364*mips32r2: 5365*mips64: 5366*mips64r2: 5367{ 5368 do_ctc1 (SD_, RT, FS); 5369} 5370 5371 5372// 5373// FIXME: Does not correctly differentiate between mips* 5374// 5375010001,10,3.FMT!1!2!3!6!7,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt 5376"cvt.d.%s<FMT> f<FD>, f<FS>" 5377*mipsI: 5378*mipsII: 5379*mipsIII: 5380*mipsIV: 5381*mipsV: 5382*mips32: 5383*mips32r2: 5384*mips64: 5385*mips64r2: 5386*vr4100: 5387*vr5000: 5388*r3900: 5389{ 5390 do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0); 5391} 5392 5393 5394010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100101:COP1:32,f::CVT.L.fmt 5395"cvt.l.%s<FMT> f<FD>, f<FS>" 5396*mipsIII: 5397*mipsIV: 5398*mipsV: 5399*mips32r2: 5400*mips64: 5401*mips64r2: 5402*vr4100: 5403*vr5000: 5404*r3900: 5405{ 5406 do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0); 5407} 5408 5409 5410010001,10,000,5.FT,5.FS,5.FD,100110:COP1:32,f::CVT.PS.S 5411"cvt.ps.s f<FD>, f<FS>, f<FT>" 5412*mipsV: 5413*mips32r2: 5414*mips64: 5415*mips64r2: 5416{ 5417 do_cvt_ps_s (SD_, FD, FS, FT, instruction_0); 5418} 5419 5420 5421// 5422// FIXME: Does not correctly differentiate between mips* 5423// 5424010001,10,3.FMT!0!2!3!6!7,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt 5425"cvt.s.%s<FMT> f<FD>, f<FS>" 5426*mipsI: 5427*mipsII: 5428*mipsIII: 5429*mipsIV: 5430*mipsV: 5431*mips32: 5432*mips32r2: 5433*mips64: 5434*mips64r2: 5435*vr4100: 5436*vr5000: 5437*r3900: 5438{ 5439 do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0); 5440} 5441 5442 5443010001,10,110,00000,5.FS,5.FD,101000:COP1:32,f::CVT.S.PL 5444"cvt.s.pl f<FD>, f<FS>" 5445*mipsV: 5446*mips32r2: 5447*mips64: 5448*mips64r2: 5449{ 5450 do_cvt_s_pl (SD_, FD, FS, instruction_0); 5451} 5452 5453 5454010001,10,110,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.PU 5455"cvt.s.pu f<FD>, f<FS>" 5456*mipsV: 5457*mips32r2: 5458*mips64: 5459*mips64r2: 5460{ 5461 do_cvt_s_pu (SD_, FD, FS, instruction_0); 5462} 5463 5464 5465010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt 5466"cvt.w.%s<FMT> f<FD>, f<FS>" 5467*mipsI: 5468*mipsII: 5469*mipsIII: 5470*mipsIV: 5471*mipsV: 5472*mips32: 5473*mips32r2: 5474*mips64: 5475*mips64r2: 5476*vr4100: 5477*vr5000: 5478*r3900: 5479{ 5480 do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0); 5481} 5482 5483 5484010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt 5485"div.%s<FMT> f<FD>, f<FS>, f<FT>" 5486*mipsI: 5487*mipsII: 5488*mipsIII: 5489*mipsIV: 5490*mipsV: 5491*mips32: 5492*mips32r2: 5493*mips64: 5494*mips64r2: 5495*vr4100: 5496*vr5000: 5497*r3900: 5498{ 5499 do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0); 5500} 5501 5502 5503010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a 5504"dmfc1 r<RT>, f<FS>" 5505*mipsIII: 5506{ 5507 unsigned64 v; 5508 check_fpu (SD_); 5509 check_u64 (SD_, instruction_0); 5510 if (SizeFGR () == 64) 5511 v = FGR[FS]; 5512 else if ((FS & 0x1) == 0) 5513 v = SET64HI (FGR[FS+1]) | FGR[FS]; 5514 else 5515 v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; 5516 PENDING_FILL (RT, v); 5517 TRACE_ALU_RESULT (v); 5518} 5519 5520010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b 5521"dmfc1 r<RT>, f<FS>" 5522*mipsIV: 5523*mipsV: 5524*mips64: 5525*mips64r2: 5526*vr4100: 5527*vr5000: 5528*r3900: 5529{ 5530 check_fpu (SD_); 5531 check_u64 (SD_, instruction_0); 5532 do_dmfc1b (SD_, RT, FS); 5533} 5534 5535 5536010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a 5537"dmtc1 r<RT>, f<FS>" 5538*mipsIII: 5539{ 5540 unsigned64 v; 5541 check_fpu (SD_); 5542 check_u64 (SD_, instruction_0); 5543 if (SizeFGR () == 64) 5544 PENDING_FILL ((FS + FGR_BASE), GPR[RT]); 5545 else if ((FS & 0x1) == 0) 5546 { 5547 PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT])); 5548 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT])); 5549 } 5550 else 5551 Unpredictable (); 5552 TRACE_FP_RESULT (GPR[RT]); 5553} 5554 5555010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b 5556"dmtc1 r<RT>, f<FS>" 5557*mipsIV: 5558*mipsV: 5559*mips64: 5560*mips64r2: 5561*vr4100: 5562*vr5000: 5563*r3900: 5564{ 5565 check_fpu (SD_); 5566 check_u64 (SD_, instruction_0); 5567 do_dmtc1b (SD_, RT, FS); 5568} 5569 5570 5571010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001011:COP1:32,f::FLOOR.L.fmt 5572"floor.l.%s<FMT> f<FD>, f<FS>" 5573*mipsIII: 5574*mipsIV: 5575*mipsV: 5576*mips32r2: 5577*mips64: 5578*mips64r2: 5579*vr4100: 5580*vr5000: 5581*r3900: 5582{ 5583 do_floor_fmt (SD_, fmt_long, FMT, FD, FS); 5584} 5585 5586 5587010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt 5588"floor.w.%s<FMT> f<FD>, f<FS>" 5589*mipsII: 5590*mipsIII: 5591*mipsIV: 5592*mipsV: 5593*mips32: 5594*mips32r2: 5595*mips64: 5596*mips64r2: 5597*vr4100: 5598*vr5000: 5599*r3900: 5600{ 5601 do_floor_fmt (SD_, fmt_word, FMT, FD, FS); 5602} 5603 5604 5605110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a 5606"ldc1 f<FT>, <OFFSET>(r<BASE>)" 5607*mipsII: 5608*mips32: 5609*mips32r2: 5610{ 5611 check_fpu (SD_); 5612 COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET))); 5613} 5614 5615 5616110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b 5617"ldc1 f<FT>, <OFFSET>(r<BASE>)" 5618*mipsIII: 5619*mipsIV: 5620*mipsV: 5621*mips64: 5622*mips64r2: 5623*vr4100: 5624*vr5000: 5625*r3900: 5626{ 5627 check_fpu (SD_); 5628 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET))); 5629} 5630 5631 5632010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:32,f::LDXC1 5633"ldxc1 f<FD>, r<INDEX>(r<BASE>)" 5634*mips32r2: 5635{ 5636 check_fpu (SD_); 5637 COP_LD (1, FD, do_load_double (SD_, GPR[BASE], GPR[INDEX])); 5638} 5639 5640 5641010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1 5642"ldxc1 f<FD>, r<INDEX>(r<BASE>)" 5643*mipsIV: 5644*mipsV: 5645*mips64: 5646*mips64r2: 5647*vr5000: 5648{ 5649 check_fpu (SD_); 5650 check_u64 (SD_, instruction_0); 5651 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX])); 5652} 5653 5654 5655010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:32,f::LUXC1 5656"luxc1 f<FD>, r<INDEX>(r<BASE>)" 5657*mips32r2: 5658{ 5659 do_luxc1_32 (SD_, FD, INDEX, BASE); 5660} 5661 5662 5663010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64,f::LUXC1 5664"luxc1 f<FD>, r<INDEX>(r<BASE>)" 5665*mipsV: 5666*mips64: 5667*mips64r2: 5668{ 5669 check_fpu (SD_); 5670 check_u64 (SD_, instruction_0); 5671 do_luxc1_64 (SD_, FD, INDEX, BASE); 5672} 5673 5674 5675110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1 5676"lwc1 f<FT>, <OFFSET>(r<BASE>)" 5677*mipsI: 5678*mipsII: 5679*mipsIII: 5680*mipsIV: 5681*mipsV: 5682*mips32: 5683*mips32r2: 5684*mips64: 5685*mips64r2: 5686*vr4100: 5687*vr5000: 5688*r3900: 5689{ 5690 do_lwc1 (SD_, FT, OFFSET, BASE); 5691} 5692 5693 5694010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32,f::LWXC1 5695"lwxc1 f<FD>, r<INDEX>(r<BASE>)" 5696*mipsIV: 5697*mipsV: 5698*mips32r2: 5699*mips64: 5700*mips64r2: 5701*vr5000: 5702{ 5703 do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0); 5704} 5705 5706 5707 5708010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT!2!3!4!5!7:COP1X:32,f::MADD.fmt 5709"madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>" 5710*mipsIV: 5711*mipsV: 5712*mips32r2: 5713*mips64: 5714*mips64r2: 5715*vr5000: 5716{ 5717 do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0); 5718} 5719 5720 5721010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a 5722"mfc1 r<RT>, f<FS>" 5723*mipsI: 5724*mipsII: 5725*mipsIII: 5726{ 5727 unsigned64 v; 5728 check_fpu (SD_); 5729 v = EXTEND32 (FGR[FS]); 5730 PENDING_FILL (RT, v); 5731 TRACE_ALU_RESULT (v); 5732} 5733 5734010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b 5735"mfc1 r<RT>, f<FS>" 5736*mipsIV: 5737*mipsV: 5738*mips32: 5739*mips32r2: 5740*mips64: 5741*mips64r2: 5742*vr4100: 5743*vr5000: 5744*r3900: 5745{ 5746 do_mfc1b (SD_, RT, FS); 5747} 5748 5749 5750010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt 5751"mov.%s<FMT> f<FD>, f<FS>" 5752*mipsI: 5753*mipsII: 5754*mipsIII: 5755*mipsIV: 5756*mipsV: 5757*mips32: 5758*mips32r2: 5759*mips64: 5760*mips64r2: 5761*vr4100: 5762*vr5000: 5763*r3900: 5764{ 5765 do_mov_fmt (SD_, FMT, FD, FS, instruction_0); 5766} 5767 5768 5769// MOVF 5770// MOVT 5771000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf 5772"mov%s<TF> r<RD>, r<RS>, <CC>" 5773*mipsIV: 5774*mipsV: 5775*mips32: 5776*mips32r2: 5777*mips64: 5778*mips64r2: 5779*vr5000: 5780{ 5781 do_movtf (SD_, TF, RD, RS, CC); 5782} 5783 5784 5785// MOVF.fmt 5786// MOVT.fmt 5787010001,10,3.FMT!2!3!4!5!7,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt 5788"mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>" 5789*mipsIV: 5790*mipsV: 5791*mips32: 5792*mips32r2: 5793*mips64: 5794*mips64r2: 5795*vr5000: 5796{ 5797 do_movtf_fmt (SD_, TF, FMT, FD, FS, CC); 5798} 5799 5800 5801010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt 5802"movn.%s<FMT> f<FD>, f<FS>, r<RT>" 5803*mipsIV: 5804*mipsV: 5805*mips32: 5806*mips32r2: 5807*mips64: 5808*mips64r2: 5809*vr5000: 5810{ 5811 do_movn_fmt (SD_, FMT, FD, FS, RT); 5812} 5813 5814 5815// MOVT see MOVtf 5816 5817 5818// MOVT.fmt see MOVtf.fmt 5819 5820 5821 5822010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt 5823"movz.%s<FMT> f<FD>, f<FS>, r<RT>" 5824*mipsIV: 5825*mipsV: 5826*mips32: 5827*mips32r2: 5828*mips64: 5829*mips64r2: 5830*vr5000: 5831{ 5832 do_movz_fmt (SD_, FMT, FD, FS, RT); 5833} 5834 5835 5836010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT!2!3!4!5!7:COP1X:32,f::MSUB.fmt 5837"msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>" 5838*mipsIV: 5839*mipsV: 5840*mips32r2: 5841*mips64: 5842*mips64r2: 5843*vr5000: 5844{ 5845 do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0); 5846} 5847 5848 5849010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a 5850"mtc1 r<RT>, f<FS>" 5851*mipsI: 5852*mipsII: 5853*mipsIII: 5854{ 5855 check_fpu (SD_); 5856 if (SizeFGR () == 64) 5857 PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT]))); 5858 else 5859 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT])); 5860 TRACE_FP_RESULT (GPR[RT]); 5861} 5862 5863010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b 5864"mtc1 r<RT>, f<FS>" 5865*mipsIV: 5866*mipsV: 5867*mips32: 5868*mips32r2: 5869*mips64: 5870*mips64r2: 5871*vr4100: 5872*vr5000: 5873*r3900: 5874{ 5875 do_mtc1b (SD_, RT, FS); 5876} 5877 5878 5879010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt 5880"mul.%s<FMT> f<FD>, f<FS>, f<FT>" 5881*mipsI: 5882*mipsII: 5883*mipsIII: 5884*mipsIV: 5885*mipsV: 5886*mips32: 5887*mips32r2: 5888*mips64: 5889*mips64r2: 5890*vr4100: 5891*vr5000: 5892*r3900: 5893{ 5894 do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0); 5895} 5896 5897 5898010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt 5899"neg.%s<FMT> f<FD>, f<FS>" 5900*mipsI: 5901*mipsII: 5902*mipsIII: 5903*mipsIV: 5904*mipsV: 5905*mips32: 5906*mips32r2: 5907*mips64: 5908*mips64r2: 5909*vr4100: 5910*vr5000: 5911*r3900: 5912{ 5913 do_neg_fmt (SD_, FMT, FD, FS, instruction_0); 5914} 5915 5916 5917010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT!2!3!4!5!7:COP1X:32,f::NMADD.fmt 5918"nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>" 5919*mipsIV: 5920*mipsV: 5921*mips32r2: 5922*mips64: 5923*mips64r2: 5924*vr5000: 5925{ 5926 do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0); 5927} 5928 5929 5930010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT!2!3!4!5!7:COP1X:32,f::NMSUB.fmt 5931"nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>" 5932*mipsIV: 5933*mipsV: 5934*mips32r2: 5935*mips64: 5936*mips64r2: 5937*vr5000: 5938{ 5939 do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0); 5940} 5941 5942 5943010001,10,110,5.FT,5.FS,5.FD,101100:COP1:32,f::PLL.PS 5944"pll.ps f<FD>, f<FS>, f<FT>" 5945*mipsV: 5946*mips32r2: 5947*mips64: 5948*mips64r2: 5949{ 5950 do_pll_ps (SD_, FD, FS, FT, instruction_0); 5951} 5952 5953 5954010001,10,110,5.FT,5.FS,5.FD,101101:COP1:32,f::PLU.PS 5955"plu.ps f<FD>, f<FS>, f<FT>" 5956*mipsV: 5957*mips32r2: 5958*mips64: 5959*mips64r2: 5960{ 5961 do_plu_ps (SD_, FD, FS, FT, instruction_0); 5962} 5963 5964 5965010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:32::PREFX 5966"prefx <HINT>, r<INDEX>(r<BASE>)" 5967*mipsIV: 5968*mipsV: 5969*mips32r2: 5970*mips64: 5971*mips64r2: 5972*vr5000: 5973{ 5974 do_prefx (SD_, HINT, INDEX, BASE); 5975} 5976 5977 5978010001,10,110,5.FT,5.FS,5.FD,101110:COP1:32,f::PUL.PS 5979"pul.ps f<FD>, f<FS>, f<FT>" 5980*mipsV: 5981*mips32r2: 5982*mips64: 5983*mips64r2: 5984{ 5985 do_pul_ps (SD_, FD, FS, FT, instruction_0); 5986} 5987 5988 5989010001,10,110,5.FT,5.FS,5.FD,101111:COP1:32,f::PUU.PS 5990"puu.ps f<FD>, f<FS>, f<FT>" 5991*mipsV: 5992*mips32r2: 5993*mips64: 5994*mips64r2: 5995{ 5996 do_puu_ps (SD_, FD, FS, FT, instruction_0); 5997} 5998 5999 6000010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt 6001"recip.%s<FMT> f<FD>, f<FS>" 6002*mipsIV: 6003*mipsV: 6004*mips32r2: 6005*mips64: 6006*mips64r2: 6007*vr5000: 6008{ 6009 do_recip_fmt (SD_, FMT, FD, FS); 6010} 6011 6012 6013010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001000:COP1:32,f::ROUND.L.fmt 6014"round.l.%s<FMT> f<FD>, f<FS>" 6015*mipsIII: 6016*mipsIV: 6017*mipsV: 6018*mips32r2: 6019*mips64: 6020*mips64r2: 6021*vr4100: 6022*vr5000: 6023*r3900: 6024{ 6025 do_round_fmt (SD_, fmt_long, FMT, FD, FS); 6026} 6027 6028 6029010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt 6030"round.w.%s<FMT> f<FD>, f<FS>" 6031*mipsII: 6032*mipsIII: 6033*mipsIV: 6034*mipsV: 6035*mips32: 6036*mips32r2: 6037*mips64: 6038*mips64r2: 6039*vr4100: 6040*vr5000: 6041*r3900: 6042{ 6043 do_round_fmt (SD_, fmt_word, FMT, FD, FS); 6044} 6045 6046 6047010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt 6048"rsqrt.%s<FMT> f<FD>, f<FS>" 6049*mipsIV: 6050*mipsV: 6051*mips32r2: 6052*mips64: 6053*mips64r2: 6054*vr5000: 6055{ 6056 do_rsqrt_fmt (SD_, FMT, FD, FS); 6057} 6058 6059 6060111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a 6061"sdc1 f<FT>, <OFFSET>(r<BASE>)" 6062*mipsII: 6063*mips32: 6064*mips32r2: 6065{ 6066 do_sdc1 (SD_, FT, OFFSET, BASE); 6067} 6068 6069 6070111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b 6071"sdc1 f<FT>, <OFFSET>(r<BASE>)" 6072*mipsIII: 6073*mipsIV: 6074*mipsV: 6075*mips64: 6076*mips64r2: 6077*vr4100: 6078*vr5000: 6079*r3900: 6080{ 6081 check_fpu (SD_); 6082 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT)); 6083} 6084 6085 6086010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:32,f::SDXC1 6087"sdxc1 f<FS>, r<INDEX>(r<BASE>)" 6088*mips32r2 6089{ 6090 check_fpu (SD_); 6091 do_store_double (SD_, GPR[BASE], GPR[INDEX], COP_SD (1, FS)); 6092} 6093 6094 6095010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1 6096"sdxc1 f<FS>, r<INDEX>(r<BASE>)" 6097*mipsIV: 6098*mipsV: 6099*mips64: 6100*mips64r2: 6101*vr5000: 6102{ 6103 check_fpu (SD_); 6104 check_u64 (SD_, instruction_0); 6105 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS)); 6106} 6107 6108 6109010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:32,f::SUXC1 6110"suxc1 f<FS>, r<INDEX>(r<BASE>)" 6111*mips32r2: 6112{ 6113 do_suxc1_32 (SD_, FS, INDEX, BASE); 6114} 6115 6116 6117010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64,f::SUXC1 6118"suxc1 f<FS>, r<INDEX>(r<BASE>)" 6119*mipsV: 6120*mips64: 6121*mips64r2: 6122{ 6123 check_fpu (SD_); 6124 check_u64 (SD_, instruction_0); 6125 do_suxc1_64 (SD_, FS, INDEX, BASE); 6126} 6127 6128 6129010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt 6130"sqrt.%s<FMT> f<FD>, f<FS>" 6131*mipsII: 6132*mipsIII: 6133*mipsIV: 6134*mipsV: 6135*mips32: 6136*mips32r2: 6137*mips64: 6138*mips64r2: 6139*vr4100: 6140*vr5000: 6141*r3900: 6142{ 6143 do_sqrt_fmt (SD_, FMT, FD, FS); 6144} 6145 6146 6147010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt 6148"sub.%s<FMT> f<FD>, f<FS>, f<FT>" 6149*mipsI: 6150*mipsII: 6151*mipsIII: 6152*mipsIV: 6153*mipsV: 6154*mips32: 6155*mips32r2: 6156*mips64: 6157*mips64r2: 6158*vr4100: 6159*vr5000: 6160*r3900: 6161{ 6162 do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0); 6163} 6164 6165 6166 6167111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1 6168"swc1 f<FT>, <OFFSET>(r<BASE>)" 6169*mipsI: 6170*mipsII: 6171*mipsIII: 6172*mipsIV: 6173*mipsV: 6174*mips32: 6175*mips32r2: 6176*mips64: 6177*mips64r2: 6178*vr4100: 6179*vr5000: 6180*r3900: 6181{ 6182 do_swc1 (SD_, FT, OFFSET, BASE, instruction_0); 6183} 6184 6185 6186010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1 6187"swxc1 f<FS>, r<INDEX>(r<BASE>)" 6188*mipsIV: 6189*mipsV: 6190*mips32r2: 6191*mips64: 6192*mips64r2: 6193*vr5000: 6194{ 6195 do_swxc1 (SD_, FS, INDEX, BASE, instruction_0); 6196} 6197 6198 6199010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001001:COP1:32,f::TRUNC.L.fmt 6200"trunc.l.%s<FMT> f<FD>, f<FS>" 6201*mipsIII: 6202*mipsIV: 6203*mipsV: 6204*mips32r2: 6205*mips64: 6206*mips64r2: 6207*vr4100: 6208*vr5000: 6209*r3900: 6210{ 6211 do_trunc_fmt (SD_, fmt_long, FMT, FD, FS); 6212} 6213 6214 6215010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W 6216"trunc.w.%s<FMT> f<FD>, f<FS>" 6217*mipsII: 6218*mipsIII: 6219*mipsIV: 6220*mipsV: 6221*mips32: 6222*mips32r2: 6223*mips64: 6224*mips64r2: 6225*vr4100: 6226*vr5000: 6227*r3900: 6228{ 6229 do_trunc_fmt (SD_, fmt_word, FMT, FD, FS); 6230} 6231 6232 6233// 6234// MIPS Architecture: 6235// 6236// System Control Instruction Set (COP0) 6237// 6238 6239 6240010000,01000,00000,16.OFFSET:COP0:32::BC0F 6241"bc0f <OFFSET>" 6242*mipsI: 6243*mipsII: 6244*mipsIII: 6245*mipsIV: 6246*mipsV: 6247*mips32: 6248*mips32r2: 6249*mips64: 6250*mips64r2: 6251*vr4100: 6252*vr5000: 6253 6254010000,01000,00000,16.OFFSET:COP0:32::BC0F 6255"bc0f <OFFSET>" 6256// stub needed for eCos as tx39 hardware bug workaround 6257*r3900: 6258{ 6259 /* do nothing */ 6260} 6261 6262 6263010000,01000,00010,16.OFFSET:COP0:32::BC0FL 6264"bc0fl <OFFSET>" 6265*mipsI: 6266*mipsII: 6267*mipsIII: 6268*mipsIV: 6269*mipsV: 6270*mips32: 6271*mips32r2: 6272*mips64: 6273*mips64r2: 6274*vr4100: 6275*vr5000: 6276 6277 6278010000,01000,00001,16.OFFSET:COP0:32::BC0T 6279"bc0t <OFFSET>" 6280*mipsI: 6281*mipsII: 6282*mipsIII: 6283*mipsIV: 6284*mipsV: 6285*mips32: 6286*mips32r2: 6287*mips64: 6288*mips64r2: 6289*vr4100: 6290 6291 6292010000,01000,00011,16.OFFSET:COP0:32::BC0TL 6293"bc0tl <OFFSET>" 6294*mipsI: 6295*mipsII: 6296*mipsIII: 6297*mipsIV: 6298*mipsV: 6299*mips32: 6300*mips32r2: 6301*mips64: 6302*mips64r2: 6303*vr4100: 6304*vr5000: 6305 6306 6307101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE 6308"cache <OP>, <OFFSET>(r<BASE>)" 6309*mipsIII: 6310*mipsIV: 6311*mipsV: 6312*mips32: 6313*mips32r2: 6314*mips64: 6315*mips64r2: 6316*vr4100: 6317*vr5000: 6318*r3900: 6319{ 6320 address_word base = GPR[BASE]; 6321 address_word offset = EXTEND16 (OFFSET); 6322 { 6323 address_word vaddr = loadstore_ea (SD_, base, offset); 6324 address_word paddr = vaddr; 6325 CacheOp(OP, vaddr, paddr, instruction_0); 6326 } 6327} 6328 6329 6330010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0 6331"dmfc0 r<RT>, r<RD>" 6332*mipsIII: 6333*mipsIV: 6334*mipsV: 6335*mips64: 6336*mips64r2: 6337{ 6338 check_u64 (SD_, instruction_0); 6339 DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL); 6340} 6341 6342 6343010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0 6344"dmtc0 r<RT>, r<RD>" 6345*mipsIII: 6346*mipsIV: 6347*mipsV: 6348*mips64: 6349*mips64r2: 6350{ 6351 check_u64 (SD_, instruction_0); 6352 DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL); 6353} 6354 6355 6356010000,1,0000000000000000000,011000:COP0:32::ERET 6357"eret" 6358*mipsIII: 6359*mipsIV: 6360*mipsV: 6361*mips32: 6362*mips32r2: 6363*mips64: 6364*mips64r2: 6365*vr4100: 6366*vr5000: 6367{ 6368 if (SR & status_ERL) 6369 { 6370 /* Oops, not yet available */ 6371 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported"); 6372 NIA = EPC; 6373 SR &= ~status_ERL; 6374 } 6375 else 6376 { 6377 NIA = EPC; 6378 SR &= ~status_EXL; 6379 } 6380} 6381 6382 6383010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0 6384"mfc0 r<RT>, r<RD> # <SEL>" 6385*mipsI: 6386*mipsII: 6387*mipsIII: 6388*mipsIV: 6389*mipsV: 6390*mips32: 6391*mips32r2: 6392*mips64: 6393*mips64r2: 6394*vr4100: 6395*vr5000: 6396*r3900: 6397{ 6398 TRACE_ALU_INPUT0 (); 6399 DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL); 6400 TRACE_ALU_RESULT (GPR[RT]); 6401} 6402 6403010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0 6404"mtc0 r<RT>, r<RD> # <SEL>" 6405*mipsI: 6406*mipsII: 6407*mipsIII: 6408*mipsIV: 6409*mipsV: 6410*mips32: 6411*mips32r2: 6412*mips64: 6413*mips64r2: 6414*vr4100: 6415*vr5000: 6416*r3900: 6417{ 6418 DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL); 6419} 6420 6421 6422010000,1,0000000000000000000,010000:COP0:32::RFE 6423"rfe" 6424*mipsI: 6425*mipsII: 6426*mipsIII: 6427*mipsIV: 6428*mipsV: 6429*vr4100: 6430*vr5000: 6431*r3900: 6432{ 6433 DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10); 6434} 6435 6436 64370100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz 6438"cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>" 6439*mipsI: 6440*mipsII: 6441*mipsIII: 6442*mipsIV: 6443*mipsV: 6444*mips32: 6445*mips32r2: 6446*mips64: 6447*mips64r2: 6448*vr4100: 6449*r3900: 6450{ 6451 DecodeCoproc (instruction_0, 2, 0, 0, 0, 0); 6452} 6453 6454 6455 6456010000,1,0000000000000000000,001000:COP0:32::TLBP 6457"tlbp" 6458*mipsI: 6459*mipsII: 6460*mipsIII: 6461*mipsIV: 6462*mipsV: 6463*mips32: 6464*mips32r2: 6465*mips64: 6466*mips64r2: 6467*vr4100: 6468*vr5000: 6469 6470 6471010000,1,0000000000000000000,000001:COP0:32::TLBR 6472"tlbr" 6473*mipsI: 6474*mipsII: 6475*mipsIII: 6476*mipsIV: 6477*mipsV: 6478*mips32: 6479*mips32r2: 6480*mips64: 6481*mips64r2: 6482*vr4100: 6483*vr5000: 6484 6485 6486010000,1,0000000000000000000,000010:COP0:32::TLBWI 6487"tlbwi" 6488*mipsI: 6489*mipsII: 6490*mipsIII: 6491*mipsIV: 6492*mipsV: 6493*mips32: 6494*mips32r2: 6495*mips64: 6496*mips64r2: 6497*vr4100: 6498*vr5000: 6499 6500 6501010000,1,0000000000000000000,000110:COP0:32::TLBWR 6502"tlbwr" 6503*mipsI: 6504*mipsII: 6505*mipsIII: 6506*mipsIV: 6507*mipsV: 6508*mips32: 6509*mips32r2: 6510*mips64: 6511*mips64r2: 6512*vr4100: 6513*vr5000: 6514 6515 6516:include:::mips3264r2.igen 6517:include:::m16.igen 6518:include:::m16e.igen 6519:include:::mdmx.igen 6520:include:::mips3d.igen 6521:include:::sb1.igen 6522:include:::tx.igen 6523:include:::vr.igen 6524:include:::dsp.igen 6525:include:::dsp2.igen 6526:include:::smartmips.igen 6527:include:::micromips.igen 6528:include:::micromipsdsp.igen 6529 6530