Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: src/mips64/simulator-mips64.cc

Issue 1356693002: MIPS64: Optimize simulator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix nit. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips64/simulator-mips64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits.h> 5 #include <limits.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <cmath> 8 #include <cmath>
9 9
10 #if V8_TARGET_ARCH_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 902
903 // The sp is initialized to point to the bottom (high address) of the 903 // The sp is initialized to point to the bottom (high address) of the
904 // allocated stack area. To be safe in potential stack underflows we leave 904 // allocated stack area. To be safe in potential stack underflows we leave
905 // some buffer below. 905 // some buffer below.
906 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64; 906 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64;
907 // The ra and pc are initialized to a known bad value that will cause an 907 // The ra and pc are initialized to a known bad value that will cause an
908 // access violation if the simulator ever tries to execute it. 908 // access violation if the simulator ever tries to execute it.
909 registers_[pc] = bad_ra; 909 registers_[pc] = bad_ra;
910 registers_[ra] = bad_ra; 910 registers_[ra] = bad_ra;
911 InitializeCoverage(); 911 InitializeCoverage();
912 for (int i = 0; i < kNumExceptions; i++) {
913 exceptions[i] = 0;
914 }
915 912
916 last_debugger_input_ = NULL; 913 last_debugger_input_ = NULL;
917 } 914 }
918 915
919 916
920 Simulator::~Simulator() { free(stack_); } 917 Simulator::~Simulator() { free(stack_); }
921 918
922 919
923 // When the generated code calls an external reference we need to catch that in 920 // When the generated code calls an external reference we need to catch that in
924 // the simulator. The external reference will be a function compiled for the 921 // the simulator. The external reference will be a function compiled for the
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i, \t%s\n", 2165 PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i, \t%s\n",
2169 code, code, state, count, watched_stops_[code].desc); 2166 code, code, state, count, watched_stops_[code].desc);
2170 } else { 2167 } else {
2171 PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i\n", 2168 PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i\n",
2172 code, code, state, count); 2169 code, code, state, count);
2173 } 2170 }
2174 } 2171 }
2175 } 2172 }
2176 2173
2177 2174
2178 void Simulator::SignalExceptions() { 2175 void Simulator::SignalException(Exception e) {
2179 for (int i = 1; i < kNumExceptions; i++) { 2176 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.",
2180 if (exceptions[i] != 0) { 2177 static_cast<int>(e));
2181 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
2182 }
2183 }
2184 } 2178 }
2185 2179
2186 2180
2187 // Handle execution based on instruction types. 2181 // Handle execution based on instruction types.
2188 2182
2189 void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out, 2183 void Simulator::DecodeTypeRegisterSRsType() {
2190 int64_t* i64hilo, uint64_t* u64hilo,
2191 int64_t* next_pc, int* return_addr_reg,
2192 bool* do_interrupt, int64_t* i128resultH,
2193 int64_t* i128resultL) {
2194 // Every local variable declared here needs to be const.
2195 // This is to make sure that changed values are sent back to
2196 // DecodeTypeRegister correctly.
2197
2198 // Instruction fields.
2199 const Opcode op = instr->OpcodeFieldRaw();
2200 const int32_t rs_reg = instr->RsValue();
2201 const int64_t rs = get_register(rs_reg);
2202 const uint64_t rs_u = static_cast<uint64_t>(rs);
2203 const int32_t rt_reg = instr->RtValue();
2204 const int64_t rt = get_register(rt_reg);
2205 const uint64_t rt_u = static_cast<uint64_t>(rt);
2206 const int32_t rd_reg = instr->RdValue();
2207 const uint64_t sa = instr->SaValue();
2208 const uint8_t bp2 = instr->Bp2Value();
2209 const uint8_t bp3 = instr->Bp3Value();
2210
2211 const int32_t fs_reg = instr->FsValue();
2212
2213
2214 // ---------- Configuration.
2215 switch (op) {
2216 case COP1: // Coprocessor instructions.
2217 switch (instr->RsFieldRaw()) {
2218 case CFC1:
2219 // At the moment only FCSR is supported.
2220 DCHECK(fs_reg == kFCSRRegister);
2221 *alu_out = FCSR_;
2222 break;
2223 case MFC1:
2224 *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg));
2225 break;
2226 case DMFC1:
2227 *alu_out = get_fpu_register(fs_reg);
2228 break;
2229 case MFHC1:
2230 *alu_out = get_fpu_register_hi_word(fs_reg);
2231 break;
2232 case CTC1:
2233 case MTC1:
2234 case DMTC1:
2235 case MTHC1:
2236 case S:
2237 case D:
2238 case W:
2239 case L:
2240 case PS:
2241 // Do everything in the execution step.
2242 break;
2243 default:
2244 // BC1 BC1EQZ BC1NEZ handled in DecodeTypeImmed, should never come here.
2245 UNREACHABLE();
2246 }
2247 break;
2248 case COP1X:
2249 break;
2250 case SPECIAL:
2251 switch (instr->FunctionFieldRaw()) {
2252 case JR:
2253 case JALR:
2254 *next_pc = get_register(instr->RsValue());
2255 *return_addr_reg = instr->RdValue();
2256 break;
2257 case SLL:
2258 *alu_out = static_cast<int32_t>(rt) << sa;
2259 break;
2260 case DSLL:
2261 *alu_out = rt << sa;
2262 break;
2263 case DSLL32:
2264 *alu_out = rt << sa << 32;
2265 break;
2266 case SRL:
2267 if (rs_reg == 0) {
2268 // Regular logical right shift of a word by a fixed number of
2269 // bits instruction. RS field is always equal to 0.
2270 // Sign-extend the 32-bit result.
2271 *alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u) >> sa);
2272 } else {
2273 // Logical right-rotate of a word by a fixed number of bits. This
2274 // is special case of SRL instruction, added in MIPS32 Release 2.
2275 // RS field is equal to 00001.
2276 *alu_out = static_cast<int32_t>(
2277 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u),
2278 static_cast<const uint32_t>(sa)));
2279 }
2280 break;
2281 case DSRL:
2282 *alu_out = rt_u >> sa;
2283 break;
2284 case DSRL32:
2285 *alu_out = rt_u >> sa >> 32;
2286 break;
2287 case SRA:
2288 *alu_out = (int32_t)rt >> sa;
2289 break;
2290 case DSRA:
2291 *alu_out = rt >> sa;
2292 break;
2293 case DSRA32:
2294 *alu_out = rt >> sa >> 32;
2295 break;
2296 case SLLV:
2297 *alu_out = (int32_t)rt << rs;
2298 break;
2299 case DSLLV:
2300 *alu_out = rt << rs;
2301 break;
2302 case SRLV:
2303 if (sa == 0) {
2304 // Regular logical right-shift of a word by a variable number of
2305 // bits instruction. SA field is always equal to 0.
2306 *alu_out = static_cast<int32_t>((uint32_t)rt_u >> rs);
2307 } else {
2308 // Logical right-rotate of a word by a variable number of bits.
2309 // This is special case od SRLV instruction, added in MIPS32
2310 // Release 2. SA field is equal to 00001.
2311 *alu_out = static_cast<int32_t>(
2312 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u),
2313 static_cast<const uint32_t>(rs_u)));
2314 }
2315 break;
2316 case DSRLV:
2317 if (sa == 0) {
2318 // Regular logical right-shift of a word by a variable number of
2319 // bits instruction. SA field is always equal to 0.
2320 *alu_out = rt_u >> rs;
2321 } else {
2322 // Logical right-rotate of a word by a variable number of bits.
2323 // This is special case od SRLV instruction, added in MIPS32
2324 // Release 2. SA field is equal to 00001.
2325 *alu_out =
2326 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u),
2327 static_cast<const uint32_t>(rs_u));
2328 }
2329 break;
2330 case SRAV:
2331 *alu_out = (int32_t)rt >> rs;
2332 break;
2333 case DSRAV:
2334 *alu_out = rt >> rs;
2335 break;
2336 case MFHI: // MFHI == CLZ on R6.
2337 if (kArchVariant != kMips64r6) {
2338 DCHECK(instr->SaValue() == 0);
2339 *alu_out = get_register(HI);
2340 } else {
2341 // MIPS spec: If no bits were set in GPR rs, the result written to
2342 // GPR rd is 32.
2343 DCHECK(instr->SaValue() == 1);
2344 *alu_out =
2345 base::bits::CountLeadingZeros32(static_cast<int32_t>(rs_u));
2346 }
2347 break;
2348 case MFLO:
2349 *alu_out = get_register(LO);
2350 break;
2351 case MULT: { // MULT == D_MUL_MUH.
2352 int32_t rs_lo = static_cast<int32_t>(rs);
2353 int32_t rt_lo = static_cast<int32_t>(rt);
2354 *i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo);
2355 break;
2356 }
2357 case MULTU:
2358 *u64hilo = static_cast<uint64_t>(rs_u & 0xffffffff) *
2359 static_cast<uint64_t>(rt_u & 0xffffffff);
2360 break;
2361 case DMULT: // DMULT == D_MUL_MUH.
2362 if (kArchVariant != kMips64r6) {
2363 *i128resultH = MultiplyHighSigned(rs, rt);
2364 *i128resultL = rs * rt;
2365 } else {
2366 switch (instr->SaValue()) {
2367 case MUL_OP:
2368 *i128resultL = rs * rt;
2369 break;
2370 case MUH_OP:
2371 *i128resultH = MultiplyHighSigned(rs, rt);
2372 break;
2373 default:
2374 UNIMPLEMENTED_MIPS();
2375 break;
2376 }
2377 }
2378 break;
2379 case DMULTU:
2380 UNIMPLEMENTED_MIPS();
2381 break;
2382 case ADD:
2383 case DADD:
2384 if (HaveSameSign(rs, rt)) {
2385 if (rs > 0) {
2386 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
2387 } else if (rs < 0) {
2388 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
2389 }
2390 }
2391 *alu_out = rs + rt;
2392 break;
2393 case ADDU: {
2394 int32_t alu32_out = static_cast<int32_t>(rs + rt);
2395 // Sign-extend result of 32bit operation into 64bit register.
2396 *alu_out = static_cast<int64_t>(alu32_out);
2397 break;
2398 }
2399 case DADDU:
2400 *alu_out = rs + rt;
2401 break;
2402 case SUB:
2403 case DSUB:
2404 if (!HaveSameSign(rs, rt)) {
2405 if (rs > 0) {
2406 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
2407 } else if (rs < 0) {
2408 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
2409 }
2410 }
2411 *alu_out = rs - rt;
2412 break;
2413 case SUBU: {
2414 int32_t alu32_out = static_cast<int32_t>(rs - rt);
2415 // Sign-extend result of 32bit operation into 64bit register.
2416 *alu_out = static_cast<int64_t>(alu32_out);
2417 break;
2418 }
2419 case DSUBU:
2420 *alu_out = rs - rt;
2421 break;
2422 case AND:
2423 *alu_out = rs & rt;
2424 break;
2425 case OR:
2426 *alu_out = rs | rt;
2427 break;
2428 case XOR:
2429 *alu_out = rs ^ rt;
2430 break;
2431 case NOR:
2432 *alu_out = ~(rs | rt);
2433 break;
2434 case SLT:
2435 *alu_out = rs < rt ? 1 : 0;
2436 break;
2437 case SLTU:
2438 *alu_out = rs_u < rt_u ? 1 : 0;
2439 break;
2440 // Break and trap instructions.
2441 case BREAK:
2442
2443 *do_interrupt = true;
2444 break;
2445 case TGE:
2446 *do_interrupt = rs >= rt;
2447 break;
2448 case TGEU:
2449 *do_interrupt = rs_u >= rt_u;
2450 break;
2451 case TLT:
2452 *do_interrupt = rs < rt;
2453 break;
2454 case TLTU:
2455 *do_interrupt = rs_u < rt_u;
2456 break;
2457 case TEQ:
2458 *do_interrupt = rs == rt;
2459 break;
2460 case TNE:
2461 *do_interrupt = rs != rt;
2462 break;
2463 case MOVN:
2464 case MOVZ:
2465 case MOVCI:
2466 // No action taken on decode.
2467 break;
2468 case DIV:
2469 case DIVU:
2470 case DDIV:
2471 case DDIVU:
2472 // div and divu never raise exceptions.
2473 break;
2474 case SELEQZ_S:
2475 case SELNEZ_S:
2476 break;
2477 default:
2478 UNREACHABLE();
2479 }
2480 break;
2481 case SPECIAL2:
2482 switch (instr->FunctionFieldRaw()) {
2483 case MUL:
2484 // Only the lower 32 bits are kept.
2485 *alu_out = (int32_t)rs_u * (int32_t)rt_u;
2486 break;
2487 case CLZ:
2488 // MIPS32 spec: If no bits were set in GPR rs, the result written to
2489 // GPR rd is 32.
2490 *alu_out =
2491 base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u));
2492 break;
2493 default:
2494 UNREACHABLE();
2495 }
2496 break;
2497 case SPECIAL3:
2498 switch (instr->FunctionFieldRaw()) {
2499 case INS: { // Mips32r2 instruction.
2500 // Interpret rd field as 5-bit msb of insert.
2501 uint16_t msb = rd_reg;
2502 // Interpret sa field as 5-bit lsb of insert.
2503 uint16_t lsb = sa;
2504 uint16_t size = msb - lsb + 1;
2505 uint64_t mask = (1ULL << size) - 1;
2506 *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
2507 break;
2508 }
2509 case EXT: { // Mips32r2 instruction.
2510 // Interpret rd field as 5-bit msb of extract.
2511 uint16_t msb = rd_reg;
2512 // Interpret sa field as 5-bit lsb of extract.
2513 uint16_t lsb = sa;
2514 uint16_t size = msb + 1;
2515 uint64_t mask = (1ULL << size) - 1;
2516 *alu_out = static_cast<int32_t>((rs_u & (mask << lsb)) >> lsb);
2517 break;
2518 }
2519 case DEXT: { // Mips32r2 instruction.
2520 // Interpret rd field as 5-bit msb of extract.
2521 uint16_t msb = rd_reg;
2522 // Interpret sa field as 5-bit lsb of extract.
2523 uint16_t lsb = sa;
2524 uint16_t size = msb + 1;
2525 uint64_t mask = (1ULL << size) - 1;
2526 *alu_out = static_cast<int64_t>((rs_u & (mask << lsb)) >> lsb);
2527 break;
2528 }
2529 case BSHFL: {
2530 int sa = instr->SaFieldRaw() >> kSaShift;
2531 switch (sa) {
2532 case BITSWAP: {
2533 uint32_t input = static_cast<uint32_t>(rt);
2534 uint32_t output = 0;
2535 uint8_t i_byte, o_byte;
2536
2537 // Reverse the bit in byte for each individual byte
2538 for (int i = 0; i < 4; i++) {
2539 output = output >> 8;
2540 i_byte = input & 0xff;
2541
2542 // Fast way to reverse bits in byte
2543 // Devised by Sean Anderson, July 13, 2001
2544 o_byte =
2545 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
2546 (i_byte * 0x8020LU & 0x88440LU)) *
2547 0x10101LU >>
2548 16);
2549
2550 output = output | (static_cast<uint32_t>(o_byte << 24));
2551 input = input >> 8;
2552 }
2553
2554 *alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
2555 break;
2556 }
2557 case SEB:
2558 case SEH:
2559 case WSBH:
2560 UNREACHABLE();
2561 break;
2562 default: {
2563 sa >>= kBp2Bits;
2564 switch (sa) {
2565 case ALIGN: {
2566 if (bp2 == 0) {
2567 *alu_out = static_cast<int32_t>(rt);
2568 } else {
2569 uint64_t rt_hi = rt << (8 * bp2);
2570 uint64_t rs_lo = rs >> (8 * (4 - bp2));
2571 *alu_out = static_cast<int32_t>(rt_hi | rs_lo);
2572 }
2573 break;
2574 }
2575 default:
2576 UNREACHABLE();
2577 break;
2578 }
2579 break;
2580 }
2581 }
2582 break;
2583 }
2584 case DBSHFL: {
2585 int sa = instr->SaFieldRaw() >> kSaShift;
2586 switch (sa) {
2587 case DBITSWAP: {
2588 switch (instr->SaFieldRaw() >> kSaShift) {
2589 case DBITSWAP_SA: { // Mips64r6
2590 uint64_t input = static_cast<uint64_t>(rt);
2591 uint64_t output = 0;
2592 uint8_t i_byte, o_byte;
2593
2594 // Reverse the bit in byte for each individual byte
2595 for (int i = 0; i < 8; i++) {
2596 output = output >> 8;
2597 i_byte = input & 0xff;
2598
2599 // Fast way to reverse bits in byte
2600 // Devised by Sean Anderson, July 13, 2001
2601 o_byte =
2602 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
2603 (i_byte * 0x8020LU & 0x88440LU)) *
2604 0x10101LU >>
2605 16);
2606
2607 output = output | ((static_cast<uint64_t>(o_byte) << 56));
2608 input = input >> 8;
2609 }
2610
2611 *alu_out = static_cast<int64_t>(output);
2612 break;
2613 }
2614 }
2615 break;
2616 }
2617 case DSBH:
2618 case DSHD:
2619 UNREACHABLE();
2620 break;
2621 default: {
2622 sa >>= kBp3Bits;
2623 switch (sa) {
2624 case DALIGN: {
2625 if (bp3 == 0) {
2626 *alu_out = static_cast<int64_t>(rt);
2627 } else {
2628 uint64_t rt_hi = rt << (8 * bp3);
2629 uint64_t rs_lo = rs >> (8 * (8 - bp3));
2630 *alu_out = static_cast<int64_t>(rt_hi | rs_lo);
2631 }
2632 break;
2633 }
2634 default:
2635 UNREACHABLE();
2636 break;
2637 }
2638 break;
2639 }
2640 }
2641 break;
2642 }
2643 default:
2644 UNREACHABLE();
2645 }
2646 break;
2647 default:
2648 UNREACHABLE();
2649 }
2650 }
2651
2652
2653 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr,
2654 const int32_t fs_reg,
2655 const int32_t ft_reg,
2656 const int32_t fd_reg) {
2657 float fs, ft, fd; 2184 float fs, ft, fd;
2658 fs = get_fpu_register_float(fs_reg); 2185 fs = get_fpu_register_float(fs_reg());
2659 ft = get_fpu_register_float(ft_reg); 2186 ft = get_fpu_register_float(ft_reg());
2660 fd = get_fpu_register_float(fd_reg); 2187 fd = get_fpu_register_float(fd_reg());
2661 int32_t ft_int = bit_cast<int32_t>(ft); 2188 int32_t ft_int = bit_cast<int32_t>(ft);
2662 int32_t fd_int = bit_cast<int32_t>(fd); 2189 int32_t fd_int = bit_cast<int32_t>(fd);
2663 uint32_t cc, fcsr_cc; 2190 uint32_t cc, fcsr_cc;
2664 cc = instr->FCccValue(); 2191 cc = get_instr()->FCccValue();
2665 fcsr_cc = get_fcsr_condition_bit(cc); 2192 fcsr_cc = get_fcsr_condition_bit(cc);
2666 switch (instr->FunctionFieldRaw()) { 2193 switch (get_instr()->FunctionFieldRaw()) {
2667 case RINT: { 2194 case RINT: {
2668 DCHECK(kArchVariant == kMips64r6); 2195 DCHECK(kArchVariant == kMips64r6);
2669 float result, temp_result; 2196 float result, temp_result;
2670 double temp; 2197 double temp;
2671 float upper = std::ceil(fs); 2198 float upper = std::ceil(fs);
2672 float lower = std::floor(fs); 2199 float lower = std::floor(fs);
2673 switch (get_fcsr_rounding_mode()) { 2200 switch (get_fcsr_rounding_mode()) {
2674 case kRoundToNearest: 2201 case kRoundToNearest:
2675 if (upper - fs < fs - lower) { 2202 if (upper - fs < fs - lower) {
2676 result = upper; 2203 result = upper;
(...skipping 12 matching lines...) Expand all
2689 case kRoundToZero: 2216 case kRoundToZero:
2690 result = (fs > 0 ? lower : upper); 2217 result = (fs > 0 ? lower : upper);
2691 break; 2218 break;
2692 case kRoundToPlusInf: 2219 case kRoundToPlusInf:
2693 result = upper; 2220 result = upper;
2694 break; 2221 break;
2695 case kRoundToMinusInf: 2222 case kRoundToMinusInf:
2696 result = lower; 2223 result = lower;
2697 break; 2224 break;
2698 } 2225 }
2699 set_fpu_register_float(fd_reg, result); 2226 set_fpu_register_float(fd_reg(), result);
2700 if (result != fs) { 2227 if (result != fs) {
2701 set_fcsr_bit(kFCSRInexactFlagBit, true); 2228 set_fcsr_bit(kFCSRInexactFlagBit, true);
2702 } 2229 }
2703 break; 2230 break;
2704 } 2231 }
2705 case ADD_S: 2232 case ADD_S:
2706 set_fpu_register_float(fd_reg, fs + ft); 2233 set_fpu_register_float(fd_reg(), fs + ft);
2707 break; 2234 break;
2708 case SUB_S: 2235 case SUB_S:
2709 set_fpu_register_float(fd_reg, fs - ft); 2236 set_fpu_register_float(fd_reg(), fs - ft);
2710 break; 2237 break;
2711 case MUL_S: 2238 case MUL_S:
2712 set_fpu_register_float(fd_reg, fs * ft); 2239 set_fpu_register_float(fd_reg(), fs * ft);
2713 break; 2240 break;
2714 case DIV_S: 2241 case DIV_S:
2715 set_fpu_register_float(fd_reg, fs / ft); 2242 set_fpu_register_float(fd_reg(), fs / ft);
2716 break; 2243 break;
2717 case ABS_S: 2244 case ABS_S:
2718 set_fpu_register_float(fd_reg, fabs(fs)); 2245 set_fpu_register_float(fd_reg(), fabs(fs));
2719 break; 2246 break;
2720 case MOV_S: 2247 case MOV_S:
2721 set_fpu_register_float(fd_reg, fs); 2248 set_fpu_register_float(fd_reg(), fs);
2722 break; 2249 break;
2723 case NEG_S: 2250 case NEG_S:
2724 set_fpu_register_float(fd_reg, -fs); 2251 set_fpu_register_float(fd_reg(), -fs);
2725 break; 2252 break;
2726 case SQRT_S: 2253 case SQRT_S:
2727 set_fpu_register_float(fd_reg, fast_sqrt(fs)); 2254 set_fpu_register_float(fd_reg(), fast_sqrt(fs));
2728 break; 2255 break;
2729 case RSQRT_S: { 2256 case RSQRT_S: {
2730 float result = 1.0 / fast_sqrt(fs); 2257 float result = 1.0 / fast_sqrt(fs);
2731 set_fpu_register_float(fd_reg, result); 2258 set_fpu_register_float(fd_reg(), result);
2732 break; 2259 break;
2733 } 2260 }
2734 case RECIP_S: { 2261 case RECIP_S: {
2735 float result = 1.0 / fs; 2262 float result = 1.0 / fs;
2736 set_fpu_register_float(fd_reg, result); 2263 set_fpu_register_float(fd_reg(), result);
2737 break; 2264 break;
2738 } 2265 }
2739 case C_F_D: 2266 case C_F_D:
2740 set_fcsr_bit(fcsr_cc, false); 2267 set_fcsr_bit(fcsr_cc, false);
2741 break; 2268 break;
2742 case C_UN_D: 2269 case C_UN_D:
2743 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2270 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2744 break; 2271 break;
2745 case C_EQ_D: 2272 case C_EQ_D:
2746 set_fcsr_bit(fcsr_cc, (fs == ft)); 2273 set_fcsr_bit(fcsr_cc, (fs == ft));
2747 break; 2274 break;
2748 case C_UEQ_D: 2275 case C_UEQ_D:
2749 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2276 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2750 break; 2277 break;
2751 case C_OLT_D: 2278 case C_OLT_D:
2752 set_fcsr_bit(fcsr_cc, (fs < ft)); 2279 set_fcsr_bit(fcsr_cc, (fs < ft));
2753 break; 2280 break;
2754 case C_ULT_D: 2281 case C_ULT_D:
2755 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 2282 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
2756 break; 2283 break;
2757 case C_OLE_D: 2284 case C_OLE_D:
2758 set_fcsr_bit(fcsr_cc, (fs <= ft)); 2285 set_fcsr_bit(fcsr_cc, (fs <= ft));
2759 break; 2286 break;
2760 case C_ULE_D: 2287 case C_ULE_D:
2761 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2288 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2762 break; 2289 break;
2763 case CVT_D_S: 2290 case CVT_D_S:
2764 set_fpu_register_double(fd_reg, static_cast<double>(fs)); 2291 set_fpu_register_double(fd_reg(), static_cast<double>(fs));
2765 break; 2292 break;
2766 case CLASS_S: { // Mips64r6 instruction 2293 case CLASS_S: { // Mips64r6 instruction
2767 // Convert float input to uint32_t for easier bit manipulation 2294 // Convert float input to uint32_t for easier bit manipulation
2768 uint32_t classed = bit_cast<uint32_t>(fs); 2295 uint32_t classed = bit_cast<uint32_t>(fs);
2769 2296
2770 // Extracting sign, exponent and mantissa from the input float 2297 // Extracting sign, exponent and mantissa from the input float
2771 uint32_t sign = (classed >> 31) & 1; 2298 uint32_t sign = (classed >> 31) & 1;
2772 uint32_t exponent = (classed >> 23) & 0x000000ff; 2299 uint32_t exponent = (classed >> 23) & 0x000000ff;
2773 uint32_t mantissa = classed & 0x007fffff; 2300 uint32_t mantissa = classed & 0x007fffff;
2774 uint32_t result; 2301 uint32_t result;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 } 2344 }
2818 2345
2819 // Calculating result according to description of CLASS.S instruction 2346 // Calculating result according to description of CLASS.S instruction
2820 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 2347 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
2821 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 2348 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
2822 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 2349 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
2823 2350
2824 DCHECK(result != 0); 2351 DCHECK(result != 0);
2825 2352
2826 fResult = bit_cast<float>(result); 2353 fResult = bit_cast<float>(result);
2827 set_fpu_register_float(fd_reg, fResult); 2354 set_fpu_register_float(fd_reg(), fResult);
2828 2355
2829 break; 2356 break;
2830 } 2357 }
2831 case CVT_L_S: { 2358 case CVT_L_S: {
2832 float rounded; 2359 float rounded;
2833 int64_t result; 2360 int64_t result;
2834 round64_according_to_fcsr(fs, rounded, result, fs); 2361 round64_according_to_fcsr(fs, rounded, result, fs);
2835 set_fpu_register(fd_reg, result); 2362 set_fpu_register(fd_reg(), result);
2836 if (set_fcsr_round64_error(fs, rounded)) { 2363 if (set_fcsr_round64_error(fs, rounded)) {
2837 set_fpu_register(fd_reg, kFPU64InvalidResult); 2364 set_fpu_register(fd_reg(), kFPU64InvalidResult);
2838 } 2365 }
2839 break; 2366 break;
2840 } 2367 }
2841 case CVT_W_S: { 2368 case CVT_W_S: {
2842 float rounded; 2369 float rounded;
2843 int32_t result; 2370 int32_t result;
2844 round_according_to_fcsr(fs, rounded, result, fs); 2371 round_according_to_fcsr(fs, rounded, result, fs);
2845 set_fpu_register_word(fd_reg, result); 2372 set_fpu_register_word(fd_reg(), result);
2846 if (set_fcsr_round_error(fs, rounded)) { 2373 if (set_fcsr_round_error(fs, rounded)) {
2847 set_fpu_register_word(fd_reg, kFPUInvalidResult); 2374 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
2848 } 2375 }
2849 break; 2376 break;
2850 } 2377 }
2851 case TRUNC_W_S: { // Truncate single to word (round towards 0). 2378 case TRUNC_W_S: { // Truncate single to word (round towards 0).
2852 float rounded = trunc(fs); 2379 float rounded = trunc(fs);
2853 int32_t result = static_cast<int32_t>(rounded); 2380 int32_t result = static_cast<int32_t>(rounded);
2854 set_fpu_register_word(fd_reg, result); 2381 set_fpu_register_word(fd_reg(), result);
2855 if (set_fcsr_round_error(fs, rounded)) { 2382 if (set_fcsr_round_error(fs, rounded)) {
2856 set_fpu_register_word(fd_reg, kFPUInvalidResult); 2383 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
2857 } 2384 }
2858 } break; 2385 } break;
2859 case TRUNC_L_S: { // Mips64r2 instruction. 2386 case TRUNC_L_S: { // Mips64r2 instruction.
2860 float rounded = trunc(fs); 2387 float rounded = trunc(fs);
2861 int64_t result = static_cast<int64_t>(rounded); 2388 int64_t result = static_cast<int64_t>(rounded);
2862 set_fpu_register(fd_reg, result); 2389 set_fpu_register(fd_reg(), result);
2863 if (set_fcsr_round64_error(fs, rounded)) { 2390 if (set_fcsr_round64_error(fs, rounded)) {
2864 set_fpu_register(fd_reg, kFPU64InvalidResult); 2391 set_fpu_register(fd_reg(), kFPU64InvalidResult);
2865 } 2392 }
2866 break; 2393 break;
2867 } 2394 }
2868 case ROUND_W_S: { 2395 case ROUND_W_S: {
2869 float rounded = std::floor(fs + 0.5); 2396 float rounded = std::floor(fs + 0.5);
2870 int32_t result = static_cast<int32_t>(rounded); 2397 int32_t result = static_cast<int32_t>(rounded);
2871 if ((result & 1) != 0 && result - fs == 0.5) { 2398 if ((result & 1) != 0 && result - fs == 0.5) {
2872 // If the number is halfway between two integers, 2399 // If the number is halfway between two integers,
2873 // round to the even one. 2400 // round to the even one.
2874 result--; 2401 result--;
2875 } 2402 }
2876 set_fpu_register_word(fd_reg, result); 2403 set_fpu_register_word(fd_reg(), result);
2877 if (set_fcsr_round_error(fs, rounded)) { 2404 if (set_fcsr_round_error(fs, rounded)) {
2878 set_fpu_register_word(fd_reg, kFPUInvalidResult); 2405 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
2879 } 2406 }
2880 break; 2407 break;
2881 } 2408 }
2882 case ROUND_L_S: { // Mips64r2 instruction. 2409 case ROUND_L_S: { // Mips64r2 instruction.
2883 float rounded = std::floor(fs + 0.5); 2410 float rounded = std::floor(fs + 0.5);
2884 int64_t result = static_cast<int64_t>(rounded); 2411 int64_t result = static_cast<int64_t>(rounded);
2885 if ((result & 1) != 0 && result - fs == 0.5) { 2412 if ((result & 1) != 0 && result - fs == 0.5) {
2886 // If the number is halfway between two integers, 2413 // If the number is halfway between two integers,
2887 // round to the even one. 2414 // round to the even one.
2888 result--; 2415 result--;
2889 } 2416 }
2890 int64_t i64 = static_cast<int64_t>(result); 2417 int64_t i64 = static_cast<int64_t>(result);
2891 set_fpu_register(fd_reg, i64); 2418 set_fpu_register(fd_reg(), i64);
2892 if (set_fcsr_round64_error(fs, rounded)) { 2419 if (set_fcsr_round64_error(fs, rounded)) {
2893 set_fpu_register(fd_reg, kFPU64InvalidResult); 2420 set_fpu_register(fd_reg(), kFPU64InvalidResult);
2894 } 2421 }
2895 break; 2422 break;
2896 } 2423 }
2897 case FLOOR_L_S: { // Mips64r2 instruction. 2424 case FLOOR_L_S: { // Mips64r2 instruction.
2898 float rounded = floor(fs); 2425 float rounded = floor(fs);
2899 int64_t result = static_cast<int64_t>(rounded); 2426 int64_t result = static_cast<int64_t>(rounded);
2900 set_fpu_register(fd_reg, result); 2427 set_fpu_register(fd_reg(), result);
2901 if (set_fcsr_round64_error(fs, rounded)) { 2428 if (set_fcsr_round64_error(fs, rounded)) {
2902 set_fpu_register(fd_reg, kFPU64InvalidResult); 2429 set_fpu_register(fd_reg(), kFPU64InvalidResult);
2903 } 2430 }
2904 break; 2431 break;
2905 } 2432 }
2906 case FLOOR_W_S: // Round double to word towards negative infinity. 2433 case FLOOR_W_S: // Round double to word towards negative infinity.
2907 { 2434 {
2908 float rounded = std::floor(fs); 2435 float rounded = std::floor(fs);
2909 int32_t result = static_cast<int32_t>(rounded); 2436 int32_t result = static_cast<int32_t>(rounded);
2910 set_fpu_register_word(fd_reg, result); 2437 set_fpu_register_word(fd_reg(), result);
2911 if (set_fcsr_round_error(fs, rounded)) { 2438 if (set_fcsr_round_error(fs, rounded)) {
2912 set_fpu_register_word(fd_reg, kFPUInvalidResult); 2439 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
2913 } 2440 }
2914 } break; 2441 } break;
2915 case CEIL_W_S: // Round double to word towards positive infinity. 2442 case CEIL_W_S: // Round double to word towards positive infinity.
2916 { 2443 {
2917 float rounded = std::ceil(fs); 2444 float rounded = std::ceil(fs);
2918 int32_t result = static_cast<int32_t>(rounded); 2445 int32_t result = static_cast<int32_t>(rounded);
2919 set_fpu_register_word(fd_reg, result); 2446 set_fpu_register_word(fd_reg(), result);
2920 if (set_fcsr_round_error(fs, rounded)) { 2447 if (set_fcsr_round_error(fs, rounded)) {
2921 set_fpu_register(fd_reg, kFPUInvalidResult); 2448 set_fpu_register(fd_reg(), kFPUInvalidResult);
2922 } 2449 }
2923 } break; 2450 } break;
2924 case CEIL_L_S: { // Mips64r2 instruction. 2451 case CEIL_L_S: { // Mips64r2 instruction.
2925 float rounded = ceil(fs); 2452 float rounded = ceil(fs);
2926 int64_t result = static_cast<int64_t>(rounded); 2453 int64_t result = static_cast<int64_t>(rounded);
2927 set_fpu_register(fd_reg, result); 2454 set_fpu_register(fd_reg(), result);
2928 if (set_fcsr_round64_error(fs, rounded)) { 2455 if (set_fcsr_round64_error(fs, rounded)) {
2929 set_fpu_register(fd_reg, kFPU64InvalidResult); 2456 set_fpu_register(fd_reg(), kFPU64InvalidResult);
2930 } 2457 }
2931 break; 2458 break;
2932 } 2459 }
2933 case MINA: 2460 case MINA:
2934 DCHECK(kArchVariant == kMips64r6); 2461 DCHECK(kArchVariant == kMips64r6);
2935 fs = get_fpu_register_float(fs_reg); 2462 fs = get_fpu_register_float(fs_reg());
2936 if (std::isnan(fs) && std::isnan(ft)) { 2463 if (std::isnan(fs) && std::isnan(ft)) {
2937 set_fpu_register_float(fd_reg, fs); 2464 set_fpu_register_float(fd_reg(), fs);
2938 } else if (std::isnan(fs) && !std::isnan(ft)) { 2465 } else if (std::isnan(fs) && !std::isnan(ft)) {
2939 set_fpu_register_float(fd_reg, ft); 2466 set_fpu_register_float(fd_reg(), ft);
2940 } else if (!std::isnan(fs) && std::isnan(ft)) { 2467 } else if (!std::isnan(fs) && std::isnan(ft)) {
2941 set_fpu_register_float(fd_reg, fs); 2468 set_fpu_register_float(fd_reg(), fs);
2942 } else { 2469 } else {
2943 float result; 2470 float result;
2944 if (fabs(fs) > fabs(ft)) { 2471 if (fabs(fs) > fabs(ft)) {
2945 result = ft; 2472 result = ft;
2946 } else if (fabs(fs) < fabs(ft)) { 2473 } else if (fabs(fs) < fabs(ft)) {
2947 result = fs; 2474 result = fs;
2948 } else { 2475 } else {
2949 result = (fs > ft ? fs : ft); 2476 result = (fs > ft ? fs : ft);
2950 } 2477 }
2951 set_fpu_register_float(fd_reg, result); 2478 set_fpu_register_float(fd_reg(), result);
2952 } 2479 }
2953 break; 2480 break;
2954 case MAXA: 2481 case MAXA:
2955 DCHECK(kArchVariant == kMips64r6); 2482 DCHECK(kArchVariant == kMips64r6);
2956 fs = get_fpu_register_float(fs_reg); 2483 fs = get_fpu_register_float(fs_reg());
2957 if (std::isnan(fs) && std::isnan(ft)) { 2484 if (std::isnan(fs) && std::isnan(ft)) {
2958 set_fpu_register_float(fd_reg, fs); 2485 set_fpu_register_float(fd_reg(), fs);
2959 } else if (std::isnan(fs) && !std::isnan(ft)) { 2486 } else if (std::isnan(fs) && !std::isnan(ft)) {
2960 set_fpu_register_float(fd_reg, ft); 2487 set_fpu_register_float(fd_reg(), ft);
2961 } else if (!std::isnan(fs) && std::isnan(ft)) { 2488 } else if (!std::isnan(fs) && std::isnan(ft)) {
2962 set_fpu_register_float(fd_reg, fs); 2489 set_fpu_register_float(fd_reg(), fs);
2963 } else { 2490 } else {
2964 float result; 2491 float result;
2965 if (fabs(fs) < fabs(ft)) { 2492 if (fabs(fs) < fabs(ft)) {
2966 result = ft; 2493 result = ft;
2967 } else if (fabs(fs) > fabs(ft)) { 2494 } else if (fabs(fs) > fabs(ft)) {
2968 result = fs; 2495 result = fs;
2969 } else { 2496 } else {
2970 result = (fs > ft ? fs : ft); 2497 result = (fs > ft ? fs : ft);
2971 } 2498 }
2972 set_fpu_register_float(fd_reg, result); 2499 set_fpu_register_float(fd_reg(), result);
2973 } 2500 }
2974 break; 2501 break;
2975 case MIN: 2502 case MIN:
2976 DCHECK(kArchVariant == kMips64r6); 2503 DCHECK(kArchVariant == kMips64r6);
2977 fs = get_fpu_register_float(fs_reg); 2504 fs = get_fpu_register_float(fs_reg());
2978 if (std::isnan(fs) && std::isnan(ft)) { 2505 if (std::isnan(fs) && std::isnan(ft)) {
2979 set_fpu_register_float(fd_reg, fs); 2506 set_fpu_register_float(fd_reg(), fs);
2980 } else if (std::isnan(fs) && !std::isnan(ft)) { 2507 } else if (std::isnan(fs) && !std::isnan(ft)) {
2981 set_fpu_register_float(fd_reg, ft); 2508 set_fpu_register_float(fd_reg(), ft);
2982 } else if (!std::isnan(fs) && std::isnan(ft)) { 2509 } else if (!std::isnan(fs) && std::isnan(ft)) {
2983 set_fpu_register_float(fd_reg, fs); 2510 set_fpu_register_float(fd_reg(), fs);
2984 } else { 2511 } else {
2985 set_fpu_register_float(fd_reg, (fs >= ft) ? ft : fs); 2512 set_fpu_register_float(fd_reg(), (fs >= ft) ? ft : fs);
2986 } 2513 }
2987 break; 2514 break;
2988 case MAX: 2515 case MAX:
2989 DCHECK(kArchVariant == kMips64r6); 2516 DCHECK(kArchVariant == kMips64r6);
2990 fs = get_fpu_register_float(fs_reg); 2517 fs = get_fpu_register_float(fs_reg());
2991 if (std::isnan(fs) && std::isnan(ft)) { 2518 if (std::isnan(fs) && std::isnan(ft)) {
2992 set_fpu_register_float(fd_reg, fs); 2519 set_fpu_register_float(fd_reg(), fs);
2993 } else if (std::isnan(fs) && !std::isnan(ft)) { 2520 } else if (std::isnan(fs) && !std::isnan(ft)) {
2994 set_fpu_register_float(fd_reg, ft); 2521 set_fpu_register_float(fd_reg(), ft);
2995 } else if (!std::isnan(fs) && std::isnan(ft)) { 2522 } else if (!std::isnan(fs) && std::isnan(ft)) {
2996 set_fpu_register_float(fd_reg, fs); 2523 set_fpu_register_float(fd_reg(), fs);
2997 } else { 2524 } else {
2998 set_fpu_register_float(fd_reg, (fs <= ft) ? ft : fs); 2525 set_fpu_register_float(fd_reg(), (fs <= ft) ? ft : fs);
2999 } 2526 }
3000 break; 2527 break;
3001 case SEL: 2528 case SEL:
3002 DCHECK(kArchVariant == kMips64r6); 2529 DCHECK(kArchVariant == kMips64r6);
3003 set_fpu_register_float(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); 2530 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
3004 break; 2531 break;
3005 case SELEQZ_C: 2532 case SELEQZ_C:
3006 DCHECK(kArchVariant == kMips64r6); 2533 DCHECK(kArchVariant == kMips64r6);
3007 set_fpu_register_float( 2534 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0
3008 fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg) : 0.0); 2535 ? get_fpu_register_float(fs_reg())
2536 : 0.0);
3009 break; 2537 break;
3010 case SELNEZ_C: 2538 case SELNEZ_C:
3011 DCHECK(kArchVariant == kMips64r6); 2539 DCHECK(kArchVariant == kMips64r6);
3012 set_fpu_register_float( 2540 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0
3013 fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg) : 0.0); 2541 ? get_fpu_register_float(fs_reg())
2542 : 0.0);
3014 break; 2543 break;
3015 case MOVZ_C: { 2544 case MOVZ_C: {
3016 DCHECK(kArchVariant == kMips64r2); 2545 DCHECK(kArchVariant == kMips64r2);
3017 int32_t rt_reg = instr->RtValue(); 2546 if (rt() == 0) {
3018 int64_t rt = get_register(rt_reg); 2547 set_fpu_register_float(fd_reg(), fs);
3019 if (rt == 0) {
3020 set_fpu_register_float(fd_reg, fs);
3021 } 2548 }
3022 break; 2549 break;
3023 } 2550 }
3024 case MOVN_C: { 2551 case MOVN_C: {
3025 DCHECK(kArchVariant == kMips64r2); 2552 DCHECK(kArchVariant == kMips64r2);
3026 int32_t rt_reg = instr->RtValue(); 2553 if (rt() != 0) {
3027 int64_t rt = get_register(rt_reg); 2554 set_fpu_register_float(fd_reg(), fs);
3028 if (rt != 0) {
3029 set_fpu_register_float(fd_reg, fs);
3030 } 2555 }
3031 break; 2556 break;
3032 } 2557 }
3033 case MOVF: { 2558 case MOVF: {
3034 // Same function field for MOVT.D and MOVF.D 2559 // Same function field for MOVT.D and MOVF.D
3035 uint32_t ft_cc = (ft_reg >> 2) & 0x7; 2560 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
3036 ft_cc = get_fcsr_condition_bit(ft_cc); 2561 ft_cc = get_fcsr_condition_bit(ft_cc);
3037 2562
3038 if (instr->Bit(16)) { // Read Tf bit. 2563 if (get_instr()->Bit(16)) { // Read Tf bit.
3039 // MOVT.D 2564 // MOVT.D
3040 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs); 2565 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3041 } else { 2566 } else {
3042 // MOVF.D 2567 // MOVF.D
3043 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs); 2568 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3044 } 2569 }
3045 break; 2570 break;
3046 } 2571 }
3047 default: 2572 default:
3048 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 2573 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
3049 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. 2574 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
3050 UNREACHABLE(); 2575 UNREACHABLE();
3051 } 2576 }
3052 } 2577 }
3053 2578
3054 2579
3055 void Simulator::DecodeTypeRegisterDRsType(Instruction* instr, 2580 void Simulator::DecodeTypeRegisterDRsType() {
3056 const int32_t fs_reg,
3057 const int32_t ft_reg,
3058 const int32_t fd_reg) {
3059 double ft, fs, fd; 2581 double ft, fs, fd;
3060 uint32_t cc, fcsr_cc; 2582 uint32_t cc, fcsr_cc;
3061 fs = get_fpu_register_double(fs_reg); 2583 fs = get_fpu_register_double(fs_reg());
3062 ft = (instr->FunctionFieldRaw() != MOVF) ? get_fpu_register_double(ft_reg) 2584 ft = (get_instr()->FunctionFieldRaw() != MOVF)
3063 : 0.0; 2585 ? get_fpu_register_double(ft_reg())
3064 fd = get_fpu_register_double(fd_reg); 2586 : 0.0;
3065 cc = instr->FCccValue(); 2587 fd = get_fpu_register_double(fd_reg());
2588 cc = get_instr()->FCccValue();
3066 fcsr_cc = get_fcsr_condition_bit(cc); 2589 fcsr_cc = get_fcsr_condition_bit(cc);
3067 int64_t ft_int = bit_cast<int64_t>(ft); 2590 int64_t ft_int = bit_cast<int64_t>(ft);
3068 int64_t fd_int = bit_cast<int64_t>(fd); 2591 int64_t fd_int = bit_cast<int64_t>(fd);
3069 switch (instr->FunctionFieldRaw()) { 2592 switch (get_instr()->FunctionFieldRaw()) {
3070 case RINT: { 2593 case RINT: {
3071 DCHECK(kArchVariant == kMips64r6); 2594 DCHECK(kArchVariant == kMips64r6);
3072 double result, temp, temp_result; 2595 double result, temp, temp_result;
3073 double upper = std::ceil(fs); 2596 double upper = std::ceil(fs);
3074 double lower = std::floor(fs); 2597 double lower = std::floor(fs);
3075 switch (get_fcsr_rounding_mode()) { 2598 switch (get_fcsr_rounding_mode()) {
3076 case kRoundToNearest: 2599 case kRoundToNearest:
3077 if (upper - fs < fs - lower) { 2600 if (upper - fs < fs - lower) {
3078 result = upper; 2601 result = upper;
3079 } else if (upper - fs > fs - lower) { 2602 } else if (upper - fs > fs - lower) {
(...skipping 11 matching lines...) Expand all
3091 case kRoundToZero: 2614 case kRoundToZero:
3092 result = (fs > 0 ? lower : upper); 2615 result = (fs > 0 ? lower : upper);
3093 break; 2616 break;
3094 case kRoundToPlusInf: 2617 case kRoundToPlusInf:
3095 result = upper; 2618 result = upper;
3096 break; 2619 break;
3097 case kRoundToMinusInf: 2620 case kRoundToMinusInf:
3098 result = lower; 2621 result = lower;
3099 break; 2622 break;
3100 } 2623 }
3101 set_fpu_register_double(fd_reg, result); 2624 set_fpu_register_double(fd_reg(), result);
3102 if (result != fs) { 2625 if (result != fs) {
3103 set_fcsr_bit(kFCSRInexactFlagBit, true); 2626 set_fcsr_bit(kFCSRInexactFlagBit, true);
3104 } 2627 }
3105 break; 2628 break;
3106 } 2629 }
3107 case SEL: 2630 case SEL:
3108 DCHECK(kArchVariant == kMips64r6); 2631 DCHECK(kArchVariant == kMips64r6);
3109 set_fpu_register_double(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); 2632 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
3110 break; 2633 break;
3111 case SELEQZ_C: 2634 case SELEQZ_C:
3112 DCHECK(kArchVariant == kMips64r6); 2635 DCHECK(kArchVariant == kMips64r6);
3113 set_fpu_register_double(fd_reg, (ft_int & 0x1) == 0 ? fs : 0.0); 2636 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0);
3114 break; 2637 break;
3115 case SELNEZ_C: 2638 case SELNEZ_C:
3116 DCHECK(kArchVariant == kMips64r6); 2639 DCHECK(kArchVariant == kMips64r6);
3117 set_fpu_register_double(fd_reg, (ft_int & 0x1) != 0 ? fs : 0.0); 2640 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0);
3118 break; 2641 break;
3119 case MOVZ_C: { 2642 case MOVZ_C: {
3120 DCHECK(kArchVariant == kMips64r2); 2643 DCHECK(kArchVariant == kMips64r2);
3121 int32_t rt_reg = instr->RtValue(); 2644 if (rt() == 0) {
3122 int64_t rt = get_register(rt_reg); 2645 set_fpu_register_double(fd_reg(), fs);
3123 if (rt == 0) {
3124 set_fpu_register_double(fd_reg, fs);
3125 } 2646 }
3126 break; 2647 break;
3127 } 2648 }
3128 case MOVN_C: { 2649 case MOVN_C: {
3129 DCHECK(kArchVariant == kMips64r2); 2650 DCHECK(kArchVariant == kMips64r2);
3130 int32_t rt_reg = instr->RtValue(); 2651 if (rt() != 0) {
3131 int64_t rt = get_register(rt_reg); 2652 set_fpu_register_double(fd_reg(), fs);
3132 if (rt != 0) {
3133 set_fpu_register_double(fd_reg, fs);
3134 } 2653 }
3135 break; 2654 break;
3136 } 2655 }
3137 case MOVF: { 2656 case MOVF: {
3138 // Same function field for MOVT.D and MOVF.D 2657 // Same function field for MOVT.D and MOVF.D
3139 uint32_t ft_cc = (ft_reg >> 2) & 0x7; 2658 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
3140 ft_cc = get_fcsr_condition_bit(ft_cc); 2659 ft_cc = get_fcsr_condition_bit(ft_cc);
3141 if (instr->Bit(16)) { // Read Tf bit. 2660 if (get_instr()->Bit(16)) { // Read Tf bit.
3142 // MOVT.D 2661 // MOVT.D
3143 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs); 2662 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
3144 } else { 2663 } else {
3145 // MOVF.D 2664 // MOVF.D
3146 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs); 2665 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
3147 } 2666 }
3148 break; 2667 break;
3149 } 2668 }
3150 case MINA: 2669 case MINA:
3151 DCHECK(kArchVariant == kMips64r6); 2670 DCHECK(kArchVariant == kMips64r6);
3152 fs = get_fpu_register_double(fs_reg); 2671 fs = get_fpu_register_double(fs_reg());
3153 if (std::isnan(fs) && std::isnan(ft)) { 2672 if (std::isnan(fs) && std::isnan(ft)) {
3154 set_fpu_register_double(fd_reg, fs); 2673 set_fpu_register_double(fd_reg(), fs);
3155 } else if (std::isnan(fs) && !std::isnan(ft)) { 2674 } else if (std::isnan(fs) && !std::isnan(ft)) {
3156 set_fpu_register_double(fd_reg, ft); 2675 set_fpu_register_double(fd_reg(), ft);
3157 } else if (!std::isnan(fs) && std::isnan(ft)) { 2676 } else if (!std::isnan(fs) && std::isnan(ft)) {
3158 set_fpu_register_double(fd_reg, fs); 2677 set_fpu_register_double(fd_reg(), fs);
3159 } else { 2678 } else {
3160 double result; 2679 double result;
3161 if (fabs(fs) > fabs(ft)) { 2680 if (fabs(fs) > fabs(ft)) {
3162 result = ft; 2681 result = ft;
3163 } else if (fabs(fs) < fabs(ft)) { 2682 } else if (fabs(fs) < fabs(ft)) {
3164 result = fs; 2683 result = fs;
3165 } else { 2684 } else {
3166 result = (fs > ft ? fs : ft); 2685 result = (fs > ft ? fs : ft);
3167 } 2686 }
3168 set_fpu_register_double(fd_reg, result); 2687 set_fpu_register_double(fd_reg(), result);
3169 } 2688 }
3170 break; 2689 break;
3171 case MAXA: 2690 case MAXA:
3172 DCHECK(kArchVariant == kMips64r6); 2691 DCHECK(kArchVariant == kMips64r6);
3173 fs = get_fpu_register_double(fs_reg); 2692 fs = get_fpu_register_double(fs_reg());
3174 if (std::isnan(fs) && std::isnan(ft)) { 2693 if (std::isnan(fs) && std::isnan(ft)) {
3175 set_fpu_register_double(fd_reg, fs); 2694 set_fpu_register_double(fd_reg(), fs);
3176 } else if (std::isnan(fs) && !std::isnan(ft)) { 2695 } else if (std::isnan(fs) && !std::isnan(ft)) {
3177 set_fpu_register_double(fd_reg, ft); 2696 set_fpu_register_double(fd_reg(), ft);
3178 } else if (!std::isnan(fs) && std::isnan(ft)) { 2697 } else if (!std::isnan(fs) && std::isnan(ft)) {
3179 set_fpu_register_double(fd_reg, fs); 2698 set_fpu_register_double(fd_reg(), fs);
3180 } else { 2699 } else {
3181 double result; 2700 double result;
3182 if (fabs(fs) < fabs(ft)) { 2701 if (fabs(fs) < fabs(ft)) {
3183 result = ft; 2702 result = ft;
3184 } else if (fabs(fs) > fabs(ft)) { 2703 } else if (fabs(fs) > fabs(ft)) {
3185 result = fs; 2704 result = fs;
3186 } else { 2705 } else {
3187 result = (fs > ft ? fs : ft); 2706 result = (fs > ft ? fs : ft);
3188 } 2707 }
3189 set_fpu_register_double(fd_reg, result); 2708 set_fpu_register_double(fd_reg(), result);
3190 } 2709 }
3191 break; 2710 break;
3192 case MIN: 2711 case MIN:
3193 DCHECK(kArchVariant == kMips64r6); 2712 DCHECK(kArchVariant == kMips64r6);
3194 fs = get_fpu_register_double(fs_reg); 2713 fs = get_fpu_register_double(fs_reg());
3195 if (std::isnan(fs) && std::isnan(ft)) { 2714 if (std::isnan(fs) && std::isnan(ft)) {
3196 set_fpu_register_double(fd_reg, fs); 2715 set_fpu_register_double(fd_reg(), fs);
3197 } else if (std::isnan(fs) && !std::isnan(ft)) { 2716 } else if (std::isnan(fs) && !std::isnan(ft)) {
3198 set_fpu_register_double(fd_reg, ft); 2717 set_fpu_register_double(fd_reg(), ft);
3199 } else if (!std::isnan(fs) && std::isnan(ft)) { 2718 } else if (!std::isnan(fs) && std::isnan(ft)) {
3200 set_fpu_register_double(fd_reg, fs); 2719 set_fpu_register_double(fd_reg(), fs);
3201 } else { 2720 } else {
3202 set_fpu_register_double(fd_reg, (fs >= ft) ? ft : fs); 2721 set_fpu_register_double(fd_reg(), (fs >= ft) ? ft : fs);
3203 } 2722 }
3204 break; 2723 break;
3205 case MAX: 2724 case MAX:
3206 DCHECK(kArchVariant == kMips64r6); 2725 DCHECK(kArchVariant == kMips64r6);
3207 fs = get_fpu_register_double(fs_reg); 2726 fs = get_fpu_register_double(fs_reg());
3208 if (std::isnan(fs) && std::isnan(ft)) { 2727 if (std::isnan(fs) && std::isnan(ft)) {
3209 set_fpu_register_double(fd_reg, fs); 2728 set_fpu_register_double(fd_reg(), fs);
3210 } else if (std::isnan(fs) && !std::isnan(ft)) { 2729 } else if (std::isnan(fs) && !std::isnan(ft)) {
3211 set_fpu_register_double(fd_reg, ft); 2730 set_fpu_register_double(fd_reg(), ft);
3212 } else if (!std::isnan(fs) && std::isnan(ft)) { 2731 } else if (!std::isnan(fs) && std::isnan(ft)) {
3213 set_fpu_register_double(fd_reg, fs); 2732 set_fpu_register_double(fd_reg(), fs);
3214 } else { 2733 } else {
3215 set_fpu_register_double(fd_reg, (fs <= ft) ? ft : fs); 2734 set_fpu_register_double(fd_reg(), (fs <= ft) ? ft : fs);
3216 } 2735 }
3217 break; 2736 break;
3218 case ADD_D: 2737 case ADD_D:
3219 set_fpu_register_double(fd_reg, fs + ft); 2738 set_fpu_register_double(fd_reg(), fs + ft);
3220 break; 2739 break;
3221 case SUB_D: 2740 case SUB_D:
3222 set_fpu_register_double(fd_reg, fs - ft); 2741 set_fpu_register_double(fd_reg(), fs - ft);
3223 break; 2742 break;
3224 case MUL_D: 2743 case MUL_D:
3225 set_fpu_register_double(fd_reg, fs * ft); 2744 set_fpu_register_double(fd_reg(), fs * ft);
3226 break; 2745 break;
3227 case DIV_D: 2746 case DIV_D:
3228 set_fpu_register_double(fd_reg, fs / ft); 2747 set_fpu_register_double(fd_reg(), fs / ft);
3229 break; 2748 break;
3230 case ABS_D: 2749 case ABS_D:
3231 set_fpu_register_double(fd_reg, fabs(fs)); 2750 set_fpu_register_double(fd_reg(), fabs(fs));
3232 break; 2751 break;
3233 case MOV_D: 2752 case MOV_D:
3234 set_fpu_register_double(fd_reg, fs); 2753 set_fpu_register_double(fd_reg(), fs);
3235 break; 2754 break;
3236 case NEG_D: 2755 case NEG_D:
3237 set_fpu_register_double(fd_reg, -fs); 2756 set_fpu_register_double(fd_reg(), -fs);
3238 break; 2757 break;
3239 case SQRT_D: 2758 case SQRT_D:
3240 set_fpu_register_double(fd_reg, fast_sqrt(fs)); 2759 set_fpu_register_double(fd_reg(), fast_sqrt(fs));
3241 break; 2760 break;
3242 case RSQRT_D: { 2761 case RSQRT_D: {
3243 double result = 1.0 / fast_sqrt(fs); 2762 double result = 1.0 / fast_sqrt(fs);
3244 set_fpu_register_double(fd_reg, result); 2763 set_fpu_register_double(fd_reg(), result);
3245 break; 2764 break;
3246 } 2765 }
3247 case RECIP_D: { 2766 case RECIP_D: {
3248 double result = 1.0 / fs; 2767 double result = 1.0 / fs;
3249 set_fpu_register_double(fd_reg, result); 2768 set_fpu_register_double(fd_reg(), result);
3250 break; 2769 break;
3251 } 2770 }
3252 case C_UN_D: 2771 case C_UN_D:
3253 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2772 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
3254 break; 2773 break;
3255 case C_EQ_D: 2774 case C_EQ_D:
3256 set_fcsr_bit(fcsr_cc, (fs == ft)); 2775 set_fcsr_bit(fcsr_cc, (fs == ft));
3257 break; 2776 break;
3258 case C_UEQ_D: 2777 case C_UEQ_D:
3259 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2778 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
3260 break; 2779 break;
3261 case C_OLT_D: 2780 case C_OLT_D:
3262 set_fcsr_bit(fcsr_cc, (fs < ft)); 2781 set_fcsr_bit(fcsr_cc, (fs < ft));
3263 break; 2782 break;
3264 case C_ULT_D: 2783 case C_ULT_D:
3265 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 2784 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
3266 break; 2785 break;
3267 case C_OLE_D: 2786 case C_OLE_D:
3268 set_fcsr_bit(fcsr_cc, (fs <= ft)); 2787 set_fcsr_bit(fcsr_cc, (fs <= ft));
3269 break; 2788 break;
3270 case C_ULE_D: 2789 case C_ULE_D:
3271 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2790 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
3272 break; 2791 break;
3273 case CVT_W_D: { // Convert double to word. 2792 case CVT_W_D: { // Convert double to word.
3274 double rounded; 2793 double rounded;
3275 int32_t result; 2794 int32_t result;
3276 round_according_to_fcsr(fs, rounded, result, fs); 2795 round_according_to_fcsr(fs, rounded, result, fs);
3277 set_fpu_register_word(fd_reg, result); 2796 set_fpu_register_word(fd_reg(), result);
3278 if (set_fcsr_round_error(fs, rounded)) { 2797 if (set_fcsr_round_error(fs, rounded)) {
3279 set_fpu_register_word(fd_reg, kFPUInvalidResult); 2798 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
3280 } 2799 }
3281 break; 2800 break;
3282 } 2801 }
3283 case ROUND_W_D: // Round double to word (round half to even). 2802 case ROUND_W_D: // Round double to word (round half to even).
3284 { 2803 {
3285 double rounded = std::floor(fs + 0.5); 2804 double rounded = std::floor(fs + 0.5);
3286 int32_t result = static_cast<int32_t>(rounded); 2805 int32_t result = static_cast<int32_t>(rounded);
3287 if ((result & 1) != 0 && result - fs == 0.5) { 2806 if ((result & 1) != 0 && result - fs == 0.5) {
3288 // If the number is halfway between two integers, 2807 // If the number is halfway between two integers,
3289 // round to the even one. 2808 // round to the even one.
3290 result--; 2809 result--;
3291 } 2810 }
3292 set_fpu_register_word(fd_reg, result); 2811 set_fpu_register_word(fd_reg(), result);
3293 if (set_fcsr_round_error(fs, rounded)) { 2812 if (set_fcsr_round_error(fs, rounded)) {
3294 set_fpu_register(fd_reg, kFPUInvalidResult); 2813 set_fpu_register(fd_reg(), kFPUInvalidResult);
3295 } 2814 }
3296 } break; 2815 } break;
3297 case TRUNC_W_D: // Truncate double to word (round towards 0). 2816 case TRUNC_W_D: // Truncate double to word (round towards 0).
3298 { 2817 {
3299 double rounded = trunc(fs); 2818 double rounded = trunc(fs);
3300 int32_t result = static_cast<int32_t>(rounded); 2819 int32_t result = static_cast<int32_t>(rounded);
3301 set_fpu_register_word(fd_reg, result); 2820 set_fpu_register_word(fd_reg(), result);
3302 if (set_fcsr_round_error(fs, rounded)) { 2821 if (set_fcsr_round_error(fs, rounded)) {
3303 set_fpu_register(fd_reg, kFPUInvalidResult); 2822 set_fpu_register(fd_reg(), kFPUInvalidResult);
3304 } 2823 }
3305 } break; 2824 } break;
3306 case FLOOR_W_D: // Round double to word towards negative infinity. 2825 case FLOOR_W_D: // Round double to word towards negative infinity.
3307 { 2826 {
3308 double rounded = std::floor(fs); 2827 double rounded = std::floor(fs);
3309 int32_t result = static_cast<int32_t>(rounded); 2828 int32_t result = static_cast<int32_t>(rounded);
3310 set_fpu_register_word(fd_reg, result); 2829 set_fpu_register_word(fd_reg(), result);
3311 if (set_fcsr_round_error(fs, rounded)) { 2830 if (set_fcsr_round_error(fs, rounded)) {
3312 set_fpu_register(fd_reg, kFPUInvalidResult); 2831 set_fpu_register(fd_reg(), kFPUInvalidResult);
3313 } 2832 }
3314 } break; 2833 } break;
3315 case CEIL_W_D: // Round double to word towards positive infinity. 2834 case CEIL_W_D: // Round double to word towards positive infinity.
3316 { 2835 {
3317 double rounded = std::ceil(fs); 2836 double rounded = std::ceil(fs);
3318 int32_t result = static_cast<int32_t>(rounded); 2837 int32_t result = static_cast<int32_t>(rounded);
3319 set_fpu_register_word(fd_reg, result); 2838 set_fpu_register_word(fd_reg(), result);
3320 if (set_fcsr_round_error(fs, rounded)) { 2839 if (set_fcsr_round_error(fs, rounded)) {
3321 set_fpu_register(fd_reg, kFPUInvalidResult); 2840 set_fpu_register(fd_reg(), kFPUInvalidResult);
3322 } 2841 }
3323 } break; 2842 } break;
3324 case CVT_S_D: // Convert double to float (single). 2843 case CVT_S_D: // Convert double to float (single).
3325 set_fpu_register_float(fd_reg, static_cast<float>(fs)); 2844 set_fpu_register_float(fd_reg(), static_cast<float>(fs));
3326 break; 2845 break;
3327 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. 2846 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word.
3328 double rounded; 2847 double rounded;
3329 int64_t result; 2848 int64_t result;
3330 round64_according_to_fcsr(fs, rounded, result, fs); 2849 round64_according_to_fcsr(fs, rounded, result, fs);
3331 set_fpu_register(fd_reg, result); 2850 set_fpu_register(fd_reg(), result);
3332 if (set_fcsr_round64_error(fs, rounded)) { 2851 if (set_fcsr_round64_error(fs, rounded)) {
3333 set_fpu_register(fd_reg, kFPU64InvalidResult); 2852 set_fpu_register(fd_reg(), kFPU64InvalidResult);
3334 } 2853 }
3335 break; 2854 break;
3336 } 2855 }
3337 case ROUND_L_D: { // Mips64r2 instruction. 2856 case ROUND_L_D: { // Mips64r2 instruction.
3338 double rounded = std::floor(fs + 0.5); 2857 double rounded = std::floor(fs + 0.5);
3339 int64_t result = static_cast<int64_t>(rounded); 2858 int64_t result = static_cast<int64_t>(rounded);
3340 if ((result & 1) != 0 && result - fs == 0.5) { 2859 if ((result & 1) != 0 && result - fs == 0.5) {
3341 // If the number is halfway between two integers, 2860 // If the number is halfway between two integers,
3342 // round to the even one. 2861 // round to the even one.
3343 result--; 2862 result--;
3344 } 2863 }
3345 int64_t i64 = static_cast<int64_t>(result); 2864 int64_t i64 = static_cast<int64_t>(result);
3346 set_fpu_register(fd_reg, i64); 2865 set_fpu_register(fd_reg(), i64);
3347 if (set_fcsr_round64_error(fs, rounded)) { 2866 if (set_fcsr_round64_error(fs, rounded)) {
3348 set_fpu_register(fd_reg, kFPU64InvalidResult); 2867 set_fpu_register(fd_reg(), kFPU64InvalidResult);
3349 } 2868 }
3350 break; 2869 break;
3351 } 2870 }
3352 case TRUNC_L_D: { // Mips64r2 instruction. 2871 case TRUNC_L_D: { // Mips64r2 instruction.
3353 double rounded = trunc(fs); 2872 double rounded = trunc(fs);
3354 int64_t result = static_cast<int64_t>(rounded); 2873 int64_t result = static_cast<int64_t>(rounded);
3355 set_fpu_register(fd_reg, result); 2874 set_fpu_register(fd_reg(), result);
3356 if (set_fcsr_round64_error(fs, rounded)) { 2875 if (set_fcsr_round64_error(fs, rounded)) {
3357 set_fpu_register(fd_reg, kFPU64InvalidResult); 2876 set_fpu_register(fd_reg(), kFPU64InvalidResult);
3358 } 2877 }
3359 break; 2878 break;
3360 } 2879 }
3361 case FLOOR_L_D: { // Mips64r2 instruction. 2880 case FLOOR_L_D: { // Mips64r2 instruction.
3362 double rounded = floor(fs); 2881 double rounded = floor(fs);
3363 int64_t result = static_cast<int64_t>(rounded); 2882 int64_t result = static_cast<int64_t>(rounded);
3364 set_fpu_register(fd_reg, result); 2883 set_fpu_register(fd_reg(), result);
3365 if (set_fcsr_round64_error(fs, rounded)) { 2884 if (set_fcsr_round64_error(fs, rounded)) {
3366 set_fpu_register(fd_reg, kFPU64InvalidResult); 2885 set_fpu_register(fd_reg(), kFPU64InvalidResult);
3367 } 2886 }
3368 break; 2887 break;
3369 } 2888 }
3370 case CEIL_L_D: { // Mips64r2 instruction. 2889 case CEIL_L_D: { // Mips64r2 instruction.
3371 double rounded = ceil(fs); 2890 double rounded = ceil(fs);
3372 int64_t result = static_cast<int64_t>(rounded); 2891 int64_t result = static_cast<int64_t>(rounded);
3373 set_fpu_register(fd_reg, result); 2892 set_fpu_register(fd_reg(), result);
3374 if (set_fcsr_round64_error(fs, rounded)) { 2893 if (set_fcsr_round64_error(fs, rounded)) {
3375 set_fpu_register(fd_reg, kFPU64InvalidResult); 2894 set_fpu_register(fd_reg(), kFPU64InvalidResult);
3376 } 2895 }
3377 break; 2896 break;
3378 } 2897 }
3379 case CLASS_D: { // Mips64r6 instruction 2898 case CLASS_D: { // Mips64r6 instruction
3380 // Convert double input to uint64_t for easier bit manipulation 2899 // Convert double input to uint64_t for easier bit manipulation
3381 uint64_t classed = bit_cast<uint64_t>(fs); 2900 uint64_t classed = bit_cast<uint64_t>(fs);
3382 2901
3383 // Extracting sign, exponent and mantissa from the input double 2902 // Extracting sign, exponent and mantissa from the input double
3384 uint32_t sign = (classed >> 63) & 1; 2903 uint32_t sign = (classed >> 63) & 1;
3385 uint32_t exponent = (classed >> 52) & 0x00000000000007ff; 2904 uint32_t exponent = (classed >> 52) & 0x00000000000007ff;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3430 } 2949 }
3431 2950
3432 // Calculating result according to description of CLASS.D instruction 2951 // Calculating result according to description of CLASS.D instruction
3433 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 2952 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
3434 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 2953 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
3435 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 2954 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
3436 2955
3437 DCHECK(result != 0); 2956 DCHECK(result != 0);
3438 2957
3439 dResult = bit_cast<double>(result); 2958 dResult = bit_cast<double>(result);
3440 set_fpu_register_double(fd_reg, dResult); 2959 set_fpu_register_double(fd_reg(), dResult);
3441 2960
3442 break; 2961 break;
3443 } 2962 }
3444 case C_F_D: { 2963 case C_F_D: {
3445 set_fcsr_bit(fcsr_cc, false); 2964 set_fcsr_bit(fcsr_cc, false);
3446 break; 2965 break;
3447 } 2966 }
3448 default: 2967 default:
3449 UNREACHABLE(); 2968 UNREACHABLE();
3450 } 2969 }
3451 } 2970 }
3452 2971
3453 2972
3454 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, 2973 void Simulator::DecodeTypeRegisterWRsType() {
3455 const int32_t fs_reg, 2974 float fs = get_fpu_register_float(fs_reg());
3456 const int32_t fd_reg, 2975 float ft = get_fpu_register_float(ft_reg());
3457 const int32_t ft_reg, 2976 int64_t alu_out = 0x12345678;
3458 int64_t& alu_out) { 2977 switch (get_instr()->FunctionFieldRaw()) {
3459 float fs = get_fpu_register_float(fs_reg);
3460 float ft = get_fpu_register_float(ft_reg);
3461 switch (instr->FunctionFieldRaw()) {
3462 case CVT_S_W: // Convert word to float (single). 2978 case CVT_S_W: // Convert word to float (single).
3463 alu_out = get_fpu_register_signed_word(fs_reg); 2979 alu_out = get_fpu_register_signed_word(fs_reg());
3464 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); 2980 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out));
3465 break; 2981 break;
3466 case CVT_D_W: // Convert word to double. 2982 case CVT_D_W: // Convert word to double.
3467 alu_out = get_fpu_register_signed_word(fs_reg); 2983 alu_out = get_fpu_register_signed_word(fs_reg());
3468 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); 2984 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out));
3469 break; 2985 break;
3470 case CMP_AF: 2986 case CMP_AF:
3471 set_fpu_register_word(fd_reg, 0); 2987 set_fpu_register_word(fd_reg(), 0);
3472 break; 2988 break;
3473 case CMP_UN: 2989 case CMP_UN:
3474 if (std::isnan(fs) || std::isnan(ft)) { 2990 if (std::isnan(fs) || std::isnan(ft)) {
3475 set_fpu_register_word(fd_reg, -1); 2991 set_fpu_register_word(fd_reg(), -1);
3476 } else { 2992 } else {
3477 set_fpu_register_word(fd_reg, 0); 2993 set_fpu_register_word(fd_reg(), 0);
3478 } 2994 }
3479 break; 2995 break;
3480 case CMP_EQ: 2996 case CMP_EQ:
3481 if (fs == ft) { 2997 if (fs == ft) {
3482 set_fpu_register_word(fd_reg, -1); 2998 set_fpu_register_word(fd_reg(), -1);
3483 } else { 2999 } else {
3484 set_fpu_register_word(fd_reg, 0); 3000 set_fpu_register_word(fd_reg(), 0);
3485 } 3001 }
3486 break; 3002 break;
3487 case CMP_UEQ: 3003 case CMP_UEQ:
3488 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 3004 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
3489 set_fpu_register_word(fd_reg, -1); 3005 set_fpu_register_word(fd_reg(), -1);
3490 } else { 3006 } else {
3491 set_fpu_register_word(fd_reg, 0); 3007 set_fpu_register_word(fd_reg(), 0);
3492 } 3008 }
3493 break; 3009 break;
3494 case CMP_LT: 3010 case CMP_LT:
3495 if (fs < ft) { 3011 if (fs < ft) {
3496 set_fpu_register_word(fd_reg, -1); 3012 set_fpu_register_word(fd_reg(), -1);
3497 } else { 3013 } else {
3498 set_fpu_register_word(fd_reg, 0); 3014 set_fpu_register_word(fd_reg(), 0);
3499 } 3015 }
3500 break; 3016 break;
3501 case CMP_ULT: 3017 case CMP_ULT:
3502 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 3018 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
3503 set_fpu_register_word(fd_reg, -1); 3019 set_fpu_register_word(fd_reg(), -1);
3504 } else { 3020 } else {
3505 set_fpu_register_word(fd_reg, 0); 3021 set_fpu_register_word(fd_reg(), 0);
3506 } 3022 }
3507 break; 3023 break;
3508 case CMP_LE: 3024 case CMP_LE:
3509 if (fs <= ft) { 3025 if (fs <= ft) {
3510 set_fpu_register_word(fd_reg, -1); 3026 set_fpu_register_word(fd_reg(), -1);
3511 } else { 3027 } else {
3512 set_fpu_register_word(fd_reg, 0); 3028 set_fpu_register_word(fd_reg(), 0);
3513 } 3029 }
3514 break; 3030 break;
3515 case CMP_ULE: 3031 case CMP_ULE:
3516 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3032 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
3517 set_fpu_register_word(fd_reg, -1); 3033 set_fpu_register_word(fd_reg(), -1);
3518 } else { 3034 } else {
3519 set_fpu_register_word(fd_reg, 0); 3035 set_fpu_register_word(fd_reg(), 0);
3520 } 3036 }
3521 break; 3037 break;
3522 case CMP_OR: 3038 case CMP_OR:
3523 if (!std::isnan(fs) && !std::isnan(ft)) { 3039 if (!std::isnan(fs) && !std::isnan(ft)) {
3524 set_fpu_register_word(fd_reg, -1); 3040 set_fpu_register_word(fd_reg(), -1);
3525 } else { 3041 } else {
3526 set_fpu_register_word(fd_reg, 0); 3042 set_fpu_register_word(fd_reg(), 0);
3527 } 3043 }
3528 break; 3044 break;
3529 case CMP_UNE: 3045 case CMP_UNE:
3530 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3046 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
3531 set_fpu_register_word(fd_reg, -1); 3047 set_fpu_register_word(fd_reg(), -1);
3532 } else { 3048 } else {
3533 set_fpu_register_word(fd_reg, 0); 3049 set_fpu_register_word(fd_reg(), 0);
3534 } 3050 }
3535 break; 3051 break;
3536 case CMP_NE: 3052 case CMP_NE:
3537 if (fs != ft) { 3053 if (fs != ft) {
3538 set_fpu_register_word(fd_reg, -1); 3054 set_fpu_register_word(fd_reg(), -1);
3539 } else { 3055 } else {
3540 set_fpu_register_word(fd_reg, 0); 3056 set_fpu_register_word(fd_reg(), 0);
3541 } 3057 }
3542 break; 3058 break;
3543 default: 3059 default:
3544 UNREACHABLE(); 3060 UNREACHABLE();
3545 } 3061 }
3546 } 3062 }
3547 3063
3548 3064
3549 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, 3065 void Simulator::DecodeTypeRegisterLRsType() {
3550 const int32_t fs_reg, 3066 double fs = get_fpu_register_double(fs_reg());
3551 const int32_t fd_reg, 3067 double ft = get_fpu_register_double(ft_reg());
3552 const int32_t ft_reg) {
3553 double fs = get_fpu_register_double(fs_reg);
3554 double ft = get_fpu_register_double(ft_reg);
3555 int64_t i64; 3068 int64_t i64;
3556 switch (instr->FunctionFieldRaw()) { 3069 switch (get_instr()->FunctionFieldRaw()) {
3557 case CVT_D_L: // Mips32r2 instruction. 3070 case CVT_D_L: // Mips32r2 instruction.
3558 i64 = get_fpu_register(fs_reg); 3071 i64 = get_fpu_register(fs_reg());
3559 set_fpu_register_double(fd_reg, static_cast<double>(i64)); 3072 set_fpu_register_double(fd_reg(), static_cast<double>(i64));
3560 break; 3073 break;
3561 case CVT_S_L: 3074 case CVT_S_L:
3562 i64 = get_fpu_register(fs_reg); 3075 i64 = get_fpu_register(fs_reg());
3563 set_fpu_register_float(fd_reg, static_cast<float>(i64)); 3076 set_fpu_register_float(fd_reg(), static_cast<float>(i64));
3564 break; 3077 break;
3565 case CMP_AF: 3078 case CMP_AF:
3566 set_fpu_register(fd_reg, 0); 3079 set_fpu_register(fd_reg(), 0);
3567 break; 3080 break;
3568 case CMP_UN: 3081 case CMP_UN:
3569 if (std::isnan(fs) || std::isnan(ft)) { 3082 if (std::isnan(fs) || std::isnan(ft)) {
3570 set_fpu_register(fd_reg, -1); 3083 set_fpu_register(fd_reg(), -1);
3571 } else { 3084 } else {
3572 set_fpu_register(fd_reg, 0); 3085 set_fpu_register(fd_reg(), 0);
3573 } 3086 }
3574 break; 3087 break;
3575 case CMP_EQ: 3088 case CMP_EQ:
3576 if (fs == ft) { 3089 if (fs == ft) {
3577 set_fpu_register(fd_reg, -1); 3090 set_fpu_register(fd_reg(), -1);
3578 } else { 3091 } else {
3579 set_fpu_register(fd_reg, 0); 3092 set_fpu_register(fd_reg(), 0);
3580 } 3093 }
3581 break; 3094 break;
3582 case CMP_UEQ: 3095 case CMP_UEQ:
3583 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 3096 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
3584 set_fpu_register(fd_reg, -1); 3097 set_fpu_register(fd_reg(), -1);
3585 } else { 3098 } else {
3586 set_fpu_register(fd_reg, 0); 3099 set_fpu_register(fd_reg(), 0);
3587 } 3100 }
3588 break; 3101 break;
3589 case CMP_LT: 3102 case CMP_LT:
3590 if (fs < ft) { 3103 if (fs < ft) {
3591 set_fpu_register(fd_reg, -1); 3104 set_fpu_register(fd_reg(), -1);
3592 } else { 3105 } else {
3593 set_fpu_register(fd_reg, 0); 3106 set_fpu_register(fd_reg(), 0);
3594 } 3107 }
3595 break; 3108 break;
3596 case CMP_ULT: 3109 case CMP_ULT:
3597 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 3110 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
3598 set_fpu_register(fd_reg, -1); 3111 set_fpu_register(fd_reg(), -1);
3599 } else { 3112 } else {
3600 set_fpu_register(fd_reg, 0); 3113 set_fpu_register(fd_reg(), 0);
3601 } 3114 }
3602 break; 3115 break;
3603 case CMP_LE: 3116 case CMP_LE:
3604 if (fs <= ft) { 3117 if (fs <= ft) {
3605 set_fpu_register(fd_reg, -1); 3118 set_fpu_register(fd_reg(), -1);
3606 } else { 3119 } else {
3607 set_fpu_register(fd_reg, 0); 3120 set_fpu_register(fd_reg(), 0);
3608 } 3121 }
3609 break; 3122 break;
3610 case CMP_ULE: 3123 case CMP_ULE:
3611 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3124 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
3612 set_fpu_register(fd_reg, -1); 3125 set_fpu_register(fd_reg(), -1);
3613 } else { 3126 } else {
3614 set_fpu_register(fd_reg, 0); 3127 set_fpu_register(fd_reg(), 0);
3615 } 3128 }
3616 break; 3129 break;
3617 case CMP_OR: 3130 case CMP_OR:
3618 if (!std::isnan(fs) && !std::isnan(ft)) { 3131 if (!std::isnan(fs) && !std::isnan(ft)) {
3619 set_fpu_register(fd_reg, -1); 3132 set_fpu_register(fd_reg(), -1);
3620 } else { 3133 } else {
3621 set_fpu_register(fd_reg, 0); 3134 set_fpu_register(fd_reg(), 0);
3622 } 3135 }
3623 break; 3136 break;
3624 case CMP_UNE: 3137 case CMP_UNE:
3625 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3138 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
3626 set_fpu_register(fd_reg, -1); 3139 set_fpu_register(fd_reg(), -1);
3627 } else { 3140 } else {
3628 set_fpu_register(fd_reg, 0); 3141 set_fpu_register(fd_reg(), 0);
3629 } 3142 }
3630 break; 3143 break;
3631 case CMP_NE: 3144 case CMP_NE:
3632 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { 3145 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) {
3633 set_fpu_register(fd_reg, -1); 3146 set_fpu_register(fd_reg(), -1);
3634 } else { 3147 } else {
3635 set_fpu_register(fd_reg, 0); 3148 set_fpu_register(fd_reg(), 0);
3636 } 3149 }
3637 break; 3150 break;
3638 default: 3151 default:
3639 UNREACHABLE(); 3152 UNREACHABLE();
3640 } 3153 }
3641 } 3154 }
3642 3155
3643 void Simulator::DecodeTypeRegisterCOP1( 3156
3644 Instruction* instr, const int32_t rs_reg, const int64_t rs, 3157 void Simulator::DecodeTypeRegisterCOP1() {
3645 const uint64_t rs_u, const int32_t rt_reg, const int64_t rt, 3158 switch (get_instr()->RsFieldRaw()) {
3646 const uint64_t rt_u, const int32_t rd_reg, const int32_t fr_reg,
3647 const int32_t fs_reg, const int32_t ft_reg, const int32_t fd_reg,
3648 int64_t& alu_out) {
3649 switch (instr->RsFieldRaw()) {
3650 case BC1: // Branch on coprocessor condition. 3159 case BC1: // Branch on coprocessor condition.
3651 case BC1EQZ: 3160 case BC1EQZ:
3652 case BC1NEZ: 3161 case BC1NEZ:
3653 UNREACHABLE(); 3162 UNREACHABLE();
3654 break; 3163 break;
3655 case CFC1: 3164 case CFC1:
3656 set_register(rt_reg, alu_out); 3165 // At the moment only FCSR is supported.
3166 DCHECK(fs_reg() == kFCSRRegister);
3167 set_register(rt_reg(), FCSR_);
3657 break; 3168 break;
3658 case MFC1: 3169 case MFC1:
3170 set_register(rt_reg(),
3171 static_cast<int64_t>(get_fpu_register_word(fs_reg())));
3172 break;
3659 case DMFC1: 3173 case DMFC1:
3174 set_register(rt_reg(), get_fpu_register(fs_reg()));
3175 break;
3660 case MFHC1: 3176 case MFHC1:
3661 set_register(rt_reg, alu_out); 3177 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg()));
3662 break; 3178 break;
3663 case CTC1: 3179 case CTC1:
3664 // At the moment only FCSR is supported. 3180 // At the moment only FCSR is supported.
3665 DCHECK(fs_reg == kFCSRRegister); 3181 DCHECK(fs_reg() == kFCSRRegister);
3666 FCSR_ = static_cast<uint32_t>(registers_[rt_reg]); 3182 FCSR_ = static_cast<uint32_t>(rt());
3667 break; 3183 break;
3668 case MTC1: 3184 case MTC1:
3669 // Hardware writes upper 32-bits to zero on mtc1. 3185 // Hardware writes upper 32-bits to zero on mtc1.
3670 set_fpu_register_hi_word(fs_reg, 0); 3186 set_fpu_register_hi_word(fs_reg(), 0);
3671 set_fpu_register_word(fs_reg, static_cast<int32_t>(registers_[rt_reg])); 3187 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt()));
3672 break; 3188 break;
3673 case DMTC1: 3189 case DMTC1:
3674 set_fpu_register(fs_reg, registers_[rt_reg]); 3190 set_fpu_register(fs_reg(), rt());
3675 break; 3191 break;
3676 case MTHC1: 3192 case MTHC1:
3677 set_fpu_register_hi_word(fs_reg, 3193 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt()));
3678 static_cast<int32_t>(registers_[rt_reg]));
3679 break; 3194 break;
3680 case S: 3195 case S:
3681 DecodeTypeRegisterSRsType(instr, fs_reg, ft_reg, fd_reg); 3196 DecodeTypeRegisterSRsType();
3682 break; 3197 break;
3683 case D: 3198 case D:
3684 DecodeTypeRegisterDRsType(instr, fs_reg, ft_reg, fd_reg); 3199 DecodeTypeRegisterDRsType();
3685 break; 3200 break;
3686 case W: 3201 case W:
3687 DecodeTypeRegisterWRsType(instr, fs_reg, fd_reg, ft_reg, alu_out); 3202 DecodeTypeRegisterWRsType();
3688 break; 3203 break;
3689 case L: 3204 case L:
3690 DecodeTypeRegisterLRsType(instr, fs_reg, fd_reg, ft_reg); 3205 DecodeTypeRegisterLRsType();
3691 break; 3206 break;
3692 default: 3207 default:
3693 UNREACHABLE(); 3208 UNREACHABLE();
3694 } 3209 }
3695 } 3210 }
3696 3211
3697 3212
3698 void Simulator::DecodeTypeRegisterCOP1X(Instruction* instr, 3213 void Simulator::DecodeTypeRegisterCOP1X() {
3699 const int32_t fr_reg, 3214 switch (get_instr()->FunctionFieldRaw()) {
3700 const int32_t fs_reg,
3701 const int32_t ft_reg,
3702 const int32_t fd_reg) {
3703 switch (instr->FunctionFieldRaw()) {
3704 case MADD_D: 3215 case MADD_D:
3705 double fr, ft, fs; 3216 double fr, ft, fs;
3706 fr = get_fpu_register_double(fr_reg); 3217 fr = get_fpu_register_double(fr_reg());
3707 fs = get_fpu_register_double(fs_reg); 3218 fs = get_fpu_register_double(fs_reg());
3708 ft = get_fpu_register_double(ft_reg); 3219 ft = get_fpu_register_double(ft_reg());
3709 set_fpu_register_double(fd_reg, fs * ft + fr); 3220 set_fpu_register_double(fd_reg(), fs * ft + fr);
3710 break; 3221 break;
3711 default: 3222 default:
3712 UNREACHABLE(); 3223 UNREACHABLE();
3713 } 3224 }
3714 } 3225 }
3715 3226
3716 3227
3717 void Simulator::DecodeTypeRegisterSPECIAL( 3228 void Simulator::DecodeTypeRegisterSPECIAL() {
3718 Instruction* instr, const int32_t rs_reg, const int64_t rs, 3229 int64_t i64hilo;
3719 const uint64_t rs_u, const int32_t rt_reg, const int64_t rt, 3230 uint64_t u64hilo;
3720 const uint64_t rt_u, const int32_t rd_reg, const int32_t fr_reg, 3231 int64_t alu_out;
3721 const int32_t fs_reg, const int32_t ft_reg, const int32_t fd_reg, 3232 bool do_interrupt = false;
3722 const int64_t i64hilo, const uint64_t u64hilo, const int64_t alu_out, 3233
3723 const bool do_interrupt, const int64_t current_pc, const int64_t next_pc, 3234 switch (get_instr()->FunctionFieldRaw()) {
3724 const int32_t return_addr_reg, const int64_t i128resultH,
3725 const int64_t i128resultL) {
3726 switch (instr->FunctionFieldRaw()) {
3727 case SELEQZ_S: 3235 case SELEQZ_S:
3728 DCHECK(kArchVariant == kMips64r6); 3236 DCHECK(kArchVariant == kMips64r6);
3729 set_register(rd_reg, rt == 0 ? rs : 0); 3237 set_register(rd_reg(), rt() == 0 ? rs() : 0);
3730 break; 3238 break;
3731 case SELNEZ_S: 3239 case SELNEZ_S:
3732 DCHECK(kArchVariant == kMips64r6); 3240 DCHECK(kArchVariant == kMips64r6);
3733 set_register(rd_reg, rt != 0 ? rs : 0); 3241 set_register(rd_reg(), rt() != 0 ? rs() : 0);
3734 break; 3242 break;
3735 case JR: { 3243 case JR: {
3244 int64_t next_pc = rs();
3245 int64_t current_pc = get_pc();
3736 Instruction* branch_delay_instr = 3246 Instruction* branch_delay_instr =
3737 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 3247 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
3738 BranchDelayInstructionDecode(branch_delay_instr); 3248 BranchDelayInstructionDecode(branch_delay_instr);
3739 set_pc(next_pc); 3249 set_pc(next_pc);
3740 pc_modified_ = true; 3250 pc_modified_ = true;
3741 break; 3251 break;
3742 } 3252 }
3743 case JALR: { 3253 case JALR: {
3254 int64_t next_pc = rs();
3255 int64_t current_pc = get_pc();
3256 int32_t return_addr_reg = rd_reg();
3744 Instruction* branch_delay_instr = 3257 Instruction* branch_delay_instr =
3745 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 3258 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
3746 BranchDelayInstructionDecode(branch_delay_instr); 3259 BranchDelayInstructionDecode(branch_delay_instr);
3747 set_register(return_addr_reg, current_pc + 2 * Instruction::kInstrSize); 3260 set_register(return_addr_reg, current_pc + 2 * Instruction::kInstrSize);
3748 set_pc(next_pc); 3261 set_pc(next_pc);
3749 pc_modified_ = true; 3262 pc_modified_ = true;
3750 break; 3263 break;
3751 } 3264 }
3265 case SLL:
3266 SetResult(rd_reg(), static_cast<int32_t>(rt()) << sa());
3267 break;
3268 case DSLL:
3269 SetResult(rd_reg(), rt() << sa());
3270 break;
3271 case DSLL32:
3272 SetResult(rd_reg(), rt() << sa() << 32);
3273 break;
3274 case SRL:
3275 if (rs_reg() == 0) {
3276 // Regular logical right shift of a word by a fixed number of
3277 // bits instruction. RS field is always equal to 0.
3278 // Sign-extend the 32-bit result.
3279 alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u()) >> sa());
3280 } else {
3281 // Logical right-rotate of a word by a fixed number of bits. This
3282 // is special case of SRL instruction, added in MIPS32 Release 2.
3283 // RS field is equal to 00001.
3284 alu_out = static_cast<int32_t>(
3285 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
3286 static_cast<const uint32_t>(sa())));
3287 }
3288 SetResult(rd_reg(), alu_out);
3289 break;
3290 case DSRL:
3291 SetResult(rd_reg(), rt_u() >> sa());
3292 break;
3293 case DSRL32:
3294 SetResult(rd_reg(), rt_u() >> sa() >> 32);
3295 break;
3296 case SRA:
3297 SetResult(rd_reg(), (int32_t)rt() >> sa());
3298 break;
3299 case DSRA:
3300 SetResult(rd_reg(), rt() >> sa());
3301 break;
3302 case DSRA32:
3303 SetResult(rd_reg(), rt() >> sa() >> 32);
3304 break;
3305 case SLLV:
3306 SetResult(rd_reg(), (int32_t)rt() << rs());
3307 break;
3308 case DSLLV:
3309 SetResult(rd_reg(), rt() << rs());
3310 break;
3311 case SRLV:
3312 if (sa() == 0) {
3313 // Regular logical right-shift of a word by a variable number of
3314 // bits instruction. SA field is always equal to 0.
3315 alu_out = static_cast<int32_t>((uint32_t)rt_u() >> rs());
3316 } else {
3317 // Logical right-rotate of a word by a variable number of bits.
3318 // This is special case od SRLV instruction, added in MIPS32
3319 // Release 2. SA field is equal to 00001.
3320 alu_out = static_cast<int32_t>(
3321 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
3322 static_cast<const uint32_t>(rs_u())));
3323 }
3324 SetResult(rd_reg(), alu_out);
3325 break;
3326 case DSRLV:
3327 if (sa() == 0) {
3328 // Regular logical right-shift of a word by a variable number of
3329 // bits instruction. SA field is always equal to 0.
3330 alu_out = rt_u() >> rs();
3331 } else {
3332 // Logical right-rotate of a word by a variable number of bits.
3333 // This is special case od SRLV instruction, added in MIPS32
3334 // Release 2. SA field is equal to 00001.
3335 alu_out =
3336 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
3337 static_cast<const uint32_t>(rs_u()));
3338 }
3339 SetResult(rd_reg(), alu_out);
3340 break;
3341 case SRAV:
3342 SetResult(rd_reg(), (int32_t)rt() >> rs());
3343 break;
3344 case DSRAV:
3345 SetResult(rd_reg(), rt() >> rs());
3346 break;
3347 case MFHI: // MFHI == CLZ on R6.
3348 if (kArchVariant != kMips64r6) {
3349 DCHECK(sa() == 0);
3350 alu_out = get_register(HI);
3351 } else {
3352 // MIPS spec: If no bits were set in GPR rs(), the result written to
3353 // GPR rd() is 32.
3354 DCHECK(sa() == 1);
3355 alu_out = base::bits::CountLeadingZeros32(static_cast<int32_t>(rs_u()));
3356 }
3357 SetResult(rd_reg(), alu_out);
3358 break;
3359 case MFLO:
3360 SetResult(rd_reg(), get_register(LO));
3361 break;
3752 // Instructions using HI and LO registers. 3362 // Instructions using HI and LO registers.
3753 case MULT: 3363 case MULT: { // MULT == D_MUL_MUH.
3364 int32_t rs_lo = static_cast<int32_t>(rs());
3365 int32_t rt_lo = static_cast<int32_t>(rt());
3366 i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo);
3754 if (kArchVariant != kMips64r6) { 3367 if (kArchVariant != kMips64r6) {
3755 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); 3368 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
3756 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); 3369 set_register(HI, static_cast<int32_t>(i64hilo >> 32));
3757 } else { 3370 } else {
3758 switch (instr->SaValue()) { 3371 switch (sa()) {
3759 case MUL_OP: 3372 case MUL_OP:
3760 set_register(rd_reg, static_cast<int32_t>(i64hilo & 0xffffffff)); 3373 set_register(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff));
3761 break; 3374 break;
3762 case MUH_OP: 3375 case MUH_OP:
3763 set_register(rd_reg, static_cast<int32_t>(i64hilo >> 32)); 3376 set_register(rd_reg(), static_cast<int32_t>(i64hilo >> 32));
3764 break; 3377 break;
3765 default: 3378 default:
3766 UNIMPLEMENTED_MIPS(); 3379 UNIMPLEMENTED_MIPS();
3767 break; 3380 break;
3768 } 3381 }
3769 } 3382 }
3770 break; 3383 break;
3384 }
3771 case MULTU: 3385 case MULTU:
3386 u64hilo = static_cast<uint64_t>(rs_u() & 0xffffffff) *
3387 static_cast<uint64_t>(rt_u() & 0xffffffff);
3772 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); 3388 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
3773 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); 3389 set_register(HI, static_cast<int32_t>(u64hilo >> 32));
3774 break; 3390 break;
3775 case DMULT: // DMULT == D_MUL_MUH. 3391 case DMULT: // DMULT == D_MUL_MUH.
3776 if (kArchVariant != kMips64r6) { 3392 if (kArchVariant != kMips64r6) {
3777 set_register(LO, static_cast<int64_t>(i128resultL)); 3393 set_register(LO, rs() * rt());
3778 set_register(HI, static_cast<int64_t>(i128resultH)); 3394 set_register(HI, MultiplyHighSigned(rs(), rt()));
3779 } else { 3395 } else {
3780 switch (instr->SaValue()) { 3396 switch (sa()) {
3781 case MUL_OP: 3397 case MUL_OP:
3782 set_register(rd_reg, static_cast<int64_t>(i128resultL)); 3398 set_register(rd_reg(), rs() * rt());
3783 break; 3399 break;
3784 case MUH_OP: 3400 case MUH_OP:
3785 set_register(rd_reg, static_cast<int64_t>(i128resultH)); 3401 set_register(rd_reg(), MultiplyHighSigned(rs(), rt()));
3786 break; 3402 break;
3787 default: 3403 default:
3788 UNIMPLEMENTED_MIPS(); 3404 UNIMPLEMENTED_MIPS();
3789 break; 3405 break;
3790 } 3406 }
3791 } 3407 }
3792 break; 3408 break;
3793 case DMULTU: 3409 case DMULTU:
3794 UNIMPLEMENTED_MIPS(); 3410 UNIMPLEMENTED_MIPS();
3795 break; 3411 break;
3796 case DSLL:
3797 set_register(rd_reg, alu_out);
3798 TraceRegWr(alu_out);
3799 break;
3800 case DIV: 3412 case DIV:
3801 case DDIV: { 3413 case DDIV: {
3802 const int64_t int_min_value = 3414 const int64_t int_min_value =
3803 instr->FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN; 3415 get_instr()->FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN;
3804 switch (kArchVariant) { 3416 switch (kArchVariant) {
3805 case kMips64r2: 3417 case kMips64r2:
3806 // Divide by zero and overflow was not checked in the 3418 // Divide by zero and overflow was not checked in the
3807 // configuration step - div and divu do not raise exceptions. On 3419 // configuration step - div and divu do not raise exceptions. On
3808 // division by 0 the result will be UNPREDICTABLE. On overflow 3420 // division by 0 the result will be UNPREDICTABLE. On overflow
3809 // (INT_MIN/-1), return INT_MIN which is what the hardware does. 3421 // (INT_MIN/-1), return INT_MIN which is what the hardware does.
3810 if (rs == int_min_value && rt == -1) { 3422 if (rs() == int_min_value && rt() == -1) {
3811 set_register(LO, int_min_value); 3423 set_register(LO, int_min_value);
3812 set_register(HI, 0); 3424 set_register(HI, 0);
3813 } else if (rt != 0) { 3425 } else if (rt() != 0) {
3814 set_register(LO, rs / rt); 3426 set_register(LO, rs() / rt());
3815 set_register(HI, rs % rt); 3427 set_register(HI, rs() % rt());
3816 } 3428 }
3817 break; 3429 break;
3818 case kMips64r6: 3430 case kMips64r6:
3819 switch (instr->SaValue()) { 3431 switch (sa()) {
3820 case DIV_OP: 3432 case DIV_OP:
3821 if (rs == int_min_value && rt == -1) { 3433 if (rs() == int_min_value && rt() == -1) {
3822 set_register(rd_reg, int_min_value); 3434 set_register(rd_reg(), int_min_value);
3823 } else if (rt != 0) { 3435 } else if (rt() != 0) {
3824 set_register(rd_reg, rs / rt); 3436 set_register(rd_reg(), rs() / rt());
3825 } 3437 }
3826 break; 3438 break;
3827 case MOD_OP: 3439 case MOD_OP:
3828 if (rs == int_min_value && rt == -1) { 3440 if (rs() == int_min_value && rt() == -1) {
3829 set_register(rd_reg, 0); 3441 set_register(rd_reg(), 0);
3830 } else if (rt != 0) { 3442 } else if (rt() != 0) {
3831 set_register(rd_reg, rs % rt); 3443 set_register(rd_reg(), rs() % rt());
3832 } 3444 }
3833 break; 3445 break;
3834 default: 3446 default:
3835 UNIMPLEMENTED_MIPS(); 3447 UNIMPLEMENTED_MIPS();
3836 break; 3448 break;
3837 } 3449 }
3838 break; 3450 break;
3839 default: 3451 default:
3840 break; 3452 break;
3841 } 3453 }
3842 break; 3454 break;
3843 } 3455 }
3844 case DIVU: 3456 case DIVU:
3845 if (rt_u != 0) { 3457 if (rt_u() != 0) {
3846 set_register(LO, rs_u / rt_u); 3458 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u());
3847 set_register(HI, rs_u % rt_u); 3459 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u());
3848 } 3460 set_register(LO, rs_u_32 / rt_u_32);
3461 set_register(HI, rs_u_32 % rt_u_32);
3462 }
3463 break;
3464 case DDIVU:
3465 if (rt_u() != 0) {
3466 set_register(LO, rs_u() / rt_u());
3467 set_register(HI, rs_u() % rt_u());
3468 }
3469 break;
3470 case ADD:
3471 case DADD:
3472 if (HaveSameSign(rs(), rt())) {
3473 if (rs() > 0) {
3474 if (rs() > (Registers::kMaxValue - rt())) {
3475 SignalException(kIntegerOverflow);
3476 }
3477 } else if (rs() < 0) {
3478 if (rs() < (Registers::kMinValue - rt())) {
3479 SignalException(kIntegerUnderflow);
3480 }
3481 }
3482 }
3483 SetResult(rd_reg(), rs() + rt());
3484 break;
3485 case ADDU: {
3486 int32_t alu32_out = static_cast<int32_t>(rs() + rt());
3487 // Sign-extend result of 32bit operation into 64bit register.
3488 SetResult(rd_reg(), static_cast<int64_t>(alu32_out));
3489 break;
3490 }
3491 case DADDU:
3492 SetResult(rd_reg(), rs() + rt());
3493 break;
3494 case SUB:
3495 case DSUB:
3496 if (!HaveSameSign(rs(), rt())) {
3497 if (rs() > 0) {
3498 if (rs() > (Registers::kMaxValue + rt())) {
3499 SignalException(kIntegerOverflow);
3500 }
3501 } else if (rs() < 0) {
3502 if (rs() < (Registers::kMinValue + rt())) {
3503 SignalException(kIntegerUnderflow);
3504 }
3505 }
3506 }
3507 SetResult(rd_reg(), rs() - rt());
3508 break;
3509 case SUBU: {
3510 int32_t alu32_out = static_cast<int32_t>(rs() - rt());
3511 // Sign-extend result of 32bit operation into 64bit register.
3512 SetResult(rd_reg(), static_cast<int64_t>(alu32_out));
3513 break;
3514 }
3515 case DSUBU:
3516 SetResult(rd_reg(), rs() - rt());
3517 break;
3518 case AND:
3519 SetResult(rd_reg(), rs() & rt());
3520 break;
3521 case OR:
3522 SetResult(rd_reg(), rs() | rt());
3523 break;
3524 case XOR:
3525 SetResult(rd_reg(), rs() ^ rt());
3526 break;
3527 case NOR:
3528 SetResult(rd_reg(), ~(rs() | rt()));
3529 break;
3530 case SLT:
3531 SetResult(rd_reg(), rs() < rt() ? 1 : 0);
3532 break;
3533 case SLTU:
3534 SetResult(rd_reg(), rs_u() < rt_u() ? 1 : 0);
3849 break; 3535 break;
3850 // Break and trap instructions. 3536 // Break and trap instructions.
3851 case BREAK: 3537 case BREAK:
3538 do_interrupt = true;
3539 break;
3852 case TGE: 3540 case TGE:
3541 do_interrupt = rs() >= rt();
3542 break;
3853 case TGEU: 3543 case TGEU:
3544 do_interrupt = rs_u() >= rt_u();
3545 break;
3854 case TLT: 3546 case TLT:
3547 do_interrupt = rs() < rt();
3548 break;
3855 case TLTU: 3549 case TLTU:
3550 do_interrupt = rs_u() < rt_u();
3551 break;
3856 case TEQ: 3552 case TEQ:
3553 do_interrupt = rs() == rt();
3554 break;
3857 case TNE: 3555 case TNE:
3858 if (do_interrupt) { 3556 do_interrupt = rs() != rt();
3859 SoftwareInterrupt(instr);
3860 }
3861 break; 3557 break;
3862 // Conditional moves. 3558 // Conditional moves.
3863 case MOVN: 3559 case MOVN:
3864 if (rt) { 3560 if (rt()) {
3865 set_register(rd_reg, rs); 3561 SetResult(rd_reg(), rs());
3866 TraceRegWr(rs);
3867 } 3562 }
3868 break; 3563 break;
3869 case MOVCI: { 3564 case MOVCI: {
3870 uint32_t cc = instr->FBccValue(); 3565 uint32_t cc = get_instr()->FBccValue();
3871 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 3566 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
3872 if (instr->Bit(16)) { // Read Tf bit. 3567 if (get_instr()->Bit(16)) { // Read Tf bit.
3873 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); 3568 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3874 } else { 3569 } else {
3875 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); 3570 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3876 } 3571 }
3877 break; 3572 break;
3878 } 3573 }
3879 case MOVZ: 3574 case MOVZ:
3880 if (!rt) { 3575 if (!rt()) {
3881 set_register(rd_reg, rs); 3576 SetResult(rd_reg(), rs());
3882 TraceRegWr(rs); 3577 }
3883 } 3578 break;
3884 break; 3579 default:
3885 default: // For other special opcodes we do the default operation. 3580 UNREACHABLE();
3886 set_register(rd_reg, alu_out); 3581 }
3887 TraceRegWr(alu_out); 3582 if (do_interrupt) {
3583 SoftwareInterrupt(get_instr());
3888 } 3584 }
3889 } 3585 }
3890 3586
3891 3587
3892 void Simulator::DecodeTypeRegisterSPECIAL2(Instruction* instr, 3588 void Simulator::DecodeTypeRegisterSPECIAL2() {
3893 const int32_t rd_reg, 3589 int64_t alu_out;
3894 int64_t alu_out) { 3590 switch (get_instr()->FunctionFieldRaw()) {
3895 switch (instr->FunctionFieldRaw()) {
3896 case MUL: 3591 case MUL:
3897 set_register(rd_reg, alu_out); 3592 alu_out = static_cast<int32_t>(rs_u()) * static_cast<int32_t>(rt_u());
3898 TraceRegWr(alu_out); 3593 SetResult(rd_reg(), alu_out);
3899 // HI and LO are UNPREDICTABLE after the operation. 3594 // HI and LO are UNPREDICTABLE after the operation.
3900 set_register(LO, Unpredictable); 3595 set_register(LO, Unpredictable);
3901 set_register(HI, Unpredictable); 3596 set_register(HI, Unpredictable);
3902 break; 3597 break;
3903 default: // For other special2 opcodes we do the default operation. 3598 case CLZ:
3904 set_register(rd_reg, alu_out); 3599 // MIPS32 spec: If no bits were set in GPR rs(), the result written to
3600 // GPR rd is 32.
3601 alu_out = base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u()));
3602 set_register(rd_reg(), alu_out);
3603 break;
3604 default:
3605 alu_out = 0x12345678;
3606 UNREACHABLE();
3905 } 3607 }
3906 } 3608 }
3907 3609
3908 3610
3909 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, 3611 void Simulator::DecodeTypeRegisterSPECIAL3() {
3910 const int32_t rt_reg, 3612 int64_t alu_out;
3911 const int32_t rd_reg, 3613 switch (get_instr()->FunctionFieldRaw()) {
3912 const int64_t alu_out) { 3614 case INS: { // Mips32r2 instruction.
3913 switch (instr->FunctionFieldRaw()) { 3615 // Interpret rd field as 5-bit msb of insert.
3914 case INS: 3616 uint16_t msb = rd_reg();
3915 // Ins instr leaves result in Rt, rather than Rd. 3617 // Interpret sa field as 5-bit lsb of insert.
3916 set_register(rt_reg, alu_out); 3618 uint16_t lsb = sa();
3917 TraceRegWr(alu_out); 3619 uint16_t size = msb - lsb + 1;
3918 break; 3620 uint64_t mask = (1ULL << size) - 1;
3919 case EXT: 3621 alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb);
3920 case DEXT: 3622 SetResult(rt_reg(), alu_out);
3921 // Dext/Ext instr leaves result in Rt, rather than Rd. 3623 break;
3922 set_register(rt_reg, alu_out); 3624 }
3923 TraceRegWr(alu_out); 3625 case EXT: { // Mips32r2 instruction.
3924 break; 3626 // Interpret rd field as 5-bit msb of extract.
3925 case BSHFL: 3627 uint16_t msb = rd_reg();
3926 case DBSHFL: 3628 // Interpret sa field as 5-bit lsb of extract.
3927 set_register(rd_reg, alu_out); 3629 uint16_t lsb = sa();
3928 TraceRegWr(alu_out); 3630 uint16_t size = msb + 1;
3929 break; 3631 uint64_t mask = (1ULL << size) - 1;
3632 alu_out = static_cast<int32_t>((rs_u() & (mask << lsb)) >> lsb);
3633 SetResult(rt_reg(), alu_out);
3634 break;
3635 }
3636 case DEXT: { // Mips32r2 instruction.
3637 // Interpret rd field as 5-bit msb of extract.
3638 uint16_t msb = rd_reg();
3639 // Interpret sa field as 5-bit lsb of extract.
3640 uint16_t lsb = sa();
3641 uint16_t size = msb + 1;
3642 uint64_t mask = (1ULL << size) - 1;
3643 alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
3644 SetResult(rt_reg(), alu_out);
3645 break;
3646 }
3647 case BSHFL: {
3648 int32_t sa = get_instr()->SaFieldRaw() >> kSaShift;
3649 switch (sa) {
3650 case BITSWAP: {
3651 uint32_t input = static_cast<uint32_t>(rt());
3652 uint32_t output = 0;
3653 uint8_t i_byte, o_byte;
3654
3655 // Reverse the bit in byte for each individual byte
3656 for (int i = 0; i < 4; i++) {
3657 output = output >> 8;
3658 i_byte = input & 0xff;
3659
3660 // Fast way to reverse bits in byte
3661 // Devised by Sean Anderson, July 13, 2001
3662 o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
3663 (i_byte * 0x8020LU & 0x88440LU)) *
3664 0x10101LU >>
3665 16);
3666
3667 output = output | (static_cast<uint32_t>(o_byte << 24));
3668 input = input >> 8;
3669 }
3670
3671 alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
3672 break;
3673 }
3674 case SEB:
3675 case SEH:
3676 case WSBH:
3677 alu_out = 0x12345678;
3678 UNREACHABLE();
3679 break;
3680 default: {
3681 const uint8_t bp2 = get_instr()->Bp2Value();
3682 sa >>= kBp2Bits;
3683 switch (sa) {
3684 case ALIGN: {
3685 if (bp2 == 0) {
3686 alu_out = static_cast<int32_t>(rt());
3687 } else {
3688 uint64_t rt_hi = rt() << (8 * bp2);
3689 uint64_t rs_lo = rs() >> (8 * (4 - bp2));
3690 alu_out = static_cast<int32_t>(rt_hi | rs_lo);
3691 }
3692 break;
3693 }
3694 default:
3695 alu_out = 0x12345678;
3696 UNREACHABLE();
3697 break;
3698 }
3699 break;
3700 }
3701 }
3702 SetResult(rd_reg(), alu_out);
3703 break;
3704 }
3705 case DBSHFL: {
3706 int32_t sa = get_instr()->SaFieldRaw() >> kSaShift;
3707 switch (sa) {
3708 case DBITSWAP: {
3709 switch (sa) {
3710 case DBITSWAP_SA: { // Mips64r6
3711 uint64_t input = static_cast<uint64_t>(rt());
3712 uint64_t output = 0;
3713 uint8_t i_byte, o_byte;
3714
3715 // Reverse the bit in byte for each individual byte
3716 for (int i = 0; i < 8; i++) {
3717 output = output >> 8;
3718 i_byte = input & 0xff;
3719
3720 // Fast way to reverse bits in byte
3721 // Devised by Sean Anderson, July 13, 2001
3722 o_byte =
3723 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
3724 (i_byte * 0x8020LU & 0x88440LU)) *
3725 0x10101LU >>
3726 16);
3727
3728 output = output | ((static_cast<uint64_t>(o_byte) << 56));
3729 input = input >> 8;
3730 }
3731
3732 alu_out = static_cast<int64_t>(output);
3733 break;
3734 }
3735 }
3736 break;
3737 }
3738 case DSBH:
3739 case DSHD:
3740 alu_out = 0x12345678;
3741 UNREACHABLE();
3742 break;
3743 default: {
3744 const uint8_t bp3 = get_instr()->Bp3Value();
3745 sa >>= kBp3Bits;
3746 switch (sa) {
3747 case DALIGN: {
3748 if (bp3 == 0) {
3749 alu_out = static_cast<int64_t>(rt());
3750 } else {
3751 uint64_t rt_hi = rt() << (8 * bp3);
3752 uint64_t rs_lo = rs() >> (8 * (8 - bp3));
3753 alu_out = static_cast<int64_t>(rt_hi | rs_lo);
3754 }
3755 break;
3756 }
3757 default:
3758 alu_out = 0x12345678;
3759 UNREACHABLE();
3760 break;
3761 }
3762 break;
3763 }
3764 }
3765 SetResult(rd_reg(), alu_out);
3766 break;
3767 }
3930 default: 3768 default:
3931 UNREACHABLE(); 3769 UNREACHABLE();
3932 } 3770 }
3933 } 3771 }
3934 3772
3935 3773
3936 void Simulator::DecodeTypeRegister(Instruction* instr) { 3774 void Simulator::DecodeTypeRegister(Instruction* instr) {
3937 // Instruction fields. 3775 set_instr(instr);
3938 const Opcode op = instr->OpcodeFieldRaw();
3939 const int32_t rs_reg = instr->RsValue();
3940 const int64_t rs = get_register(rs_reg);
3941 const uint64_t rs_u = static_cast<uint32_t>(rs);
3942 const int32_t rt_reg = instr->RtValue();
3943 const int64_t rt = get_register(rt_reg);
3944 const uint64_t rt_u = static_cast<uint32_t>(rt);
3945 const int32_t rd_reg = instr->RdValue();
3946
3947 const int32_t fr_reg = instr->FrValue();
3948 const int32_t fs_reg = instr->FsValue();
3949 const int32_t ft_reg = instr->FtValue();
3950 const int32_t fd_reg = instr->FdValue();
3951 int64_t i64hilo = 0;
3952 uint64_t u64hilo = 0;
3953
3954 // ALU output.
3955 // It should not be used as is. Instructions using it should always
3956 // initialize it first.
3957 int64_t alu_out = 0x12345678;
3958
3959 // For break and trap instructions.
3960 bool do_interrupt = false;
3961
3962 // For jr and jalr.
3963 // Get current pc.
3964 int64_t current_pc = get_pc();
3965 // Next pc
3966 int64_t next_pc = 0;
3967 int32_t return_addr_reg = 31;
3968
3969 int64_t i128resultH;
3970 int64_t i128resultL;
3971
3972 // Set up the variables if needed before executing the instruction.
3973 ConfigureTypeRegister(instr,
3974 &alu_out,
3975 &i64hilo,
3976 &u64hilo,
3977 &next_pc,
3978 &return_addr_reg,
3979 &do_interrupt,
3980 &i128resultH,
3981 &i128resultL);
3982
3983 // ---------- Raise exceptions triggered.
3984 SignalExceptions();
3985 3776
3986 // ---------- Execution. 3777 // ---------- Execution.
3987 switch (op) { 3778 switch (instr->OpcodeFieldRaw()) {
3988 case COP1: 3779 case COP1:
3989 DecodeTypeRegisterCOP1(instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, rd_reg, 3780 DecodeTypeRegisterCOP1();
3990 fr_reg, fs_reg, ft_reg, fd_reg, alu_out);
3991 break; 3781 break;
3992 case COP1X: 3782 case COP1X:
3993 DecodeTypeRegisterCOP1X(instr, fr_reg, fs_reg, ft_reg, fd_reg); 3783 DecodeTypeRegisterCOP1X();
3994 break; 3784 break;
3995 case SPECIAL: 3785 case SPECIAL:
3996 DecodeTypeRegisterSPECIAL( 3786 DecodeTypeRegisterSPECIAL();
3997 instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, rd_reg, fr_reg, fs_reg,
3998 ft_reg, fd_reg, i64hilo, u64hilo, alu_out, do_interrupt, current_pc,
3999 next_pc, return_addr_reg, i128resultH, i128resultL);
4000 break; 3787 break;
4001 case SPECIAL2: 3788 case SPECIAL2:
4002 DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out); 3789 DecodeTypeRegisterSPECIAL2();
4003 break; 3790 break;
4004 case SPECIAL3: 3791 case SPECIAL3:
4005 switch (instr->FunctionFieldRaw()) { 3792 switch (instr->FunctionFieldRaw()) {
4006 case BSHFL: { 3793 case BSHFL: {
4007 int sa = instr->SaValue(); 3794 int32_t saVal = sa();
4008 sa >>= kBp2Bits; 3795 saVal >>= kBp2Bits;
4009 switch (sa) { 3796 switch (saVal) {
4010 case ALIGN: { 3797 case ALIGN: {
4011 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); 3798 DecodeTypeRegisterSPECIAL3();
4012 break; 3799 break;
4013 } 3800 }
4014 } 3801 }
4015 } 3802 }
4016 case DBSHFL: { 3803 case DBSHFL: {
4017 int sa = instr->SaValue(); 3804 int32_t saVal = sa();
4018 sa >>= kBp3Bits; 3805 saVal >>= kBp2Bits;
4019 switch (sa) { 3806 switch (saVal) {
4020 case DALIGN: { 3807 case DALIGN: {
4021 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); 3808 DecodeTypeRegisterSPECIAL3();
4022 break; 3809 break;
4023 } 3810 }
4024 } 3811 }
4025 } 3812 }
4026 default: 3813 default:
4027 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); 3814 DecodeTypeRegisterSPECIAL3();
4028 break; 3815 break;
4029 } 3816 }
4030 break; 3817 break;
4031 // Unimplemented opcodes raised an error in the configuration step before, 3818 // Unimplemented opcodes raised an error in the configuration step before,
4032 // so we can use the default here to set the destination register in common 3819 // so we can use the default here to set the destination register in common
4033 // cases. 3820 // cases.
4034 default: 3821 default:
4035 set_register(rd_reg, alu_out); 3822 UNREACHABLE();
4036 TraceRegWr(alu_out);
4037 } 3823 }
4038 } 3824 }
4039 3825
4040 3826
3827 // Branch instructions common part.
3828 #define BranchAndLinkHelper(do_branch) \
3829 execute_branch_delay_instruction = true; \
3830 if (do_branch) { \
3831 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \
3832 set_register(31, current_pc + kBranchReturnOffset); \
3833 } else { \
3834 next_pc = current_pc + kBranchReturnOffset; \
3835 }
3836
3837
3838 #define BranchHelper(do_branch) \
3839 execute_branch_delay_instruction = true; \
3840 if (do_branch) { \
3841 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \
3842 } else { \
3843 next_pc = current_pc + kBranchReturnOffset; \
3844 }
3845
3846
4041 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). 3847 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
4042 void Simulator::DecodeTypeImmediate(Instruction* instr) { 3848 void Simulator::DecodeTypeImmediate(Instruction* instr) {
4043 // Instruction fields. 3849 // Instruction fields.
4044 Opcode op = instr->OpcodeFieldRaw(); 3850 Opcode op = instr->OpcodeFieldRaw();
4045 int32_t rs_reg = instr->RsValue(); 3851 int32_t rs_reg = instr->RsValue();
4046 int64_t rs = get_register(instr->RsValue()); 3852 int64_t rs = get_register(instr->RsValue());
4047 uint64_t rs_u = static_cast<uint64_t>(rs); 3853 uint64_t rs_u = static_cast<uint64_t>(rs);
4048 int32_t rt_reg = instr->RtValue(); // Destination register. 3854 int32_t rt_reg = instr->RtValue(); // Destination register.
4049 int64_t rt = get_register(rt_reg); 3855 int64_t rt = get_register(rt_reg);
4050 int16_t imm16 = instr->Imm16Value(); 3856 int16_t imm16 = instr->Imm16Value();
4051 int32_t imm18 = instr->Imm18Value(); 3857 int32_t imm18 = instr->Imm18Value();
4052 int32_t imm19 = instr->Imm19Value();
4053 int32_t imm21 = instr->Imm21Value(); 3858 int32_t imm21 = instr->Imm21Value();
4054 int32_t imm26 = instr->Imm26Value(); 3859 int32_t imm26 = instr->Imm26Value();
4055 3860
4056 int32_t ft_reg = instr->FtValue(); // Destination register. 3861 int32_t ft_reg = instr->FtValue(); // Destination register.
4057 int64_t ft = get_fpu_register(ft_reg); 3862 int64_t ft = get_fpu_register(ft_reg);
4058 3863
4059 // Zero extended immediate. 3864 // Zero extended immediate.
4060 uint64_t oe_imm16 = 0xffff & imm16; 3865 uint64_t oe_imm16 = 0xffff & imm16;
4061 // Sign extended immediate. 3866 // Sign extended immediate.
4062 int64_t se_imm16 = imm16; 3867 int64_t se_imm16 = imm16;
4063 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0); 3868 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0);
4064 int64_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0);
4065 int64_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfffffffffc000000 : 0); 3869 int64_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfffffffffc000000 : 0);
4066 3870
4067
4068 // Get current pc. 3871 // Get current pc.
4069 int64_t current_pc = get_pc(); 3872 int64_t current_pc = get_pc();
4070 // Next pc. 3873 // Next pc.
4071 int64_t next_pc = bad_ra; 3874 int64_t next_pc = bad_ra;
4072 // pc increment
4073 int16_t pc_increment;
4074 3875
4075 // Used for conditional branch instructions. 3876 // Used for conditional branch instructions.
4076 bool do_branch = false;
4077 bool execute_branch_delay_instruction = false; 3877 bool execute_branch_delay_instruction = false;
4078 3878
4079 // Used for arithmetic instructions. 3879 // Used for arithmetic instructions.
4080 int64_t alu_out = 0; 3880 int64_t alu_out = 0;
4081 // Floating point.
4082 double fp_out = 0.0;
4083 uint32_t cc, cc_value, fcsr_cc;
4084 3881
4085 // Used for memory instructions. 3882 // Used for memory instructions.
4086 int64_t addr = 0x0; 3883 int64_t addr = 0x0;
4087 // Value to be written in memory.
4088 uint64_t mem_value = 0x0;
4089 // Alignment for 32-bit integers used in LWL, LWR, etc. 3884 // Alignment for 32-bit integers used in LWL, LWR, etc.
4090 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; 3885 const int kInt32AlignmentMask = sizeof(uint32_t) - 1;
4091 3886
4092 // ---------- Configuration (and execution for REGIMM). 3887 // ---------- Configuration (and execution for REGIMM).
4093 switch (op) { 3888 switch (op) {
4094 // ------------- COP1. Coprocessor instructions. 3889 // ------------- COP1. Coprocessor instructions.
4095 case COP1: 3890 case COP1:
4096 switch (instr->RsFieldRaw()) { 3891 switch (instr->RsFieldRaw()) {
4097 case BC1: // Branch on coprocessor condition. 3892 case BC1: { // Branch on coprocessor condition.
4098 cc = instr->FBccValue(); 3893 uint32_t cc = instr->FBccValue();
4099 fcsr_cc = get_fcsr_condition_bit(cc); 3894 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
4100 cc_value = test_fcsr_bit(fcsr_cc); 3895 uint32_t cc_value = test_fcsr_bit(fcsr_cc);
4101 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 3896 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
4102 execute_branch_delay_instruction = true; 3897 execute_branch_delay_instruction = true;
4103 // Set next_pc. 3898 // Set next_pc.
4104 if (do_branch) { 3899 if (do_branch) {
4105 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 3900 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4106 } else { 3901 } else {
4107 next_pc = current_pc + kBranchReturnOffset; 3902 next_pc = current_pc + kBranchReturnOffset;
4108 } 3903 }
4109 break; 3904 break;
3905 }
4110 case BC1EQZ: 3906 case BC1EQZ:
4111 do_branch = (ft & 0x1) ? false : true;
4112 execute_branch_delay_instruction = true; 3907 execute_branch_delay_instruction = true;
4113 // Set next_pc. 3908 // Set next_pc.
4114 if (do_branch) { 3909 if (!(ft & 0x1)) {
4115 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 3910 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4116 } else { 3911 } else {
4117 next_pc = current_pc + kBranchReturnOffset; 3912 next_pc = current_pc + kBranchReturnOffset;
4118 } 3913 }
4119 break; 3914 break;
4120 case BC1NEZ: 3915 case BC1NEZ:
4121 do_branch = (ft & 0x1) ? true : false;
4122 execute_branch_delay_instruction = true; 3916 execute_branch_delay_instruction = true;
4123 // Set next_pc. 3917 // Set next_pc.
4124 if (do_branch) { 3918 if (ft & 0x1) {
4125 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 3919 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4126 } else { 3920 } else {
4127 next_pc = current_pc + kBranchReturnOffset; 3921 next_pc = current_pc + kBranchReturnOffset;
4128 } 3922 }
4129 break; 3923 break;
4130 default: 3924 default:
4131 UNREACHABLE(); 3925 UNREACHABLE();
4132 } 3926 }
4133 break; 3927 break;
4134 // ------------- REGIMM class. 3928 // ------------- REGIMM class.
4135 case REGIMM: 3929 case REGIMM:
4136 switch (instr->RtFieldRaw()) { 3930 switch (instr->RtFieldRaw()) {
4137 case BLTZ: 3931 case BLTZ:
4138 do_branch = (rs < 0); 3932 BranchHelper(rs < 0);
3933 break;
3934 case BGEZ:
3935 BranchHelper(rs >= 0);
4139 break; 3936 break;
4140 case BLTZAL: 3937 case BLTZAL:
4141 do_branch = rs < 0; 3938 BranchAndLinkHelper(rs < 0);
4142 break;
4143 case BGEZ:
4144 do_branch = rs >= 0;
4145 break; 3939 break;
4146 case BGEZAL: 3940 case BGEZAL:
4147 do_branch = rs >= 0; 3941 BranchAndLinkHelper(rs >= 0);
4148 break; 3942 break;
4149 default: 3943 default:
4150 UNREACHABLE(); 3944 UNREACHABLE();
4151 } 3945 }
4152 switch (instr->RtFieldRaw()) { 3946 break; // case REGIMM.
4153 case BLTZ:
4154 case BLTZAL:
4155 case BGEZ:
4156 case BGEZAL:
4157 // Branch instructions common part.
4158 execute_branch_delay_instruction = true;
4159 // Set next_pc.
4160 if (do_branch) {
4161 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4162 if (instr->IsLinkingInstruction()) {
4163 set_register(31, current_pc + kBranchReturnOffset);
4164 }
4165 } else {
4166 next_pc = current_pc + kBranchReturnOffset;
4167 }
4168 default:
4169 break;
4170 }
4171 break; // case REGIMM.
4172 // ------------- Branch instructions. 3947 // ------------- Branch instructions.
4173 // When comparing to zero, the encoding of rt field is always 0, so we don't 3948 // When comparing to zero, the encoding of rt field is always 0, so we don't
4174 // need to replace rt with zero. 3949 // need to replace rt with zero.
4175 case BEQ: 3950 case BEQ:
4176 do_branch = (rs == rt); 3951 BranchHelper(rs == rt);
4177 break; 3952 break;
4178 case BNE: 3953 case BNE:
4179 do_branch = rs != rt; 3954 BranchHelper(rs != rt);
4180 break; 3955 break;
4181 case BLEZ: 3956 case BLEZ:
4182 do_branch = rs <= 0; 3957 BranchHelper(rs <= 0);
4183 break; 3958 break;
4184 case BGTZ: 3959 case BGTZ:
4185 do_branch = rs > 0; 3960 BranchHelper(rs > 0);
4186 break; 3961 break;
4187 case POP66: { 3962 case POP66: {
4188 if (rs_reg) { // BEQZC 3963 if (rs_reg) { // BEQZC
4189 int32_t se_imm21 = 3964 int32_t se_imm21 =
4190 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); 3965 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits));
4191 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); 3966 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits);
4192 if (rs == 0) 3967 if (rs == 0)
4193 next_pc = current_pc + 4 + (se_imm21 << 2); 3968 next_pc = current_pc + 4 + (se_imm21 << 2);
4194 else 3969 else
4195 next_pc = current_pc + 4; 3970 next_pc = current_pc + 4;
(...skipping 13 matching lines...) Expand all
4209 next_pc = current_pc + 4 + (se_imm26 << 2); 3984 next_pc = current_pc + 4 + (se_imm26 << 2);
4210 set_pc(next_pc); 3985 set_pc(next_pc);
4211 pc_modified_ = true; 3986 pc_modified_ = true;
4212 break; 3987 break;
4213 } 3988 }
4214 // ------------- Arithmetic instructions. 3989 // ------------- Arithmetic instructions.
4215 case ADDI: 3990 case ADDI:
4216 case DADDI: 3991 case DADDI:
4217 if (HaveSameSign(rs, se_imm16)) { 3992 if (HaveSameSign(rs, se_imm16)) {
4218 if (rs > 0) { 3993 if (rs > 0) {
4219 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); 3994 if (rs > Registers::kMaxValue - se_imm16) {
3995 SignalException(kIntegerOverflow);
3996 }
4220 } else if (rs < 0) { 3997 } else if (rs < 0) {
4221 exceptions[kIntegerUnderflow] = 3998 if (rs < Registers::kMinValue - se_imm16) {
4222 rs < (Registers::kMinValue - se_imm16); 3999 SignalException(kIntegerUnderflow);
4000 }
4223 } 4001 }
4224 } 4002 }
4225 alu_out = rs + se_imm16; 4003 SetResult(rt_reg, rs + se_imm16);
4226 break; 4004 break;
4227 case ADDIU: { 4005 case ADDIU: {
4228 int32_t alu32_out = static_cast<int32_t>(rs + se_imm16); 4006 int32_t alu32_out = static_cast<int32_t>(rs + se_imm16);
4229 // Sign-extend result of 32bit operation into 64bit register. 4007 // Sign-extend result of 32bit operation into 64bit register.
4230 alu_out = static_cast<int64_t>(alu32_out); 4008 SetResult(rt_reg, static_cast<int64_t>(alu32_out));
4231 break; 4009 break;
4232 } 4010 }
4233 case DADDIU: 4011 case DADDIU:
4234 alu_out = rs + se_imm16; 4012 SetResult(rt_reg, rs + se_imm16);
4235 break; 4013 break;
4236 case SLTI: 4014 case SLTI:
4237 alu_out = (rs < se_imm16) ? 1 : 0; 4015 SetResult(rt_reg, rs < se_imm16 ? 1 : 0);
4238 break; 4016 break;
4239 case SLTIU: 4017 case SLTIU:
4240 alu_out = (rs_u < static_cast<uint64_t>(se_imm16)) ? 1 : 0; 4018 SetResult(rt_reg, rs_u < static_cast<uint64_t>(se_imm16) ? 1 : 0);
4241 break; 4019 break;
4242 case ANDI: 4020 case ANDI:
4243 alu_out = rs & oe_imm16; 4021 SetResult(rt_reg, rs & oe_imm16);
4244 break; 4022 break;
4245 case ORI: 4023 case ORI:
4246 alu_out = rs | oe_imm16; 4024 SetResult(rt_reg, rs | oe_imm16);
4247 break; 4025 break;
4248 case XORI: 4026 case XORI:
4249 alu_out = rs ^ oe_imm16; 4027 SetResult(rt_reg, rs ^ oe_imm16);
4250 break; 4028 break;
4251 case LUI: { 4029 case LUI: {
4252 int32_t alu32_out = static_cast<int32_t>(oe_imm16 << 16); 4030 int32_t alu32_out = static_cast<int32_t>(oe_imm16 << 16);
4253 // Sign-extend result of 32bit operation into 64bit register. 4031 // Sign-extend result of 32bit operation into 64bit register.
4254 alu_out = static_cast<int64_t>(alu32_out); 4032 SetResult(rt_reg, static_cast<int64_t>(alu32_out));
4255 break; 4033 break;
4256 } 4034 }
4257 // ------------- Memory instructions. 4035 // ------------- Memory instructions.
4258 case LB: 4036 case LB:
4259 addr = rs + se_imm16; 4037 set_register(rt_reg, ReadB(rs + se_imm16));
4260 alu_out = ReadB(addr);
4261 break; 4038 break;
4262 case LH: 4039 case LH:
4263 addr = rs + se_imm16; 4040 set_register(rt_reg, ReadH(rs + se_imm16, instr));
4264 alu_out = ReadH(addr, instr);
4265 break; 4041 break;
4266 case LWL: { 4042 case LWL: {
4267 // al_offset is offset of the effective address within an aligned word. 4043 // al_offset is offset of the effective address within an aligned word.
4268 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4044 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4269 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4045 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4270 uint32_t mask = (1 << byte_shift * 8) - 1; 4046 uint32_t mask = (1 << byte_shift * 8) - 1;
4271 addr = rs + se_imm16 - al_offset; 4047 addr = rs + se_imm16 - al_offset;
4272 alu_out = ReadW(addr, instr); 4048 alu_out = ReadW(addr, instr);
4273 alu_out <<= byte_shift * 8; 4049 alu_out <<= byte_shift * 8;
4274 alu_out |= rt & mask; 4050 alu_out |= rt & mask;
4051 set_register(rt_reg, alu_out);
4275 break; 4052 break;
4276 } 4053 }
4277 case LW: 4054 case LW:
4278 addr = rs + se_imm16; 4055 set_register(rt_reg, ReadW(rs + se_imm16, instr));
4279 alu_out = ReadW(addr, instr);
4280 break; 4056 break;
4281 case LWU: 4057 case LWU:
4282 addr = rs + se_imm16; 4058 set_register(rt_reg, ReadWU(rs + se_imm16, instr));
4283 alu_out = ReadWU(addr, instr);
4284 break; 4059 break;
4285 case LD: 4060 case LD:
4286 addr = rs + se_imm16; 4061 set_register(rt_reg, Read2W(rs + se_imm16, instr));
4287 alu_out = Read2W(addr, instr);
4288 break; 4062 break;
4289 case LBU: 4063 case LBU:
4290 addr = rs + se_imm16; 4064 set_register(rt_reg, ReadBU(rs + se_imm16));
4291 alu_out = ReadBU(addr);
4292 break; 4065 break;
4293 case LHU: 4066 case LHU:
4294 addr = rs + se_imm16; 4067 set_register(rt_reg, ReadHU(rs + se_imm16, instr));
4295 alu_out = ReadHU(addr, instr);
4296 break; 4068 break;
4297 case LWR: { 4069 case LWR: {
4298 // al_offset is offset of the effective address within an aligned word. 4070 // al_offset is offset of the effective address within an aligned word.
4299 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4071 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4300 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4072 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4301 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; 4073 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
4302 addr = rs + se_imm16 - al_offset; 4074 addr = rs + se_imm16 - al_offset;
4303 alu_out = ReadW(addr, instr); 4075 alu_out = ReadW(addr, instr);
4304 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; 4076 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
4305 alu_out |= rt & mask; 4077 alu_out |= rt & mask;
4078 set_register(rt_reg, alu_out);
4306 break; 4079 break;
4307 } 4080 }
4308 case SB: 4081 case SB:
4309 addr = rs + se_imm16; 4082 WriteB(rs + se_imm16, static_cast<int8_t>(rt));
4310 break; 4083 break;
4311 case SH: 4084 case SH:
4312 addr = rs + se_imm16; 4085 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr);
4313 break; 4086 break;
4314 case SWL: { 4087 case SWL: {
4315 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4088 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4316 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4089 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4317 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; 4090 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
4318 addr = rs + se_imm16 - al_offset; 4091 addr = rs + se_imm16 - al_offset;
4319 mem_value = ReadW(addr, instr) & mask; 4092 uint64_t mem_value = ReadW(addr, instr) & mask;
4320 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8; 4093 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
4094 WriteW(addr, static_cast<int32_t>(mem_value), instr);
4321 break; 4095 break;
4322 } 4096 }
4323 case SW: 4097 case SW:
4098 WriteW(rs + se_imm16, static_cast<int32_t>(rt), instr);
4099 break;
4324 case SD: 4100 case SD:
4325 addr = rs + se_imm16; 4101 Write2W(rs + se_imm16, rt, instr);
4326 break; 4102 break;
4327 case SWR: { 4103 case SWR: {
4328 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4104 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4329 uint32_t mask = (1 << al_offset * 8) - 1; 4105 uint32_t mask = (1 << al_offset * 8) - 1;
4330 addr = rs + se_imm16 - al_offset; 4106 addr = rs + se_imm16 - al_offset;
4331 mem_value = ReadW(addr, instr); 4107 uint64_t mem_value = ReadW(addr, instr);
4332 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4108 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4109 WriteW(addr, static_cast<int32_t>(mem_value), instr);
4333 break; 4110 break;
4334 } 4111 }
4335 case LWC1: 4112 case LWC1:
4336 addr = rs + se_imm16; 4113 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits.
4337 alu_out = ReadW(addr, instr); 4114 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr));
4338 break; 4115 break;
4339 case LDC1: 4116 case LDC1:
4340 addr = rs + se_imm16; 4117 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr));
4341 fp_out = ReadD(addr, instr);
4342 break; 4118 break;
4343 case SWC1: 4119 case SWC1: {
4120 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg));
4121 WriteW(rs + se_imm16, alu_out_32, instr);
4122 break;
4123 }
4344 case SDC1: 4124 case SDC1:
4345 addr = rs + se_imm16; 4125 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr);
4346 break; 4126 break;
4347 // ------------- JIALC and BNEZC instructions. 4127 // ------------- JIALC and BNEZC instructions.
4348 case POP76: 4128 case POP76: {
4349 // Next pc. 4129 // Next pc.
4350 next_pc = rt + se_imm16; 4130 next_pc = rt + se_imm16;
4351 // The instruction after the jump is NOT executed. 4131 // The instruction after the jump is NOT executed.
4352 pc_increment = Instruction::kInstrSize; 4132 uint16_t pc_increment = Instruction::kInstrSize;
4353 if (instr->IsLinkingInstruction()) { 4133 if (instr->IsLinkingInstruction()) {
4354 set_register(31, current_pc + pc_increment); 4134 set_register(31, current_pc + pc_increment);
4355 } 4135 }
4356 set_pc(next_pc); 4136 set_pc(next_pc);
4357 pc_modified_ = true; 4137 pc_modified_ = true;
4358 break; 4138 break;
4139 }
4359 // ------------- PC-Relative instructions. 4140 // ------------- PC-Relative instructions.
4360 case PCREL: { 4141 case PCREL: {
4361 // rt field: checking 5-bits. 4142 // rt field: checking 5-bits.
4362 uint8_t rt = (imm21 >> kImm16Bits); 4143 uint8_t rt = (imm21 >> kImm16Bits);
4363 switch (rt) { 4144 switch (rt) {
4364 case ALUIPC: 4145 case ALUIPC:
4365 addr = current_pc + (se_imm16 << 16); 4146 addr = current_pc + (se_imm16 << 16);
4366 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; 4147 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4367 break; 4148 break;
4368 case AUIPC: 4149 case AUIPC:
4369 alu_out = current_pc + (se_imm16 << 16); 4150 alu_out = current_pc + (se_imm16 << 16);
4370 break; 4151 break;
4371 default: { 4152 default: {
4153 int32_t imm19 = instr->Imm19Value();
4372 // rt field: checking the most significant 3-bits. 4154 // rt field: checking the most significant 3-bits.
4373 rt = (imm21 >> kImm18Bits); 4155 rt = (imm21 >> kImm18Bits);
4374 switch (rt) { 4156 switch (rt) {
4375 case LDPC: 4157 case LDPC:
4376 addr = 4158 addr =
4377 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3); 4159 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3);
4378 alu_out = Read2W(addr, instr); 4160 alu_out = Read2W(addr, instr);
4379 break; 4161 break;
4380 default: { 4162 default: {
4381 // rt field: checking the most significant 2-bits. 4163 // rt field: checking the most significant 2-bits.
4382 rt = (imm21 >> kImm19Bits); 4164 rt = (imm21 >> kImm19Bits);
4383 switch (rt) { 4165 switch (rt) {
4384 case LWUPC: { 4166 case LWUPC: {
4385 int32_t offset = imm19;
4386 // Set sign. 4167 // Set sign.
4387 offset <<= (kOpcodeBits + kRsBits + 2); 4168 imm19 <<= (kOpcodeBits + kRsBits + 2);
4388 offset >>= (kOpcodeBits + kRsBits + 2); 4169 imm19 >>= (kOpcodeBits + kRsBits + 2);
4389 addr = current_pc + (offset << 2); 4170 addr = current_pc + (imm19 << 2);
4390 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 4171 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
4391 alu_out = *ptr; 4172 alu_out = *ptr;
4392 break; 4173 break;
4393 } 4174 }
4394 case LWPC: { 4175 case LWPC: {
4395 int32_t offset = imm19;
4396 // Set sign. 4176 // Set sign.
4397 offset <<= (kOpcodeBits + kRsBits + 2); 4177 imm19 <<= (kOpcodeBits + kRsBits + 2);
4398 offset >>= (kOpcodeBits + kRsBits + 2); 4178 imm19 >>= (kOpcodeBits + kRsBits + 2);
4399 addr = current_pc + (offset << 2); 4179 addr = current_pc + (imm19 << 2);
4400 int32_t* ptr = reinterpret_cast<int32_t*>(addr); 4180 int32_t* ptr = reinterpret_cast<int32_t*>(addr);
4401 alu_out = *ptr; 4181 alu_out = *ptr;
4402 break; 4182 break;
4403 } 4183 }
4404 case ADDIUPC: 4184 case ADDIUPC: {
4185 int64_t se_imm19 =
4186 imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0);
4405 alu_out = current_pc + (se_imm19 << 2); 4187 alu_out = current_pc + (se_imm19 << 2);
4406 break; 4188 break;
4189 }
4407 default: 4190 default:
4408 UNREACHABLE(); 4191 UNREACHABLE();
4409 break; 4192 break;
4410 } 4193 }
4411 break; 4194 break;
4412 } 4195 }
4413 } 4196 }
4414 break; 4197 break;
4415 } 4198 }
4416 } 4199 }
4200 set_register(rs_reg, alu_out);
4417 break; 4201 break;
4418 } 4202 }
4419 default: 4203 default:
4420 UNREACHABLE(); 4204 UNREACHABLE();
4421 } 4205 }
4422 4206
4423 // ---------- Raise exceptions triggered.
4424 SignalExceptions();
4425
4426 // ---------- Execution.
4427 switch (op) {
4428 // ------------- Branch instructions.
4429 case BEQ:
4430 case BNE:
4431 case BLEZ:
4432 case BGTZ:
4433 // Branch instructions common part.
4434 execute_branch_delay_instruction = true;
4435 // Set next_pc.
4436 if (do_branch) {
4437 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4438 if (instr->IsLinkingInstruction()) {
4439 set_register(31, current_pc + 2* Instruction::kInstrSize);
4440 }
4441 } else {
4442 next_pc = current_pc + 2 * Instruction::kInstrSize;
4443 }
4444 break;
4445 // ------------- Arithmetic instructions.
4446 case ADDI:
4447 case DADDI:
4448 case ADDIU:
4449 case DADDIU:
4450 case SLTI:
4451 case SLTIU:
4452 case ANDI:
4453 case ORI:
4454 case XORI:
4455 case LUI:
4456 set_register(rt_reg, alu_out);
4457 TraceRegWr(alu_out);
4458 break;
4459 // ------------- Memory instructions.
4460 case LB:
4461 case LH:
4462 case LWL:
4463 case LW:
4464 case LWU:
4465 case LD:
4466 case LBU:
4467 case LHU:
4468 case LWR:
4469 set_register(rt_reg, alu_out);
4470 break;
4471 case SB:
4472 WriteB(addr, static_cast<int8_t>(rt));
4473 break;
4474 case SH:
4475 WriteH(addr, static_cast<uint16_t>(rt), instr);
4476 break;
4477 case SWL:
4478 WriteW(addr, static_cast<int32_t>(mem_value), instr);
4479 break;
4480 case SW:
4481 WriteW(addr, static_cast<int32_t>(rt), instr);
4482 break;
4483 case SD:
4484 Write2W(addr, rt, instr);
4485 break;
4486 case SWR:
4487 WriteW(addr, static_cast<int32_t>(mem_value), instr);
4488 break;
4489 case LWC1:
4490 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits.
4491 set_fpu_register_word(ft_reg, static_cast<int32_t>(alu_out));
4492 break;
4493 case LDC1:
4494 set_fpu_register_double(ft_reg, fp_out);
4495 break;
4496 case SWC1:
4497 addr = rs + se_imm16;
4498 WriteW(addr, static_cast<int32_t>(get_fpu_register(ft_reg)), instr);
4499 break;
4500 case SDC1:
4501 addr = rs + se_imm16;
4502 WriteD(addr, get_fpu_register_double(ft_reg), instr);
4503 break;
4504 case PCREL:
4505 set_register(rs_reg, alu_out);
4506 default:
4507 break;
4508 }
4509
4510
4511 if (execute_branch_delay_instruction) { 4207 if (execute_branch_delay_instruction) {
4512 // Execute branch delay slot 4208 // Execute branch delay slot
4513 // We don't check for end_sim_pc. First it should not be met as the current 4209 // We don't check for end_sim_pc. First it should not be met as the current
4514 // pc is valid. Secondly a jump should always execute its branch delay slot. 4210 // pc is valid. Secondly a jump should always execute its branch delay slot.
4515 Instruction* branch_delay_instr = 4211 Instruction* branch_delay_instr =
4516 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); 4212 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize);
4517 BranchDelayInstructionDecode(branch_delay_instr); 4213 BranchDelayInstructionDecode(branch_delay_instr);
4518 } 4214 }
4519 4215
4520 // If needed update pc after the branch delay execution. 4216 // If needed update pc after the branch delay execution.
4521 if (next_pc != bad_ra) { 4217 if (next_pc != bad_ra) {
4522 set_pc(next_pc); 4218 set_pc(next_pc);
4523 } 4219 }
4524 } 4220 }
4525 4221
4222 #undef BranchHelper
4223 #undef BranchAndLinkHelper
4224
4526 4225
4527 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). 4226 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
4528 void Simulator::DecodeTypeJump(Instruction* instr) { 4227 void Simulator::DecodeTypeJump(Instruction* instr) {
4529 // Get current pc. 4228 // Get current pc.
4530 int64_t current_pc = get_pc(); 4229 int64_t current_pc = get_pc();
4531 // Get unchanged bits of pc. 4230 // Get unchanged bits of pc.
4532 int64_t pc_high_bits = current_pc & 0xfffffffff0000000; 4231 int64_t pc_high_bits = current_pc & 0xfffffffff0000000;
4533 // Next pc. 4232 // Next pc.
4534 int64_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); 4233 int64_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
4535 4234
(...skipping 24 matching lines...) Expand all
4560 v8::internal::EmbeddedVector<char, 256> buffer; 4259 v8::internal::EmbeddedVector<char, 256> buffer;
4561 4260
4562 if (::v8::internal::FLAG_trace_sim) { 4261 if (::v8::internal::FLAG_trace_sim) {
4563 SNPrintF(trace_buf_, " "); 4262 SNPrintF(trace_buf_, " ");
4564 disasm::NameConverter converter; 4263 disasm::NameConverter converter;
4565 disasm::Disassembler dasm(converter); 4264 disasm::Disassembler dasm(converter);
4566 // Use a reasonably large buffer. 4265 // Use a reasonably large buffer.
4567 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 4266 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
4568 } 4267 }
4569 4268
4570 switch (instr->InstructionType()) { 4269 switch (instr->InstructionType(Instruction::TypeChecks::EXTRA)) {
4571 case Instruction::kRegisterType: 4270 case Instruction::kRegisterType:
4572 DecodeTypeRegister(instr); 4271 DecodeTypeRegister(instr);
4573 break; 4272 break;
4574 case Instruction::kImmediateType: 4273 case Instruction::kImmediateType:
4575 DecodeTypeImmediate(instr); 4274 DecodeTypeImmediate(instr);
4576 break; 4275 break;
4577 case Instruction::kJumpType: 4276 case Instruction::kJumpType:
4578 DecodeTypeJump(instr); 4277 DecodeTypeJump(instr);
4579 break; 4278 break;
4580 default: 4279 default:
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4788 } 4487 }
4789 4488
4790 4489
4791 #undef UNSUPPORTED 4490 #undef UNSUPPORTED
4792 } // namespace internal 4491 } // namespace internal
4793 } // namespace v8 4492 } // namespace v8
4794 4493
4795 #endif // USE_SIMULATOR 4494 #endif // USE_SIMULATOR
4796 4495
4797 #endif // V8_TARGET_ARCH_MIPS64 4496 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/simulator-mips64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698