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