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 "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); | 775 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); |
776 return one == two; | 776 return one == two; |
777 } | 777 } |
778 | 778 |
779 | 779 |
780 static uint32_t ICacheHash(void* key) { | 780 static uint32_t ICacheHash(void* key) { |
781 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; | 781 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; |
782 } | 782 } |
783 | 783 |
784 | 784 |
785 static bool AllOnOnePage(uintptr_t start, int size) { | 785 static bool AllOnOnePage(uintptr_t start, size_t size) { |
786 intptr_t start_page = (start & ~CachePage::kPageMask); | 786 intptr_t start_page = (start & ~CachePage::kPageMask); |
787 intptr_t end_page = ((start + size) & ~CachePage::kPageMask); | 787 intptr_t end_page = ((start + size) & ~CachePage::kPageMask); |
788 return start_page == end_page; | 788 return start_page == end_page; |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 void Simulator::set_last_debugger_input(char* input) { | 792 void Simulator::set_last_debugger_input(char* input) { |
793 DeleteArray(last_debugger_input_); | 793 DeleteArray(last_debugger_input_); |
794 last_debugger_input_ = input; | 794 last_debugger_input_ = input; |
795 } | 795 } |
(...skipping 27 matching lines...) Expand all Loading... |
823 i_cache->LookupOrInsert(page, ICacheHash(page)); | 823 i_cache->LookupOrInsert(page, ICacheHash(page)); |
824 if (entry->value == NULL) { | 824 if (entry->value == NULL) { |
825 CachePage* new_page = new CachePage(); | 825 CachePage* new_page = new CachePage(); |
826 entry->value = new_page; | 826 entry->value = new_page; |
827 } | 827 } |
828 return reinterpret_cast<CachePage*>(entry->value); | 828 return reinterpret_cast<CachePage*>(entry->value); |
829 } | 829 } |
830 | 830 |
831 | 831 |
832 // Flush from start up to and not including start + size. | 832 // Flush from start up to and not including start + size. |
833 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, | 833 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start, |
834 intptr_t start, | 834 size_t size) { |
835 int size) { | |
836 DCHECK(size <= CachePage::kPageSize); | 835 DCHECK(size <= CachePage::kPageSize); |
837 DCHECK(AllOnOnePage(start, size - 1)); | 836 DCHECK(AllOnOnePage(start, size - 1)); |
838 DCHECK((start & CachePage::kLineMask) == 0); | 837 DCHECK((start & CachePage::kLineMask) == 0); |
839 DCHECK((size & CachePage::kLineMask) == 0); | 838 DCHECK((size & CachePage::kLineMask) == 0); |
840 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); | 839 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); |
841 int offset = (start & CachePage::kPageMask); | 840 int offset = (start & CachePage::kPageMask); |
842 CachePage* cache_page = GetCachePage(i_cache, page); | 841 CachePage* cache_page = GetCachePage(i_cache, page); |
843 char* valid_bytemap = cache_page->ValidityByte(offset); | 842 char* valid_bytemap = cache_page->ValidityByte(offset); |
844 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); | 843 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); |
845 } | 844 } |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 | 1147 |
1149 | 1148 |
1150 // Runtime FP routines take up to two double arguments and zero | 1149 // Runtime FP routines take up to two double arguments and zero |
1151 // or one integer arguments. All are constructed here, | 1150 // or one integer arguments. All are constructed here, |
1152 // from a0-a3 or f12 and f13 (n64), or f14 (O32). | 1151 // from a0-a3 or f12 and f13 (n64), or f14 (O32). |
1153 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1152 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1154 if (!IsMipsSoftFloatABI) { | 1153 if (!IsMipsSoftFloatABI) { |
1155 const int fparg2 = (kMipsAbi == kN64) ? 13 : 14; | 1154 const int fparg2 = (kMipsAbi == kN64) ? 13 : 14; |
1156 *x = get_fpu_register_double(12); | 1155 *x = get_fpu_register_double(12); |
1157 *y = get_fpu_register_double(fparg2); | 1156 *y = get_fpu_register_double(fparg2); |
1158 *z = get_register(a2); | 1157 *z = static_cast<int32_t>(get_register(a2)); |
1159 } else { | 1158 } else { |
1160 // TODO(plind): bad ABI stuff, refactor or remove. | 1159 // TODO(plind): bad ABI stuff, refactor or remove. |
1161 // We use a char buffer to get around the strict-aliasing rules which | 1160 // We use a char buffer to get around the strict-aliasing rules which |
1162 // otherwise allow the compiler to optimize away the copy. | 1161 // otherwise allow the compiler to optimize away the copy. |
1163 char buffer[sizeof(*x)]; | 1162 char buffer[sizeof(*x)]; |
1164 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); | 1163 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); |
1165 | 1164 |
1166 // Registers a0 and a1 -> x. | 1165 // Registers a0 and a1 -> x. |
1167 reg_buffer[0] = get_register(a0); | 1166 reg_buffer[0] = get_register(a0); |
1168 reg_buffer[1] = get_register(a1); | 1167 reg_buffer[1] = get_register(a1); |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 return *ptr; | 1623 return *ptr; |
1625 } | 1624 } |
1626 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1625 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1627 addr, | 1626 addr, |
1628 reinterpret_cast<intptr_t>(instr)); | 1627 reinterpret_cast<intptr_t>(instr)); |
1629 DieOrDebug(); | 1628 DieOrDebug(); |
1630 return 0; | 1629 return 0; |
1631 } | 1630 } |
1632 | 1631 |
1633 | 1632 |
1634 void Simulator::WriteW(int64_t addr, int value, Instruction* instr) { | 1633 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
1635 if (addr >= 0 && addr < 0x400) { | 1634 if (addr >= 0 && addr < 0x400) { |
1636 // This has to be a NULL-dereference, drop into debugger. | 1635 // This has to be a NULL-dereference, drop into debugger. |
1637 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", | 1636 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", |
1638 addr, reinterpret_cast<intptr_t>(instr)); | 1637 addr, reinterpret_cast<intptr_t>(instr)); |
1639 DieOrDebug(); | 1638 DieOrDebug(); |
1640 } | 1639 } |
1641 if ((addr & 0x3) == 0) { | 1640 if ((addr & 0x3) == 0) { |
1642 TraceMemWr(addr, value, WORD); | 1641 TraceMemWr(addr, value, WORD); |
1643 int* ptr = reinterpret_cast<int*>(addr); | 1642 int* ptr = reinterpret_cast<int*>(addr); |
1644 *ptr = value; | 1643 *ptr = value; |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 for (int i = 1; i < kNumExceptions; i++) { | 2175 for (int i = 1; i < kNumExceptions; i++) { |
2177 if (exceptions[i] != 0) { | 2176 if (exceptions[i] != 0) { |
2178 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); | 2177 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); |
2179 } | 2178 } |
2180 } | 2179 } |
2181 } | 2180 } |
2182 | 2181 |
2183 | 2182 |
2184 // Handle execution based on instruction types. | 2183 // Handle execution based on instruction types. |
2185 | 2184 |
2186 void Simulator::ConfigureTypeRegister(Instruction* instr, | 2185 void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out, |
2187 int64_t* alu_out, | 2186 int64_t* i64hilo, uint64_t* u64hilo, |
2188 int64_t* i64hilo, | 2187 int64_t* next_pc, int* return_addr_reg, |
2189 uint64_t* u64hilo, | 2188 bool* do_interrupt, int64_t* i128resultH, |
2190 int64_t* next_pc, | |
2191 int64_t* return_addr_reg, | |
2192 bool* do_interrupt, | |
2193 int64_t* i128resultH, | |
2194 int64_t* i128resultL) { | 2189 int64_t* i128resultL) { |
2195 // Every local variable declared here needs to be const. | 2190 // Every local variable declared here needs to be const. |
2196 // This is to make sure that changed values are sent back to | 2191 // This is to make sure that changed values are sent back to |
2197 // DecodeTypeRegister correctly. | 2192 // DecodeTypeRegister correctly. |
2198 | 2193 |
2199 // Instruction fields. | 2194 // Instruction fields. |
2200 const Opcode op = instr->OpcodeFieldRaw(); | 2195 const Opcode op = instr->OpcodeFieldRaw(); |
2201 const int64_t rs_reg = instr->RsValue(); | 2196 const int32_t rs_reg = instr->RsValue(); |
2202 const int64_t rs = get_register(rs_reg); | 2197 const int64_t rs = get_register(rs_reg); |
2203 const uint64_t rs_u = static_cast<uint64_t>(rs); | 2198 const uint64_t rs_u = static_cast<uint64_t>(rs); |
2204 const int64_t rt_reg = instr->RtValue(); | 2199 const int32_t rt_reg = instr->RtValue(); |
2205 const int64_t rt = get_register(rt_reg); | 2200 const int64_t rt = get_register(rt_reg); |
2206 const uint64_t rt_u = static_cast<uint64_t>(rt); | 2201 const uint64_t rt_u = static_cast<uint64_t>(rt); |
2207 const int64_t rd_reg = instr->RdValue(); | 2202 const int32_t rd_reg = instr->RdValue(); |
2208 const uint64_t sa = instr->SaValue(); | 2203 const uint64_t sa = instr->SaValue(); |
2209 | 2204 |
2210 const int32_t fs_reg = instr->FsValue(); | 2205 const int32_t fs_reg = instr->FsValue(); |
2211 | 2206 |
2212 | 2207 |
2213 // ---------- Configuration. | 2208 // ---------- Configuration. |
2214 switch (op) { | 2209 switch (op) { |
2215 case COP1: // Coprocessor instructions. | 2210 case COP1: // Coprocessor instructions. |
2216 switch (instr->RsFieldRaw()) { | 2211 switch (instr->RsFieldRaw()) { |
2217 case CFC1: | 2212 case CFC1: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 if (rs_reg == 0) { | 2261 if (rs_reg == 0) { |
2267 // Regular logical right shift of a word by a fixed number of | 2262 // Regular logical right shift of a word by a fixed number of |
2268 // bits instruction. RS field is always equal to 0. | 2263 // bits instruction. RS field is always equal to 0. |
2269 // Sign-extend the 32-bit result. | 2264 // Sign-extend the 32-bit result. |
2270 *alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u) >> sa); | 2265 *alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u) >> sa); |
2271 } else { | 2266 } else { |
2272 // Logical right-rotate of a word by a fixed number of bits. This | 2267 // Logical right-rotate of a word by a fixed number of bits. This |
2273 // is special case of SRL instruction, added in MIPS32 Release 2. | 2268 // is special case of SRL instruction, added in MIPS32 Release 2. |
2274 // RS field is equal to 00001. | 2269 // RS field is equal to 00001. |
2275 *alu_out = static_cast<int32_t>( | 2270 *alu_out = static_cast<int32_t>( |
2276 base::bits::RotateRight32((uint32_t)rt_u, sa)); | 2271 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u), |
| 2272 static_cast<const uint32_t>(sa))); |
2277 } | 2273 } |
2278 break; | 2274 break; |
2279 case DSRL: | 2275 case DSRL: |
2280 *alu_out = rt_u >> sa; | 2276 *alu_out = rt_u >> sa; |
2281 break; | 2277 break; |
2282 case DSRL32: | 2278 case DSRL32: |
2283 *alu_out = rt_u >> sa >> 32; | 2279 *alu_out = rt_u >> sa >> 32; |
2284 break; | 2280 break; |
2285 case SRA: | 2281 case SRA: |
2286 *alu_out = (int32_t)rt >> sa; | 2282 *alu_out = (int32_t)rt >> sa; |
(...skipping 13 matching lines...) Expand all Loading... |
2300 case SRLV: | 2296 case SRLV: |
2301 if (sa == 0) { | 2297 if (sa == 0) { |
2302 // Regular logical right-shift of a word by a variable number of | 2298 // Regular logical right-shift of a word by a variable number of |
2303 // bits instruction. SA field is always equal to 0. | 2299 // bits instruction. SA field is always equal to 0. |
2304 *alu_out = static_cast<int32_t>((uint32_t)rt_u >> rs); | 2300 *alu_out = static_cast<int32_t>((uint32_t)rt_u >> rs); |
2305 } else { | 2301 } else { |
2306 // Logical right-rotate of a word by a variable number of bits. | 2302 // Logical right-rotate of a word by a variable number of bits. |
2307 // This is special case od SRLV instruction, added in MIPS32 | 2303 // This is special case od SRLV instruction, added in MIPS32 |
2308 // Release 2. SA field is equal to 00001. | 2304 // Release 2. SA field is equal to 00001. |
2309 *alu_out = static_cast<int32_t>( | 2305 *alu_out = static_cast<int32_t>( |
2310 base::bits::RotateRight32((uint32_t)rt_u, rs_u)); | 2306 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u), |
| 2307 static_cast<const uint32_t>(rs_u))); |
2311 } | 2308 } |
2312 break; | 2309 break; |
2313 case DSRLV: | 2310 case DSRLV: |
2314 if (sa == 0) { | 2311 if (sa == 0) { |
2315 // Regular logical right-shift of a word by a variable number of | 2312 // Regular logical right-shift of a word by a variable number of |
2316 // bits instruction. SA field is always equal to 0. | 2313 // bits instruction. SA field is always equal to 0. |
2317 *alu_out = rt_u >> rs; | 2314 *alu_out = rt_u >> rs; |
2318 } else { | 2315 } else { |
2319 // Logical right-rotate of a word by a variable number of bits. | 2316 // Logical right-rotate of a word by a variable number of bits. |
2320 // This is special case od SRLV instruction, added in MIPS32 | 2317 // This is special case od SRLV instruction, added in MIPS32 |
2321 // Release 2. SA field is equal to 00001. | 2318 // Release 2. SA field is equal to 00001. |
2322 *alu_out = base::bits::RotateRight32(rt_u, rs_u); | 2319 *alu_out = |
| 2320 base::bits::RotateRight32(static_cast<const uint32_t>(rt_u), |
| 2321 static_cast<const uint32_t>(rs_u)); |
2323 } | 2322 } |
2324 break; | 2323 break; |
2325 case SRAV: | 2324 case SRAV: |
2326 *alu_out = (int32_t)rt >> rs; | 2325 *alu_out = (int32_t)rt >> rs; |
2327 break; | 2326 break; |
2328 case DSRAV: | 2327 case DSRAV: |
2329 *alu_out = rt >> rs; | 2328 *alu_out = rt >> rs; |
2330 break; | 2329 break; |
2331 case MFHI: // MFHI == CLZ on R6. | 2330 case MFHI: // MFHI == CLZ on R6. |
2332 if (kArchVariant != kMips64r6) { | 2331 if (kArchVariant != kMips64r6) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2378 if (HaveSameSign(rs, rt)) { | 2377 if (HaveSameSign(rs, rt)) { |
2379 if (rs > 0) { | 2378 if (rs > 0) { |
2380 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); | 2379 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); |
2381 } else if (rs < 0) { | 2380 } else if (rs < 0) { |
2382 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); | 2381 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); |
2383 } | 2382 } |
2384 } | 2383 } |
2385 *alu_out = rs + rt; | 2384 *alu_out = rs + rt; |
2386 break; | 2385 break; |
2387 case ADDU: { | 2386 case ADDU: { |
2388 int32_t alu32_out = rs + rt; | 2387 int32_t alu32_out = static_cast<int32_t>(rs + rt); |
2389 // Sign-extend result of 32bit operation into 64bit register. | 2388 // Sign-extend result of 32bit operation into 64bit register. |
2390 *alu_out = static_cast<int64_t>(alu32_out); | 2389 *alu_out = static_cast<int64_t>(alu32_out); |
2391 } | |
2392 break; | 2390 break; |
| 2391 } |
2393 case DADDU: | 2392 case DADDU: |
2394 *alu_out = rs + rt; | 2393 *alu_out = rs + rt; |
2395 break; | 2394 break; |
2396 case SUB: | 2395 case SUB: |
2397 case DSUB: | 2396 case DSUB: |
2398 if (!HaveSameSign(rs, rt)) { | 2397 if (!HaveSameSign(rs, rt)) { |
2399 if (rs > 0) { | 2398 if (rs > 0) { |
2400 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt); | 2399 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt); |
2401 } else if (rs < 0) { | 2400 } else if (rs < 0) { |
2402 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt); | 2401 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt); |
2403 } | 2402 } |
2404 } | 2403 } |
2405 *alu_out = rs - rt; | 2404 *alu_out = rs - rt; |
2406 break; | 2405 break; |
2407 case SUBU: { | 2406 case SUBU: { |
2408 int32_t alu32_out = rs - rt; | 2407 int32_t alu32_out = static_cast<int32_t>(rs - rt); |
2409 // Sign-extend result of 32bit operation into 64bit register. | 2408 // Sign-extend result of 32bit operation into 64bit register. |
2410 *alu_out = static_cast<int64_t>(alu32_out); | 2409 *alu_out = static_cast<int64_t>(alu32_out); |
2411 } | |
2412 break; | 2410 break; |
| 2411 } |
2413 case DSUBU: | 2412 case DSUBU: |
2414 *alu_out = rs - rt; | 2413 *alu_out = rs - rt; |
2415 break; | 2414 break; |
2416 case AND: | 2415 case AND: |
2417 *alu_out = rs & rt; | 2416 *alu_out = rs & rt; |
2418 break; | 2417 break; |
2419 case OR: | 2418 case OR: |
2420 *alu_out = rs | rt; | 2419 *alu_out = rs | rt; |
2421 break; | 2420 break; |
2422 case XOR: | 2421 case XOR: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 break; | 2473 break; |
2475 case SPECIAL2: | 2474 case SPECIAL2: |
2476 switch (instr->FunctionFieldRaw()) { | 2475 switch (instr->FunctionFieldRaw()) { |
2477 case MUL: | 2476 case MUL: |
2478 // Only the lower 32 bits are kept. | 2477 // Only the lower 32 bits are kept. |
2479 *alu_out = (int32_t)rs_u * (int32_t)rt_u; | 2478 *alu_out = (int32_t)rs_u * (int32_t)rt_u; |
2480 break; | 2479 break; |
2481 case CLZ: | 2480 case CLZ: |
2482 // MIPS32 spec: If no bits were set in GPR rs, the result written to | 2481 // MIPS32 spec: If no bits were set in GPR rs, the result written to |
2483 // GPR rd is 32. | 2482 // GPR rd is 32. |
2484 *alu_out = base::bits::CountLeadingZeros32(rs_u); | 2483 *alu_out = |
| 2484 base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u)); |
2485 break; | 2485 break; |
2486 default: | 2486 default: |
2487 UNREACHABLE(); | 2487 UNREACHABLE(); |
2488 } | 2488 } |
2489 break; | 2489 break; |
2490 case SPECIAL3: | 2490 case SPECIAL3: |
2491 switch (instr->FunctionFieldRaw()) { | 2491 switch (instr->FunctionFieldRaw()) { |
2492 case INS: { // Mips32r2 instruction. | 2492 case INS: { // Mips32r2 instruction. |
2493 // Interpret rd field as 5-bit msb of insert. | 2493 // Interpret rd field as 5-bit msb of insert. |
2494 uint16_t msb = rd_reg; | 2494 uint16_t msb = rd_reg; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2579 UNREACHABLE(); | 2579 UNREACHABLE(); |
2580 } | 2580 } |
2581 break; | 2581 break; |
2582 default: | 2582 default: |
2583 UNREACHABLE(); | 2583 UNREACHABLE(); |
2584 } | 2584 } |
2585 } | 2585 } |
2586 | 2586 |
2587 | 2587 |
2588 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, | 2588 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, |
2589 const int32_t& fs_reg, | 2589 const int32_t fs_reg, |
2590 const int32_t& ft_reg, | 2590 const int32_t ft_reg, |
2591 const int32_t& fd_reg) { | 2591 const int32_t fd_reg) { |
2592 float fs, ft, fd; | 2592 float fs, ft, fd; |
2593 fs = get_fpu_register_float(fs_reg); | 2593 fs = get_fpu_register_float(fs_reg); |
2594 ft = get_fpu_register_float(ft_reg); | 2594 ft = get_fpu_register_float(ft_reg); |
2595 fd = get_fpu_register_float(fd_reg); | 2595 fd = get_fpu_register_float(fd_reg); |
2596 int32_t ft_int = bit_cast<int32_t>(ft); | 2596 int32_t ft_int = bit_cast<int32_t>(ft); |
2597 int32_t fd_int = bit_cast<int32_t>(fd); | 2597 int32_t fd_int = bit_cast<int32_t>(fd); |
2598 uint32_t cc, fcsr_cc; | 2598 uint32_t cc, fcsr_cc; |
2599 cc = instr->FCccValue(); | 2599 cc = instr->FCccValue(); |
2600 fcsr_cc = get_fcsr_condition_bit(cc); | 2600 fcsr_cc = get_fcsr_condition_bit(cc); |
2601 switch (instr->FunctionFieldRaw()) { | 2601 switch (instr->FunctionFieldRaw()) { |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 } | 2981 } |
2982 default: | 2982 default: |
2983 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 2983 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
2984 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. | 2984 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
2985 UNREACHABLE(); | 2985 UNREACHABLE(); |
2986 } | 2986 } |
2987 } | 2987 } |
2988 | 2988 |
2989 | 2989 |
2990 void Simulator::DecodeTypeRegisterDRsType(Instruction* instr, | 2990 void Simulator::DecodeTypeRegisterDRsType(Instruction* instr, |
2991 const int32_t& fs_reg, | 2991 const int32_t fs_reg, |
2992 const int32_t& ft_reg, | 2992 const int32_t ft_reg, |
2993 const int32_t& fd_reg) { | 2993 const int32_t fd_reg) { |
2994 double ft, fs, fd; | 2994 double ft, fs, fd; |
2995 uint32_t cc, fcsr_cc; | 2995 uint32_t cc, fcsr_cc; |
2996 fs = get_fpu_register_double(fs_reg); | 2996 fs = get_fpu_register_double(fs_reg); |
2997 ft = (instr->FunctionFieldRaw() != MOVF) ? get_fpu_register_double(ft_reg) | 2997 ft = (instr->FunctionFieldRaw() != MOVF) ? get_fpu_register_double(ft_reg) |
2998 : 0.0; | 2998 : 0.0; |
2999 fd = get_fpu_register_double(fd_reg); | 2999 fd = get_fpu_register_double(fd_reg); |
3000 cc = instr->FCccValue(); | 3000 cc = instr->FCccValue(); |
3001 fcsr_cc = get_fcsr_condition_bit(cc); | 3001 fcsr_cc = get_fcsr_condition_bit(cc); |
3002 int64_t ft_int = bit_cast<int64_t>(ft); | 3002 int64_t ft_int = bit_cast<int64_t>(ft); |
3003 int64_t fd_int = bit_cast<int64_t>(fd); | 3003 int64_t fd_int = bit_cast<int64_t>(fd); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3380 set_fcsr_bit(fcsr_cc, false); | 3380 set_fcsr_bit(fcsr_cc, false); |
3381 break; | 3381 break; |
3382 } | 3382 } |
3383 default: | 3383 default: |
3384 UNREACHABLE(); | 3384 UNREACHABLE(); |
3385 } | 3385 } |
3386 } | 3386 } |
3387 | 3387 |
3388 | 3388 |
3389 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, | 3389 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, |
3390 const int32_t& fs_reg, | 3390 const int32_t fs_reg, |
3391 const int32_t& fd_reg, | 3391 const int32_t fd_reg, |
3392 const int32_t& ft_reg, | 3392 const int32_t ft_reg, |
3393 int64_t& alu_out) { | 3393 int64_t& alu_out) { |
3394 float fs = get_fpu_register_float(fs_reg); | 3394 float fs = get_fpu_register_float(fs_reg); |
3395 float ft = get_fpu_register_float(ft_reg); | 3395 float ft = get_fpu_register_float(ft_reg); |
3396 switch (instr->FunctionFieldRaw()) { | 3396 switch (instr->FunctionFieldRaw()) { |
3397 case CVT_S_W: // Convert word to float (single). | 3397 case CVT_S_W: // Convert word to float (single). |
3398 alu_out = get_fpu_register_signed_word(fs_reg); | 3398 alu_out = get_fpu_register_signed_word(fs_reg); |
3399 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); | 3399 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); |
3400 break; | 3400 break; |
3401 case CVT_D_W: // Convert word to double. | 3401 case CVT_D_W: // Convert word to double. |
3402 alu_out = get_fpu_register_signed_word(fs_reg); | 3402 alu_out = get_fpu_register_signed_word(fs_reg); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3475 set_fpu_register_word(fd_reg, 0); | 3475 set_fpu_register_word(fd_reg, 0); |
3476 } | 3476 } |
3477 break; | 3477 break; |
3478 default: | 3478 default: |
3479 UNREACHABLE(); | 3479 UNREACHABLE(); |
3480 } | 3480 } |
3481 } | 3481 } |
3482 | 3482 |
3483 | 3483 |
3484 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, | 3484 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, |
3485 const int32_t& fs_reg, | 3485 const int32_t fs_reg, |
3486 const int32_t& fd_reg, | 3486 const int32_t fd_reg, |
3487 const int32_t& ft_reg) { | 3487 const int32_t ft_reg) { |
3488 double fs = get_fpu_register_double(fs_reg); | 3488 double fs = get_fpu_register_double(fs_reg); |
3489 double ft = get_fpu_register_double(ft_reg); | 3489 double ft = get_fpu_register_double(ft_reg); |
3490 int64_t i64; | 3490 int64_t i64; |
3491 switch (instr->FunctionFieldRaw()) { | 3491 switch (instr->FunctionFieldRaw()) { |
3492 case CVT_D_L: // Mips32r2 instruction. | 3492 case CVT_D_L: // Mips32r2 instruction. |
3493 i64 = get_fpu_register(fs_reg); | 3493 i64 = get_fpu_register(fs_reg); |
3494 set_fpu_register_double(fd_reg, static_cast<double>(i64)); | 3494 set_fpu_register_double(fd_reg, static_cast<double>(i64)); |
3495 break; | 3495 break; |
3496 case CVT_S_L: | 3496 case CVT_S_L: |
3497 i64 = get_fpu_register(fs_reg); | 3497 i64 = get_fpu_register(fs_reg); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3568 set_fpu_register(fd_reg, -1); | 3568 set_fpu_register(fd_reg, -1); |
3569 } else { | 3569 } else { |
3570 set_fpu_register(fd_reg, 0); | 3570 set_fpu_register(fd_reg, 0); |
3571 } | 3571 } |
3572 break; | 3572 break; |
3573 default: | 3573 default: |
3574 UNREACHABLE(); | 3574 UNREACHABLE(); |
3575 } | 3575 } |
3576 } | 3576 } |
3577 | 3577 |
3578 | |
3579 void Simulator::DecodeTypeRegisterCOP1( | 3578 void Simulator::DecodeTypeRegisterCOP1( |
3580 Instruction* instr, const int32_t& rs_reg, const int64_t& rs, | 3579 Instruction* instr, const int32_t rs_reg, const int64_t rs, |
3581 const uint64_t& rs_u, const int32_t& rt_reg, const int64_t& rt, | 3580 const uint64_t rs_u, const int32_t rt_reg, const int64_t rt, |
3582 const uint64_t& rt_u, const int32_t& rd_reg, const int32_t& fr_reg, | 3581 const uint64_t rt_u, const int32_t rd_reg, const int32_t fr_reg, |
3583 const int32_t& fs_reg, const int32_t& ft_reg, const int32_t& fd_reg, | 3582 const int32_t fs_reg, const int32_t ft_reg, const int32_t fd_reg, |
3584 int64_t& alu_out) { | 3583 int64_t& alu_out) { |
3585 switch (instr->RsFieldRaw()) { | 3584 switch (instr->RsFieldRaw()) { |
3586 case BC1: // Branch on coprocessor condition. | 3585 case BC1: // Branch on coprocessor condition. |
3587 case BC1EQZ: | 3586 case BC1EQZ: |
3588 case BC1NEZ: | 3587 case BC1NEZ: |
3589 UNREACHABLE(); | 3588 UNREACHABLE(); |
3590 break; | 3589 break; |
3591 case CFC1: | 3590 case CFC1: |
3592 set_register(rt_reg, alu_out); | 3591 set_register(rt_reg, alu_out); |
3593 break; | 3592 break; |
3594 case MFC1: | 3593 case MFC1: |
3595 case DMFC1: | 3594 case DMFC1: |
3596 case MFHC1: | 3595 case MFHC1: |
3597 set_register(rt_reg, alu_out); | 3596 set_register(rt_reg, alu_out); |
3598 break; | 3597 break; |
3599 case CTC1: | 3598 case CTC1: |
3600 // At the moment only FCSR is supported. | 3599 // At the moment only FCSR is supported. |
3601 DCHECK(fs_reg == kFCSRRegister); | 3600 DCHECK(fs_reg == kFCSRRegister); |
3602 FCSR_ = registers_[rt_reg]; | 3601 FCSR_ = static_cast<uint32_t>(registers_[rt_reg]); |
3603 break; | 3602 break; |
3604 case MTC1: | 3603 case MTC1: |
3605 // Hardware writes upper 32-bits to zero on mtc1. | 3604 // Hardware writes upper 32-bits to zero on mtc1. |
3606 set_fpu_register_hi_word(fs_reg, 0); | 3605 set_fpu_register_hi_word(fs_reg, 0); |
3607 set_fpu_register_word(fs_reg, registers_[rt_reg]); | 3606 set_fpu_register_word(fs_reg, static_cast<int32_t>(registers_[rt_reg])); |
3608 break; | 3607 break; |
3609 case DMTC1: | 3608 case DMTC1: |
3610 set_fpu_register(fs_reg, registers_[rt_reg]); | 3609 set_fpu_register(fs_reg, registers_[rt_reg]); |
3611 break; | 3610 break; |
3612 case MTHC1: | 3611 case MTHC1: |
3613 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]); | 3612 set_fpu_register_hi_word(fs_reg, |
| 3613 static_cast<int32_t>(registers_[rt_reg])); |
3614 break; | 3614 break; |
3615 case S: | 3615 case S: |
3616 DecodeTypeRegisterSRsType(instr, fs_reg, ft_reg, fd_reg); | 3616 DecodeTypeRegisterSRsType(instr, fs_reg, ft_reg, fd_reg); |
3617 break; | 3617 break; |
3618 case D: | 3618 case D: |
3619 DecodeTypeRegisterDRsType(instr, fs_reg, ft_reg, fd_reg); | 3619 DecodeTypeRegisterDRsType(instr, fs_reg, ft_reg, fd_reg); |
3620 break; | 3620 break; |
3621 case W: | 3621 case W: |
3622 DecodeTypeRegisterWRsType(instr, fs_reg, fd_reg, ft_reg, alu_out); | 3622 DecodeTypeRegisterWRsType(instr, fs_reg, fd_reg, ft_reg, alu_out); |
3623 break; | 3623 break; |
3624 case L: | 3624 case L: |
3625 DecodeTypeRegisterLRsType(instr, fs_reg, fd_reg, ft_reg); | 3625 DecodeTypeRegisterLRsType(instr, fs_reg, fd_reg, ft_reg); |
3626 break; | 3626 break; |
3627 default: | 3627 default: |
3628 UNREACHABLE(); | 3628 UNREACHABLE(); |
3629 } | 3629 } |
3630 } | 3630 } |
3631 | 3631 |
3632 | 3632 |
3633 void Simulator::DecodeTypeRegisterCOP1X(Instruction* instr, | 3633 void Simulator::DecodeTypeRegisterCOP1X(Instruction* instr, |
3634 const int32_t& fr_reg, | 3634 const int32_t fr_reg, |
3635 const int32_t& fs_reg, | 3635 const int32_t fs_reg, |
3636 const int32_t& ft_reg, | 3636 const int32_t ft_reg, |
3637 const int32_t& fd_reg) { | 3637 const int32_t fd_reg) { |
3638 switch (instr->FunctionFieldRaw()) { | 3638 switch (instr->FunctionFieldRaw()) { |
3639 case MADD_D: | 3639 case MADD_D: |
3640 double fr, ft, fs; | 3640 double fr, ft, fs; |
3641 fr = get_fpu_register_double(fr_reg); | 3641 fr = get_fpu_register_double(fr_reg); |
3642 fs = get_fpu_register_double(fs_reg); | 3642 fs = get_fpu_register_double(fs_reg); |
3643 ft = get_fpu_register_double(ft_reg); | 3643 ft = get_fpu_register_double(ft_reg); |
3644 set_fpu_register_double(fd_reg, fs * ft + fr); | 3644 set_fpu_register_double(fd_reg, fs * ft + fr); |
3645 break; | 3645 break; |
3646 default: | 3646 default: |
3647 UNREACHABLE(); | 3647 UNREACHABLE(); |
3648 } | 3648 } |
3649 } | 3649 } |
3650 | 3650 |
3651 | 3651 |
3652 void Simulator::DecodeTypeRegisterSPECIAL( | 3652 void Simulator::DecodeTypeRegisterSPECIAL( |
3653 Instruction* instr, const int64_t& rs_reg, const int64_t& rs, | 3653 Instruction* instr, const int32_t rs_reg, const int64_t rs, |
3654 const uint64_t& rs_u, const int64_t& rt_reg, const int64_t& rt, | 3654 const uint64_t rs_u, const int32_t rt_reg, const int64_t rt, |
3655 const uint64_t& rt_u, const int64_t& rd_reg, const int32_t& fr_reg, | 3655 const uint64_t rt_u, const int32_t rd_reg, const int32_t fr_reg, |
3656 const int32_t& fs_reg, const int32_t& ft_reg, const int64_t& fd_reg, | 3656 const int32_t fs_reg, const int32_t ft_reg, const int32_t fd_reg, |
3657 int64_t& i64hilo, uint64_t& u64hilo, int64_t& alu_out, bool& do_interrupt, | 3657 const int64_t i64hilo, const uint64_t u64hilo, const int64_t alu_out, |
3658 int64_t& current_pc, int64_t& next_pc, int64_t& return_addr_reg, | 3658 const bool do_interrupt, const int64_t current_pc, const int64_t next_pc, |
3659 int64_t& i128resultH, int64_t& i128resultL) { | 3659 const int32_t return_addr_reg, const int64_t i128resultH, |
| 3660 const int64_t i128resultL) { |
3660 switch (instr->FunctionFieldRaw()) { | 3661 switch (instr->FunctionFieldRaw()) { |
3661 case SELEQZ_S: | 3662 case SELEQZ_S: |
3662 DCHECK(kArchVariant == kMips64r6); | 3663 DCHECK(kArchVariant == kMips64r6); |
3663 set_register(rd_reg, rt == 0 ? rs : 0); | 3664 set_register(rd_reg, rt == 0 ? rs : 0); |
3664 break; | 3665 break; |
3665 case SELNEZ_S: | 3666 case SELNEZ_S: |
3666 DCHECK(kArchVariant == kMips64r6); | 3667 DCHECK(kArchVariant == kMips64r6); |
3667 set_register(rd_reg, rt != 0 ? rs : 0); | 3668 set_register(rd_reg, rt != 0 ? rs : 0); |
3668 break; | 3669 break; |
3669 case JR: { | 3670 case JR: { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3813 } | 3814 } |
3814 break; | 3815 break; |
3815 default: // For other special opcodes we do the default operation. | 3816 default: // For other special opcodes we do the default operation. |
3816 set_register(rd_reg, alu_out); | 3817 set_register(rd_reg, alu_out); |
3817 TraceRegWr(alu_out); | 3818 TraceRegWr(alu_out); |
3818 } | 3819 } |
3819 } | 3820 } |
3820 | 3821 |
3821 | 3822 |
3822 void Simulator::DecodeTypeRegisterSPECIAL2(Instruction* instr, | 3823 void Simulator::DecodeTypeRegisterSPECIAL2(Instruction* instr, |
3823 const int64_t& rd_reg, | 3824 const int32_t rd_reg, |
3824 int64_t& alu_out) { | 3825 int64_t alu_out) { |
3825 switch (instr->FunctionFieldRaw()) { | 3826 switch (instr->FunctionFieldRaw()) { |
3826 case MUL: | 3827 case MUL: |
3827 set_register(rd_reg, alu_out); | 3828 set_register(rd_reg, alu_out); |
3828 TraceRegWr(alu_out); | 3829 TraceRegWr(alu_out); |
3829 // HI and LO are UNPREDICTABLE after the operation. | 3830 // HI and LO are UNPREDICTABLE after the operation. |
3830 set_register(LO, Unpredictable); | 3831 set_register(LO, Unpredictable); |
3831 set_register(HI, Unpredictable); | 3832 set_register(HI, Unpredictable); |
3832 break; | 3833 break; |
3833 default: // For other special2 opcodes we do the default operation. | 3834 default: // For other special2 opcodes we do the default operation. |
3834 set_register(rd_reg, alu_out); | 3835 set_register(rd_reg, alu_out); |
3835 } | 3836 } |
3836 } | 3837 } |
3837 | 3838 |
3838 | 3839 |
3839 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, | 3840 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, |
3840 const int64_t& rt_reg, | 3841 const int32_t rt_reg, |
3841 const int64_t& rd_reg, | 3842 const int32_t rd_reg, |
3842 int64_t& alu_out) { | 3843 const int64_t alu_out) { |
3843 switch (instr->FunctionFieldRaw()) { | 3844 switch (instr->FunctionFieldRaw()) { |
3844 case INS: | 3845 case INS: |
3845 // Ins instr leaves result in Rt, rather than Rd. | 3846 // Ins instr leaves result in Rt, rather than Rd. |
3846 set_register(rt_reg, alu_out); | 3847 set_register(rt_reg, alu_out); |
3847 TraceRegWr(alu_out); | 3848 TraceRegWr(alu_out); |
3848 break; | 3849 break; |
3849 case EXT: | 3850 case EXT: |
3850 case DEXT: | 3851 case DEXT: |
3851 // Dext/Ext instr leaves result in Rt, rather than Rd. | 3852 // Dext/Ext instr leaves result in Rt, rather than Rd. |
3852 set_register(rt_reg, alu_out); | 3853 set_register(rt_reg, alu_out); |
3853 TraceRegWr(alu_out); | 3854 TraceRegWr(alu_out); |
3854 break; | 3855 break; |
3855 case BITSWAP: | 3856 case BITSWAP: |
3856 case DBITSWAP: | 3857 case DBITSWAP: |
3857 set_register(rd_reg, alu_out); | 3858 set_register(rd_reg, alu_out); |
3858 TraceRegWr(alu_out); | 3859 TraceRegWr(alu_out); |
3859 break; | 3860 break; |
3860 default: | 3861 default: |
3861 UNREACHABLE(); | 3862 UNREACHABLE(); |
3862 } | 3863 } |
3863 } | 3864 } |
3864 | 3865 |
3865 | 3866 |
3866 void Simulator::DecodeTypeRegister(Instruction* instr) { | 3867 void Simulator::DecodeTypeRegister(Instruction* instr) { |
3867 // Instruction fields. | 3868 // Instruction fields. |
3868 const Opcode op = instr->OpcodeFieldRaw(); | 3869 const Opcode op = instr->OpcodeFieldRaw(); |
3869 const int64_t rs_reg = instr->RsValue(); | 3870 const int32_t rs_reg = instr->RsValue(); |
3870 const int64_t rs = get_register(rs_reg); | 3871 const int64_t rs = get_register(rs_reg); |
3871 const uint64_t rs_u = static_cast<uint32_t>(rs); | 3872 const uint64_t rs_u = static_cast<uint32_t>(rs); |
3872 const int64_t rt_reg = instr->RtValue(); | 3873 const int32_t rt_reg = instr->RtValue(); |
3873 const int64_t rt = get_register(rt_reg); | 3874 const int64_t rt = get_register(rt_reg); |
3874 const uint64_t rt_u = static_cast<uint32_t>(rt); | 3875 const uint64_t rt_u = static_cast<uint32_t>(rt); |
3875 const int64_t rd_reg = instr->RdValue(); | 3876 const int32_t rd_reg = instr->RdValue(); |
3876 | 3877 |
3877 const int32_t fr_reg = instr->FrValue(); | 3878 const int32_t fr_reg = instr->FrValue(); |
3878 const int32_t fs_reg = instr->FsValue(); | 3879 const int32_t fs_reg = instr->FsValue(); |
3879 const int32_t ft_reg = instr->FtValue(); | 3880 const int32_t ft_reg = instr->FtValue(); |
3880 const int32_t fd_reg = instr->FdValue(); | 3881 const int32_t fd_reg = instr->FdValue(); |
3881 int64_t i64hilo = 0; | 3882 int64_t i64hilo = 0; |
3882 uint64_t u64hilo = 0; | 3883 uint64_t u64hilo = 0; |
3883 | 3884 |
3884 // ALU output. | 3885 // ALU output. |
3885 // It should not be used as is. Instructions using it should always | 3886 // It should not be used as is. Instructions using it should always |
3886 // initialize it first. | 3887 // initialize it first. |
3887 int64_t alu_out = 0x12345678; | 3888 int64_t alu_out = 0x12345678; |
3888 | 3889 |
3889 // For break and trap instructions. | 3890 // For break and trap instructions. |
3890 bool do_interrupt = false; | 3891 bool do_interrupt = false; |
3891 | 3892 |
3892 // For jr and jalr. | 3893 // For jr and jalr. |
3893 // Get current pc. | 3894 // Get current pc. |
3894 int64_t current_pc = get_pc(); | 3895 int64_t current_pc = get_pc(); |
3895 // Next pc | 3896 // Next pc |
3896 int64_t next_pc = 0; | 3897 int64_t next_pc = 0; |
3897 int64_t return_addr_reg = 31; | 3898 int32_t return_addr_reg = 31; |
3898 | 3899 |
3899 int64_t i128resultH; | 3900 int64_t i128resultH; |
3900 int64_t i128resultL; | 3901 int64_t i128resultL; |
3901 | 3902 |
3902 // Set up the variables if needed before executing the instruction. | 3903 // Set up the variables if needed before executing the instruction. |
3903 ConfigureTypeRegister(instr, | 3904 ConfigureTypeRegister(instr, |
3904 &alu_out, | 3905 &alu_out, |
3905 &i64hilo, | 3906 &i64hilo, |
3906 &u64hilo, | 3907 &u64hilo, |
3907 &next_pc, | 3908 &next_pc, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3943 } | 3944 } |
3944 } | 3945 } |
3945 | 3946 |
3946 | 3947 |
3947 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). | 3948 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). |
3948 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 3949 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
3949 // Instruction fields. | 3950 // Instruction fields. |
3950 Opcode op = instr->OpcodeFieldRaw(); | 3951 Opcode op = instr->OpcodeFieldRaw(); |
3951 int64_t rs = get_register(instr->RsValue()); | 3952 int64_t rs = get_register(instr->RsValue()); |
3952 uint64_t rs_u = static_cast<uint64_t>(rs); | 3953 uint64_t rs_u = static_cast<uint64_t>(rs); |
3953 int64_t rt_reg = instr->RtValue(); // Destination register. | 3954 int32_t rt_reg = instr->RtValue(); // Destination register. |
3954 int64_t rt = get_register(rt_reg); | 3955 int64_t rt = get_register(rt_reg); |
3955 int16_t imm16 = instr->Imm16Value(); | 3956 int16_t imm16 = instr->Imm16Value(); |
3956 | 3957 |
3957 int32_t ft_reg = instr->FtValue(); // Destination register. | 3958 int32_t ft_reg = instr->FtValue(); // Destination register. |
3958 int64_t ft = get_fpu_register(ft_reg); | 3959 int64_t ft = get_fpu_register(ft_reg); |
3959 | 3960 |
3960 // Zero extended immediate. | 3961 // Zero extended immediate. |
3961 uint64_t oe_imm16 = 0xffff & imm16; | 3962 uint64_t oe_imm16 = 0xffff & imm16; |
3962 // Sign extended immediate. | 3963 // Sign extended immediate. |
3963 int64_t se_imm16 = imm16; | 3964 int64_t se_imm16 = imm16; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4086 if (rs > 0) { | 4087 if (rs > 0) { |
4087 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); | 4088 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); |
4088 } else if (rs < 0) { | 4089 } else if (rs < 0) { |
4089 exceptions[kIntegerUnderflow] = | 4090 exceptions[kIntegerUnderflow] = |
4090 rs < (Registers::kMinValue - se_imm16); | 4091 rs < (Registers::kMinValue - se_imm16); |
4091 } | 4092 } |
4092 } | 4093 } |
4093 alu_out = rs + se_imm16; | 4094 alu_out = rs + se_imm16; |
4094 break; | 4095 break; |
4095 case ADDIU: { | 4096 case ADDIU: { |
4096 int32_t alu32_out = rs + se_imm16; | 4097 int32_t alu32_out = static_cast<int32_t>(rs + se_imm16); |
4097 // Sign-extend result of 32bit operation into 64bit register. | 4098 // Sign-extend result of 32bit operation into 64bit register. |
4098 alu_out = static_cast<int64_t>(alu32_out); | 4099 alu_out = static_cast<int64_t>(alu32_out); |
4099 } | |
4100 break; | 4100 break; |
| 4101 } |
4101 case DADDIU: | 4102 case DADDIU: |
4102 alu_out = rs + se_imm16; | 4103 alu_out = rs + se_imm16; |
4103 break; | 4104 break; |
4104 case SLTI: | 4105 case SLTI: |
4105 alu_out = (rs < se_imm16) ? 1 : 0; | 4106 alu_out = (rs < se_imm16) ? 1 : 0; |
4106 break; | 4107 break; |
4107 case SLTIU: | 4108 case SLTIU: |
4108 alu_out = (rs_u < static_cast<uint64_t>(se_imm16)) ? 1 : 0; | 4109 alu_out = (rs_u < static_cast<uint64_t>(se_imm16)) ? 1 : 0; |
4109 break; | 4110 break; |
4110 case ANDI: | 4111 case ANDI: |
4111 alu_out = rs & oe_imm16; | 4112 alu_out = rs & oe_imm16; |
4112 break; | 4113 break; |
4113 case ORI: | 4114 case ORI: |
4114 alu_out = rs | oe_imm16; | 4115 alu_out = rs | oe_imm16; |
4115 break; | 4116 break; |
4116 case XORI: | 4117 case XORI: |
4117 alu_out = rs ^ oe_imm16; | 4118 alu_out = rs ^ oe_imm16; |
4118 break; | 4119 break; |
4119 case LUI: { | 4120 case LUI: { |
4120 int32_t alu32_out = (oe_imm16 << 16); | 4121 int32_t alu32_out = static_cast<int32_t>(oe_imm16 << 16); |
4121 // Sign-extend result of 32bit operation into 64bit register. | 4122 // Sign-extend result of 32bit operation into 64bit register. |
4122 alu_out = static_cast<int64_t>(alu32_out); | 4123 alu_out = static_cast<int64_t>(alu32_out); |
4123 } | |
4124 break; | 4124 break; |
| 4125 } |
4125 // ------------- Memory instructions. | 4126 // ------------- Memory instructions. |
4126 case LB: | 4127 case LB: |
4127 addr = rs + se_imm16; | 4128 addr = rs + se_imm16; |
4128 alu_out = ReadB(addr); | 4129 alu_out = ReadB(addr); |
4129 break; | 4130 break; |
4130 case LH: | 4131 case LH: |
4131 addr = rs + se_imm16; | 4132 addr = rs + se_imm16; |
4132 alu_out = ReadH(addr, instr); | 4133 alu_out = ReadH(addr, instr); |
4133 break; | 4134 break; |
4134 case LWL: { | 4135 case LWL: { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4264 case LWR: | 4265 case LWR: |
4265 set_register(rt_reg, alu_out); | 4266 set_register(rt_reg, alu_out); |
4266 break; | 4267 break; |
4267 case SB: | 4268 case SB: |
4268 WriteB(addr, static_cast<int8_t>(rt)); | 4269 WriteB(addr, static_cast<int8_t>(rt)); |
4269 break; | 4270 break; |
4270 case SH: | 4271 case SH: |
4271 WriteH(addr, static_cast<uint16_t>(rt), instr); | 4272 WriteH(addr, static_cast<uint16_t>(rt), instr); |
4272 break; | 4273 break; |
4273 case SWL: | 4274 case SWL: |
4274 WriteW(addr, mem_value, instr); | 4275 WriteW(addr, static_cast<int32_t>(mem_value), instr); |
4275 break; | 4276 break; |
4276 case SW: | 4277 case SW: |
4277 WriteW(addr, rt, instr); | 4278 WriteW(addr, static_cast<int32_t>(rt), instr); |
4278 break; | 4279 break; |
4279 case SD: | 4280 case SD: |
4280 Write2W(addr, rt, instr); | 4281 Write2W(addr, rt, instr); |
4281 break; | 4282 break; |
4282 case SWR: | 4283 case SWR: |
4283 WriteW(addr, mem_value, instr); | 4284 WriteW(addr, static_cast<int32_t>(mem_value), instr); |
4284 break; | 4285 break; |
4285 case LWC1: | 4286 case LWC1: |
4286 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4287 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
4287 set_fpu_register_word(ft_reg, static_cast<int32_t>(alu_out)); | 4288 set_fpu_register_word(ft_reg, static_cast<int32_t>(alu_out)); |
4288 break; | 4289 break; |
4289 case LDC1: | 4290 case LDC1: |
4290 set_fpu_register_double(ft_reg, fp_out); | 4291 set_fpu_register_double(ft_reg, fp_out); |
4291 break; | 4292 break; |
4292 case SWC1: | 4293 case SWC1: |
4293 addr = rs + se_imm16; | 4294 addr = rs + se_imm16; |
4294 WriteW(addr, get_fpu_register(ft_reg), instr); | 4295 WriteW(addr, static_cast<int32_t>(get_fpu_register(ft_reg)), instr); |
4295 break; | 4296 break; |
4296 case SDC1: | 4297 case SDC1: |
4297 addr = rs + se_imm16; | 4298 addr = rs + se_imm16; |
4298 WriteD(addr, get_fpu_register_double(ft_reg), instr); | 4299 WriteD(addr, get_fpu_register_double(ft_reg), instr); |
4299 break; | 4300 break; |
4300 default: | 4301 default: |
4301 break; | 4302 break; |
4302 } | 4303 } |
4303 | 4304 |
4304 | 4305 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4579 } | 4580 } |
4580 | 4581 |
4581 | 4582 |
4582 #undef UNSUPPORTED | 4583 #undef UNSUPPORTED |
4583 } // namespace internal | 4584 } // namespace internal |
4584 } // namespace v8 | 4585 } // namespace v8 |
4585 | 4586 |
4586 #endif // USE_SIMULATOR | 4587 #endif // USE_SIMULATOR |
4587 | 4588 |
4588 #endif // V8_TARGET_ARCH_MIPS64 | 4589 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |