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

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: Implementation BC and BALC. 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();
3890 int32_t imm26 = instr->Imm26Value();
3857 3891
3858 int32_t ft_reg = instr->FtValue(); // Destination register. 3892 int32_t ft_reg = instr->FtValue(); // Destination register.
3859 int64_t ft; 3893 int64_t ft;
3860 3894
3861 // Zero extended immediate. 3895 // Zero extended immediate.
3862 uint32_t oe_imm16 = 0xffff & imm16; 3896 uint32_t oe_imm16 = 0xffff & imm16;
3863 // Sign extended immediate. 3897 // Sign extended immediate.
3864 int32_t se_imm16 = imm16; 3898 int32_t se_imm16 = imm16;
3899 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0);
3900 int32_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfc000000 : 0);
3901
3865 3902
3866 // Get current pc. 3903 // Get current pc.
3867 int32_t current_pc = get_pc(); 3904 int32_t current_pc = get_pc();
3868 // Next pc. 3905 // Next pc.
3869 int32_t next_pc = bad_ra; 3906 int32_t next_pc = bad_ra;
3907 // pc increment
3908 int16_t pc_increment;
3870 3909
3871 // Used for conditional branch instructions. 3910 // Used for conditional branch instructions.
3872 bool do_branch = false; 3911 bool do_branch = false;
3873 bool execute_branch_delay_instruction = false; 3912 bool execute_branch_delay_instruction = false;
3874 3913
3875 // Used for arithmetic instructions. 3914 // Used for arithmetic instructions.
3876 int32_t alu_out = 0; 3915 int32_t alu_out = 0;
3877 // Floating point. 3916 // Floating point.
3878 double fp_out = 0.0; 3917 double fp_out = 0.0;
3879 uint32_t cc, cc_value, fcsr_cc; 3918 uint32_t cc, cc_value, fcsr_cc;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 break; 4012 break;
3974 case BNE: 4013 case BNE:
3975 do_branch = rs != rt; 4014 do_branch = rs != rt;
3976 break; 4015 break;
3977 case BLEZ: 4016 case BLEZ:
3978 do_branch = rs <= 0; 4017 do_branch = rs <= 0;
3979 break; 4018 break;
3980 case BGTZ: 4019 case BGTZ:
3981 do_branch = rs > 0; 4020 do_branch = rs > 0;
3982 break; 4021 break;
4022 case POP66: {
4023 if (rs_reg) { // BEQZC
4024 int32_t se_imm21 =
4025 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits));
4026 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits);
4027 if (rs == 0)
4028 next_pc = current_pc + 4 + (se_imm21 << 2);
4029 else
4030 next_pc = current_pc + 4;
4031 } else { // JIC
4032 next_pc = rt + imm16;
4033 }
4034 break;
4035 }
4036 case BC: {
4037 next_pc = current_pc + 4 + (se_imm26 << 2);
4038 set_pc(next_pc);
4039 pc_modified_ = true;
4040 break;
4041 }
4042 case BALC: {
4043 set_register(31, current_pc + 4);
4044 next_pc = current_pc + 4 + (se_imm26 << 2);
4045 set_pc(next_pc);
4046 pc_modified_ = true;
4047 break;
4048 }
3983 // ------------- Arithmetic instructions. 4049 // ------------- Arithmetic instructions.
3984 case ADDI: 4050 case ADDI:
3985 if (HaveSameSign(rs, se_imm16)) { 4051 if (HaveSameSign(rs, se_imm16)) {
3986 if (rs > 0) { 4052 if (rs > 0) {
3987 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); 4053 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
3988 } else if (rs < 0) { 4054 } else if (rs < 0) {
3989 exceptions[kIntegerUnderflow] = 4055 exceptions[kIntegerUnderflow] =
3990 rs < (Registers::kMinValue - se_imm16); 4056 rs < (Registers::kMinValue - se_imm16);
3991 } 4057 }
3992 } 4058 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4087 alu_out = ReadW(addr, instr); 4153 alu_out = ReadW(addr, instr);
4088 break; 4154 break;
4089 case LDC1: 4155 case LDC1:
4090 addr = rs + se_imm16; 4156 addr = rs + se_imm16;
4091 fp_out = ReadD(addr, instr); 4157 fp_out = ReadD(addr, instr);
4092 break; 4158 break;
4093 case SWC1: 4159 case SWC1:
4094 case SDC1: 4160 case SDC1:
4095 addr = rs + se_imm16; 4161 addr = rs + se_imm16;
4096 break; 4162 break;
4163 // ------------- JIALC and BNEZC instructions.
4164 case POP76:
4165 // Next pc.
4166 next_pc = rt + se_imm16;
4167 // The instruction after the jump is NOT executed.
4168 pc_increment = Instruction::kInstrSize;
4169 if (instr->IsLinkingInstruction()) {
4170 set_register(31, current_pc + pc_increment);
4171 }
4172 set_pc(next_pc);
4173 pc_modified_ = true;
4174 break;
4175 // ---------PC-Relative instructions-----------
4176 case PCREL: {
4177 // rt field: checking 5-bits
paul.l... 2015/06/10 03:49:26 nits: comments end with periods, several places.
ilija.pavlovic 2015/06/12 09:51:33 Done.
4178 uint8_t rt = (imm21 >> kImm16Bits);
4179 switch (rt) {
4180 case ALUIPC:
4181 addr = current_pc + (se_imm16 << 16);
4182 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4183 break;
4184 case AUIPC:
4185 alu_out = current_pc + (se_imm16 << 16);
4186 break;
4187 default: {
4188 // rt field: checking the most significant 2-bits
4189 rt = (imm21 >> kImm19Bits);
4190 switch (rt) {
4191 case LWPC: {
4192 int32_t offset = imm19;
4193 // set sign
4194 offset <<= (kOpcodeBits + kRsBits + 2);
4195 offset >>= (kOpcodeBits + kRsBits + 2);
4196 addr = current_pc + (offset << 2);
4197 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
4198 alu_out = *ptr;
4199 break;
4200 }
4201 case ADDIUPC:
4202 alu_out = current_pc + (se_imm19 << 2);
4203 break;
4204 default:
4205 UNREACHABLE();
4206 break;
4207 }
4208 }
4209 }
4210 break;
4211 }
4097 default: 4212 default:
4098 UNREACHABLE(); 4213 UNREACHABLE();
4099 } 4214 }
4100 4215
4101 // ---------- Raise exceptions triggered. 4216 // ---------- Raise exceptions triggered.
4102 SignalExceptions(); 4217 SignalExceptions();
4103 4218
4104 // ---------- Execution. 4219 // ---------- Execution.
4105 switch (op) { 4220 switch (op) {
4106 // ------------- Branch instructions. 4221 // ------------- Branch instructions.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4164 set_fpu_register_double(ft_reg, fp_out); 4279 set_fpu_register_double(ft_reg, fp_out);
4165 break; 4280 break;
4166 case SWC1: 4281 case SWC1:
4167 addr = rs + se_imm16; 4282 addr = rs + se_imm16;
4168 WriteW(addr, get_fpu_register_word(ft_reg), instr); 4283 WriteW(addr, get_fpu_register_word(ft_reg), instr);
4169 break; 4284 break;
4170 case SDC1: 4285 case SDC1:
4171 addr = rs + se_imm16; 4286 addr = rs + se_imm16;
4172 WriteD(addr, get_fpu_register_double(ft_reg), instr); 4287 WriteD(addr, get_fpu_register_double(ft_reg), instr);
4173 break; 4288 break;
4289 case PCREL:
4290 set_register(rs_reg, alu_out);
4174 default: 4291 default:
4175 break; 4292 break;
4176 } 4293 }
4177 4294
4178 4295
4179 if (execute_branch_delay_instruction) { 4296 if (execute_branch_delay_instruction) {
4180 // Execute branch delay slot 4297 // Execute branch delay slot
4181 // We don't check for end_sim_pc. First it should not be met as the current 4298 // 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. 4299 // pc is valid. Secondly a jump should always execute its branch delay slot.
4183 Instruction* branch_delay_instr = 4300 Instruction* branch_delay_instr =
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
4431 } 4548 }
4432 4549
4433 4550
4434 #undef UNSUPPORTED 4551 #undef UNSUPPORTED
4435 4552
4436 } } // namespace v8::internal 4553 } } // namespace v8::internal
4437 4554
4438 #endif // USE_SIMULATOR 4555 #endif // USE_SIMULATOR
4439 4556
4440 #endif // V8_TARGET_ARCH_MIPS 4557 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698