OLD | NEW |
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 #include "v8.h" | 10 #include "v8.h" |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 intptr_t address = reinterpret_cast<intptr_t>(instr); | 833 intptr_t address = reinterpret_cast<intptr_t>(instr); |
834 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); | 834 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); |
835 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); | 835 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); |
836 int offset = (address & CachePage::kPageMask); | 836 int offset = (address & CachePage::kPageMask); |
837 CachePage* cache_page = GetCachePage(i_cache, page); | 837 CachePage* cache_page = GetCachePage(i_cache, page); |
838 char* cache_valid_byte = cache_page->ValidityByte(offset); | 838 char* cache_valid_byte = cache_page->ValidityByte(offset); |
839 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); | 839 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); |
840 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); | 840 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); |
841 if (cache_hit) { | 841 if (cache_hit) { |
842 // Check that the data in memory matches the contents of the I-cache. | 842 // Check that the data in memory matches the contents of the I-cache. |
843 CHECK(memcmp(reinterpret_cast<void*>(instr), | 843 CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr), |
844 cache_page->CachedData(offset), | 844 cache_page->CachedData(offset), |
845 Instruction::kInstrSize) == 0); | 845 Instruction::kInstrSize)); |
846 } else { | 846 } else { |
847 // Cache miss. Load memory into the cache. | 847 // Cache miss. Load memory into the cache. |
848 OS::MemCopy(cached_line, line, CachePage::kLineLength); | 848 OS::MemCopy(cached_line, line, CachePage::kLineLength); |
849 *cache_valid_byte = CachePage::LINE_VALID; | 849 *cache_valid_byte = CachePage::LINE_VALID; |
850 } | 850 } |
851 } | 851 } |
852 | 852 |
853 | 853 |
854 void Simulator::Initialize(Isolate* isolate) { | 854 void Simulator::Initialize(Isolate* isolate) { |
855 if (isolate->simulator_initialized()) return; | 855 if (isolate->simulator_initialized()) return; |
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1755 break; | 1755 break; |
1756 case S: | 1756 case S: |
1757 case D: | 1757 case D: |
1758 case W: | 1758 case W: |
1759 case L: | 1759 case L: |
1760 case PS: | 1760 case PS: |
1761 // Do everything in the execution step. | 1761 // Do everything in the execution step. |
1762 break; | 1762 break; |
1763 default: | 1763 default: |
1764 UNIMPLEMENTED_MIPS(); | 1764 UNIMPLEMENTED_MIPS(); |
1765 }; | 1765 } |
1766 break; | 1766 break; |
1767 case COP1X: | 1767 case COP1X: |
1768 break; | 1768 break; |
1769 case SPECIAL: | 1769 case SPECIAL: |
1770 switch (instr->FunctionFieldRaw()) { | 1770 switch (instr->FunctionFieldRaw()) { |
1771 case JR: | 1771 case JR: |
1772 case JALR: | 1772 case JALR: |
1773 next_pc = get_register(instr->RsValue()); | 1773 next_pc = get_register(instr->RsValue()); |
1774 return_addr_reg = instr->RdValue(); | 1774 return_addr_reg = instr->RdValue(); |
1775 break; | 1775 break; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1892 case MOVZ: | 1892 case MOVZ: |
1893 case MOVCI: | 1893 case MOVCI: |
1894 // No action taken on decode. | 1894 // No action taken on decode. |
1895 break; | 1895 break; |
1896 case DIV: | 1896 case DIV: |
1897 case DIVU: | 1897 case DIVU: |
1898 // div and divu never raise exceptions. | 1898 // div and divu never raise exceptions. |
1899 break; | 1899 break; |
1900 default: | 1900 default: |
1901 UNREACHABLE(); | 1901 UNREACHABLE(); |
1902 }; | 1902 } |
1903 break; | 1903 break; |
1904 case SPECIAL2: | 1904 case SPECIAL2: |
1905 switch (instr->FunctionFieldRaw()) { | 1905 switch (instr->FunctionFieldRaw()) { |
1906 case MUL: | 1906 case MUL: |
1907 alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. | 1907 alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. |
1908 break; | 1908 break; |
1909 case CLZ: | 1909 case CLZ: |
1910 // MIPS32 spec: If no bits were set in GPR rs, the result written to | 1910 // MIPS32 spec: If no bits were set in GPR rs, the result written to |
1911 // GPR rd is 32. | 1911 // GPR rd is 32. |
1912 // GCC __builtin_clz: If input is 0, the result is undefined. | 1912 // GCC __builtin_clz: If input is 0, the result is undefined. |
1913 alu_out = | 1913 alu_out = |
1914 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); | 1914 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); |
1915 break; | 1915 break; |
1916 default: | 1916 default: |
1917 UNREACHABLE(); | 1917 UNREACHABLE(); |
1918 }; | 1918 } |
1919 break; | 1919 break; |
1920 case SPECIAL3: | 1920 case SPECIAL3: |
1921 switch (instr->FunctionFieldRaw()) { | 1921 switch (instr->FunctionFieldRaw()) { |
1922 case INS: { // Mips32r2 instruction. | 1922 case INS: { // Mips32r2 instruction. |
1923 // Interpret rd field as 5-bit msb of insert. | 1923 // Interpret rd field as 5-bit msb of insert. |
1924 uint16_t msb = rd_reg; | 1924 uint16_t msb = rd_reg; |
1925 // Interpret sa field as 5-bit lsb of insert. | 1925 // Interpret sa field as 5-bit lsb of insert. |
1926 uint16_t lsb = sa; | 1926 uint16_t lsb = sa; |
1927 uint16_t size = msb - lsb + 1; | 1927 uint16_t size = msb - lsb + 1; |
1928 uint32_t mask = (1 << size) - 1; | 1928 uint32_t mask = (1 << size) - 1; |
1929 alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); | 1929 alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); |
1930 break; | 1930 break; |
1931 } | 1931 } |
1932 case EXT: { // Mips32r2 instruction. | 1932 case EXT: { // Mips32r2 instruction. |
1933 // Interpret rd field as 5-bit msb of extract. | 1933 // Interpret rd field as 5-bit msb of extract. |
1934 uint16_t msb = rd_reg; | 1934 uint16_t msb = rd_reg; |
1935 // Interpret sa field as 5-bit lsb of extract. | 1935 // Interpret sa field as 5-bit lsb of extract. |
1936 uint16_t lsb = sa; | 1936 uint16_t lsb = sa; |
1937 uint16_t size = msb + 1; | 1937 uint16_t size = msb + 1; |
1938 uint32_t mask = (1 << size) - 1; | 1938 uint32_t mask = (1 << size) - 1; |
1939 alu_out = (rs_u & (mask << lsb)) >> lsb; | 1939 alu_out = (rs_u & (mask << lsb)) >> lsb; |
1940 break; | 1940 break; |
1941 } | 1941 } |
1942 default: | 1942 default: |
1943 UNREACHABLE(); | 1943 UNREACHABLE(); |
1944 }; | 1944 } |
1945 break; | 1945 break; |
1946 default: | 1946 default: |
1947 UNREACHABLE(); | 1947 UNREACHABLE(); |
1948 }; | 1948 } |
1949 } | 1949 } |
1950 | 1950 |
1951 | 1951 |
1952 void Simulator::DecodeTypeRegister(Instruction* instr) { | 1952 void Simulator::DecodeTypeRegister(Instruction* instr) { |
1953 // Instruction fields. | 1953 // Instruction fields. |
1954 const Opcode op = instr->OpcodeFieldRaw(); | 1954 const Opcode op = instr->OpcodeFieldRaw(); |
1955 const int32_t rs_reg = instr->RsValue(); | 1955 const int32_t rs_reg = instr->RsValue(); |
1956 const int32_t rs = get_register(rs_reg); | 1956 const int32_t rs = get_register(rs_reg); |
1957 const uint32_t rs_u = static_cast<uint32_t>(rs); | 1957 const uint32_t rs_u = static_cast<uint32_t>(rs); |
1958 const int32_t rt_reg = instr->RtValue(); | 1958 const int32_t rt_reg = instr->RtValue(); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2197 case CVT_S_W: // Convert word to float (single). | 2197 case CVT_S_W: // Convert word to float (single). |
2198 alu_out = get_fpu_register(fs_reg); | 2198 alu_out = get_fpu_register(fs_reg); |
2199 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); | 2199 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); |
2200 break; | 2200 break; |
2201 case CVT_D_W: // Convert word to double. | 2201 case CVT_D_W: // Convert word to double. |
2202 alu_out = get_fpu_register(fs_reg); | 2202 alu_out = get_fpu_register(fs_reg); |
2203 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); | 2203 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); |
2204 break; | 2204 break; |
2205 default: | 2205 default: |
2206 UNREACHABLE(); | 2206 UNREACHABLE(); |
2207 }; | 2207 } |
2208 break; | 2208 break; |
2209 case L: | 2209 case L: |
2210 switch (instr->FunctionFieldRaw()) { | 2210 switch (instr->FunctionFieldRaw()) { |
2211 case CVT_D_L: // Mips32r2 instruction. | 2211 case CVT_D_L: // Mips32r2 instruction. |
2212 // Watch the signs here, we want 2 32-bit vals | 2212 // Watch the signs here, we want 2 32-bit vals |
2213 // to make a sign-64. | 2213 // to make a sign-64. |
2214 i64 = static_cast<uint32_t>(get_fpu_register(fs_reg)); | 2214 i64 = static_cast<uint32_t>(get_fpu_register(fs_reg)); |
2215 i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32; | 2215 i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32; |
2216 set_fpu_register_double(fd_reg, static_cast<double>(i64)); | 2216 set_fpu_register_double(fd_reg, static_cast<double>(i64)); |
2217 break; | 2217 break; |
2218 case CVT_S_L: | 2218 case CVT_S_L: |
2219 UNIMPLEMENTED_MIPS(); | 2219 UNIMPLEMENTED_MIPS(); |
2220 break; | 2220 break; |
2221 default: | 2221 default: |
2222 UNREACHABLE(); | 2222 UNREACHABLE(); |
2223 } | 2223 } |
2224 break; | 2224 break; |
2225 case PS: | 2225 case PS: |
2226 break; | 2226 break; |
2227 default: | 2227 default: |
2228 UNREACHABLE(); | 2228 UNREACHABLE(); |
2229 }; | 2229 } |
2230 break; | 2230 break; |
2231 case COP1X: | 2231 case COP1X: |
2232 switch (instr->FunctionFieldRaw()) { | 2232 switch (instr->FunctionFieldRaw()) { |
2233 case MADD_D: | 2233 case MADD_D: |
2234 double fr, ft, fs; | 2234 double fr, ft, fs; |
2235 fr = get_fpu_register_double(fr_reg); | 2235 fr = get_fpu_register_double(fr_reg); |
2236 fs = get_fpu_register_double(fs_reg); | 2236 fs = get_fpu_register_double(fs_reg); |
2237 ft = get_fpu_register_double(ft_reg); | 2237 ft = get_fpu_register_double(ft_reg); |
2238 set_fpu_register_double(fd_reg, fs * ft + fr); | 2238 set_fpu_register_double(fd_reg, fs * ft + fr); |
2239 break; | 2239 break; |
2240 default: | 2240 default: |
2241 UNREACHABLE(); | 2241 UNREACHABLE(); |
2242 }; | 2242 } |
2243 break; | 2243 break; |
2244 case SPECIAL: | 2244 case SPECIAL: |
2245 switch (instr->FunctionFieldRaw()) { | 2245 switch (instr->FunctionFieldRaw()) { |
2246 case JR: { | 2246 case JR: { |
2247 Instruction* branch_delay_instr = reinterpret_cast<Instruction*>( | 2247 Instruction* branch_delay_instr = reinterpret_cast<Instruction*>( |
2248 current_pc+Instruction::kInstrSize); | 2248 current_pc+Instruction::kInstrSize); |
2249 BranchDelayInstructionDecode(branch_delay_instr); | 2249 BranchDelayInstructionDecode(branch_delay_instr); |
2250 set_pc(next_pc); | 2250 set_pc(next_pc); |
2251 pc_modified_ = true; | 2251 pc_modified_ = true; |
2252 break; | 2252 break; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 } else { | 2313 } else { |
2314 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); | 2314 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); |
2315 } | 2315 } |
2316 break; | 2316 break; |
2317 } | 2317 } |
2318 case MOVZ: | 2318 case MOVZ: |
2319 if (!rt) set_register(rd_reg, rs); | 2319 if (!rt) set_register(rd_reg, rs); |
2320 break; | 2320 break; |
2321 default: // For other special opcodes we do the default operation. | 2321 default: // For other special opcodes we do the default operation. |
2322 set_register(rd_reg, alu_out); | 2322 set_register(rd_reg, alu_out); |
2323 }; | 2323 } |
2324 break; | 2324 break; |
2325 case SPECIAL2: | 2325 case SPECIAL2: |
2326 switch (instr->FunctionFieldRaw()) { | 2326 switch (instr->FunctionFieldRaw()) { |
2327 case MUL: | 2327 case MUL: |
2328 set_register(rd_reg, alu_out); | 2328 set_register(rd_reg, alu_out); |
2329 // HI and LO are UNPREDICTABLE after the operation. | 2329 // HI and LO are UNPREDICTABLE after the operation. |
2330 set_register(LO, Unpredictable); | 2330 set_register(LO, Unpredictable); |
2331 set_register(HI, Unpredictable); | 2331 set_register(HI, Unpredictable); |
2332 break; | 2332 break; |
2333 default: // For other special2 opcodes we do the default operation. | 2333 default: // For other special2 opcodes we do the default operation. |
2334 set_register(rd_reg, alu_out); | 2334 set_register(rd_reg, alu_out); |
2335 } | 2335 } |
2336 break; | 2336 break; |
2337 case SPECIAL3: | 2337 case SPECIAL3: |
2338 switch (instr->FunctionFieldRaw()) { | 2338 switch (instr->FunctionFieldRaw()) { |
2339 case INS: | 2339 case INS: |
2340 // Ins instr leaves result in Rt, rather than Rd. | 2340 // Ins instr leaves result in Rt, rather than Rd. |
2341 set_register(rt_reg, alu_out); | 2341 set_register(rt_reg, alu_out); |
2342 break; | 2342 break; |
2343 case EXT: | 2343 case EXT: |
2344 // Ext instr leaves result in Rt, rather than Rd. | 2344 // Ext instr leaves result in Rt, rather than Rd. |
2345 set_register(rt_reg, alu_out); | 2345 set_register(rt_reg, alu_out); |
2346 break; | 2346 break; |
2347 default: | 2347 default: |
2348 UNREACHABLE(); | 2348 UNREACHABLE(); |
2349 }; | 2349 } |
2350 break; | 2350 break; |
2351 // Unimplemented opcodes raised an error in the configuration step before, | 2351 // Unimplemented opcodes raised an error in the configuration step before, |
2352 // so we can use the default here to set the destination register in common | 2352 // so we can use the default here to set the destination register in common |
2353 // cases. | 2353 // cases. |
2354 default: | 2354 default: |
2355 set_register(rd_reg, alu_out); | 2355 set_register(rd_reg, alu_out); |
2356 }; | 2356 } |
2357 } | 2357 } |
2358 | 2358 |
2359 | 2359 |
2360 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). | 2360 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). |
2361 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 2361 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
2362 // Instruction fields. | 2362 // Instruction fields. |
2363 Opcode op = instr->OpcodeFieldRaw(); | 2363 Opcode op = instr->OpcodeFieldRaw(); |
2364 int32_t rs = get_register(instr->RsValue()); | 2364 int32_t rs = get_register(instr->RsValue()); |
2365 uint32_t rs_u = static_cast<uint32_t>(rs); | 2365 uint32_t rs_u = static_cast<uint32_t>(rs); |
2366 int32_t rt_reg = instr->RtValue(); // Destination register. | 2366 int32_t rt_reg = instr->RtValue(); // Destination register. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2407 execute_branch_delay_instruction = true; | 2407 execute_branch_delay_instruction = true; |
2408 // Set next_pc. | 2408 // Set next_pc. |
2409 if (do_branch) { | 2409 if (do_branch) { |
2410 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 2410 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
2411 } else { | 2411 } else { |
2412 next_pc = current_pc + kBranchReturnOffset; | 2412 next_pc = current_pc + kBranchReturnOffset; |
2413 } | 2413 } |
2414 break; | 2414 break; |
2415 default: | 2415 default: |
2416 UNREACHABLE(); | 2416 UNREACHABLE(); |
2417 }; | 2417 } |
2418 break; | 2418 break; |
2419 // ------------- REGIMM class. | 2419 // ------------- REGIMM class. |
2420 case REGIMM: | 2420 case REGIMM: |
2421 switch (instr->RtFieldRaw()) { | 2421 switch (instr->RtFieldRaw()) { |
2422 case BLTZ: | 2422 case BLTZ: |
2423 do_branch = (rs < 0); | 2423 do_branch = (rs < 0); |
2424 break; | 2424 break; |
2425 case BLTZAL: | 2425 case BLTZAL: |
2426 do_branch = rs < 0; | 2426 do_branch = rs < 0; |
2427 break; | 2427 break; |
2428 case BGEZ: | 2428 case BGEZ: |
2429 do_branch = rs >= 0; | 2429 do_branch = rs >= 0; |
2430 break; | 2430 break; |
2431 case BGEZAL: | 2431 case BGEZAL: |
2432 do_branch = rs >= 0; | 2432 do_branch = rs >= 0; |
2433 break; | 2433 break; |
2434 default: | 2434 default: |
2435 UNREACHABLE(); | 2435 UNREACHABLE(); |
2436 }; | 2436 } |
2437 switch (instr->RtFieldRaw()) { | 2437 switch (instr->RtFieldRaw()) { |
2438 case BLTZ: | 2438 case BLTZ: |
2439 case BLTZAL: | 2439 case BLTZAL: |
2440 case BGEZ: | 2440 case BGEZ: |
2441 case BGEZAL: | 2441 case BGEZAL: |
2442 // Branch instructions common part. | 2442 // Branch instructions common part. |
2443 execute_branch_delay_instruction = true; | 2443 execute_branch_delay_instruction = true; |
2444 // Set next_pc. | 2444 // Set next_pc. |
2445 if (do_branch) { | 2445 if (do_branch) { |
2446 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 2446 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
2447 if (instr->IsLinkingInstruction()) { | 2447 if (instr->IsLinkingInstruction()) { |
2448 set_register(31, current_pc + kBranchReturnOffset); | 2448 set_register(31, current_pc + kBranchReturnOffset); |
2449 } | 2449 } |
2450 } else { | 2450 } else { |
2451 next_pc = current_pc + kBranchReturnOffset; | 2451 next_pc = current_pc + kBranchReturnOffset; |
2452 } | 2452 } |
2453 default: | 2453 default: |
2454 break; | 2454 break; |
2455 }; | 2455 } |
2456 break; // case REGIMM. | 2456 break; // case REGIMM. |
2457 // ------------- Branch instructions. | 2457 // ------------- Branch instructions. |
2458 // When comparing to zero, the encoding of rt field is always 0, so we don't | 2458 // When comparing to zero, the encoding of rt field is always 0, so we don't |
2459 // need to replace rt with zero. | 2459 // need to replace rt with zero. |
2460 case BEQ: | 2460 case BEQ: |
2461 do_branch = (rs == rt); | 2461 do_branch = (rs == rt); |
2462 break; | 2462 break; |
2463 case BNE: | 2463 case BNE: |
2464 do_branch = rs != rt; | 2464 do_branch = rs != rt; |
2465 break; | 2465 break; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 case LDC1: | 2578 case LDC1: |
2579 addr = rs + se_imm16; | 2579 addr = rs + se_imm16; |
2580 fp_out = ReadD(addr, instr); | 2580 fp_out = ReadD(addr, instr); |
2581 break; | 2581 break; |
2582 case SWC1: | 2582 case SWC1: |
2583 case SDC1: | 2583 case SDC1: |
2584 addr = rs + se_imm16; | 2584 addr = rs + se_imm16; |
2585 break; | 2585 break; |
2586 default: | 2586 default: |
2587 UNREACHABLE(); | 2587 UNREACHABLE(); |
2588 }; | 2588 } |
2589 | 2589 |
2590 // ---------- Raise exceptions triggered. | 2590 // ---------- Raise exceptions triggered. |
2591 SignalExceptions(); | 2591 SignalExceptions(); |
2592 | 2592 |
2593 // ---------- Execution. | 2593 // ---------- Execution. |
2594 switch (op) { | 2594 switch (op) { |
2595 // ------------- Branch instructions. | 2595 // ------------- Branch instructions. |
2596 case BEQ: | 2596 case BEQ: |
2597 case BNE: | 2597 case BNE: |
2598 case BLEZ: | 2598 case BLEZ: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2654 case SWC1: | 2654 case SWC1: |
2655 addr = rs + se_imm16; | 2655 addr = rs + se_imm16; |
2656 WriteW(addr, get_fpu_register(ft_reg), instr); | 2656 WriteW(addr, get_fpu_register(ft_reg), instr); |
2657 break; | 2657 break; |
2658 case SDC1: | 2658 case SDC1: |
2659 addr = rs + se_imm16; | 2659 addr = rs + se_imm16; |
2660 WriteD(addr, get_fpu_register_double(ft_reg), instr); | 2660 WriteD(addr, get_fpu_register_double(ft_reg), instr); |
2661 break; | 2661 break; |
2662 default: | 2662 default: |
2663 break; | 2663 break; |
2664 }; | 2664 } |
2665 | 2665 |
2666 | 2666 |
2667 if (execute_branch_delay_instruction) { | 2667 if (execute_branch_delay_instruction) { |
2668 // Execute branch delay slot | 2668 // Execute branch delay slot |
2669 // We don't check for end_sim_pc. First it should not be met as the current | 2669 // We don't check for end_sim_pc. First it should not be met as the current |
2670 // pc is valid. Secondly a jump should always execute its branch delay slot. | 2670 // pc is valid. Secondly a jump should always execute its branch delay slot. |
2671 Instruction* branch_delay_instr = | 2671 Instruction* branch_delay_instr = |
2672 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); | 2672 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); |
2673 BranchDelayInstructionDecode(branch_delay_instr); | 2673 BranchDelayInstructionDecode(branch_delay_instr); |
2674 } | 2674 } |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2919 } | 2919 } |
2920 | 2920 |
2921 | 2921 |
2922 #undef UNSUPPORTED | 2922 #undef UNSUPPORTED |
2923 | 2923 |
2924 } } // namespace v8::internal | 2924 } } // namespace v8::internal |
2925 | 2925 |
2926 #endif // USE_SIMULATOR | 2926 #endif // USE_SIMULATOR |
2927 | 2927 |
2928 #endif // V8_TARGET_ARCH_MIPS | 2928 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |