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 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 // Instruction fields. | 2194 // Instruction fields. |
2195 const Opcode op = instr->OpcodeFieldRaw(); | 2195 const Opcode op = instr->OpcodeFieldRaw(); |
2196 const int32_t rs_reg = instr->RsValue(); | 2196 const int32_t rs_reg = instr->RsValue(); |
2197 const int64_t rs = get_register(rs_reg); | 2197 const int64_t rs = get_register(rs_reg); |
2198 const uint64_t rs_u = static_cast<uint64_t>(rs); | 2198 const uint64_t rs_u = static_cast<uint64_t>(rs); |
2199 const int32_t rt_reg = instr->RtValue(); | 2199 const int32_t rt_reg = instr->RtValue(); |
2200 const int64_t rt = get_register(rt_reg); | 2200 const int64_t rt = get_register(rt_reg); |
2201 const uint64_t rt_u = static_cast<uint64_t>(rt); | 2201 const uint64_t rt_u = static_cast<uint64_t>(rt); |
2202 const int32_t rd_reg = instr->RdValue(); | 2202 const int32_t rd_reg = instr->RdValue(); |
2203 const uint64_t sa = instr->SaValue(); | 2203 const uint64_t sa = instr->SaValue(); |
| 2204 const uint8_t bp2 = instr->Bp2Value(); |
| 2205 const uint8_t bp3 = instr->Bp3Value(); |
2204 | 2206 |
2205 const int32_t fs_reg = instr->FsValue(); | 2207 const int32_t fs_reg = instr->FsValue(); |
2206 | 2208 |
2207 | 2209 |
2208 // ---------- Configuration. | 2210 // ---------- Configuration. |
2209 switch (op) { | 2211 switch (op) { |
2210 case COP1: // Coprocessor instructions. | 2212 case COP1: // Coprocessor instructions. |
2211 switch (instr->RsFieldRaw()) { | 2213 switch (instr->RsFieldRaw()) { |
2212 case CFC1: | 2214 case CFC1: |
2213 // At the moment only FCSR is supported. | 2215 // At the moment only FCSR is supported. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2328 *alu_out = rt >> rs; | 2330 *alu_out = rt >> rs; |
2329 break; | 2331 break; |
2330 case MFHI: // MFHI == CLZ on R6. | 2332 case MFHI: // MFHI == CLZ on R6. |
2331 if (kArchVariant != kMips64r6) { | 2333 if (kArchVariant != kMips64r6) { |
2332 DCHECK(instr->SaValue() == 0); | 2334 DCHECK(instr->SaValue() == 0); |
2333 *alu_out = get_register(HI); | 2335 *alu_out = get_register(HI); |
2334 } else { | 2336 } else { |
2335 // MIPS spec: If no bits were set in GPR rs, the result written to | 2337 // MIPS spec: If no bits were set in GPR rs, the result written to |
2336 // GPR rd is 32. | 2338 // GPR rd is 32. |
2337 DCHECK(instr->SaValue() == 1); | 2339 DCHECK(instr->SaValue() == 1); |
2338 *alu_out = base::bits::CountLeadingZeros32(rs_u); | 2340 *alu_out = |
| 2341 base::bits::CountLeadingZeros32(static_cast<int32_t>(rs_u)); |
2339 } | 2342 } |
2340 break; | 2343 break; |
2341 case MFLO: | 2344 case MFLO: |
2342 *alu_out = get_register(LO); | 2345 *alu_out = get_register(LO); |
2343 break; | 2346 break; |
2344 case MULT: { // MULT == D_MUL_MUH. | 2347 case MULT: { // MULT == D_MUL_MUH. |
2345 int32_t rs_lo = static_cast<int32_t>(rs); | 2348 int32_t rs_lo = static_cast<int32_t>(rs); |
2346 int32_t rt_lo = static_cast<int32_t>(rt); | 2349 int32_t rt_lo = static_cast<int32_t>(rt); |
2347 *i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo); | 2350 *i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo); |
2348 break; | 2351 break; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2512 case DEXT: { // Mips32r2 instruction. | 2515 case DEXT: { // Mips32r2 instruction. |
2513 // Interpret rd field as 5-bit msb of extract. | 2516 // Interpret rd field as 5-bit msb of extract. |
2514 uint16_t msb = rd_reg; | 2517 uint16_t msb = rd_reg; |
2515 // Interpret sa field as 5-bit lsb of extract. | 2518 // Interpret sa field as 5-bit lsb of extract. |
2516 uint16_t lsb = sa; | 2519 uint16_t lsb = sa; |
2517 uint16_t size = msb + 1; | 2520 uint16_t size = msb + 1; |
2518 uint64_t mask = (1ULL << size) - 1; | 2521 uint64_t mask = (1ULL << size) - 1; |
2519 *alu_out = static_cast<int64_t>((rs_u & (mask << lsb)) >> lsb); | 2522 *alu_out = static_cast<int64_t>((rs_u & (mask << lsb)) >> lsb); |
2520 break; | 2523 break; |
2521 } | 2524 } |
2522 case BITSWAP: { // Mips32r6 instruction | 2525 case BSHFL: { |
2523 uint32_t input = static_cast<uint32_t>(rt); | 2526 int sa = instr->SaFieldRaw() >> kSaShift; |
2524 uint32_t output = 0; | 2527 switch (sa) { |
2525 uint8_t i_byte, o_byte; | 2528 case BITSWAP: { |
2526 | 2529 uint32_t input = static_cast<uint32_t>(rt); |
2527 // Reverse the bit in byte for each individual byte | 2530 uint32_t output = 0; |
2528 for (int i = 0; i < 4; i++) { | |
2529 output = output >> 8; | |
2530 i_byte = input & 0xff; | |
2531 | |
2532 // Fast way to reverse bits in byte | |
2533 // Devised by Sean Anderson, July 13, 2001 | |
2534 o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | | |
2535 (i_byte * 0x8020LU & 0x88440LU)) * | |
2536 0x10101LU >> | |
2537 16); | |
2538 | |
2539 output = output | (static_cast<uint32_t>(o_byte << 24)); | |
2540 input = input >> 8; | |
2541 } | |
2542 | |
2543 *alu_out = static_cast<int64_t>(static_cast<int32_t>(output)); | |
2544 break; | |
2545 } | |
2546 case DBITSWAP: { | |
2547 switch (instr->SaFieldRaw()) { | |
2548 case DBITSWAP_SA: { // Mips64r6 | |
2549 uint64_t input = static_cast<uint64_t>(rt); | |
2550 uint64_t output = 0; | |
2551 uint8_t i_byte, o_byte; | 2531 uint8_t i_byte, o_byte; |
2552 | 2532 |
2553 // Reverse the bit in byte for each individual byte | 2533 // Reverse the bit in byte for each individual byte |
2554 for (int i = 0; i < 8; i++) { | 2534 for (int i = 0; i < 4; i++) { |
2555 output = output >> 8; | 2535 output = output >> 8; |
2556 i_byte = input & 0xff; | 2536 i_byte = input & 0xff; |
2557 | 2537 |
2558 // Fast way to reverse bits in byte | 2538 // Fast way to reverse bits in byte |
2559 // Devised by Sean Anderson, July 13, 2001 | 2539 // Devised by Sean Anderson, July 13, 2001 |
2560 o_byte = | 2540 o_byte = |
2561 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | | 2541 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | |
2562 (i_byte * 0x8020LU & 0x88440LU)) * | 2542 (i_byte * 0x8020LU & 0x88440LU)) * |
2563 0x10101LU >> | 2543 0x10101LU >> |
2564 16); | 2544 16); |
2565 | 2545 |
2566 output = output | ((static_cast<uint64_t>(o_byte) << 56)); | 2546 output = output | (static_cast<uint32_t>(o_byte << 24)); |
2567 input = input >> 8; | 2547 input = input >> 8; |
2568 } | 2548 } |
2569 | 2549 |
2570 *alu_out = static_cast<int64_t>(output); | 2550 *alu_out = static_cast<int64_t>(static_cast<int32_t>(output)); |
2571 break; | 2551 break; |
2572 } | 2552 } |
2573 default: | 2553 case SEB: |
| 2554 case SEH: |
| 2555 case WSBH: |
2574 UNREACHABLE(); | 2556 UNREACHABLE(); |
| 2557 break; |
| 2558 default: { |
| 2559 sa >>= kBp2Bits; |
| 2560 switch (sa) { |
| 2561 case ALIGN: { |
| 2562 if (bp2 == 0) { |
| 2563 *alu_out = static_cast<int32_t>(rt); |
| 2564 } else { |
| 2565 uint64_t rt_hi = rt << (8 * bp2); |
| 2566 uint64_t rs_lo = rs >> (8 * (4 - bp2)); |
| 2567 *alu_out = static_cast<int32_t>(rt_hi | rs_lo); |
| 2568 } |
| 2569 break; |
| 2570 } |
| 2571 default: |
| 2572 UNREACHABLE(); |
| 2573 break; |
| 2574 } |
| 2575 break; |
| 2576 } |
2575 } | 2577 } |
2576 break; | 2578 break; |
2577 } | 2579 } |
| 2580 case DBSHFL: { |
| 2581 int sa = instr->SaFieldRaw() >> kSaShift; |
| 2582 switch (sa) { |
| 2583 case DBITSWAP: { |
| 2584 switch (instr->SaFieldRaw() >> kSaShift) { |
| 2585 case DBITSWAP_SA: { // Mips64r6 |
| 2586 uint64_t input = static_cast<uint64_t>(rt); |
| 2587 uint64_t output = 0; |
| 2588 uint8_t i_byte, o_byte; |
| 2589 |
| 2590 // Reverse the bit in byte for each individual byte |
| 2591 for (int i = 0; i < 8; i++) { |
| 2592 output = output >> 8; |
| 2593 i_byte = input & 0xff; |
| 2594 |
| 2595 // Fast way to reverse bits in byte |
| 2596 // Devised by Sean Anderson, July 13, 2001 |
| 2597 o_byte = |
| 2598 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | |
| 2599 (i_byte * 0x8020LU & 0x88440LU)) * |
| 2600 0x10101LU >> |
| 2601 16); |
| 2602 |
| 2603 output = output | ((static_cast<uint64_t>(o_byte) << 56)); |
| 2604 input = input >> 8; |
| 2605 } |
| 2606 |
| 2607 *alu_out = static_cast<int64_t>(output); |
| 2608 break; |
| 2609 } |
| 2610 } |
| 2611 break; |
| 2612 } |
| 2613 case DSBH: |
| 2614 case DSHD: |
| 2615 UNREACHABLE(); |
| 2616 break; |
| 2617 default: { |
| 2618 sa >>= kBp3Bits; |
| 2619 switch (sa) { |
| 2620 case DALIGN: { |
| 2621 if (bp3 == 0) { |
| 2622 *alu_out = static_cast<int64_t>(rt); |
| 2623 } else { |
| 2624 uint64_t rt_hi = rt << (8 * bp3); |
| 2625 uint64_t rs_lo = rs >> (8 * (8 - bp3)); |
| 2626 *alu_out = static_cast<int64_t>(rt_hi | rs_lo); |
| 2627 } |
| 2628 break; |
| 2629 } |
| 2630 default: |
| 2631 UNREACHABLE(); |
| 2632 break; |
| 2633 } |
| 2634 break; |
| 2635 } |
| 2636 } |
| 2637 break; |
| 2638 } |
2578 default: | 2639 default: |
2579 UNREACHABLE(); | 2640 UNREACHABLE(); |
2580 } | 2641 } |
2581 break; | 2642 break; |
2582 default: | 2643 default: |
2583 UNREACHABLE(); | 2644 UNREACHABLE(); |
2584 } | 2645 } |
2585 } | 2646 } |
2586 | 2647 |
2587 | 2648 |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3846 // Ins instr leaves result in Rt, rather than Rd. | 3907 // Ins instr leaves result in Rt, rather than Rd. |
3847 set_register(rt_reg, alu_out); | 3908 set_register(rt_reg, alu_out); |
3848 TraceRegWr(alu_out); | 3909 TraceRegWr(alu_out); |
3849 break; | 3910 break; |
3850 case EXT: | 3911 case EXT: |
3851 case DEXT: | 3912 case DEXT: |
3852 // Dext/Ext instr leaves result in Rt, rather than Rd. | 3913 // Dext/Ext instr leaves result in Rt, rather than Rd. |
3853 set_register(rt_reg, alu_out); | 3914 set_register(rt_reg, alu_out); |
3854 TraceRegWr(alu_out); | 3915 TraceRegWr(alu_out); |
3855 break; | 3916 break; |
3856 case BITSWAP: | 3917 case BSHFL: |
3857 case DBITSWAP: | 3918 case DBSHFL: |
3858 set_register(rd_reg, alu_out); | 3919 set_register(rd_reg, alu_out); |
3859 TraceRegWr(alu_out); | 3920 TraceRegWr(alu_out); |
3860 break; | 3921 break; |
3861 default: | 3922 default: |
3862 UNREACHABLE(); | 3923 UNREACHABLE(); |
3863 } | 3924 } |
3864 } | 3925 } |
3865 | 3926 |
3866 | 3927 |
3867 void Simulator::DecodeTypeRegister(Instruction* instr) { | 3928 void Simulator::DecodeTypeRegister(Instruction* instr) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3926 case SPECIAL: | 3987 case SPECIAL: |
3927 DecodeTypeRegisterSPECIAL( | 3988 DecodeTypeRegisterSPECIAL( |
3928 instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, rd_reg, fr_reg, fs_reg, | 3989 instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, rd_reg, fr_reg, fs_reg, |
3929 ft_reg, fd_reg, i64hilo, u64hilo, alu_out, do_interrupt, current_pc, | 3990 ft_reg, fd_reg, i64hilo, u64hilo, alu_out, do_interrupt, current_pc, |
3930 next_pc, return_addr_reg, i128resultH, i128resultL); | 3991 next_pc, return_addr_reg, i128resultH, i128resultL); |
3931 break; | 3992 break; |
3932 case SPECIAL2: | 3993 case SPECIAL2: |
3933 DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out); | 3994 DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out); |
3934 break; | 3995 break; |
3935 case SPECIAL3: | 3996 case SPECIAL3: |
3936 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); | 3997 switch (instr->FunctionFieldRaw()) { |
| 3998 case BSHFL: { |
| 3999 int sa = instr->SaValue(); |
| 4000 sa >>= kBp2Bits; |
| 4001 switch (sa) { |
| 4002 case ALIGN: { |
| 4003 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); |
| 4004 break; |
| 4005 } |
| 4006 } |
| 4007 } |
| 4008 case DBSHFL: { |
| 4009 int sa = instr->SaValue(); |
| 4010 sa >>= kBp3Bits; |
| 4011 switch (sa) { |
| 4012 case DALIGN: { |
| 4013 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); |
| 4014 break; |
| 4015 } |
| 4016 } |
| 4017 } |
| 4018 default: |
| 4019 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); |
| 4020 break; |
| 4021 } |
3937 break; | 4022 break; |
3938 // Unimplemented opcodes raised an error in the configuration step before, | 4023 // Unimplemented opcodes raised an error in the configuration step before, |
3939 // so we can use the default here to set the destination register in common | 4024 // so we can use the default here to set the destination register in common |
3940 // cases. | 4025 // cases. |
3941 default: | 4026 default: |
3942 set_register(rd_reg, alu_out); | 4027 set_register(rd_reg, alu_out); |
3943 TraceRegWr(alu_out); | 4028 TraceRegWr(alu_out); |
3944 } | 4029 } |
3945 } | 4030 } |
3946 | 4031 |
3947 | 4032 |
3948 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). | 4033 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). |
3949 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 4034 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
3950 // Instruction fields. | 4035 // Instruction fields. |
3951 Opcode op = instr->OpcodeFieldRaw(); | 4036 Opcode op = instr->OpcodeFieldRaw(); |
| 4037 int32_t rs_reg = instr->RsValue(); |
3952 int64_t rs = get_register(instr->RsValue()); | 4038 int64_t rs = get_register(instr->RsValue()); |
3953 uint64_t rs_u = static_cast<uint64_t>(rs); | 4039 uint64_t rs_u = static_cast<uint64_t>(rs); |
3954 int32_t rt_reg = instr->RtValue(); // Destination register. | 4040 int32_t rt_reg = instr->RtValue(); // Destination register. |
3955 int64_t rt = get_register(rt_reg); | 4041 int64_t rt = get_register(rt_reg); |
3956 int16_t imm16 = instr->Imm16Value(); | 4042 int16_t imm16 = instr->Imm16Value(); |
| 4043 int32_t imm18 = instr->Imm18Value(); |
| 4044 int32_t imm19 = instr->Imm19Value(); |
| 4045 int32_t imm21 = instr->Imm21Value(); |
| 4046 int32_t imm26 = instr->Imm26Value(); |
3957 | 4047 |
3958 int32_t ft_reg = instr->FtValue(); // Destination register. | 4048 int32_t ft_reg = instr->FtValue(); // Destination register. |
3959 int64_t ft = get_fpu_register(ft_reg); | 4049 int64_t ft = get_fpu_register(ft_reg); |
3960 | 4050 |
3961 // Zero extended immediate. | 4051 // Zero extended immediate. |
3962 uint64_t oe_imm16 = 0xffff & imm16; | 4052 uint64_t oe_imm16 = 0xffff & imm16; |
3963 // Sign extended immediate. | 4053 // Sign extended immediate. |
3964 int64_t se_imm16 = imm16; | 4054 int64_t se_imm16 = imm16; |
| 4055 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0); |
| 4056 int64_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0); |
| 4057 int64_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfffffffffc000000 : 0); |
| 4058 |
3965 | 4059 |
3966 // Get current pc. | 4060 // Get current pc. |
3967 int64_t current_pc = get_pc(); | 4061 int64_t current_pc = get_pc(); |
3968 // Next pc. | 4062 // Next pc. |
3969 int64_t next_pc = bad_ra; | 4063 int64_t next_pc = bad_ra; |
| 4064 // pc increment |
| 4065 int16_t pc_increment; |
3970 | 4066 |
3971 // Used for conditional branch instructions. | 4067 // Used for conditional branch instructions. |
3972 bool do_branch = false; | 4068 bool do_branch = false; |
3973 bool execute_branch_delay_instruction = false; | 4069 bool execute_branch_delay_instruction = false; |
3974 | 4070 |
3975 // Used for arithmetic instructions. | 4071 // Used for arithmetic instructions. |
3976 int64_t alu_out = 0; | 4072 int64_t alu_out = 0; |
3977 // Floating point. | 4073 // Floating point. |
3978 double fp_out = 0.0; | 4074 double fp_out = 0.0; |
3979 uint32_t cc, cc_value, fcsr_cc; | 4075 uint32_t cc, cc_value, fcsr_cc; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4073 break; | 4169 break; |
4074 case BNE: | 4170 case BNE: |
4075 do_branch = rs != rt; | 4171 do_branch = rs != rt; |
4076 break; | 4172 break; |
4077 case BLEZ: | 4173 case BLEZ: |
4078 do_branch = rs <= 0; | 4174 do_branch = rs <= 0; |
4079 break; | 4175 break; |
4080 case BGTZ: | 4176 case BGTZ: |
4081 do_branch = rs > 0; | 4177 do_branch = rs > 0; |
4082 break; | 4178 break; |
| 4179 case POP66: { |
| 4180 if (rs_reg) { // BEQZC |
| 4181 int32_t se_imm21 = |
| 4182 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); |
| 4183 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); |
| 4184 if (rs == 0) |
| 4185 next_pc = current_pc + 4 + (se_imm21 << 2); |
| 4186 else |
| 4187 next_pc = current_pc + 4; |
| 4188 } else { // JIC |
| 4189 next_pc = rt + imm16; |
| 4190 } |
| 4191 break; |
| 4192 } |
| 4193 case BC: { |
| 4194 next_pc = current_pc + 4 + (se_imm26 << 2); |
| 4195 set_pc(next_pc); |
| 4196 pc_modified_ = true; |
| 4197 break; |
| 4198 } |
| 4199 case BALC: { |
| 4200 set_register(31, current_pc + 4); |
| 4201 next_pc = current_pc + 4 + (se_imm26 << 2); |
| 4202 set_pc(next_pc); |
| 4203 pc_modified_ = true; |
| 4204 break; |
| 4205 } |
4083 // ------------- Arithmetic instructions. | 4206 // ------------- Arithmetic instructions. |
4084 case ADDI: | 4207 case ADDI: |
4085 case DADDI: | 4208 case DADDI: |
4086 if (HaveSameSign(rs, se_imm16)) { | 4209 if (HaveSameSign(rs, se_imm16)) { |
4087 if (rs > 0) { | 4210 if (rs > 0) { |
4088 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); | 4211 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); |
4089 } else if (rs < 0) { | 4212 } else if (rs < 0) { |
4090 exceptions[kIntegerUnderflow] = | 4213 exceptions[kIntegerUnderflow] = |
4091 rs < (Registers::kMinValue - se_imm16); | 4214 rs < (Registers::kMinValue - se_imm16); |
4092 } | 4215 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4206 alu_out = ReadW(addr, instr); | 4329 alu_out = ReadW(addr, instr); |
4207 break; | 4330 break; |
4208 case LDC1: | 4331 case LDC1: |
4209 addr = rs + se_imm16; | 4332 addr = rs + se_imm16; |
4210 fp_out = ReadD(addr, instr); | 4333 fp_out = ReadD(addr, instr); |
4211 break; | 4334 break; |
4212 case SWC1: | 4335 case SWC1: |
4213 case SDC1: | 4336 case SDC1: |
4214 addr = rs + se_imm16; | 4337 addr = rs + se_imm16; |
4215 break; | 4338 break; |
| 4339 // ------------- JIALC and BNEZC instructions. |
| 4340 case POP76: |
| 4341 // Next pc. |
| 4342 next_pc = rt + se_imm16; |
| 4343 // The instruction after the jump is NOT executed. |
| 4344 pc_increment = Instruction::kInstrSize; |
| 4345 if (instr->IsLinkingInstruction()) { |
| 4346 set_register(31, current_pc + pc_increment); |
| 4347 } |
| 4348 set_pc(next_pc); |
| 4349 pc_modified_ = true; |
| 4350 break; |
| 4351 // ------------- PC-Relative instructions. |
| 4352 case PCREL: { |
| 4353 // rt field: checking 5-bits. |
| 4354 uint8_t rt = (imm21 >> kImm16Bits); |
| 4355 switch (rt) { |
| 4356 case ALUIPC: |
| 4357 addr = current_pc + (se_imm16 << 16); |
| 4358 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; |
| 4359 break; |
| 4360 case AUIPC: |
| 4361 alu_out = current_pc + (se_imm16 << 16); |
| 4362 break; |
| 4363 default: { |
| 4364 // rt field: checking the most significant 3-bits. |
| 4365 rt = (imm21 >> kImm18Bits); |
| 4366 switch (rt) { |
| 4367 case LDPC: |
| 4368 addr = |
| 4369 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3); |
| 4370 alu_out = Read2W(addr, instr); |
| 4371 break; |
| 4372 default: { |
| 4373 // rt field: checking the most significant 2-bits. |
| 4374 rt = (imm21 >> kImm19Bits); |
| 4375 switch (rt) { |
| 4376 case LWUPC: { |
| 4377 int32_t offset = imm19; |
| 4378 // Set sign. |
| 4379 offset <<= (kOpcodeBits + kRsBits + 2); |
| 4380 offset >>= (kOpcodeBits + kRsBits + 2); |
| 4381 addr = current_pc + (offset << 2); |
| 4382 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
| 4383 alu_out = *ptr; |
| 4384 break; |
| 4385 } |
| 4386 case LWPC: { |
| 4387 int32_t offset = imm19; |
| 4388 // Set sign. |
| 4389 offset <<= (kOpcodeBits + kRsBits + 2); |
| 4390 offset >>= (kOpcodeBits + kRsBits + 2); |
| 4391 addr = current_pc + (offset << 2); |
| 4392 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 4393 alu_out = *ptr; |
| 4394 break; |
| 4395 } |
| 4396 case ADDIUPC: |
| 4397 alu_out = current_pc + (se_imm19 << 2); |
| 4398 break; |
| 4399 default: |
| 4400 UNREACHABLE(); |
| 4401 break; |
| 4402 } |
| 4403 break; |
| 4404 } |
| 4405 } |
| 4406 break; |
| 4407 } |
| 4408 } |
| 4409 break; |
| 4410 } |
4216 default: | 4411 default: |
4217 UNREACHABLE(); | 4412 UNREACHABLE(); |
4218 } | 4413 } |
4219 | 4414 |
| 4415 |
4220 // ---------- Raise exceptions triggered. | 4416 // ---------- Raise exceptions triggered. |
4221 SignalExceptions(); | 4417 SignalExceptions(); |
4222 | 4418 |
4223 // ---------- Execution. | 4419 // ---------- Execution. |
4224 switch (op) { | 4420 switch (op) { |
4225 // ------------- Branch instructions. | 4421 // ------------- Branch instructions. |
4226 case BEQ: | 4422 case BEQ: |
4227 case BNE: | 4423 case BNE: |
4228 case BLEZ: | 4424 case BLEZ: |
4229 case BGTZ: | 4425 case BGTZ: |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4291 set_fpu_register_double(ft_reg, fp_out); | 4487 set_fpu_register_double(ft_reg, fp_out); |
4292 break; | 4488 break; |
4293 case SWC1: | 4489 case SWC1: |
4294 addr = rs + se_imm16; | 4490 addr = rs + se_imm16; |
4295 WriteW(addr, static_cast<int32_t>(get_fpu_register(ft_reg)), instr); | 4491 WriteW(addr, static_cast<int32_t>(get_fpu_register(ft_reg)), instr); |
4296 break; | 4492 break; |
4297 case SDC1: | 4493 case SDC1: |
4298 addr = rs + se_imm16; | 4494 addr = rs + se_imm16; |
4299 WriteD(addr, get_fpu_register_double(ft_reg), instr); | 4495 WriteD(addr, get_fpu_register_double(ft_reg), instr); |
4300 break; | 4496 break; |
| 4497 case PCREL: |
| 4498 set_register(rs_reg, alu_out); |
4301 default: | 4499 default: |
4302 break; | 4500 break; |
4303 } | 4501 } |
4304 | 4502 |
4305 | 4503 |
4306 if (execute_branch_delay_instruction) { | 4504 if (execute_branch_delay_instruction) { |
4307 // Execute branch delay slot | 4505 // Execute branch delay slot |
4308 // We don't check for end_sim_pc. First it should not be met as the current | 4506 // We don't check for end_sim_pc. First it should not be met as the current |
4309 // pc is valid. Secondly a jump should always execute its branch delay slot. | 4507 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4310 Instruction* branch_delay_instr = | 4508 Instruction* branch_delay_instr = |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4580 } | 4778 } |
4581 | 4779 |
4582 | 4780 |
4583 #undef UNSUPPORTED | 4781 #undef UNSUPPORTED |
4584 } // namespace internal | 4782 } // namespace internal |
4585 } // namespace v8 | 4783 } // namespace v8 |
4586 | 4784 |
4587 #endif // USE_SIMULATOR | 4785 #endif // USE_SIMULATOR |
4588 | 4786 |
4589 #endif // V8_TARGET_ARCH_MIPS64 | 4787 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |