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

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

Issue 1195793002: 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
« no previous file with comments | « src/mips/disasm-mips.cc ('k') | src/mips64/assembler-mips64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after
3753 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, 3784 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr,
3754 const int32_t& rt_reg, 3785 const int32_t& rt_reg,
3755 const int32_t& rd_reg, 3786 const int32_t& rd_reg,
3756 int32_t& alu_out) { 3787 int32_t& alu_out) {
3757 switch (instr->FunctionFieldRaw()) { 3788 switch (instr->FunctionFieldRaw()) {
3758 case INS: 3789 case INS:
3759 // Ins instr leaves result in Rt, rather than Rd. 3790 // Ins instr leaves result in Rt, rather than Rd.
3760 set_register(rt_reg, alu_out); 3791 set_register(rt_reg, alu_out);
3761 break; 3792 break;
3762 case EXT: 3793 case EXT:
3763 // Ext instr leaves result in Rt, rather than Rd.
3764 set_register(rt_reg, alu_out); 3794 set_register(rt_reg, alu_out);
3765 break; 3795 break;
3766 case BITSWAP: 3796 case BSHFL:
3767 set_register(rd_reg, alu_out); 3797 set_register(rd_reg, alu_out);
3768 break; 3798 break;
3769 default: 3799 default:
3770 UNREACHABLE(); 3800 UNREACHABLE();
3771 } 3801 }
3772 } 3802 }
3773 3803
3774 3804
3775 void Simulator::DecodeTypeRegister(Instruction* instr) { 3805 void Simulator::DecodeTypeRegister(Instruction* instr) {
3776 // Instruction fields. 3806 // Instruction fields.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3841 default: 3871 default:
3842 set_register(rd_reg, alu_out); 3872 set_register(rd_reg, alu_out);
3843 } 3873 }
3844 } 3874 }
3845 3875
3846 3876
3847 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). 3877 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
3848 void Simulator::DecodeTypeImmediate(Instruction* instr) { 3878 void Simulator::DecodeTypeImmediate(Instruction* instr) {
3849 // Instruction fields. 3879 // Instruction fields.
3850 Opcode op = instr->OpcodeFieldRaw(); 3880 Opcode op = instr->OpcodeFieldRaw();
3881 int32_t rs_reg = instr->RsValue();
3851 int32_t rs = get_register(instr->RsValue()); 3882 int32_t rs = get_register(instr->RsValue());
3852 uint32_t rs_u = static_cast<uint32_t>(rs); 3883 uint32_t rs_u = static_cast<uint32_t>(rs);
3853 int32_t rt_reg = instr->RtValue(); // Destination register. 3884 int32_t rt_reg = instr->RtValue(); // Destination register.
3854 int32_t rt = get_register(rt_reg); 3885 int32_t rt = get_register(rt_reg);
3855 int16_t imm16 = instr->Imm16Value(); 3886 int16_t imm16 = instr->Imm16Value();
3887 int32_t imm19 = instr->Imm19Value();
3888 int32_t imm21 = instr->Imm21Value();
3889 int32_t imm26 = instr->Imm26Value();
3856 3890
3857 int32_t ft_reg = instr->FtValue(); // Destination register. 3891 int32_t ft_reg = instr->FtValue(); // Destination register.
3858 int64_t ft; 3892 int64_t ft;
3859 3893
3860 // Zero extended immediate. 3894 // Zero extended immediate.
3861 uint32_t oe_imm16 = 0xffff & imm16; 3895 uint32_t oe_imm16 = 0xffff & imm16;
3862 // Sign extended immediate. 3896 // Sign extended immediate.
3863 int32_t se_imm16 = imm16; 3897 int32_t se_imm16 = imm16;
3898 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0);
3899 int32_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfc000000 : 0);
3900
3864 3901
3865 // Get current pc. 3902 // Get current pc.
3866 int32_t current_pc = get_pc(); 3903 int32_t current_pc = get_pc();
3867 // Next pc. 3904 // Next pc.
3868 int32_t next_pc = bad_ra; 3905 int32_t next_pc = bad_ra;
3906 // pc increment
3907 int16_t pc_increment;
3869 3908
3870 // Used for conditional branch instructions. 3909 // Used for conditional branch instructions.
3871 bool do_branch = false; 3910 bool do_branch = false;
3872 bool execute_branch_delay_instruction = false; 3911 bool execute_branch_delay_instruction = false;
3873 3912
3874 // Used for arithmetic instructions. 3913 // Used for arithmetic instructions.
3875 int32_t alu_out = 0; 3914 int32_t alu_out = 0;
3876 // Floating point. 3915 // Floating point.
3877 double fp_out = 0.0; 3916 double fp_out = 0.0;
3878 uint32_t cc, cc_value, fcsr_cc; 3917 uint32_t cc, cc_value, fcsr_cc;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3972 break; 4011 break;
3973 case BNE: 4012 case BNE:
3974 do_branch = rs != rt; 4013 do_branch = rs != rt;
3975 break; 4014 break;
3976 case BLEZ: 4015 case BLEZ:
3977 do_branch = rs <= 0; 4016 do_branch = rs <= 0;
3978 break; 4017 break;
3979 case BGTZ: 4018 case BGTZ:
3980 do_branch = rs > 0; 4019 do_branch = rs > 0;
3981 break; 4020 break;
4021 case POP66: {
4022 if (rs_reg) { // BEQZC
4023 int32_t se_imm21 =
4024 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits));
4025 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits);
4026 if (rs == 0)
4027 next_pc = current_pc + 4 + (se_imm21 << 2);
4028 else
4029 next_pc = current_pc + 4;
4030 } else { // JIC
4031 next_pc = rt + imm16;
4032 }
4033 break;
4034 }
4035 case BC: {
4036 next_pc = current_pc + 4 + (se_imm26 << 2);
4037 set_pc(next_pc);
4038 pc_modified_ = true;
4039 break;
4040 }
4041 case BALC: {
4042 set_register(31, current_pc + 4);
4043 next_pc = current_pc + 4 + (se_imm26 << 2);
4044 set_pc(next_pc);
4045 pc_modified_ = true;
4046 break;
4047 }
3982 // ------------- Arithmetic instructions. 4048 // ------------- Arithmetic instructions.
3983 case ADDI: 4049 case ADDI:
3984 if (HaveSameSign(rs, se_imm16)) { 4050 if (HaveSameSign(rs, se_imm16)) {
3985 if (rs > 0) { 4051 if (rs > 0) {
3986 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); 4052 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
3987 } else if (rs < 0) { 4053 } else if (rs < 0) {
3988 exceptions[kIntegerUnderflow] = 4054 exceptions[kIntegerUnderflow] =
3989 rs < (Registers::kMinValue - se_imm16); 4055 rs < (Registers::kMinValue - se_imm16);
3990 } 4056 }
3991 } 4057 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4086 alu_out = ReadW(addr, instr); 4152 alu_out = ReadW(addr, instr);
4087 break; 4153 break;
4088 case LDC1: 4154 case LDC1:
4089 addr = rs + se_imm16; 4155 addr = rs + se_imm16;
4090 fp_out = ReadD(addr, instr); 4156 fp_out = ReadD(addr, instr);
4091 break; 4157 break;
4092 case SWC1: 4158 case SWC1:
4093 case SDC1: 4159 case SDC1:
4094 addr = rs + se_imm16; 4160 addr = rs + se_imm16;
4095 break; 4161 break;
4162 // ------------- JIALC and BNEZC instructions.
4163 case POP76:
4164 // Next pc.
4165 next_pc = rt + se_imm16;
4166 // The instruction after the jump is NOT executed.
4167 pc_increment = Instruction::kInstrSize;
4168 if (instr->IsLinkingInstruction()) {
4169 set_register(31, current_pc + pc_increment);
4170 }
4171 set_pc(next_pc);
4172 pc_modified_ = true;
4173 break;
4174 // ------------- PC-Relative instructions.
4175 case PCREL: {
4176 // rt field: checking 5-bits.
4177 uint8_t rt = (imm21 >> kImm16Bits);
4178 switch (rt) {
4179 case ALUIPC:
4180 addr = current_pc + (se_imm16 << 16);
4181 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4182 break;
4183 case AUIPC:
4184 alu_out = current_pc + (se_imm16 << 16);
4185 break;
4186 default: {
4187 // rt field: checking the most significant 2-bits.
4188 rt = (imm21 >> kImm19Bits);
4189 switch (rt) {
4190 case LWPC: {
4191 int32_t offset = imm19;
4192 // Set sign.
4193 offset <<= (kOpcodeBits + kRsBits + 2);
4194 offset >>= (kOpcodeBits + kRsBits + 2);
4195 addr = current_pc + (offset << 2);
4196 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
4197 alu_out = *ptr;
4198 break;
4199 }
4200 case ADDIUPC:
4201 alu_out = current_pc + (se_imm19 << 2);
4202 break;
4203 default:
4204 UNREACHABLE();
4205 break;
4206 }
4207 }
4208 }
4209 break;
4210 }
4096 default: 4211 default:
4097 UNREACHABLE(); 4212 UNREACHABLE();
4098 } 4213 }
4099 4214
4100 // ---------- Raise exceptions triggered. 4215 // ---------- Raise exceptions triggered.
4101 SignalExceptions(); 4216 SignalExceptions();
4102 4217
4103 // ---------- Execution. 4218 // ---------- Execution.
4104 switch (op) { 4219 switch (op) {
4105 // ------------- Branch instructions. 4220 // ------------- Branch instructions.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4163 set_fpu_register_double(ft_reg, fp_out); 4278 set_fpu_register_double(ft_reg, fp_out);
4164 break; 4279 break;
4165 case SWC1: 4280 case SWC1:
4166 addr = rs + se_imm16; 4281 addr = rs + se_imm16;
4167 WriteW(addr, get_fpu_register_word(ft_reg), instr); 4282 WriteW(addr, get_fpu_register_word(ft_reg), instr);
4168 break; 4283 break;
4169 case SDC1: 4284 case SDC1:
4170 addr = rs + se_imm16; 4285 addr = rs + se_imm16;
4171 WriteD(addr, get_fpu_register_double(ft_reg), instr); 4286 WriteD(addr, get_fpu_register_double(ft_reg), instr);
4172 break; 4287 break;
4288 case PCREL:
4289 set_register(rs_reg, alu_out);
4173 default: 4290 default:
4174 break; 4291 break;
4175 } 4292 }
4176 4293
4177 4294
4178 if (execute_branch_delay_instruction) { 4295 if (execute_branch_delay_instruction) {
4179 // Execute branch delay slot 4296 // Execute branch delay slot
4180 // We don't check for end_sim_pc. First it should not be met as the current 4297 // We don't check for end_sim_pc. First it should not be met as the current
4181 // pc is valid. Secondly a jump should always execute its branch delay slot. 4298 // pc is valid. Secondly a jump should always execute its branch delay slot.
4182 Instruction* branch_delay_instr = 4299 Instruction* branch_delay_instr =
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4431 4548
4432 4549
4433 #undef UNSUPPORTED 4550 #undef UNSUPPORTED
4434 4551
4435 } // namespace internal 4552 } // namespace internal
4436 } // namespace v8 4553 } // namespace v8
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
« no previous file with comments | « src/mips/disasm-mips.cc ('k') | src/mips64/assembler-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698