Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/mips/simulator-mips.cc

Issue 1144373003: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 // Instruction fields. 2162 // Instruction fields.
2163 const Opcode op = instr->OpcodeFieldRaw(); 2163 const Opcode op = instr->OpcodeFieldRaw();
2164 const int32_t rs_reg = instr->RsValue(); 2164 const int32_t rs_reg = instr->RsValue();
2165 const int32_t rs = get_register(rs_reg); 2165 const int32_t rs = get_register(rs_reg);
2166 const uint32_t rs_u = static_cast<uint32_t>(rs); 2166 const uint32_t rs_u = static_cast<uint32_t>(rs);
2167 const int32_t rt_reg = instr->RtValue(); 2167 const int32_t rt_reg = instr->RtValue();
2168 const int32_t rt = get_register(rt_reg); 2168 const int32_t rt = get_register(rt_reg);
2169 const uint32_t rt_u = static_cast<uint32_t>(rt); 2169 const uint32_t rt_u = static_cast<uint32_t>(rt);
2170 const int32_t rd_reg = instr->RdValue(); 2170 const int32_t rd_reg = instr->RdValue();
2171 const uint32_t sa = instr->SaValue(); 2171 const uint32_t sa = instr->SaValue();
2172 const uint8_t bp = instr->Bp2Value();
2172 2173
2173 const int32_t fs_reg = instr->FsValue(); 2174 const int32_t fs_reg = instr->FsValue();
2174 2175
2175 2176
2176 // ---------- Configuration. 2177 // ---------- Configuration.
2177 switch (op) { 2178 switch (op) {
2178 case COP1: // Coprocessor instructions. 2179 case COP1: // Coprocessor instructions.
2179 switch (instr->RsFieldRaw()) { 2180 switch (instr->RsFieldRaw()) {
2180 case CFC1: 2181 case CFC1:
2181 // At the moment only FCSR is supported. 2182 // At the moment only FCSR is supported.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 case EXT: { // Mips32r2 instruction. 2405 case EXT: { // Mips32r2 instruction.
2405 // Interpret rd field as 5-bit msb of extract. 2406 // Interpret rd field as 5-bit msb of extract.
2406 uint16_t msb = rd_reg; 2407 uint16_t msb = rd_reg;
2407 // Interpret sa field as 5-bit lsb of extract. 2408 // Interpret sa field as 5-bit lsb of extract.
2408 uint16_t lsb = sa; 2409 uint16_t lsb = sa;
2409 uint16_t size = msb + 1; 2410 uint16_t size = msb + 1;
2410 uint32_t mask = (1 << size) - 1; 2411 uint32_t mask = (1 << size) - 1;
2411 *alu_out = (rs_u & (mask << lsb)) >> lsb; 2412 *alu_out = (rs_u & (mask << lsb)) >> lsb;
2412 break; 2413 break;
2413 } 2414 }
2414 case BITSWAP: { // Mips32r6 instruction 2415 case BSHFL: {
2415 uint32_t input = static_cast<uint32_t>(rt); 2416 int sa = instr->SaFieldRaw() >> kSaShift;
2416 uint32_t output = 0; 2417 switch (sa) {
2417 uint8_t i_byte, o_byte; 2418 case BITSWAP: {
2419 uint32_t input = static_cast<uint32_t>(rt);
2420 uint32_t output = 0;
2421 uint8_t i_byte, o_byte;
2418 2422
2419 // Reverse the bit in byte for each individual byte 2423 // Reverse the bit in byte for each individual byte
2420 for (int i = 0; i < 4; i++) { 2424 for (int i = 0; i < 4; i++) {
2421 output = output >> 8; 2425 output = output >> 8;
2422 i_byte = input & 0xff; 2426 i_byte = input & 0xff;
2423 2427
2424 // Fast way to reverse bits in byte 2428 // Fast way to reverse bits in byte
2425 // Devised by Sean Anderson, July 13, 2001 2429 // Devised by Sean Anderson, July 13, 2001
2426 o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | 2430 o_byte =
2427 (i_byte * 0x8020LU & 0x88440LU)) * 2431 static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
2428 0x10101LU >> 2432 (i_byte * 0x8020LU & 0x88440LU)) *
2429 16); 2433 0x10101LU >>
2434 16);
2430 2435
2431 output = output | (static_cast<uint32_t>(o_byte << 24)); 2436 output = output | (static_cast<uint32_t>(o_byte << 24));
2432 input = input >> 8; 2437 input = input >> 8;
2438 }
2439
2440 *alu_out = static_cast<int32_t>(output);
2441 break;
2442 }
2443 case SEB:
2444 case SEH:
2445 case WSBH:
2446 UNREACHABLE();
2447 break;
2448 default: {
2449 sa >>= kBp2Bits;
2450 switch (sa) {
2451 case ALIGN: {
2452 if (bp == 0) {
2453 *alu_out = static_cast<int32_t>(rt);
2454 } else {
2455 uint32_t rt_hi = rt << (8 * bp);
2456 uint32_t rs_lo = rs >> (8 * (4 - bp));
2457 *alu_out = static_cast<int32_t>(rt_hi | rs_lo);
2458 }
2459 break;
2460 }
2461 default:
2462 UNREACHABLE();
2463 break;
2464 }
2465 }
2433 } 2466 }
2434
2435 *alu_out = static_cast<int32_t>(output);
2436 break; 2467 break;
2437 } 2468 }
2438 default: 2469 default:
2439 UNREACHABLE(); 2470 UNREACHABLE();
2440 } 2471 }
2441 break; 2472 break;
2442 default: 2473 default:
2443 UNREACHABLE(); 2474 UNREACHABLE();
2444 } 2475 }
2445 } 2476 }
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, 3785 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr,
3755 const int32_t& rt_reg, 3786 const int32_t& rt_reg,
3756 const int32_t& rd_reg, 3787 const int32_t& rd_reg,
3757 int32_t& alu_out) { 3788 int32_t& alu_out) {
3758 switch (instr->FunctionFieldRaw()) { 3789 switch (instr->FunctionFieldRaw()) {
3759 case INS: 3790 case INS:
3760 // Ins instr leaves result in Rt, rather than Rd. 3791 // Ins instr leaves result in Rt, rather than Rd.
3761 set_register(rt_reg, alu_out); 3792 set_register(rt_reg, alu_out);
3762 break; 3793 break;
3763 case EXT: 3794 case EXT:
3764 // Ext instr leaves result in Rt, rather than Rd.
3765 set_register(rt_reg, alu_out); 3795 set_register(rt_reg, alu_out);
3766 break; 3796 break;
3767 case BITSWAP: 3797 case BSHFL:
3768 set_register(rd_reg, alu_out); 3798 set_register(rd_reg, alu_out);
3769 break; 3799 break;
3770 default: 3800 default:
3771 UNREACHABLE(); 3801 UNREACHABLE();
3772 } 3802 }
3773 } 3803 }
3774 3804
3775 3805
3776 void Simulator::DecodeTypeRegister(Instruction* instr) { 3806 void Simulator::DecodeTypeRegister(Instruction* instr) {
3777 // Instruction fields. 3807 // Instruction fields.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3842 default: 3872 default:
3843 set_register(rd_reg, alu_out); 3873 set_register(rd_reg, alu_out);
3844 } 3874 }
3845 } 3875 }
3846 3876
3847 3877
3848 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). 3878 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
3849 void Simulator::DecodeTypeImmediate(Instruction* instr) { 3879 void Simulator::DecodeTypeImmediate(Instruction* instr) {
3850 // Instruction fields. 3880 // Instruction fields.
3851 Opcode op = instr->OpcodeFieldRaw(); 3881 Opcode op = instr->OpcodeFieldRaw();
3882 int32_t rs_reg = instr->RsValue();
3852 int32_t rs = get_register(instr->RsValue()); 3883 int32_t rs = get_register(instr->RsValue());
3853 uint32_t rs_u = static_cast<uint32_t>(rs); 3884 uint32_t rs_u = static_cast<uint32_t>(rs);
3854 int32_t rt_reg = instr->RtValue(); // Destination register. 3885 int32_t rt_reg = instr->RtValue(); // Destination register.
3855 int32_t rt = get_register(rt_reg); 3886 int32_t rt = get_register(rt_reg);
3856 int16_t imm16 = instr->Imm16Value(); 3887 int16_t imm16 = instr->Imm16Value();
3888 int32_t imm19 = instr->Imm19Value();
3889 int32_t imm21 = instr->Imm21Value();
3857 3890
3858 int32_t ft_reg = instr->FtValue(); // Destination register. 3891 int32_t ft_reg = instr->FtValue(); // Destination register.
3859 int64_t ft; 3892 int64_t ft;
3860 3893
3861 // Zero extended immediate. 3894 // Zero extended immediate.
3862 uint32_t oe_imm16 = 0xffff & imm16; 3895 uint32_t oe_imm16 = 0xffff & imm16;
3863 // Sign extended immediate. 3896 // Sign extended immediate.
3864 int32_t se_imm16 = imm16; 3897 int32_t se_imm16 = imm16;
3898 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0);
3899
3865 3900
3866 // Get current pc. 3901 // Get current pc.
3867 int32_t current_pc = get_pc(); 3902 int32_t current_pc = get_pc();
3868 // Next pc. 3903 // Next pc.
3869 int32_t next_pc = bad_ra; 3904 int32_t next_pc = bad_ra;
3905 // pc increment
3906 int16_t pc_increment;
3870 3907
3871 // Used for conditional branch instructions. 3908 // Used for conditional branch instructions.
3872 bool do_branch = false; 3909 bool do_branch = false;
3873 bool execute_branch_delay_instruction = false; 3910 bool execute_branch_delay_instruction = false;
3874 3911
3875 // Used for arithmetic instructions. 3912 // Used for arithmetic instructions.
3876 int32_t alu_out = 0; 3913 int32_t alu_out = 0;
3877 // Floating point. 3914 // Floating point.
3878 double fp_out = 0.0; 3915 double fp_out = 0.0;
3879 uint32_t cc, cc_value, fcsr_cc; 3916 uint32_t cc, cc_value, fcsr_cc;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 break; 4010 break;
3974 case BNE: 4011 case BNE:
3975 do_branch = rs != rt; 4012 do_branch = rs != rt;
3976 break; 4013 break;
3977 case BLEZ: 4014 case BLEZ:
3978 do_branch = rs <= 0; 4015 do_branch = rs <= 0;
3979 break; 4016 break;
3980 case BGTZ: 4017 case BGTZ:
3981 do_branch = rs > 0; 4018 do_branch = rs > 0;
3982 break; 4019 break;
4020 case POP66: {
4021 if (rs_reg) { // BEQZC
4022 int32_t se_imm21 =
4023 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits));
4024 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits);
4025 if (rs == 0)
4026 next_pc = current_pc + 4 + (se_imm21 << 2);
4027 else
4028 next_pc = current_pc + 4;
4029 } else { // JIC
4030 next_pc = rt + imm16;
4031 }
4032 break;
4033 }
3983 // ------------- Arithmetic instructions. 4034 // ------------- Arithmetic instructions.
3984 case ADDI: 4035 case ADDI:
3985 if (HaveSameSign(rs, se_imm16)) { 4036 if (HaveSameSign(rs, se_imm16)) {
3986 if (rs > 0) { 4037 if (rs > 0) {
3987 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); 4038 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
3988 } else if (rs < 0) { 4039 } else if (rs < 0) {
3989 exceptions[kIntegerUnderflow] = 4040 exceptions[kIntegerUnderflow] =
3990 rs < (Registers::kMinValue - se_imm16); 4041 rs < (Registers::kMinValue - se_imm16);
3991 } 4042 }
3992 } 4043 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4087 alu_out = ReadW(addr, instr); 4138 alu_out = ReadW(addr, instr);
4088 break; 4139 break;
4089 case LDC1: 4140 case LDC1:
4090 addr = rs + se_imm16; 4141 addr = rs + se_imm16;
4091 fp_out = ReadD(addr, instr); 4142 fp_out = ReadD(addr, instr);
4092 break; 4143 break;
4093 case SWC1: 4144 case SWC1:
4094 case SDC1: 4145 case SDC1:
4095 addr = rs + se_imm16; 4146 addr = rs + se_imm16;
4096 break; 4147 break;
4148 // ------------- JIALC and BNEZC instructions.
4149 case POP76:
4150 // Next pc.
4151 next_pc = rt + se_imm16;
4152 // The instruction after the jump is NOT executed.
4153 pc_increment = Instruction::kInstrSize;
4154 if (instr->IsLinkingInstruction()) {
4155 set_register(31, current_pc + pc_increment);
4156 }
4157 set_pc(next_pc);
4158 pc_modified_ = true;
4159 break;
4160 // ---------PC-Relative instructions-----------
4161 case PCREL: {
4162 // rt field: checking 5-bits
4163 uint8_t rt = (imm21 >> kImm16Bits);
4164 switch (rt) {
4165 case ALUIPC:
4166 addr = current_pc + (se_imm16 << 16);
4167 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4168 break;
4169 case AUIPC:
4170 UNREACHABLE();
4171 break;
4172 default: {
4173 // rt field: checking the most significant 2-bits
4174 rt = (imm21 >> kImm19Bits);
4175 switch (rt) {
4176 case LWPC: {
4177 int32_t offset = imm19;
4178 // set sign
4179 offset <<= (kOpcodeBits + kRsBits + 2);
4180 offset >>= (kOpcodeBits + kRsBits + 2);
4181 addr = current_pc + (offset << 2);
4182 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
4183 alu_out = *ptr;
4184 break;
4185 }
4186 case ADDIUPC:
4187 alu_out = current_pc + (se_imm19 << 2);
4188 break;
4189 default:
4190 UNREACHABLE();
4191 break;
4192 }
4193 }
4194 }
4195 break;
4196 }
4097 default: 4197 default:
4098 UNREACHABLE(); 4198 UNREACHABLE();
4099 } 4199 }
4100 4200
4101 // ---------- Raise exceptions triggered. 4201 // ---------- Raise exceptions triggered.
4102 SignalExceptions(); 4202 SignalExceptions();
4103 4203
4104 // ---------- Execution. 4204 // ---------- Execution.
4105 switch (op) { 4205 switch (op) {
4106 // ------------- Branch instructions. 4206 // ------------- Branch instructions.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4164 set_fpu_register_double(ft_reg, fp_out); 4264 set_fpu_register_double(ft_reg, fp_out);
4165 break; 4265 break;
4166 case SWC1: 4266 case SWC1:
4167 addr = rs + se_imm16; 4267 addr = rs + se_imm16;
4168 WriteW(addr, get_fpu_register_word(ft_reg), instr); 4268 WriteW(addr, get_fpu_register_word(ft_reg), instr);
4169 break; 4269 break;
4170 case SDC1: 4270 case SDC1:
4171 addr = rs + se_imm16; 4271 addr = rs + se_imm16;
4172 WriteD(addr, get_fpu_register_double(ft_reg), instr); 4272 WriteD(addr, get_fpu_register_double(ft_reg), instr);
4173 break; 4273 break;
4274 case PCREL:
4275 set_register(rs_reg, alu_out);
4174 default: 4276 default:
4175 break; 4277 break;
4176 } 4278 }
4177 4279
4178 4280
4179 if (execute_branch_delay_instruction) { 4281 if (execute_branch_delay_instruction) {
4180 // Execute branch delay slot 4282 // Execute branch delay slot
4181 // We don't check for end_sim_pc. First it should not be met as the current 4283 // We don't check for end_sim_pc. First it should not be met as the current
4182 // pc is valid. Secondly a jump should always execute its branch delay slot. 4284 // pc is valid. Secondly a jump should always execute its branch delay slot.
4183 Instruction* branch_delay_instr = 4285 Instruction* branch_delay_instr =
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
4431 } 4533 }
4432 4534
4433 4535
4434 #undef UNSUPPORTED 4536 #undef UNSUPPORTED
4435 4537
4436 } } // namespace v8::internal 4538 } } // namespace v8::internal
4437 4539
4438 #endif // USE_SIMULATOR 4540 #endif // USE_SIMULATOR
4439 4541
4440 #endif // V8_TARGET_ARCH_MIPS 4542 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698