| 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(); |
| 3957 | 4045 |
| 3958 int32_t ft_reg = instr->FtValue(); // Destination register. | 4046 int32_t ft_reg = instr->FtValue(); // Destination register. |
| 3959 int64_t ft = get_fpu_register(ft_reg); | 4047 int64_t ft = get_fpu_register(ft_reg); |
| 3960 | 4048 |
| 3961 // Zero extended immediate. | 4049 // Zero extended immediate. |
| 3962 uint64_t oe_imm16 = 0xffff & imm16; | 4050 uint64_t oe_imm16 = 0xffff & imm16; |
| 3963 // Sign extended immediate. | 4051 // Sign extended immediate. |
| 3964 int64_t se_imm16 = imm16; | 4052 int64_t se_imm16 = imm16; |
| 4053 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0); |
| 4054 int64_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0); |
| 4055 |
| 3965 | 4056 |
| 3966 // Get current pc. | 4057 // Get current pc. |
| 3967 int64_t current_pc = get_pc(); | 4058 int64_t current_pc = get_pc(); |
| 3968 // Next pc. | 4059 // Next pc. |
| 3969 int64_t next_pc = bad_ra; | 4060 int64_t next_pc = bad_ra; |
| 4061 // pc increment |
| 4062 int16_t pc_increment; |
| 3970 | 4063 |
| 3971 // Used for conditional branch instructions. | 4064 // Used for conditional branch instructions. |
| 3972 bool do_branch = false; | 4065 bool do_branch = false; |
| 3973 bool execute_branch_delay_instruction = false; | 4066 bool execute_branch_delay_instruction = false; |
| 3974 | 4067 |
| 3975 // Used for arithmetic instructions. | 4068 // Used for arithmetic instructions. |
| 3976 int64_t alu_out = 0; | 4069 int64_t alu_out = 0; |
| 3977 // Floating point. | 4070 // Floating point. |
| 3978 double fp_out = 0.0; | 4071 double fp_out = 0.0; |
| 3979 uint32_t cc, cc_value, fcsr_cc; | 4072 uint32_t cc, cc_value, fcsr_cc; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4073 break; | 4166 break; |
| 4074 case BNE: | 4167 case BNE: |
| 4075 do_branch = rs != rt; | 4168 do_branch = rs != rt; |
| 4076 break; | 4169 break; |
| 4077 case BLEZ: | 4170 case BLEZ: |
| 4078 do_branch = rs <= 0; | 4171 do_branch = rs <= 0; |
| 4079 break; | 4172 break; |
| 4080 case BGTZ: | 4173 case BGTZ: |
| 4081 do_branch = rs > 0; | 4174 do_branch = rs > 0; |
| 4082 break; | 4175 break; |
| 4176 case POP66: { |
| 4177 if (rs_reg) { // BEQZC |
| 4178 int32_t se_imm21 = |
| 4179 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); |
| 4180 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); |
| 4181 if (rs == 0) |
| 4182 next_pc = current_pc + 4 + (se_imm21 << 2); |
| 4183 else |
| 4184 next_pc = current_pc + 4; |
| 4185 } else { // JIC |
| 4186 next_pc = rt + imm16; |
| 4187 } |
| 4188 break; |
| 4189 } |
| 4083 // ------------- Arithmetic instructions. | 4190 // ------------- Arithmetic instructions. |
| 4084 case ADDI: | 4191 case ADDI: |
| 4085 case DADDI: | 4192 case DADDI: |
| 4086 if (HaveSameSign(rs, se_imm16)) { | 4193 if (HaveSameSign(rs, se_imm16)) { |
| 4087 if (rs > 0) { | 4194 if (rs > 0) { |
| 4088 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); | 4195 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); |
| 4089 } else if (rs < 0) { | 4196 } else if (rs < 0) { |
| 4090 exceptions[kIntegerUnderflow] = | 4197 exceptions[kIntegerUnderflow] = |
| 4091 rs < (Registers::kMinValue - se_imm16); | 4198 rs < (Registers::kMinValue - se_imm16); |
| 4092 } | 4199 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4206 alu_out = ReadW(addr, instr); | 4313 alu_out = ReadW(addr, instr); |
| 4207 break; | 4314 break; |
| 4208 case LDC1: | 4315 case LDC1: |
| 4209 addr = rs + se_imm16; | 4316 addr = rs + se_imm16; |
| 4210 fp_out = ReadD(addr, instr); | 4317 fp_out = ReadD(addr, instr); |
| 4211 break; | 4318 break; |
| 4212 case SWC1: | 4319 case SWC1: |
| 4213 case SDC1: | 4320 case SDC1: |
| 4214 addr = rs + se_imm16; | 4321 addr = rs + se_imm16; |
| 4215 break; | 4322 break; |
| 4323 // ------------- JIALC and BNEZC instructions. |
| 4324 case POP76: |
| 4325 // Next pc. |
| 4326 next_pc = rt + se_imm16; |
| 4327 // The instruction after the jump is NOT executed. |
| 4328 pc_increment = Instruction::kInstrSize; |
| 4329 if (instr->IsLinkingInstruction()) { |
| 4330 set_register(31, current_pc + pc_increment); |
| 4331 } |
| 4332 set_pc(next_pc); |
| 4333 pc_modified_ = true; |
| 4334 break; |
| 4335 // ---------PC-Relative instructions----------- |
| 4336 case PCREL: { |
| 4337 // rt field: checking 5-bits |
| 4338 uint8_t rt = (imm21 >> kImm16Bits); |
| 4339 switch (rt) { |
| 4340 case ALUIPC: |
| 4341 addr = current_pc + (se_imm16 << 16); |
| 4342 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; |
| 4343 break; |
| 4344 case AUIPC: |
| 4345 UNREACHABLE(); |
| 4346 break; |
| 4347 default: { |
| 4348 // rt field: checking the most significant 3-bits |
| 4349 rt = (imm21 >> kImm18Bits); |
| 4350 switch (rt) { |
| 4351 case LDPC: |
| 4352 // addr = (current_pc & 0xfffffffffffffff8) + (se_imm18 << 3); |
| 4353 addr = |
| 4354 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3); |
| 4355 alu_out = Read2W(addr, instr); |
| 4356 break; |
| 4357 default: { |
| 4358 // rt field: checking the most significant 2-bits |
| 4359 rt = (imm21 >> kImm19Bits); |
| 4360 switch (rt) { |
| 4361 case LWUPC: |
| 4362 UNREACHABLE(); |
| 4363 break; |
| 4364 case LWPC: { |
| 4365 int32_t offset = imm19; |
| 4366 // set sign |
| 4367 offset <<= (kOpcodeBits + kRsBits + 2); |
| 4368 offset >>= (kOpcodeBits + kRsBits + 2); |
| 4369 addr = current_pc + (offset << 2); |
| 4370 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
| 4371 alu_out = *ptr; |
| 4372 break; |
| 4373 } |
| 4374 case ADDIUPC: |
| 4375 alu_out = current_pc + (se_imm19 << 2); |
| 4376 break; |
| 4377 default: |
| 4378 UNREACHABLE(); |
| 4379 break; |
| 4380 } |
| 4381 break; |
| 4382 } |
| 4383 } |
| 4384 break; |
| 4385 } |
| 4386 } |
| 4387 break; |
| 4388 } |
| 4216 default: | 4389 default: |
| 4217 UNREACHABLE(); | 4390 UNREACHABLE(); |
| 4218 } | 4391 } |
| 4219 | 4392 |
| 4393 |
| 4220 // ---------- Raise exceptions triggered. | 4394 // ---------- Raise exceptions triggered. |
| 4221 SignalExceptions(); | 4395 SignalExceptions(); |
| 4222 | 4396 |
| 4223 // ---------- Execution. | 4397 // ---------- Execution. |
| 4224 switch (op) { | 4398 switch (op) { |
| 4225 // ------------- Branch instructions. | 4399 // ------------- Branch instructions. |
| 4226 case BEQ: | 4400 case BEQ: |
| 4227 case BNE: | 4401 case BNE: |
| 4228 case BLEZ: | 4402 case BLEZ: |
| 4229 case BGTZ: | 4403 case BGTZ: |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4291 set_fpu_register_double(ft_reg, fp_out); | 4465 set_fpu_register_double(ft_reg, fp_out); |
| 4292 break; | 4466 break; |
| 4293 case SWC1: | 4467 case SWC1: |
| 4294 addr = rs + se_imm16; | 4468 addr = rs + se_imm16; |
| 4295 WriteW(addr, get_fpu_register(ft_reg), instr); | 4469 WriteW(addr, get_fpu_register(ft_reg), instr); |
| 4296 break; | 4470 break; |
| 4297 case SDC1: | 4471 case SDC1: |
| 4298 addr = rs + se_imm16; | 4472 addr = rs + se_imm16; |
| 4299 WriteD(addr, get_fpu_register_double(ft_reg), instr); | 4473 WriteD(addr, get_fpu_register_double(ft_reg), instr); |
| 4300 break; | 4474 break; |
| 4475 case PCREL: |
| 4476 set_register(rs_reg, alu_out); |
| 4301 default: | 4477 default: |
| 4302 break; | 4478 break; |
| 4303 } | 4479 } |
| 4304 | 4480 |
| 4305 | 4481 |
| 4306 if (execute_branch_delay_instruction) { | 4482 if (execute_branch_delay_instruction) { |
| 4307 // Execute branch delay slot | 4483 // Execute branch delay slot |
| 4308 // We don't check for end_sim_pc. First it should not be met as the current | 4484 // 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. | 4485 // pc is valid. Secondly a jump should always execute its branch delay slot. |
| 4310 Instruction* branch_delay_instr = | 4486 Instruction* branch_delay_instr = |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4579 return address; | 4755 return address; |
| 4580 } | 4756 } |
| 4581 | 4757 |
| 4582 | 4758 |
| 4583 #undef UNSUPPORTED | 4759 #undef UNSUPPORTED |
| 4584 } } // namespace v8::internal | 4760 } } // namespace v8::internal |
| 4585 | 4761 |
| 4586 #endif // USE_SIMULATOR | 4762 #endif // USE_SIMULATOR |
| 4587 | 4763 |
| 4588 #endif // V8_TARGET_ARCH_MIPS64 | 4764 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |