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