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

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

Issue 453043002: MIPS: Add support for arch. revision 6 to mips32 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/simulator-mips.h ('k') | test/cctest/test-assembler-mips.cc » ('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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 void PrintAllRegsIncludingFPU(); 60 void PrintAllRegsIncludingFPU();
61 61
62 private: 62 private:
63 // We set the breakpoint code to 0xfffff to easily recognize it. 63 // We set the breakpoint code to 0xfffff to easily recognize it.
64 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; 64 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6;
65 static const Instr kNopInstr = 0x0; 65 static const Instr kNopInstr = 0x0;
66 66
67 Simulator* sim_; 67 Simulator* sim_;
68 68
69 int32_t GetRegisterValue(int regnum); 69 int32_t GetRegisterValue(int regnum);
70 int32_t GetFPURegisterValueInt(int regnum); 70 int32_t GetFPURegisterValue32(int regnum);
71 int64_t GetFPURegisterValueLong(int regnum); 71 int64_t GetFPURegisterValue64(int regnum);
72 float GetFPURegisterValueFloat(int regnum); 72 float GetFPURegisterValueFloat(int regnum);
73 double GetFPURegisterValueDouble(int regnum); 73 double GetFPURegisterValueDouble(int regnum);
74 bool GetValue(const char* desc, int32_t* value); 74 bool GetValue(const char* desc, int32_t* value);
75 bool GetValue(const char* desc, int64_t* value);
75 76
76 // Set or delete a breakpoint. Returns true if successful. 77 // Set or delete a breakpoint. Returns true if successful.
77 bool SetBreakpoint(Instruction* breakpc); 78 bool SetBreakpoint(Instruction* breakpc);
78 bool DeleteBreakpoint(Instruction* breakpc); 79 bool DeleteBreakpoint(Instruction* breakpc);
79 80
80 // Undo and redo all breakpoints. This is needed to bracket disassembly and 81 // Undo and redo all breakpoints. This is needed to bracket disassembly and
81 // execution to skip past breakpoints when run from the debugger. 82 // execution to skip past breakpoints when run from the debugger.
82 void UndoBreakpoints(); 83 void UndoBreakpoints();
83 void RedoBreakpoints(); 84 void RedoBreakpoints();
84 }; 85 };
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 154
154 int32_t MipsDebugger::GetRegisterValue(int regnum) { 155 int32_t MipsDebugger::GetRegisterValue(int regnum) {
155 if (regnum == kNumSimuRegisters) { 156 if (regnum == kNumSimuRegisters) {
156 return sim_->get_pc(); 157 return sim_->get_pc();
157 } else { 158 } else {
158 return sim_->get_register(regnum); 159 return sim_->get_register(regnum);
159 } 160 }
160 } 161 }
161 162
162 163
163 int32_t MipsDebugger::GetFPURegisterValueInt(int regnum) { 164 int32_t MipsDebugger::GetFPURegisterValue32(int regnum) {
165 if (regnum == kNumFPURegisters) {
166 return sim_->get_pc();
167 } else {
168 return sim_->get_fpu_register_word(regnum);
169 }
170 }
171
172
173 int64_t MipsDebugger::GetFPURegisterValue64(int regnum) {
164 if (regnum == kNumFPURegisters) { 174 if (regnum == kNumFPURegisters) {
165 return sim_->get_pc(); 175 return sim_->get_pc();
166 } else { 176 } else {
167 return sim_->get_fpu_register(regnum); 177 return sim_->get_fpu_register(regnum);
168 } 178 }
169 } 179 }
170 180
171
172 int64_t MipsDebugger::GetFPURegisterValueLong(int regnum) {
173 if (regnum == kNumFPURegisters) {
174 return sim_->get_pc();
175 } else {
176 return sim_->get_fpu_register_long(regnum);
177 }
178 }
179
180 181
181 float MipsDebugger::GetFPURegisterValueFloat(int regnum) { 182 float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
182 if (regnum == kNumFPURegisters) { 183 if (regnum == kNumFPURegisters) {
183 return sim_->get_pc(); 184 return sim_->get_pc();
184 } else { 185 } else {
185 return sim_->get_fpu_register_float(regnum); 186 return sim_->get_fpu_register_float(regnum);
186 } 187 }
187 } 188 }
188 189
189 190
190 double MipsDebugger::GetFPURegisterValueDouble(int regnum) { 191 double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
191 if (regnum == kNumFPURegisters) { 192 if (regnum == kNumFPURegisters) {
192 return sim_->get_pc(); 193 return sim_->get_pc();
193 } else { 194 } else {
194 return sim_->get_fpu_register_double(regnum); 195 return sim_->get_fpu_register_double(regnum);
195 } 196 }
196 } 197 }
197 198
198 199
199 bool MipsDebugger::GetValue(const char* desc, int32_t* value) { 200 bool MipsDebugger::GetValue(const char* desc, int32_t* value) {
200 int regnum = Registers::Number(desc); 201 int regnum = Registers::Number(desc);
201 int fpuregnum = FPURegisters::Number(desc); 202 int fpuregnum = FPURegisters::Number(desc);
202 203
203 if (regnum != kInvalidRegister) { 204 if (regnum != kInvalidRegister) {
204 *value = GetRegisterValue(regnum); 205 *value = GetRegisterValue(regnum);
205 return true; 206 return true;
206 } else if (fpuregnum != kInvalidFPURegister) { 207 } else if (fpuregnum != kInvalidFPURegister) {
207 *value = GetFPURegisterValueInt(fpuregnum); 208 *value = GetFPURegisterValue32(fpuregnum);
208 return true; 209 return true;
209 } else if (strncmp(desc, "0x", 2) == 0) { 210 } else if (strncmp(desc, "0x", 2) == 0) {
210 return SScanF(desc, "%x", reinterpret_cast<uint32_t*>(value)) == 1; 211 return SScanF(desc, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
211 } else { 212 } else {
212 return SScanF(desc, "%i", value) == 1; 213 return SScanF(desc, "%i", value) == 1;
213 } 214 }
214 return false; 215 return false;
215 } 216 }
216 217
217 218
219 bool MipsDebugger::GetValue(const char* desc, int64_t* value) {
220 int regnum = Registers::Number(desc);
221 int fpuregnum = FPURegisters::Number(desc);
222
223 if (regnum != kInvalidRegister) {
224 *value = GetRegisterValue(regnum);
225 return true;
226 } else if (fpuregnum != kInvalidFPURegister) {
227 *value = GetFPURegisterValue64(fpuregnum);
228 return true;
229 } else if (strncmp(desc, "0x", 2) == 0) {
230 return SScanF(desc + 2, "%" SCNx64,
231 reinterpret_cast<uint64_t*>(value)) == 1;
232 } else {
233 return SScanF(desc, "%" SCNu64, reinterpret_cast<uint64_t*>(value)) == 1;
234 }
235 return false;
236 }
237
238
218 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) { 239 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) {
219 // Check if a breakpoint can be set. If not return without any side-effects. 240 // Check if a breakpoint can be set. If not return without any side-effects.
220 if (sim_->break_pc_ != NULL) { 241 if (sim_->break_pc_ != NULL) {
221 return false; 242 return false;
222 } 243 }
223 244
224 // Set the breakpoint. 245 // Set the breakpoint.
225 sim_->break_pc_ = breakpc; 246 sim_->break_pc_ = breakpc;
226 sim_->break_instr_ = breakpc->InstructionBits(); 247 sim_->break_instr_ = breakpc->InstructionBits();
227 // Not setting the breakpoint instruction in the code itself. It will be set 248 // Not setting the breakpoint instruction in the code itself. It will be set
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // pc. 309 // pc.
289 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 310 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
290 REG_INFO(31), REG_INFO(34)); 311 REG_INFO(31), REG_INFO(34));
291 312
292 #undef REG_INFO 313 #undef REG_INFO
293 #undef FPU_REG_INFO 314 #undef FPU_REG_INFO
294 } 315 }
295 316
296 317
297 void MipsDebugger::PrintAllRegsIncludingFPU() { 318 void MipsDebugger::PrintAllRegsIncludingFPU() {
298 #define FPU_REG_INFO(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \ 319 #define FPU_REG_INFO32(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \
299 GetFPURegisterValueInt(n+1), \ 320 GetFPURegisterValue32(n+1), \
300 GetFPURegisterValueInt(n), \ 321 GetFPURegisterValue32(n), \
301 GetFPURegisterValueDouble(n) 322 GetFPURegisterValueDouble(n)
323
324 #define FPU_REG_INFO64(n) FPURegisters::Name(n), \
325 GetFPURegisterValue64(n), \
326 GetFPURegisterValueDouble(n)
302 327
303 PrintAllRegs(); 328 PrintAllRegs();
304 329
305 PrintF("\n\n"); 330 PrintF("\n\n");
306 // f0, f1, f2, ... f31. 331 // f0, f1, f2, ... f31.
307 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(0) ); 332 // This must be a compile-time switch,
308 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(2) ); 333 // compiler will throw out warnings otherwise.
309 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(4) ); 334 if (kFpuMode == kFP64) {
310 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(6) ); 335 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(0) );
311 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(8) ); 336 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(1) );
312 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(10)); 337 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(2) );
313 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(12)); 338 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(3) );
314 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(14)); 339 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(4) );
315 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(16)); 340 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(5) );
316 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(18)); 341 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(6) );
317 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(20)); 342 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(7) );
318 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(22)); 343 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(8) );
319 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(24)); 344 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(9) );
320 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(26)); 345 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(10));
321 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(28)); 346 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(11));
322 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(30)); 347 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(12));
348 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(13));
349 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(14));
350 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(15));
351 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(16));
352 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(17));
353 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(18));
354 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(19));
355 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(20));
356 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(21));
357 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(22));
358 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(23));
359 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(24));
360 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(25));
361 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(26));
362 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(27));
363 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(28));
364 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(29));
365 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(30));
366 PrintF("%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(31));
367 } else {
368 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(0) );
369 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(2) );
370 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(4) );
371 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(6) );
372 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(8) );
373 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(10));
374 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(12));
375 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(14));
376 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(16));
377 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(18));
378 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(20));
379 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(22));
380 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(24));
381 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(26));
382 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(28));
383 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(30));
384 }
323 385
324 #undef REG_INFO 386 #undef REG_INFO
325 #undef FPU_REG_INFO 387 #undef FPU_REG_INFO32
388 #undef FPU_REG_INFO64
326 } 389 }
327 390
328 391
329 void MipsDebugger::Debug() { 392 void MipsDebugger::Debug() {
330 intptr_t last_pc = -1; 393 intptr_t last_pc = -1;
331 bool done = false; 394 bool done = false;
332 395
333 #define COMMAND_SIZE 63 396 #define COMMAND_SIZE 63
334 #define ARG_SIZE 255 397 #define ARG_SIZE 255
335 398
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 PrintF("/!\\ Jumping over generated breakpoint.\n"); 453 PrintF("/!\\ Jumping over generated breakpoint.\n");
391 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 454 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
392 } 455 }
393 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 456 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
394 // Execute the one instruction we broke at with breakpoints disabled. 457 // Execute the one instruction we broke at with breakpoints disabled.
395 sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc())); 458 sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
396 // Leave the debugger shell. 459 // Leave the debugger shell.
397 done = true; 460 done = true;
398 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 461 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
399 if (argc == 2) { 462 if (argc == 2) {
400 int32_t value;
401 float fvalue;
402 if (strcmp(arg1, "all") == 0) { 463 if (strcmp(arg1, "all") == 0) {
403 PrintAllRegs(); 464 PrintAllRegs();
404 } else if (strcmp(arg1, "allf") == 0) { 465 } else if (strcmp(arg1, "allf") == 0) {
405 PrintAllRegsIncludingFPU(); 466 PrintAllRegsIncludingFPU();
406 } else { 467 } else {
407 int regnum = Registers::Number(arg1); 468 int regnum = Registers::Number(arg1);
408 int fpuregnum = FPURegisters::Number(arg1); 469 int fpuregnum = FPURegisters::Number(arg1);
409 470
410 if (regnum != kInvalidRegister) { 471 if (regnum != kInvalidRegister) {
472 int32_t value;
411 value = GetRegisterValue(regnum); 473 value = GetRegisterValue(regnum);
412 PrintF("%s: 0x%08x %d \n", arg1, value, value); 474 PrintF("%s: 0x%08x %d \n", arg1, value, value);
413 } else if (fpuregnum != kInvalidFPURegister) { 475 } else if (fpuregnum != kInvalidFPURegister) {
414 if (fpuregnum % 2 == 1) { 476 if (IsFp64Mode()) {
415 value = GetFPURegisterValueInt(fpuregnum); 477 int64_t value;
416 fvalue = GetFPURegisterValueFloat(fpuregnum); 478 double dvalue;
417 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue); 479 value = GetFPURegisterValue64(fpuregnum);
480 dvalue = GetFPURegisterValueDouble(fpuregnum);
481 PrintF("%3s: 0x%016llx %16.4e\n",
482 FPURegisters::Name(fpuregnum), value, dvalue);
418 } else { 483 } else {
419 double dfvalue; 484 if (fpuregnum % 2 == 1) {
420 int32_t lvalue1 = GetFPURegisterValueInt(fpuregnum); 485 int32_t value;
421 int32_t lvalue2 = GetFPURegisterValueInt(fpuregnum + 1); 486 float fvalue;
422 dfvalue = GetFPURegisterValueDouble(fpuregnum); 487 value = GetFPURegisterValue32(fpuregnum);
423 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", 488 fvalue = GetFPURegisterValueFloat(fpuregnum);
424 FPURegisters::Name(fpuregnum+1), 489 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
425 FPURegisters::Name(fpuregnum), 490 } else {
426 lvalue1, 491 double dfvalue;
427 lvalue2, 492 int32_t lvalue1 = GetFPURegisterValue32(fpuregnum);
428 dfvalue); 493 int32_t lvalue2 = GetFPURegisterValue32(fpuregnum + 1);
494 dfvalue = GetFPURegisterValueDouble(fpuregnum);
495 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n",
496 FPURegisters::Name(fpuregnum+1),
497 FPURegisters::Name(fpuregnum),
498 lvalue1,
499 lvalue2,
500 dfvalue);
501 }
429 } 502 }
430 } else { 503 } else {
431 PrintF("%s unrecognized\n", arg1); 504 PrintF("%s unrecognized\n", arg1);
432 } 505 }
433 } 506 }
434 } else { 507 } else {
435 if (argc == 3) { 508 if (argc == 3) {
436 if (strcmp(arg2, "single") == 0) { 509 if (strcmp(arg2, "single") == 0) {
437 int32_t value; 510 int32_t value;
438 float fvalue; 511 float fvalue;
439 int fpuregnum = FPURegisters::Number(arg1); 512 int fpuregnum = FPURegisters::Number(arg1);
440 513
441 if (fpuregnum != kInvalidFPURegister) { 514 if (fpuregnum != kInvalidFPURegister) {
442 value = GetFPURegisterValueInt(fpuregnum); 515 value = GetFPURegisterValue32(fpuregnum);
443 fvalue = GetFPURegisterValueFloat(fpuregnum); 516 fvalue = GetFPURegisterValueFloat(fpuregnum);
444 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue); 517 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
445 } else { 518 } else {
446 PrintF("%s unrecognized\n", arg1); 519 PrintF("%s unrecognized\n", arg1);
447 } 520 }
448 } else { 521 } else {
449 PrintF("print <fpu register> single\n"); 522 PrintF("print <fpu register> single\n");
450 } 523 }
451 } else { 524 } else {
452 PrintF("print <register> or print <fpu register> single\n"); 525 PrintF("print <register> or print <fpu register> single\n");
(...skipping 29 matching lines...) Expand all
482 } else { // Command "mem". 555 } else { // Command "mem".
483 int32_t value; 556 int32_t value;
484 if (!GetValue(arg1, &value)) { 557 if (!GetValue(arg1, &value)) {
485 PrintF("%s unrecognized\n", arg1); 558 PrintF("%s unrecognized\n", arg1);
486 continue; 559 continue;
487 } 560 }
488 cur = reinterpret_cast<int32_t*>(value); 561 cur = reinterpret_cast<int32_t*>(value);
489 next_arg++; 562 next_arg++;
490 } 563 }
491 564
492 int32_t words; 565 // TODO(palfia): optimize this.
493 if (argc == next_arg) { 566 if (IsFp64Mode()) {
494 words = 10; 567 int64_t words;
568 if (argc == next_arg) {
569 words = 10;
570 } else {
571 if (!GetValue(argv[next_arg], &words)) {
572 words = 10;
573 }
574 }
575 end = cur + words;
495 } else { 576 } else {
496 if (!GetValue(argv[next_arg], &words)) { 577 int32_t words;
578 if (argc == next_arg) {
497 words = 10; 579 words = 10;
580 } else {
581 if (!GetValue(argv[next_arg], &words)) {
582 words = 10;
583 }
498 } 584 }
585 end = cur + words;
499 } 586 }
500 end = cur + words;
501 587
502 while (cur < end) { 588 while (cur < end) {
503 PrintF(" 0x%08x: 0x%08x %10d", 589 PrintF(" 0x%08x: 0x%08x %10d",
504 reinterpret_cast<intptr_t>(cur), *cur, *cur); 590 reinterpret_cast<intptr_t>(cur), *cur, *cur);
505 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); 591 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
506 int value = *cur; 592 int value = *cur;
507 Heap* current_heap = v8::internal::Isolate::Current()->heap(); 593 Heap* current_heap = v8::internal::Isolate::Current()->heap();
508 if (((value & 1) == 0) || current_heap->Contains(obj)) { 594 if (((value & 1) == 0) || current_heap->Contains(obj)) {
509 PrintF(" ("); 595 PrintF(" (");
510 if ((value & 1) == 0) { 596 if ((value & 1) == 0) {
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 } 1091 }
1006 1092
1007 1093
1008 void Simulator::set_dw_register(int reg, const int* dbl) { 1094 void Simulator::set_dw_register(int reg, const int* dbl) {
1009 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); 1095 DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
1010 registers_[reg] = dbl[0]; 1096 registers_[reg] = dbl[0];
1011 registers_[reg + 1] = dbl[1]; 1097 registers_[reg + 1] = dbl[1];
1012 } 1098 }
1013 1099
1014 1100
1015 void Simulator::set_fpu_register(int fpureg, int32_t value) { 1101 void Simulator::set_fpu_register(int fpureg, int64_t value) {
1102 DCHECK(IsFp64Mode());
1016 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1103 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1017 FPUregisters_[fpureg] = value; 1104 FPUregisters_[fpureg] = value;
1018 } 1105 }
1019 1106
1020 1107
1108 void Simulator::set_fpu_register_word(int fpureg, int32_t value) {
1109 // Set ONLY lower 32-bits, leaving upper bits untouched.
1110 // TODO(plind): big endian issue.
1111 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1112 int32_t *pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
1113 *pword = value;
1114 }
1115
1116
1117 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) {
1118 // Set ONLY upper 32-bits, leaving lower bits untouched.
1119 // TODO(plind): big endian issue.
1120 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1121 int32_t *phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1;
1122 *phiword = value;
1123 }
1124
1125
1021 void Simulator::set_fpu_register_float(int fpureg, float value) { 1126 void Simulator::set_fpu_register_float(int fpureg, float value) {
1022 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1127 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1023 *BitCast<float*>(&FPUregisters_[fpureg]) = value; 1128 *BitCast<float*>(&FPUregisters_[fpureg]) = value;
1024 } 1129 }
1025 1130
1026 1131
1027 void Simulator::set_fpu_register_double(int fpureg, double value) { 1132 void Simulator::set_fpu_register_double(int fpureg, double value) {
1028 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1133 if (IsFp64Mode()) {
1029 *BitCast<double*>(&FPUregisters_[fpureg]) = value; 1134 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1135 *BitCast<double*>(&FPUregisters_[fpureg]) = value;
1136 } else {
1137 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1138 int64_t i64 = BitCast<int64_t>(value);
1139 set_fpu_register_word(fpureg, i64 & 0xffffffff);
1140 set_fpu_register_word(fpureg + 1, i64 >> 32);
1141 }
1030 } 1142 }
1031 1143
1032 1144
1033 // Get the register from the architecture state. This function does handle 1145 // Get the register from the architecture state. This function does handle
1034 // the special case of accessing the PC register. 1146 // the special case of accessing the PC register.
1035 int32_t Simulator::get_register(int reg) const { 1147 int32_t Simulator::get_register(int reg) const {
1036 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); 1148 DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
1037 if (reg == 0) 1149 if (reg == 0)
1038 return 0; 1150 return 0;
1039 else 1151 else
1040 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); 1152 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
1041 } 1153 }
1042 1154
1043 1155
1044 double Simulator::get_double_from_register_pair(int reg) { 1156 double Simulator::get_double_from_register_pair(int reg) {
1157 // TODO(plind): bad ABI stuff, refactor or remove.
1045 DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); 1158 DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0));
1046 1159
1047 double dm_val = 0.0; 1160 double dm_val = 0.0;
1048 // Read the bits from the unsigned integer register_[] array 1161 // Read the bits from the unsigned integer register_[] array
1049 // into the double precision floating point value and return it. 1162 // into the double precision floating point value and return it.
1050 char buffer[2 * sizeof(registers_[0])]; 1163 char buffer[2 * sizeof(registers_[0])];
1051 memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0])); 1164 memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
1052 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); 1165 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
1053 return(dm_val); 1166 return(dm_val);
1054 } 1167 }
1055 1168
1056 1169
1057 int32_t Simulator::get_fpu_register(int fpureg) const { 1170 int64_t Simulator::get_fpu_register(int fpureg) const {
1171 DCHECK(IsFp64Mode());
1058 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1172 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1059 return FPUregisters_[fpureg]; 1173 return FPUregisters_[fpureg];
1060 } 1174 }
1061 1175
1062 1176
1063 int64_t Simulator::get_fpu_register_long(int fpureg) const { 1177 int32_t Simulator::get_fpu_register_word(int fpureg) const {
1064 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1178 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1065 return *BitCast<int64_t*>( 1179 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
1066 const_cast<int32_t*>(&FPUregisters_[fpureg])); 1180 }
1181
1182
1183 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const {
1184 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1185 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
1186 }
1187
1188
1189 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const {
1190 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1191 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff);
1067 } 1192 }
1068 1193
1069 1194
1070 float Simulator::get_fpu_register_float(int fpureg) const { 1195 float Simulator::get_fpu_register_float(int fpureg) const {
1071 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1196 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1072 return *BitCast<float*>( 1197 return *BitCast<float*>(
1073 const_cast<int32_t*>(&FPUregisters_[fpureg])); 1198 const_cast<int64_t*>(&FPUregisters_[fpureg]));
1074 } 1199 }
1075 1200
1076 1201
1077 double Simulator::get_fpu_register_double(int fpureg) const { 1202 double Simulator::get_fpu_register_double(int fpureg) const {
1078 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1203 if (IsFp64Mode()) {
1079 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); 1204 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
1205 return *BitCast<double*>(&FPUregisters_[fpureg]);
1206 } else {
1207 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1208 int64_t i64;
1209 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg));
1210 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32;
1211 return BitCast<double>(i64);
1212 }
1080 } 1213 }
1081 1214
1082 1215
1083 // Runtime FP routines take up to two double arguments and zero 1216 // Runtime FP routines take up to two double arguments and zero
1084 // or one integer arguments. All are constructed here, 1217 // or one integer arguments. All are constructed here,
1085 // from a0-a3 or f12 and f14. 1218 // from a0-a3 or f12 and f14.
1086 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { 1219 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
1087 if (!IsMipsSoftFloatABI) { 1220 if (!IsMipsSoftFloatABI) {
1088 *x = get_fpu_register_double(12); 1221 *x = get_fpu_register_double(12);
1089 *y = get_fpu_register_double(14); 1222 *y = get_fpu_register_double(14);
1090 *z = get_register(a2); 1223 *z = get_register(a2);
1091 } else { 1224 } else {
1225 // TODO(plind): bad ABI stuff, refactor or remove.
1092 // We use a char buffer to get around the strict-aliasing rules which 1226 // We use a char buffer to get around the strict-aliasing rules which
1093 // otherwise allow the compiler to optimize away the copy. 1227 // otherwise allow the compiler to optimize away the copy.
1094 char buffer[sizeof(*x)]; 1228 char buffer[sizeof(*x)];
1095 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); 1229 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1096 1230
1097 // Registers a0 and a1 -> x. 1231 // Registers a0 and a1 -> x.
1098 reg_buffer[0] = get_register(a0); 1232 reg_buffer[0] = get_register(a0);
1099 reg_buffer[1] = get_register(a1); 1233 reg_buffer[1] = get_register(a1);
1100 memcpy(x, buffer, sizeof(buffer)); 1234 memcpy(x, buffer, sizeof(buffer));
1101 // Registers a2 and a3 -> y. 1235 // Registers a2 and a3 -> y.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1270
1137 bool Simulator::test_fcsr_bit(uint32_t cc) { 1271 bool Simulator::test_fcsr_bit(uint32_t cc) {
1138 return FCSR_ & (1 << cc); 1272 return FCSR_ & (1 << cc);
1139 } 1273 }
1140 1274
1141 1275
1142 // Sets the rounding error codes in FCSR based on the result of the rounding. 1276 // Sets the rounding error codes in FCSR based on the result of the rounding.
1143 // Returns true if the operation was invalid. 1277 // Returns true if the operation was invalid.
1144 bool Simulator::set_fcsr_round_error(double original, double rounded) { 1278 bool Simulator::set_fcsr_round_error(double original, double rounded) {
1145 bool ret = false; 1279 bool ret = false;
1280 double max_int32 = std::numeric_limits<int32_t>::max();
1281 double min_int32 = std::numeric_limits<int32_t>::min();
1146 1282
1147 if (!std::isfinite(original) || !std::isfinite(rounded)) { 1283 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1148 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1284 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1149 ret = true; 1285 ret = true;
1150 } 1286 }
1151 1287
1152 if (original != rounded) { 1288 if (original != rounded) {
1153 set_fcsr_bit(kFCSRInexactFlagBit, true); 1289 set_fcsr_bit(kFCSRInexactFlagBit, true);
1154 } 1290 }
1155 1291
1156 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { 1292 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1157 set_fcsr_bit(kFCSRUnderflowFlagBit, true); 1293 set_fcsr_bit(kFCSRUnderflowFlagBit, true);
1158 ret = true; 1294 ret = true;
1159 } 1295 }
1160 1296
1161 if (rounded > INT_MAX || rounded < INT_MIN) { 1297 if (rounded > max_int32 || rounded < min_int32) {
1162 set_fcsr_bit(kFCSROverflowFlagBit, true); 1298 set_fcsr_bit(kFCSROverflowFlagBit, true);
1163 // The reference is not really clear but it seems this is required: 1299 // The reference is not really clear but it seems this is required:
1164 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1300 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1165 ret = true; 1301 ret = true;
1166 } 1302 }
1167 1303
1168 return ret; 1304 return ret;
1169 } 1305 }
1170 1306
1171 1307
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); 1549 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1414 1550
1415 if (!IsMipsSoftFloatABI) { 1551 if (!IsMipsSoftFloatABI) {
1416 // With the hard floating point calling convention, double 1552 // With the hard floating point calling convention, double
1417 // arguments are passed in FPU registers. Fetch the arguments 1553 // arguments are passed in FPU registers. Fetch the arguments
1418 // from there and call the builtin using soft floating point 1554 // from there and call the builtin using soft floating point
1419 // convention. 1555 // convention.
1420 switch (redirection->type()) { 1556 switch (redirection->type()) {
1421 case ExternalReference::BUILTIN_FP_FP_CALL: 1557 case ExternalReference::BUILTIN_FP_FP_CALL:
1422 case ExternalReference::BUILTIN_COMPARE_CALL: 1558 case ExternalReference::BUILTIN_COMPARE_CALL:
1423 arg0 = get_fpu_register(f12); 1559 if (IsFp64Mode()) {
1424 arg1 = get_fpu_register(f13); 1560 arg0 = get_fpu_register_word(f12);
1425 arg2 = get_fpu_register(f14); 1561 arg1 = get_fpu_register_hi_word(f12);
1426 arg3 = get_fpu_register(f15); 1562 arg2 = get_fpu_register_word(f14);
1563 arg3 = get_fpu_register_hi_word(f14);
1564 } else {
1565 arg0 = get_fpu_register_word(f12);
1566 arg1 = get_fpu_register_word(f13);
1567 arg2 = get_fpu_register_word(f14);
1568 arg3 = get_fpu_register_word(f15);
1569 }
1427 break; 1570 break;
1428 case ExternalReference::BUILTIN_FP_CALL: 1571 case ExternalReference::BUILTIN_FP_CALL:
1429 arg0 = get_fpu_register(f12); 1572 if (IsFp64Mode()) {
1430 arg1 = get_fpu_register(f13); 1573 arg0 = get_fpu_register_word(f12);
1574 arg1 = get_fpu_register_hi_word(f12);
1575 } else {
1576 arg0 = get_fpu_register_word(f12);
1577 arg1 = get_fpu_register_word(f13);
1578 }
1431 break; 1579 break;
1432 case ExternalReference::BUILTIN_FP_INT_CALL: 1580 case ExternalReference::BUILTIN_FP_INT_CALL:
1433 arg0 = get_fpu_register(f12); 1581 if (IsFp64Mode()) {
1434 arg1 = get_fpu_register(f13); 1582 arg0 = get_fpu_register_word(f12);
1583 arg1 = get_fpu_register_hi_word(f12);
1584 } else {
1585 arg0 = get_fpu_register_word(f12);
1586 arg1 = get_fpu_register_word(f13);
1587 }
1435 arg2 = get_register(a2); 1588 arg2 = get_register(a2);
1436 break; 1589 break;
1437 default: 1590 default:
1438 break; 1591 break;
1439 } 1592 }
1440 } 1593 }
1441 1594
1442 // This is dodgy but it works because the C entry stubs are never moved. 1595 // This is dodgy but it works because the C entry stubs are never moved.
1443 // See comment in codegen-arm.cc and bug 1242173. 1596 // See comment in codegen-arm.cc and bug 1242173.
1444 int32_t saved_ra = get_register(ra); 1597 int32_t saved_ra = get_register(ra);
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 const int32_t rd_reg = instr->RdValue(); 1881 const int32_t rd_reg = instr->RdValue();
1729 const uint32_t sa = instr->SaValue(); 1882 const uint32_t sa = instr->SaValue();
1730 1883
1731 const int32_t fs_reg = instr->FsValue(); 1884 const int32_t fs_reg = instr->FsValue();
1732 1885
1733 1886
1734 // ---------- Configuration. 1887 // ---------- Configuration.
1735 switch (op) { 1888 switch (op) {
1736 case COP1: // Coprocessor instructions. 1889 case COP1: // Coprocessor instructions.
1737 switch (instr->RsFieldRaw()) { 1890 switch (instr->RsFieldRaw()) {
1738 case BC1: // Handled in DecodeTypeImmed, should never come here.
1739 UNREACHABLE();
1740 break;
1741 case CFC1: 1891 case CFC1:
1742 // At the moment only FCSR is supported. 1892 // At the moment only FCSR is supported.
1743 DCHECK(fs_reg == kFCSRRegister); 1893 DCHECK(fs_reg == kFCSRRegister);
1744 *alu_out = FCSR_; 1894 *alu_out = FCSR_;
1745 break; 1895 break;
1746 case MFC1: 1896 case MFC1:
1747 *alu_out = get_fpu_register(fs_reg); 1897 *alu_out = get_fpu_register_word(fs_reg);
1748 break; 1898 break;
1749 case MFHC1: 1899 case MFHC1:
1750 UNIMPLEMENTED_MIPS(); 1900 *alu_out = get_fpu_register_hi_word(fs_reg);
1751 break; 1901 break;
1752 case CTC1: 1902 case CTC1:
1753 case MTC1: 1903 case MTC1:
1754 case MTHC1: 1904 case MTHC1:
1755 // Do the store in the execution step.
1756 break;
1757 case S: 1905 case S:
1758 case D: 1906 case D:
1759 case W: 1907 case W:
1760 case L: 1908 case L:
1761 case PS: 1909 case PS:
1762 // Do everything in the execution step. 1910 // Do everything in the execution step.
1763 break; 1911 break;
1764 default: 1912 default:
1765 UNIMPLEMENTED_MIPS(); 1913 // BC1 BC1EQZ BC1NEZ handled in DecodeTypeImmed, should never come here.
1914 UNREACHABLE();
1766 } 1915 }
1767 break; 1916 break;
1768 case COP1X: 1917 case COP1X:
1769 break; 1918 break;
1770 case SPECIAL: 1919 case SPECIAL:
1771 switch (instr->FunctionFieldRaw()) { 1920 switch (instr->FunctionFieldRaw()) {
1772 case JR: 1921 case JR:
1773 case JALR: 1922 case JALR:
1774 *next_pc = get_register(instr->RsValue()); 1923 *next_pc = get_register(instr->RsValue());
1775 *return_addr_reg = instr->RdValue(); 1924 *return_addr_reg = instr->RdValue();
(...skipping 27 matching lines...) Expand all
1803 } else { 1952 } else {
1804 // Logical right-rotate of a word by a variable number of bits. 1953 // Logical right-rotate of a word by a variable number of bits.
1805 // This is special case od SRLV instruction, added in MIPS32 1954 // This is special case od SRLV instruction, added in MIPS32
1806 // Release 2. SA field is equal to 00001. 1955 // Release 2. SA field is equal to 00001.
1807 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); 1956 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
1808 } 1957 }
1809 break; 1958 break;
1810 case SRAV: 1959 case SRAV:
1811 *alu_out = rt >> rs; 1960 *alu_out = rt >> rs;
1812 break; 1961 break;
1813 case MFHI: 1962 case MFHI: // MFHI == CLZ on R6.
1814 *alu_out = get_register(HI); 1963 if (!IsMipsArchVariant(kMips32r6)) {
1964 DCHECK(instr->SaValue() == 0);
1965 *alu_out = get_register(HI);
1966 } else {
1967 // MIPS spec: If no bits were set in GPR rs, the result written to
1968 // GPR rd is 32.
1969 // GCC __builtin_clz: If input is 0, the result is undefined.
1970 DCHECK(instr->SaValue() == 1);
1971 *alu_out =
1972 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u);
1973 }
1815 break; 1974 break;
1816 case MFLO: 1975 case MFLO:
1817 *alu_out = get_register(LO); 1976 *alu_out = get_register(LO);
1818 break; 1977 break;
1819 case MULT: 1978 case MULT: // MULT == MUL_MUH.
1820 *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt); 1979 if (!IsMipsArchVariant(kMips32r6)) {
1980 *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt);
1981 } else {
1982 switch (instr->SaValue()) {
1983 case MUL_OP:
1984 case MUH_OP:
1985 *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt);
1986 break;
1987 default:
1988 UNIMPLEMENTED_MIPS();
1989 break;
1990 }
1991 }
1821 break; 1992 break;
1822 case MULTU: 1993 case MULTU: // MULTU == MUL_MUH_U.
1823 *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); 1994 if (!IsMipsArchVariant(kMips32r6)) {
1995 *u64hilo = static_cast<uint64_t>(rs_u) *
1996 static_cast<uint64_t>(rt_u);
1997 } else {
1998 switch (instr->SaValue()) {
1999 case MUL_OP:
2000 case MUH_OP:
2001 *u64hilo = static_cast<uint64_t>(rs_u) *
2002 static_cast<uint64_t>(rt_u);
2003 break;
2004 default:
2005 UNIMPLEMENTED_MIPS();
2006 break;
2007 }
2008 }
1824 break; 2009 break;
1825 case ADD: 2010 case ADD:
1826 if (HaveSameSign(rs, rt)) { 2011 if (HaveSameSign(rs, rt)) {
1827 if (rs > 0) { 2012 if (rs > 0) {
1828 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); 2013 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
1829 } else if (rs < 0) { 2014 } else if (rs < 0) {
1830 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); 2015 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
1831 } 2016 }
1832 } 2017 }
1833 *alu_out = rs + rt; 2018 *alu_out = rs + rt;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 &return_addr_reg, 2176 &return_addr_reg,
1992 &do_interrupt); 2177 &do_interrupt);
1993 2178
1994 // ---------- Raise exceptions triggered. 2179 // ---------- Raise exceptions triggered.
1995 SignalExceptions(); 2180 SignalExceptions();
1996 2181
1997 // ---------- Execution. 2182 // ---------- Execution.
1998 switch (op) { 2183 switch (op) {
1999 case COP1: 2184 case COP1:
2000 switch (instr->RsFieldRaw()) { 2185 switch (instr->RsFieldRaw()) {
2001 case BC1: // Branch on coprocessor condition.
2002 UNREACHABLE();
2003 break;
2004 case CFC1: 2186 case CFC1:
2005 set_register(rt_reg, alu_out); 2187 set_register(rt_reg, alu_out);
2188 break;
2006 case MFC1: 2189 case MFC1:
2007 set_register(rt_reg, alu_out); 2190 set_register(rt_reg, alu_out);
2008 break; 2191 break;
2009 case MFHC1: 2192 case MFHC1:
2010 UNIMPLEMENTED_MIPS(); 2193 set_register(rt_reg, alu_out);
2011 break; 2194 break;
2012 case CTC1: 2195 case CTC1:
2013 // At the moment only FCSR is supported. 2196 // At the moment only FCSR is supported.
2014 DCHECK(fs_reg == kFCSRRegister); 2197 DCHECK(fs_reg == kFCSRRegister);
2015 FCSR_ = registers_[rt_reg]; 2198 FCSR_ = registers_[rt_reg];
2016 break; 2199 break;
2017 case MTC1: 2200 case MTC1:
2018 FPUregisters_[fs_reg] = registers_[rt_reg]; 2201 // Hardware writes upper 32-bits to zero on mtc1.
2202 set_fpu_register_hi_word(fs_reg, 0);
2203 set_fpu_register_word(fs_reg, registers_[rt_reg]);
2019 break; 2204 break;
2020 case MTHC1: 2205 case MTHC1:
2021 UNIMPLEMENTED_MIPS(); 2206 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]);
2022 break; 2207 break;
2023 case S: 2208 case S:
2024 float f; 2209 float f;
2025 switch (instr->FunctionFieldRaw()) { 2210 switch (instr->FunctionFieldRaw()) {
2026 case CVT_D_S: 2211 case CVT_D_S:
2027 f = get_fpu_register_float(fs_reg); 2212 f = get_fpu_register_float(fs_reg);
2028 set_fpu_register_double(fd_reg, static_cast<double>(f)); 2213 set_fpu_register_double(fd_reg, static_cast<double>(f));
2029 break; 2214 break;
2030 case CVT_W_S:
2031 case CVT_L_S:
2032 case TRUNC_W_S:
2033 case TRUNC_L_S:
2034 case ROUND_W_S:
2035 case ROUND_L_S:
2036 case FLOOR_W_S:
2037 case FLOOR_L_S:
2038 case CEIL_W_S:
2039 case CEIL_L_S:
2040 case CVT_PS_S:
2041 UNIMPLEMENTED_MIPS();
2042 break;
2043 default: 2215 default:
2216 // CVT_W_S CVT_L_S TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
2217 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
2044 UNREACHABLE(); 2218 UNREACHABLE();
2045 } 2219 }
2046 break; 2220 break;
2047 case D: 2221 case D:
2048 double ft, fs; 2222 double ft, fs;
2049 uint32_t cc, fcsr_cc; 2223 uint32_t cc, fcsr_cc;
2050 int64_t i64; 2224 int64_t i64;
2051 fs = get_fpu_register_double(fs_reg); 2225 fs = get_fpu_register_double(fs_reg);
2052 ft = get_fpu_register_double(ft_reg); 2226 ft = get_fpu_register_double(ft_reg);
2053 cc = instr->FCccValue(); 2227 cc = instr->FCccValue();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 // In rounding mode 0 it should behave like ROUND. 2281 // In rounding mode 0 it should behave like ROUND.
2108 case ROUND_W_D: // Round double to word (round half to even). 2282 case ROUND_W_D: // Round double to word (round half to even).
2109 { 2283 {
2110 double rounded = std::floor(fs + 0.5); 2284 double rounded = std::floor(fs + 0.5);
2111 int32_t result = static_cast<int32_t>(rounded); 2285 int32_t result = static_cast<int32_t>(rounded);
2112 if ((result & 1) != 0 && result - fs == 0.5) { 2286 if ((result & 1) != 0 && result - fs == 0.5) {
2113 // If the number is halfway between two integers, 2287 // If the number is halfway between two integers,
2114 // round to the even one. 2288 // round to the even one.
2115 result--; 2289 result--;
2116 } 2290 }
2117 set_fpu_register(fd_reg, result); 2291 set_fpu_register_word(fd_reg, result);
2118 if (set_fcsr_round_error(fs, rounded)) { 2292 if (set_fcsr_round_error(fs, rounded)) {
2119 set_fpu_register(fd_reg, kFPUInvalidResult); 2293 set_fpu_register(fd_reg, kFPUInvalidResult);
2120 } 2294 }
2121 } 2295 }
2122 break; 2296 break;
2123 case TRUNC_W_D: // Truncate double to word (round towards 0). 2297 case TRUNC_W_D: // Truncate double to word (round towards 0).
2124 { 2298 {
2125 double rounded = trunc(fs); 2299 double rounded = trunc(fs);
2126 int32_t result = static_cast<int32_t>(rounded); 2300 int32_t result = static_cast<int32_t>(rounded);
2127 set_fpu_register(fd_reg, result); 2301 set_fpu_register_word(fd_reg, result);
2128 if (set_fcsr_round_error(fs, rounded)) { 2302 if (set_fcsr_round_error(fs, rounded)) {
2129 set_fpu_register(fd_reg, kFPUInvalidResult); 2303 set_fpu_register(fd_reg, kFPUInvalidResult);
2130 } 2304 }
2131 } 2305 }
2132 break; 2306 break;
2133 case FLOOR_W_D: // Round double to word towards negative infinity. 2307 case FLOOR_W_D: // Round double to word towards negative infinity.
2134 { 2308 {
2135 double rounded = std::floor(fs); 2309 double rounded = std::floor(fs);
2136 int32_t result = static_cast<int32_t>(rounded); 2310 int32_t result = static_cast<int32_t>(rounded);
2137 set_fpu_register(fd_reg, result); 2311 set_fpu_register_word(fd_reg, result);
2138 if (set_fcsr_round_error(fs, rounded)) { 2312 if (set_fcsr_round_error(fs, rounded)) {
2139 set_fpu_register(fd_reg, kFPUInvalidResult); 2313 set_fpu_register(fd_reg, kFPUInvalidResult);
2140 } 2314 }
2141 } 2315 }
2142 break; 2316 break;
2143 case CEIL_W_D: // Round double to word towards positive infinity. 2317 case CEIL_W_D: // Round double to word towards positive infinity.
2144 { 2318 {
2145 double rounded = std::ceil(fs); 2319 double rounded = std::ceil(fs);
2146 int32_t result = static_cast<int32_t>(rounded); 2320 int32_t result = static_cast<int32_t>(rounded);
2147 set_fpu_register(fd_reg, result); 2321 set_fpu_register_word(fd_reg, result);
2148 if (set_fcsr_round_error(fs, rounded)) { 2322 if (set_fcsr_round_error(fs, rounded)) {
2149 set_fpu_register(fd_reg, kFPUInvalidResult); 2323 set_fpu_register(fd_reg, kFPUInvalidResult);
2150 } 2324 }
2151 } 2325 }
2152 break; 2326 break;
2153 case CVT_S_D: // Convert double to float (single). 2327 case CVT_S_D: // Convert double to float (single).
2154 set_fpu_register_float(fd_reg, static_cast<float>(fs)); 2328 set_fpu_register_float(fd_reg, static_cast<float>(fs));
2155 break; 2329 break;
2156 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. 2330 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
2157 double rounded = trunc(fs); 2331 double rounded = trunc(fs);
2158 i64 = static_cast<int64_t>(rounded); 2332 i64 = static_cast<int64_t>(rounded);
2159 set_fpu_register(fd_reg, i64 & 0xffffffff); 2333 if (IsFp64Mode()) {
2160 set_fpu_register(fd_reg + 1, i64 >> 32); 2334 set_fpu_register(fd_reg, i64);
2335 } else {
2336 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2337 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2338 }
2161 break; 2339 break;
2162 } 2340 }
2163 case TRUNC_L_D: { // Mips32r2 instruction. 2341 case TRUNC_L_D: { // Mips32r2 instruction.
2164 double rounded = trunc(fs); 2342 double rounded = trunc(fs);
2165 i64 = static_cast<int64_t>(rounded); 2343 i64 = static_cast<int64_t>(rounded);
2166 set_fpu_register(fd_reg, i64 & 0xffffffff); 2344 if (IsFp64Mode()) {
2167 set_fpu_register(fd_reg + 1, i64 >> 32); 2345 set_fpu_register(fd_reg, i64);
2346 } else {
2347 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2348 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2349 }
2168 break; 2350 break;
2169 } 2351 }
2170 case ROUND_L_D: { // Mips32r2 instruction. 2352 case ROUND_L_D: { // Mips32r2 instruction.
2171 double rounded = 2353 double rounded =
2172 fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5); 2354 fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5);
2173 i64 = static_cast<int64_t>(rounded); 2355 i64 = static_cast<int64_t>(rounded);
2174 set_fpu_register(fd_reg, i64 & 0xffffffff); 2356 if (IsFp64Mode()) {
2175 set_fpu_register(fd_reg + 1, i64 >> 32); 2357 set_fpu_register(fd_reg, i64);
2358 } else {
2359 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2360 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2361 }
2176 break; 2362 break;
2177 } 2363 }
2178 case FLOOR_L_D: // Mips32r2 instruction. 2364 case FLOOR_L_D: // Mips32r2 instruction.
2179 i64 = static_cast<int64_t>(std::floor(fs)); 2365 i64 = static_cast<int64_t>(std::floor(fs));
2180 set_fpu_register(fd_reg, i64 & 0xffffffff); 2366 if (IsFp64Mode()) {
2181 set_fpu_register(fd_reg + 1, i64 >> 32); 2367 set_fpu_register(fd_reg, i64);
2368 } else {
2369 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2370 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2371 }
2182 break; 2372 break;
2183 case CEIL_L_D: // Mips32r2 instruction. 2373 case CEIL_L_D: // Mips32r2 instruction.
2184 i64 = static_cast<int64_t>(std::ceil(fs)); 2374 i64 = static_cast<int64_t>(std::ceil(fs));
2185 set_fpu_register(fd_reg, i64 & 0xffffffff); 2375 if (IsFp64Mode()) {
2186 set_fpu_register(fd_reg + 1, i64 >> 32); 2376 set_fpu_register(fd_reg, i64);
2377 } else {
2378 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2379 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2380 }
2187 break; 2381 break;
2188 case C_F_D: 2382 case C_F_D:
2189 UNIMPLEMENTED_MIPS(); 2383 UNIMPLEMENTED_MIPS();
2190 break; 2384 break;
2191 default: 2385 default:
2192 UNREACHABLE(); 2386 UNREACHABLE();
2193 } 2387 }
2194 break; 2388 break;
2195 case W: 2389 case W:
2196 switch (instr->FunctionFieldRaw()) { 2390 switch (instr->FunctionFieldRaw()) {
2197 case CVT_S_W: // Convert word to float (single). 2391 case CVT_S_W: // Convert word to float (single).
2198 alu_out = get_fpu_register(fs_reg); 2392 alu_out = get_fpu_register_signed_word(fs_reg);
2199 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); 2393 set_fpu_register_float(fd_reg, static_cast<float>(alu_out));
2200 break; 2394 break;
2201 case CVT_D_W: // Convert word to double. 2395 case CVT_D_W: // Convert word to double.
2202 alu_out = get_fpu_register(fs_reg); 2396 alu_out = get_fpu_register_signed_word(fs_reg);
2203 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); 2397 set_fpu_register_double(fd_reg, static_cast<double>(alu_out));
2204 break; 2398 break;
2205 default: 2399 default: // Mips64r6 CMP.S instructions unimplemented.
2206 UNREACHABLE(); 2400 UNREACHABLE();
2207 } 2401 }
2208 break; 2402 break;
2209 case L: 2403 case L:
2404 fs = get_fpu_register_double(fs_reg);
2405 ft = get_fpu_register_double(ft_reg);
2210 switch (instr->FunctionFieldRaw()) { 2406 switch (instr->FunctionFieldRaw()) {
2211 case CVT_D_L: // Mips32r2 instruction. 2407 case CVT_D_L: // Mips32r2 instruction.
2212 // Watch the signs here, we want 2 32-bit vals 2408 // Watch the signs here, we want 2 32-bit vals
2213 // to make a sign-64. 2409 // to make a sign-64.
2214 i64 = static_cast<uint32_t>(get_fpu_register(fs_reg)); 2410 if (IsFp64Mode()) {
2215 i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32; 2411 i64 = get_fpu_register(fs_reg);
2412 } else {
2413 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg));
2414 i64 |= static_cast<int64_t>(
2415 get_fpu_register_word(fs_reg + 1)) << 32;
2416 }
2216 set_fpu_register_double(fd_reg, static_cast<double>(i64)); 2417 set_fpu_register_double(fd_reg, static_cast<double>(i64));
2217 break; 2418 break;
2218 case CVT_S_L: 2419 case CVT_S_L:
2219 UNIMPLEMENTED_MIPS(); 2420 UNIMPLEMENTED_MIPS();
2220 break; 2421 break;
2221 default: 2422 case CMP_AF: // Mips64r6 CMP.D instructions.
2423 UNIMPLEMENTED_MIPS();
2424 break;
2425 case CMP_UN:
2426 if (std::isnan(fs) || std::isnan(ft)) {
2427 set_fpu_register(fd_reg, -1);
2428 } else {
2429 set_fpu_register(fd_reg, 0);
2430 }
2431 break;
2432 case CMP_EQ:
2433 if (fs == ft) {
2434 set_fpu_register(fd_reg, -1);
2435 } else {
2436 set_fpu_register(fd_reg, 0);
2437 }
2438 break;
2439 case CMP_UEQ:
2440 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
2441 set_fpu_register(fd_reg, -1);
2442 } else {
2443 set_fpu_register(fd_reg, 0);
2444 }
2445 break;
2446 case CMP_LT:
2447 if (fs < ft) {
2448 set_fpu_register(fd_reg, -1);
2449 } else {
2450 set_fpu_register(fd_reg, 0);
2451 }
2452 break;
2453 case CMP_ULT:
2454 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
2455 set_fpu_register(fd_reg, -1);
2456 } else {
2457 set_fpu_register(fd_reg, 0);
2458 }
2459 break;
2460 case CMP_LE:
2461 if (fs <= ft) {
2462 set_fpu_register(fd_reg, -1);
2463 } else {
2464 set_fpu_register(fd_reg, 0);
2465 }
2466 break;
2467 case CMP_ULE:
2468 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
2469 set_fpu_register(fd_reg, -1);
2470 } else {
2471 set_fpu_register(fd_reg, 0);
2472 }
2473 break;
2474 default: // CMP_OR CMP_UNE CMP_NE UNIMPLEMENTED.
2222 UNREACHABLE(); 2475 UNREACHABLE();
2223 } 2476 }
2224 break; 2477 break;
2225 case PS:
2226 break;
2227 default: 2478 default:
2228 UNREACHABLE(); 2479 UNREACHABLE();
2229 } 2480 }
2230 break; 2481 break;
2231 case COP1X: 2482 case COP1X:
2232 switch (instr->FunctionFieldRaw()) { 2483 switch (instr->FunctionFieldRaw()) {
2233 case MADD_D: 2484 case MADD_D:
2234 double fr, ft, fs; 2485 double fr, ft, fs;
2235 fr = get_fpu_register_double(fr_reg); 2486 fr = get_fpu_register_double(fr_reg);
2236 fs = get_fpu_register_double(fs_reg); 2487 fs = get_fpu_register_double(fs_reg);
(...skipping 19 matching lines...) Expand all
2256 current_pc+Instruction::kInstrSize); 2507 current_pc+Instruction::kInstrSize);
2257 BranchDelayInstructionDecode(branch_delay_instr); 2508 BranchDelayInstructionDecode(branch_delay_instr);
2258 set_register(return_addr_reg, 2509 set_register(return_addr_reg,
2259 current_pc + 2 * Instruction::kInstrSize); 2510 current_pc + 2 * Instruction::kInstrSize);
2260 set_pc(next_pc); 2511 set_pc(next_pc);
2261 pc_modified_ = true; 2512 pc_modified_ = true;
2262 break; 2513 break;
2263 } 2514 }
2264 // Instructions using HI and LO registers. 2515 // Instructions using HI and LO registers.
2265 case MULT: 2516 case MULT:
2266 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); 2517 if (!IsMipsArchVariant(kMips32r6)) {
2267 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); 2518 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
2519 set_register(HI, static_cast<int32_t>(i64hilo >> 32));
2520 } else {
2521 switch (instr->SaValue()) {
2522 case MUL_OP:
2523 set_register(rd_reg,
2524 static_cast<int32_t>(i64hilo & 0xffffffff));
2525 break;
2526 case MUH_OP:
2527 set_register(rd_reg, static_cast<int32_t>(i64hilo >> 32));
2528 break;
2529 default:
2530 UNIMPLEMENTED_MIPS();
2531 break;
2532 }
2533 }
2268 break; 2534 break;
2269 case MULTU: 2535 case MULTU:
2270 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); 2536 if (!IsMipsArchVariant(kMips32r6)) {
2271 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); 2537 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
2538 set_register(HI, static_cast<int32_t>(u64hilo >> 32));
2539 } else {
2540 switch (instr->SaValue()) {
2541 case MUL_OP:
2542 set_register(rd_reg,
2543 static_cast<int32_t>(u64hilo & 0xffffffff));
2544 break;
2545 case MUH_OP:
2546 set_register(rd_reg, static_cast<int32_t>(u64hilo >> 32));
2547 break;
2548 default:
2549 UNIMPLEMENTED_MIPS();
2550 break;
2551 }
2552 }
2272 break; 2553 break;
2273 case DIV: 2554 case DIV:
2274 // Divide by zero and overflow was not checked in the configuration 2555 if (IsMipsArchVariant(kMips32r6)) {
2275 // step - div and divu do not raise exceptions. On division by 0 2556 switch (instr->SaValue()) {
2276 // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1), 2557 case DIV_OP:
2277 // return INT_MIN which is what the hardware does. 2558 if (rs == INT_MIN && rt == -1) {
2278 if (rs == INT_MIN && rt == -1) { 2559 set_register(rd_reg, INT_MIN);
2279 set_register(LO, INT_MIN); 2560 } else if (rt != 0) {
2280 set_register(HI, 0); 2561 set_register(rd_reg, rs / rt);
2281 } else if (rt != 0) { 2562 }
2282 set_register(LO, rs / rt); 2563 break;
2283 set_register(HI, rs % rt); 2564 case MOD_OP:
2565 if (rs == INT_MIN && rt == -1) {
2566 set_register(rd_reg, 0);
2567 } else if (rt != 0) {
2568 set_register(rd_reg, rs % rt);
2569 }
2570 break;
2571 default:
2572 UNIMPLEMENTED_MIPS();
2573 break;
2574 }
2575 } else {
2576 // Divide by zero and overflow was not checked in the
2577 // configuration step - div and divu do not raise exceptions. On
2578 // division by 0 the result will be UNPREDICTABLE. On overflow
2579 // (INT_MIN/-1), return INT_MIN which is what the hardware does.
2580 if (rs == INT_MIN && rt == -1) {
2581 set_register(LO, INT_MIN);
2582 set_register(HI, 0);
2583 } else if (rt != 0) {
2584 set_register(LO, rs / rt);
2585 set_register(HI, rs % rt);
2586 }
2284 } 2587 }
2285 break; 2588 break;
2286 case DIVU: 2589 case DIVU:
2287 if (rt_u != 0) { 2590 if (IsMipsArchVariant(kMips32r6)) {
2288 set_register(LO, rs_u / rt_u); 2591 switch (instr->SaValue()) {
2289 set_register(HI, rs_u % rt_u); 2592 case DIV_OP:
2593 if (rt_u != 0) {
2594 set_register(rd_reg, rs_u / rt_u);
2595 }
2596 break;
2597 case MOD_OP:
2598 if (rt_u != 0) {
2599 set_register(rd_reg, rs_u % rt_u);
2600 }
2601 break;
2602 default:
2603 UNIMPLEMENTED_MIPS();
2604 break;
2605 }
2606 } else {
2607 if (rt_u != 0) {
2608 set_register(LO, rs_u / rt_u);
2609 set_register(HI, rs_u % rt_u);
2610 }
2290 } 2611 }
2291 break; 2612 break;
2292 // Break and trap instructions. 2613 // Break and trap instructions.
2293 case BREAK: 2614 case BREAK:
2294 case TGE: 2615 case TGE:
2295 case TGEU: 2616 case TGEU:
2296 case TLT: 2617 case TLT:
2297 case TLTU: 2618 case TLTU:
2298 case TEQ: 2619 case TEQ:
2299 case TNE: 2620 case TNE:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 void Simulator::DecodeTypeImmediate(Instruction* instr) { 2682 void Simulator::DecodeTypeImmediate(Instruction* instr) {
2362 // Instruction fields. 2683 // Instruction fields.
2363 Opcode op = instr->OpcodeFieldRaw(); 2684 Opcode op = instr->OpcodeFieldRaw();
2364 int32_t rs = get_register(instr->RsValue()); 2685 int32_t rs = get_register(instr->RsValue());
2365 uint32_t rs_u = static_cast<uint32_t>(rs); 2686 uint32_t rs_u = static_cast<uint32_t>(rs);
2366 int32_t rt_reg = instr->RtValue(); // Destination register. 2687 int32_t rt_reg = instr->RtValue(); // Destination register.
2367 int32_t rt = get_register(rt_reg); 2688 int32_t rt = get_register(rt_reg);
2368 int16_t imm16 = instr->Imm16Value(); 2689 int16_t imm16 = instr->Imm16Value();
2369 2690
2370 int32_t ft_reg = instr->FtValue(); // Destination register. 2691 int32_t ft_reg = instr->FtValue(); // Destination register.
2692 int64_t ft;
2371 2693
2372 // Zero extended immediate. 2694 // Zero extended immediate.
2373 uint32_t oe_imm16 = 0xffff & imm16; 2695 uint32_t oe_imm16 = 0xffff & imm16;
2374 // Sign extended immediate. 2696 // Sign extended immediate.
2375 int32_t se_imm16 = imm16; 2697 int32_t se_imm16 = imm16;
2376 2698
2377 // Get current pc. 2699 // Get current pc.
2378 int32_t current_pc = get_pc(); 2700 int32_t current_pc = get_pc();
2379 // Next pc. 2701 // Next pc.
2380 int32_t next_pc = bad_ra; 2702 int32_t next_pc = bad_ra;
(...skipping 24 matching lines...) Expand all
2405 cc_value = test_fcsr_bit(fcsr_cc); 2727 cc_value = test_fcsr_bit(fcsr_cc);
2406 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 2728 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
2407 execute_branch_delay_instruction = true; 2729 execute_branch_delay_instruction = true;
2408 // Set next_pc. 2730 // Set next_pc.
2409 if (do_branch) { 2731 if (do_branch) {
2410 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 2732 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2411 } else { 2733 } else {
2412 next_pc = current_pc + kBranchReturnOffset; 2734 next_pc = current_pc + kBranchReturnOffset;
2413 } 2735 }
2414 break; 2736 break;
2737 case BC1EQZ:
2738 ft = get_fpu_register(ft_reg);
2739 do_branch = (ft & 0x1) ? false : true;
2740 execute_branch_delay_instruction = true;
2741 // Set next_pc.
2742 if (do_branch) {
2743 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2744 } else {
2745 next_pc = current_pc + kBranchReturnOffset;
2746 }
2747 break;
2748 case BC1NEZ:
2749 ft = get_fpu_register(ft_reg);
2750 do_branch = (ft & 0x1) ? true : false;
2751 execute_branch_delay_instruction = true;
2752 // Set next_pc.
2753 if (do_branch) {
2754 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2755 } else {
2756 next_pc = current_pc + kBranchReturnOffset;
2757 }
2758 break;
2415 default: 2759 default:
2416 UNREACHABLE(); 2760 UNREACHABLE();
2417 } 2761 }
2418 break; 2762 break;
2419 // ------------- REGIMM class. 2763 // ------------- REGIMM class.
2420 case REGIMM: 2764 case REGIMM:
2421 switch (instr->RtFieldRaw()) { 2765 switch (instr->RtFieldRaw()) {
2422 case BLTZ: 2766 case BLTZ:
2423 do_branch = (rs < 0); 2767 do_branch = (rs < 0);
2424 break; 2768 break;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 case SWL: 2983 case SWL:
2640 WriteW(addr, mem_value, instr); 2984 WriteW(addr, mem_value, instr);
2641 break; 2985 break;
2642 case SW: 2986 case SW:
2643 WriteW(addr, rt, instr); 2987 WriteW(addr, rt, instr);
2644 break; 2988 break;
2645 case SWR: 2989 case SWR:
2646 WriteW(addr, mem_value, instr); 2990 WriteW(addr, mem_value, instr);
2647 break; 2991 break;
2648 case LWC1: 2992 case LWC1:
2649 set_fpu_register(ft_reg, alu_out); 2993 set_fpu_register_hi_word(ft_reg, 0);
2994 set_fpu_register_word(ft_reg, alu_out);
2650 break; 2995 break;
2651 case LDC1: 2996 case LDC1:
2652 set_fpu_register_double(ft_reg, fp_out); 2997 set_fpu_register_double(ft_reg, fp_out);
2653 break; 2998 break;
2654 case SWC1: 2999 case SWC1:
2655 addr = rs + se_imm16; 3000 addr = rs + se_imm16;
2656 WriteW(addr, get_fpu_register(ft_reg), instr); 3001 WriteW(addr, get_fpu_register_word(ft_reg), instr);
2657 break; 3002 break;
2658 case SDC1: 3003 case SDC1:
2659 addr = rs + se_imm16; 3004 addr = rs + se_imm16;
2660 WriteD(addr, get_fpu_register_double(ft_reg), instr); 3005 WriteD(addr, get_fpu_register_double(ft_reg), instr);
2661 break; 3006 break;
2662 default: 3007 default:
2663 break; 3008 break;
2664 } 3009 }
2665 3010
2666 3011
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 } 3264 }
2920 3265
2921 3266
2922 #undef UNSUPPORTED 3267 #undef UNSUPPORTED
2923 3268
2924 } } // namespace v8::internal 3269 } } // namespace v8::internal
2925 3270
2926 #endif // USE_SIMULATOR 3271 #endif // USE_SIMULATOR
2927 3272
2928 #endif // V8_TARGET_ARCH_MIPS 3273 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.h ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698