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

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

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