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

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

Issue 1534183002: MIPS64: r6 compact branch optimization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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 #if V8_TARGET_ARCH_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 instr->SetInstructionBits(kNopInstr); 139 instr->SetInstructionBits(kNopInstr);
140 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); 140 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
141 } 141 }
142 // TODO(yuyin): 2 -> 3? 142 // TODO(yuyin): 2 -> 3?
143 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstructionSize); 143 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstructionSize);
144 } 144 }
145 145
146 146
147 #else // GENERATED_CODE_COVERAGE 147 #else // GENERATED_CODE_COVERAGE
148 148
149 #define UNSUPPORTED() printf("Unsupported instruction.\n"); 149 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n");
balazs.kilvady 2015/12/18 19:18:05 I just forgot to remove it from the final CL but I
ivica.bogosavljevic 2015/12/22 10:22:40 Ok, I'll remove Sim here as well as for MIPS32
balazs.kilvady 2015/12/22 11:01:56 Please do not remove it. I think it is fine to mak
ivica.bogosavljevic 2015/12/22 12:23:41 Acknowledged.
150 150
151 static void InitializeCoverage() {} 151 static void InitializeCoverage() {}
152 152
153 153
154 void MipsDebugger::Stop(Instruction* instr) { 154 void MipsDebugger::Stop(Instruction* instr) {
155 // Get the stop code. 155 // Get the stop code.
156 uint32_t code = instr->Bits(25, 6); 156 uint32_t code = instr->Bits(25, 6);
157 // Retrieve the encoded address, which comes just after this stop. 157 // Retrieve the encoded address, which comes just after this stop.
158 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + 158 char* msg = *reinterpret_cast<char**>(sim_->get_pc() +
159 Instruction::kInstrSize); 159 Instruction::kInstrSize);
(...skipping 3884 matching lines...) Expand 10 before | Expand all | Expand 10 after
4044 break; 4044 break;
4045 // Unimplemented opcodes raised an error in the configuration step before, 4045 // Unimplemented opcodes raised an error in the configuration step before,
4046 // so we can use the default here to set the destination register in common 4046 // so we can use the default here to set the destination register in common
4047 // cases. 4047 // cases.
4048 default: 4048 default:
4049 UNREACHABLE(); 4049 UNREACHABLE();
4050 } 4050 }
4051 } 4051 }
4052 4052
4053 4053
4054 // Branch instructions common part. 4054 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc).
4055 #define BranchAndLinkHelper(do_branch) \
4056 execute_branch_delay_instruction = true; \
4057 if (do_branch) { \
4058 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \
4059 set_register(31, current_pc + kBranchReturnOffset); \
4060 } else { \
4061 next_pc = current_pc + kBranchReturnOffset; \
4062 }
4063
4064
4065 #define BranchHelper(do_branch) \
4066 execute_branch_delay_instruction = true; \
4067 if (do_branch) { \
4068 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \
4069 } else { \
4070 next_pc = current_pc + kBranchReturnOffset; \
4071 }
4072
4073
4074 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
4075 void Simulator::DecodeTypeImmediate(Instruction* instr) { 4055 void Simulator::DecodeTypeImmediate(Instruction* instr) {
4076 // Instruction fields. 4056 // Instruction fields.
4077 Opcode op = instr->OpcodeFieldRaw(); 4057 Opcode op = instr->OpcodeFieldRaw();
4078 int32_t rs_reg = instr->RsValue(); 4058 int32_t rs_reg = instr->RsValue();
4079 int64_t rs = get_register(instr->RsValue()); 4059 int64_t rs = get_register(instr->RsValue());
4080 uint64_t rs_u = static_cast<uint64_t>(rs); 4060 uint64_t rs_u = static_cast<uint64_t>(rs);
4081 int32_t rt_reg = instr->RtValue(); // Destination register. 4061 int32_t rt_reg = instr->RtValue(); // Destination register.
4082 int64_t rt = get_register(rt_reg); 4062 int64_t rt = get_register(rt_reg);
4083 int16_t imm16 = instr->Imm16Value(); 4063 int16_t imm16 = instr->Imm16Value();
4084 int32_t imm18 = instr->Imm18Value(); 4064 int32_t imm18 = instr->Imm18Value();
4085 int32_t imm21 = instr->Imm21Value();
4086 int32_t imm26 = instr->Imm26Value();
4087 4065
4088 int32_t ft_reg = instr->FtValue(); // Destination register. 4066 int32_t ft_reg = instr->FtValue(); // Destination register.
4089 int64_t ft = get_fpu_register(ft_reg);
4090 4067
4091 // Zero extended immediate. 4068 // Zero extended immediate.
4092 uint64_t oe_imm16 = 0xffff & imm16; 4069 uint64_t oe_imm16 = 0xffff & imm16;
4093 // Sign extended immediate. 4070 // Sign extended immediate.
4094 int64_t se_imm16 = imm16; 4071 int64_t se_imm16 = imm16;
4095 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0); 4072 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0);
4096 int64_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfffffffffc000000 : 0);
4097 4073
4098 // Get current pc.
4099 int64_t current_pc = get_pc();
4100 // Next pc. 4074 // Next pc.
4101 int64_t next_pc = bad_ra; 4075 int64_t next_pc = bad_ra;
4102 4076
4103 // Used for conditional branch instructions. 4077 // Used for conditional branch instructions.
4104 bool execute_branch_delay_instruction = false; 4078 bool execute_branch_delay_instruction = false;
4105 4079
4106 // Used for arithmetic instructions. 4080 // Used for arithmetic instructions.
4107 int64_t alu_out = 0; 4081 int64_t alu_out = 0;
4108 4082
4109 // Used for memory instructions. 4083 // Used for memory instructions.
4110 int64_t addr = 0x0; 4084 int64_t addr = 0x0;
4111 // Alignment for 32-bit integers used in LWL, LWR, etc. 4085 // Alignment for 32-bit integers used in LWL, LWR, etc.
4112 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; 4086 const int kInt32AlignmentMask = sizeof(uint32_t) - 1;
4113 4087
4114 // ---------- Configuration (and execution for REGIMM). 4088 // Branch instructions common part.
4089 auto BranchAndLinkHelper = [this, instr, &next_pc,
4090 &execute_branch_delay_instruction](
4091 bool do_branch) {
4092 execute_branch_delay_instruction = true;
4093 int64_t current_pc = get_pc();
4094 if (do_branch) {
4095 int16_t imm16 = instr->Imm16Value();
4096 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4097 set_register(31, current_pc + 2 * Instruction::kInstrSize);
4098 } else {
4099 next_pc = current_pc + 2 * Instruction::kInstrSize;
4100 }
4101 };
4102
4103 auto BranchHelper = [this, instr, &next_pc,
4104 &execute_branch_delay_instruction](bool do_branch) {
4105 execute_branch_delay_instruction = true;
4106 int64_t current_pc = get_pc();
4107 if (do_branch) {
4108 int16_t imm16 = instr->Imm16Value();
4109 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4110 } else {
4111 next_pc = current_pc + 2 * Instruction::kInstrSize;
4112 }
4113 };
4114
4115 auto BranchAndLinkCompactHelper = [this, instr, &next_pc](bool do_branch,
4116 int bits) {
4117 int64_t current_pc = get_pc();
4118 CheckForbiddenSlot(current_pc);
4119 if (do_branch) {
4120 int32_t imm = instr->ImmValue(bits);
4121 imm <<= 32 - bits;
4122 imm >>= 32 - bits;
4123 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize;
4124 set_register(31, current_pc + Instruction::kInstrSize);
4125 }
4126 };
4127
4128 auto BranchCompactHelper = [&next_pc, this, instr](bool do_branch, int bits) {
4129 int64_t current_pc = get_pc();
4130 CheckForbiddenSlot(current_pc);
4131 if (do_branch) {
4132 int32_t imm = instr->ImmValue(bits);
4133 imm <<= 32 - bits;
4134 imm >>= 32 - bits;
4135 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize;
4136 }
4137 };
4115 switch (op) { 4138 switch (op) {
4116 // ------------- COP1. Coprocessor instructions. 4139 // ------------- COP1. Coprocessor instructions.
4117 case COP1: 4140 case COP1:
4118 switch (instr->RsFieldRaw()) { 4141 switch (instr->RsFieldRaw()) {
4119 case BC1: { // Branch on coprocessor condition. 4142 case BC1: { // Branch on coprocessor condition.
4120 uint32_t cc = instr->FBccValue(); 4143 uint32_t cc = instr->FBccValue();
4121 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 4144 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
4122 uint32_t cc_value = test_fcsr_bit(fcsr_cc); 4145 uint32_t cc_value = test_fcsr_bit(fcsr_cc);
4123 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 4146 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
4124 execute_branch_delay_instruction = true; 4147 BranchHelper(do_branch);
4125 // Set next_pc.
4126 if (do_branch) {
4127 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4128 } else {
4129 next_pc = current_pc + kBranchReturnOffset;
4130 }
4131 break; 4148 break;
4132 } 4149 }
4133 case BC1EQZ: 4150 case BC1EQZ:
4134 execute_branch_delay_instruction = true; 4151 BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
4135 // Set next_pc.
4136 if (!(ft & 0x1)) {
4137 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4138 } else {
4139 next_pc = current_pc + kBranchReturnOffset;
4140 }
4141 break; 4152 break;
4142 case BC1NEZ: 4153 case BC1NEZ:
4143 execute_branch_delay_instruction = true; 4154 BranchHelper(get_fpu_register(ft_reg) & 0x1);
4144 // Set next_pc.
4145 if (ft & 0x1) {
4146 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4147 } else {
4148 next_pc = current_pc + kBranchReturnOffset;
4149 }
4150 break; 4155 break;
4151 default: 4156 default:
4152 UNREACHABLE(); 4157 UNREACHABLE();
4153 } 4158 }
4154 break; 4159 break;
4155 // ------------- REGIMM class. 4160 // ------------- REGIMM class.
4156 case REGIMM: 4161 case REGIMM:
4157 switch (instr->RtFieldRaw()) { 4162 switch (instr->RtFieldRaw()) {
4158 case BLTZ: 4163 case BLTZ:
4159 BranchHelper(rs < 0); 4164 BranchHelper(rs < 0);
(...skipping 19 matching lines...) Expand all
4179 break; // case REGIMM. 4184 break; // case REGIMM.
4180 // ------------- Branch instructions. 4185 // ------------- Branch instructions.
4181 // When comparing to zero, the encoding of rt field is always 0, so we don't 4186 // When comparing to zero, the encoding of rt field is always 0, so we don't
4182 // need to replace rt with zero. 4187 // need to replace rt with zero.
4183 case BEQ: 4188 case BEQ:
4184 BranchHelper(rs == rt); 4189 BranchHelper(rs == rt);
4185 break; 4190 break;
4186 case BNE: 4191 case BNE:
4187 BranchHelper(rs != rt); 4192 BranchHelper(rs != rt);
4188 break; 4193 break;
4189 case BLEZ: 4194 case POP06: // BLEZALC, BGEZALC, BGEUC, BLEZ (pre-r6)
4190 BranchHelper(rs <= 0); 4195 if (kArchVariant == kMips64r6) {
4196 if (rt_reg != 0) {
4197 if (rs_reg == 0) { // BLEZALC
4198 BranchAndLinkCompactHelper(rt <= 0, 16);
4199 } else {
4200 if (rs_reg == rt_reg) { // BGEZALC
4201 BranchAndLinkCompactHelper(rt >= 0, 16);
4202 } else { // BGEUC
4203 BranchCompactHelper(
4204 static_cast<uint64_t>(rs) >= static_cast<uint64_t>(rt), 16);
4205 }
4206 }
4207 } else { // BLEZ
4208 BranchHelper(rs <= 0);
4209 }
4210 } else { // BLEZ
4211 BranchHelper(rs <= 0);
4212 }
4191 break; 4213 break;
4192 case BGTZ: 4214 case POP07: // BGTZALC, BLTZALC, BLTUC, BGTZ (pre-r6)
4193 BranchHelper(rs > 0); 4215 if (kArchVariant == kMips64r6) {
4216 if (rt_reg != 0) {
4217 if (rs_reg == 0) { // BGTZALC
4218 BranchAndLinkCompactHelper(rt > 0, 16);
4219 } else {
4220 if (rt_reg == rs_reg) { // BLTZALC
4221 BranchAndLinkCompactHelper(rt < 0, 16);
4222 } else { // BLTUC
4223 BranchCompactHelper(
4224 static_cast<uint64_t>(rs) < static_cast<uint64_t>(rt), 16);
4225 }
4226 }
4227 } else { // BGTZ
4228 BranchHelper(rs > 0);
4229 }
4230 } else { // BGTZ
4231 BranchHelper(rs > 0);
4232 }
4194 break; 4233 break;
4195 case POP66: { 4234 case POP26: // BLEZC, BGEZC, BGEC/BLEC / BLEZL (pre-r6)
4196 if (rs_reg) { // BEQZC 4235 if (kArchVariant == kMips64r6) {
4197 int32_t se_imm21 = 4236 if (rt_reg != 0) {
4198 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); 4237 if (rs_reg == 0) { // BLEZC
4199 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); 4238 BranchCompactHelper(rt <= 0, 16);
4200 if (rs == 0) 4239 } else {
4201 next_pc = current_pc + 4 + (se_imm21 << 2); 4240 if (rs_reg == rt_reg) { // BGEZC
4202 else 4241 BranchCompactHelper(rt >= 0, 16);
4203 next_pc = current_pc + 4; 4242 } else { // BGEC/BLEC
4243 BranchCompactHelper(rs >= rt, 16);
4244 }
4245 }
4246 }
4247 } else { // BLEZL
4248 BranchAndLinkHelper(rs <= 0);
4249 }
4250 break;
4251 case POP27: // BGTZC, BLTZC, BLTC/BGTC / BGTZL (pre-r6)
4252 if (kArchVariant == kMips64r6) {
4253 if (rt_reg != 0) {
4254 if (rs_reg == 0) { // BGTZC
4255 BranchCompactHelper(rt > 0, 16);
4256 } else {
4257 if (rs_reg == rt_reg) { // BLTZC
4258 BranchCompactHelper(rt < 0, 16);
4259 } else { // BLTC/BGTC
4260 BranchCompactHelper(rs < rt, 16);
4261 }
4262 }
4263 }
4264 } else { // BGTZL
4265 BranchAndLinkHelper(rs > 0);
4266 }
4267 break;
4268 case POP66: // BEQZC, JIC
4269 if (rs_reg != 0) { // BEQZC
4270 BranchCompactHelper(rs == 0, 21);
4204 } else { // JIC 4271 } else { // JIC
4272 CheckForbiddenSlot(get_pc());
4205 next_pc = rt + imm16; 4273 next_pc = rt + imm16;
4206 } 4274 }
4207 break; 4275 break;
4208 } 4276 case POP76: // BNEZC, JIALC
4209 case BC: { 4277 if (rs_reg != 0) { // BNEZC
4210 next_pc = current_pc + 4 + (se_imm26 << 2); 4278 BranchCompactHelper(rs != 0, 21);
4211 set_pc(next_pc); 4279 } else { // JIALC
4212 pc_modified_ = true; 4280 int64_t current_pc = get_pc();
4281 CheckForbiddenSlot(current_pc);
4282 set_register(31, current_pc + Instruction::kInstrSize);
4283 next_pc = rt + imm16;
4284 }
4213 break; 4285 break;
4214 } 4286 case BC:
4215 case BALC: { 4287 BranchCompactHelper(true, 26);
4216 set_register(31, current_pc + 4);
4217 next_pc = current_pc + 4 + (se_imm26 << 2);
4218 set_pc(next_pc);
4219 pc_modified_ = true;
4220 break; 4288 break;
4221 } 4289 case BALC:
4222 // ------------- Arithmetic instructions. 4290 BranchAndLinkCompactHelper(true, 26);
4223 case ADDI: 4291 break;
4224 case DADDI: 4292 case POP10: // BOVC, BEQZALC, BEQC / ADDI (pre-r6)
4225 if (HaveSameSign(rs, se_imm16)) { 4293 if (kArchVariant == kMips64r6) {
4226 if (rs > 0) { 4294 if (rs_reg >= rt_reg) { // BOVC
4227 if (rs > Registers::kMaxValue - se_imm16) { 4295 if (HaveSameSign(rs, rt)) {
4228 SignalException(kIntegerOverflow); 4296 if (rs > 0) {
4297 BranchCompactHelper(rs > Registers::kMaxValue - rt, 16);
4298 } else if (rs < 0) {
4299 BranchCompactHelper(rs < Registers::kMinValue - rt, 16);
4300 }
4229 } 4301 }
4230 } else if (rs < 0) { 4302 } else {
4231 if (rs < Registers::kMinValue - se_imm16) { 4303 if (rs_reg == 0) { // BEQZALC
4232 SignalException(kIntegerUnderflow); 4304 BranchAndLinkCompactHelper(rt == 0, 16);
4305 } else { // BEQC
4306 BranchCompactHelper(rt == rs, 16);
4307 }
4308 }
4309 } else { // ADDI
4310 if (HaveSameSign(rs, se_imm16)) {
4311 if (rs > 0) {
4312 if (rs <= Registers::kMaxValue - se_imm16) {
4313 SignalException(kIntegerOverflow);
4314 }
4315 } else if (rs < 0) {
4316 if (rs >= Registers::kMinValue - se_imm16) {
4317 SignalException(kIntegerUnderflow);
4318 }
4319 }
4320 }
4321 SetResult(rt_reg, rs + se_imm16);
4322 }
4323 break;
4324 case POP30: // BNVC, BNEZALC, BNEC / DADDI (pre-r6)
4325 if (kArchVariant == kMips64r6) {
4326 if (rs_reg >= rt_reg) { // BNVC
4327 if (!HaveSameSign(rs, rt) || rs == 0 || rt == 0) {
4328 BranchCompactHelper(true, 16);
4329 } else {
4330 if (rs > 0) {
4331 BranchCompactHelper(rs <= Registers::kMaxValue - rt, 16);
4332 } else if (rs < 0) {
4333 BranchCompactHelper(rs >= Registers::kMinValue - rt, 16);
4334 }
4335 }
4336 } else {
4337 if (rs_reg == 0) { // BNEZALC
4338 BranchAndLinkCompactHelper(rt != 0, 16);
4339 } else { // BNEC
4340 BranchCompactHelper(rt != rs, 16);
4233 } 4341 }
4234 } 4342 }
4235 } 4343 }
4236 SetResult(rt_reg, rs + se_imm16);
4237 break; 4344 break;
4345 // ------------- Arithmetic instructions.
4238 case ADDIU: { 4346 case ADDIU: {
4239 int32_t alu32_out = static_cast<int32_t>(rs + se_imm16); 4347 int32_t alu32_out = static_cast<int32_t>(rs + se_imm16);
4240 // Sign-extend result of 32bit operation into 64bit register. 4348 // Sign-extend result of 32bit operation into 64bit register.
4241 SetResult(rt_reg, static_cast<int64_t>(alu32_out)); 4349 SetResult(rt_reg, static_cast<int64_t>(alu32_out));
4242 break; 4350 break;
4243 } 4351 }
4244 case DADDIU: 4352 case DADDIU:
4245 SetResult(rt_reg, rs + se_imm16); 4353 SetResult(rt_reg, rs + se_imm16);
4246 break; 4354 break;
4247 case SLTI: 4355 case SLTI:
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4362 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); 4470 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr));
4363 break; 4471 break;
4364 case SWC1: { 4472 case SWC1: {
4365 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); 4473 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg));
4366 WriteW(rs + se_imm16, alu_out_32, instr); 4474 WriteW(rs + se_imm16, alu_out_32, instr);
4367 break; 4475 break;
4368 } 4476 }
4369 case SDC1: 4477 case SDC1:
4370 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); 4478 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr);
4371 break; 4479 break;
4372 // ------------- JIALC and BNEZC instructions.
4373 case POP76: {
4374 // Next pc.
4375 next_pc = rt + se_imm16;
4376 // The instruction after the jump is NOT executed.
4377 uint16_t pc_increment = Instruction::kInstrSize;
4378 if (instr->IsLinkingInstruction()) {
4379 set_register(31, current_pc + pc_increment);
4380 }
4381 set_pc(next_pc);
4382 pc_modified_ = true;
4383 break;
4384 }
4385 // ------------- PC-Relative instructions. 4480 // ------------- PC-Relative instructions.
4386 case PCREL: { 4481 case PCREL: {
4387 // rt field: checking 5-bits. 4482 // rt field: checking 5-bits.
4483 int32_t imm21 = instr->Imm21Value();
4484 int64_t current_pc = get_pc();
4388 uint8_t rt = (imm21 >> kImm16Bits); 4485 uint8_t rt = (imm21 >> kImm16Bits);
4389 switch (rt) { 4486 switch (rt) {
4390 case ALUIPC: 4487 case ALUIPC:
4391 addr = current_pc + (se_imm16 << 16); 4488 addr = current_pc + (se_imm16 << 16);
4392 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; 4489 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4393 break; 4490 break;
4394 case AUIPC: 4491 case AUIPC:
4395 alu_out = current_pc + (se_imm16 << 16); 4492 alu_out = current_pc + (se_imm16 << 16);
4396 break; 4493 break;
4397 default: { 4494 default: {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 } 4544 }
4448 default: 4545 default:
4449 UNREACHABLE(); 4546 UNREACHABLE();
4450 } 4547 }
4451 4548
4452 if (execute_branch_delay_instruction) { 4549 if (execute_branch_delay_instruction) {
4453 // Execute branch delay slot 4550 // Execute branch delay slot
4454 // We don't check for end_sim_pc. First it should not be met as the current 4551 // We don't check for end_sim_pc. First it should not be met as the current
4455 // pc is valid. Secondly a jump should always execute its branch delay slot. 4552 // pc is valid. Secondly a jump should always execute its branch delay slot.
4456 Instruction* branch_delay_instr = 4553 Instruction* branch_delay_instr =
4457 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); 4554 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize);
4458 BranchDelayInstructionDecode(branch_delay_instr); 4555 BranchDelayInstructionDecode(branch_delay_instr);
4459 } 4556 }
4460 4557
4461 // If needed update pc after the branch delay execution. 4558 // If needed update pc after the branch delay execution.
4462 if (next_pc != bad_ra) { 4559 if (next_pc != bad_ra) {
4463 set_pc(next_pc); 4560 set_pc(next_pc);
4464 } 4561 }
4465 } 4562 }
4466 4563
4467 #undef BranchHelper
4468 #undef BranchAndLinkHelper
4469
4470 4564
4471 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). 4565 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
4472 void Simulator::DecodeTypeJump(Instruction* instr) { 4566 void Simulator::DecodeTypeJump(Instruction* instr) {
4473 // Get current pc. 4567 // Get current pc.
4474 int64_t current_pc = get_pc(); 4568 int64_t current_pc = get_pc();
4475 // Get unchanged bits of pc. 4569 // Get unchanged bits of pc.
4476 int64_t pc_high_bits = current_pc & 0xfffffffff0000000; 4570 int64_t pc_high_bits = current_pc & 0xfffffffff0000000;
4477 // Next pc. 4571 // Next pc.
4478 int64_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); 4572 int64_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
4479 4573
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4550 icount_++; 4644 icount_++;
4551 InstructionDecode(instr); 4645 InstructionDecode(instr);
4552 program_counter = get_pc(); 4646 program_counter = get_pc();
4553 } 4647 }
4554 } else { 4648 } else {
4555 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 4649 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
4556 // we reach the particular instuction count. 4650 // we reach the particular instuction count.
4557 while (program_counter != end_sim_pc) { 4651 while (program_counter != end_sim_pc) {
4558 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 4652 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
4559 icount_++; 4653 icount_++;
4560 if (icount_ == static_cast<int64_t>(::v8::internal::FLAG_stop_sim_at)) { 4654 if (icount_ == static_cast<uint64_t>(::v8::internal::FLAG_stop_sim_at)) {
4561 MipsDebugger dbg(this); 4655 MipsDebugger dbg(this);
4562 dbg.Debug(); 4656 dbg.Debug();
4563 } else { 4657 } else {
4564 InstructionDecode(instr); 4658 InstructionDecode(instr);
4565 } 4659 }
4566 program_counter = get_pc(); 4660 program_counter = get_pc();
4567 } 4661 }
4568 } 4662 }
4569 } 4663 }
4570 4664
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4732 } 4826 }
4733 4827
4734 4828
4735 #undef UNSUPPORTED 4829 #undef UNSUPPORTED
4736 } // namespace internal 4830 } // namespace internal
4737 } // namespace v8 4831 } // namespace v8
4738 4832
4739 #endif // USE_SIMULATOR 4833 #endif // USE_SIMULATOR
4740 4834
4741 #endif // V8_TARGET_ARCH_MIPS64 4835 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698