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

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

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 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/arm/simulator-arm.h ('k') | src/arm/stub-cache-arm.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 22 matching lines...) Expand all
33 #if defined(V8_TARGET_ARCH_ARM) 33 #if defined(V8_TARGET_ARCH_ARM)
34 34
35 #include "disasm.h" 35 #include "disasm.h"
36 #include "assembler.h" 36 #include "assembler.h"
37 #include "arm/constants-arm.h" 37 #include "arm/constants-arm.h"
38 #include "arm/simulator-arm.h" 38 #include "arm/simulator-arm.h"
39 39
40 #if defined(USE_SIMULATOR) 40 #if defined(USE_SIMULATOR)
41 41
42 // Only build the simulator if not compiling for real ARM hardware. 42 // Only build the simulator if not compiling for real ARM hardware.
43 namespace assembler { 43 namespace v8 {
44 namespace arm { 44 namespace internal {
45
46 using ::v8::internal::Object;
47 using ::v8::internal::PrintF;
48 using ::v8::internal::OS;
49 using ::v8::internal::ReadLine;
50 using ::v8::internal::DeleteArray;
51 45
52 // This macro provides a platform independent use of sscanf. The reason for 46 // This macro provides a platform independent use of sscanf. The reason for
53 // SScanF not being implemented in a platform independent way through 47 // SScanF not being implemented in a platform independent way through
54 // ::v8::internal::OS in the same way as SNPrintF is that the 48 // ::v8::internal::OS in the same way as SNPrintF is that the
55 // Windows C Run-Time Library does not provide vsscanf. 49 // Windows C Run-Time Library does not provide vsscanf.
56 #define SScanF sscanf // NOLINT 50 #define SScanF sscanf // NOLINT
57 51
58 // The Debugger class is used by the simulator while debugging simulated ARM 52 // The Debugger class is used by the simulator while debugging simulated ARM
59 // code. 53 // code.
60 class Debugger { 54 class Debugger {
61 public: 55 public:
62 explicit Debugger(Simulator* sim); 56 explicit Debugger(Simulator* sim);
63 ~Debugger(); 57 ~Debugger();
64 58
65 void Stop(Instr* instr); 59 void Stop(Instruction* instr);
66 void Debug(); 60 void Debug();
67 61
68 private: 62 private:
69 static const instr_t kBreakpointInstr = 63 static const Instr kBreakpointInstr =
70 ((AL << 28) | (7 << 25) | (1 << 24) | break_point); 64 (al | (7*B25) | (1*B24) | kBreakpoint);
71 static const instr_t kNopInstr = 65 static const Instr kNopInstr = (al | (13*B21));
72 ((AL << 28) | (13 << 21));
73 66
74 Simulator* sim_; 67 Simulator* sim_;
75 68
76 int32_t GetRegisterValue(int regnum); 69 int32_t GetRegisterValue(int regnum);
77 double GetVFPDoubleRegisterValue(int regnum); 70 double GetVFPDoubleRegisterValue(int regnum);
78 bool GetValue(const char* desc, int32_t* value); 71 bool GetValue(const char* desc, int32_t* value);
79 bool GetVFPSingleValue(const char* desc, float* value); 72 bool GetVFPSingleValue(const char* desc, float* value);
80 bool GetVFPDoubleValue(const char* desc, double* value); 73 bool GetVFPDoubleValue(const char* desc, double* value);
81 74
82 // Set or delete a breakpoint. Returns true if successful. 75 // Set or delete a breakpoint. Returns true if successful.
83 bool SetBreakpoint(Instr* breakpc); 76 bool SetBreakpoint(Instruction* breakpc);
84 bool DeleteBreakpoint(Instr* breakpc); 77 bool DeleteBreakpoint(Instruction* breakpc);
85 78
86 // Undo and redo all breakpoints. This is needed to bracket disassembly and 79 // Undo and redo all breakpoints. This is needed to bracket disassembly and
87 // execution to skip past breakpoints when run from the debugger. 80 // execution to skip past breakpoints when run from the debugger.
88 void UndoBreakpoints(); 81 void UndoBreakpoints();
89 void RedoBreakpoints(); 82 void RedoBreakpoints();
90 }; 83 };
91 84
92 85
93 Debugger::Debugger(Simulator* sim) { 86 Debugger::Debugger(Simulator* sim) {
94 sim_ = sim; 87 sim_ = sim;
(...skipping 10 matching lines...) Expand all
105 98
106 99
107 static void InitializeCoverage() { 100 static void InitializeCoverage() {
108 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 101 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
109 if (file_name != NULL) { 102 if (file_name != NULL) {
110 coverage_log = fopen(file_name, "aw+"); 103 coverage_log = fopen(file_name, "aw+");
111 } 104 }
112 } 105 }
113 106
114 107
115 void Debugger::Stop(Instr* instr) { 108 void Debugger::Stop(Instruction* instr) {
116 // Get the stop code. 109 // Get the stop code.
117 uint32_t code = instr->SvcField() & kStopCodeMask; 110 uint32_t code = instr->SvcValue() & kStopCodeMask;
118 // Retrieve the encoded address, which comes just after this stop. 111 // Retrieve the encoded address, which comes just after this stop.
119 char** msg_address = 112 char** msg_address =
120 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); 113 reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
121 char* msg = *msg_address; 114 char* msg = *msg_address;
122 ASSERT(msg != NULL); 115 ASSERT(msg != NULL);
123 116
124 // Update this stop description. 117 // Update this stop description.
125 if (isWatchedStop(code) && !watched_stops[code].desc) { 118 if (isWatchedStop(code) && !watched_stops[code].desc) {
126 watched_stops[code].desc = msg; 119 watched_stops[code].desc = msg;
127 } 120 }
128 121
129 if (strlen(msg) > 0) { 122 if (strlen(msg) > 0) {
130 if (coverage_log != NULL) { 123 if (coverage_log != NULL) {
131 fprintf(coverage_log, "%s\n", msg); 124 fprintf(coverage_log, "%s\n", msg);
132 fflush(coverage_log); 125 fflush(coverage_log);
133 } 126 }
134 // Overwrite the instruction and address with nops. 127 // Overwrite the instruction and address with nops.
135 instr->SetInstructionBits(kNopInstr); 128 instr->SetInstructionBits(kNopInstr);
136 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); 129 reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
137 } 130 }
138 sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize); 131 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
139 } 132 }
140 133
141 #else // ndef GENERATED_CODE_COVERAGE 134 #else // ndef GENERATED_CODE_COVERAGE
142 135
143 static void InitializeCoverage() { 136 static void InitializeCoverage() {
144 } 137 }
145 138
146 139
147 void Debugger::Stop(Instr* instr) { 140 void Debugger::Stop(Instruction* instr) {
148 // Get the stop code. 141 // Get the stop code.
149 uint32_t code = instr->SvcField() & kStopCodeMask; 142 uint32_t code = instr->SvcValue() & kStopCodeMask;
150 // Retrieve the encoded address, which comes just after this stop. 143 // Retrieve the encoded address, which comes just after this stop.
151 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); 144 char* msg = *reinterpret_cast<char**>(sim_->get_pc()
145 + Instruction::kInstrSize);
152 // Update this stop description. 146 // Update this stop description.
153 if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) { 147 if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) {
154 sim_->watched_stops[code].desc = msg; 148 sim_->watched_stops[code].desc = msg;
155 } 149 }
156 PrintF("Simulator hit %s\n", msg); 150 // Print the stop message and code if it is not the default code.
157 sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize); 151 if (code != kMaxStopCode) {
152 PrintF("Simulator hit stop %u: %s\n", code, msg);
153 } else {
154 PrintF("Simulator hit %s\n", msg);
155 }
156 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
158 Debug(); 157 Debug();
159 } 158 }
160 #endif 159 #endif
161 160
162 161
163 int32_t Debugger::GetRegisterValue(int regnum) { 162 int32_t Debugger::GetRegisterValue(int regnum) {
164 if (regnum == kPCRegister) { 163 if (regnum == kPCRegister) {
165 return sim_->get_pc(); 164 return sim_->get_pc();
166 } else { 165 } else {
167 return sim_->get_register(regnum); 166 return sim_->get_register(regnum);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 bool is_double; 204 bool is_double;
206 int regnum = VFPRegisters::Number(desc, &is_double); 205 int regnum = VFPRegisters::Number(desc, &is_double);
207 if (regnum != kNoRegister && is_double) { 206 if (regnum != kNoRegister && is_double) {
208 *value = sim_->get_double_from_d_register(regnum); 207 *value = sim_->get_double_from_d_register(regnum);
209 return true; 208 return true;
210 } 209 }
211 return false; 210 return false;
212 } 211 }
213 212
214 213
215 bool Debugger::SetBreakpoint(Instr* breakpc) { 214 bool Debugger::SetBreakpoint(Instruction* breakpc) {
216 // Check if a breakpoint can be set. If not return without any side-effects. 215 // Check if a breakpoint can be set. If not return without any side-effects.
217 if (sim_->break_pc_ != NULL) { 216 if (sim_->break_pc_ != NULL) {
218 return false; 217 return false;
219 } 218 }
220 219
221 // Set the breakpoint. 220 // Set the breakpoint.
222 sim_->break_pc_ = breakpc; 221 sim_->break_pc_ = breakpc;
223 sim_->break_instr_ = breakpc->InstructionBits(); 222 sim_->break_instr_ = breakpc->InstructionBits();
224 // Not setting the breakpoint instruction in the code itself. It will be set 223 // Not setting the breakpoint instruction in the code itself. It will be set
225 // when the debugger shell continues. 224 // when the debugger shell continues.
226 return true; 225 return true;
227 } 226 }
228 227
229 228
230 bool Debugger::DeleteBreakpoint(Instr* breakpc) { 229 bool Debugger::DeleteBreakpoint(Instruction* breakpc) {
231 if (sim_->break_pc_ != NULL) { 230 if (sim_->break_pc_ != NULL) {
232 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 231 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
233 } 232 }
234 233
235 sim_->break_pc_ = NULL; 234 sim_->break_pc_ = NULL;
236 sim_->break_instr_ = 0; 235 sim_->break_instr_ = 0;
237 return true; 236 return true;
238 } 237 }
239 238
240 239
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 break; 291 break;
293 } else { 292 } else {
294 // Use sscanf to parse the individual parts of the command line. At the 293 // Use sscanf to parse the individual parts of the command line. At the
295 // moment no command expects more than two parameters. 294 // moment no command expects more than two parameters.
296 int argc = SScanF(line, 295 int argc = SScanF(line,
297 "%" XSTR(COMMAND_SIZE) "s " 296 "%" XSTR(COMMAND_SIZE) "s "
298 "%" XSTR(ARG_SIZE) "s " 297 "%" XSTR(ARG_SIZE) "s "
299 "%" XSTR(ARG_SIZE) "s", 298 "%" XSTR(ARG_SIZE) "s",
300 cmd, arg1, arg2); 299 cmd, arg1, arg2);
301 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 300 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
302 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 301 sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
303 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 302 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
304 // Execute the one instruction we broke at with breakpoints disabled. 303 // Execute the one instruction we broke at with breakpoints disabled.
305 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 304 sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
306 // Leave the debugger shell. 305 // Leave the debugger shell.
307 done = true; 306 done = true;
308 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 307 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
309 if (argc == 2) { 308 if (argc == 2) {
310 int32_t value; 309 int32_t value;
311 float svalue; 310 float svalue;
312 double dvalue; 311 double dvalue;
313 if (strcmp(arg1, "all") == 0) { 312 if (strcmp(arg1, "all") == 0) {
314 for (int i = 0; i < kNumRegisters; i++) { 313 for (int i = 0; i < kNumRegisters; i++) {
315 value = GetRegisterValue(i); 314 value = GetRegisterValue(i);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 disasm::Disassembler dasm(converter); 389 disasm::Disassembler dasm(converter);
391 // use a reasonably large buffer 390 // use a reasonably large buffer
392 v8::internal::EmbeddedVector<char, 256> buffer; 391 v8::internal::EmbeddedVector<char, 256> buffer;
393 392
394 byte* prev = NULL; 393 byte* prev = NULL;
395 byte* cur = NULL; 394 byte* cur = NULL;
396 byte* end = NULL; 395 byte* end = NULL;
397 396
398 if (argc == 1) { 397 if (argc == 1) {
399 cur = reinterpret_cast<byte*>(sim_->get_pc()); 398 cur = reinterpret_cast<byte*>(sim_->get_pc());
400 end = cur + (10 * Instr::kInstrSize); 399 end = cur + (10 * Instruction::kInstrSize);
401 } else if (argc == 2) { 400 } else if (argc == 2) {
402 int32_t value; 401 int32_t value;
403 if (GetValue(arg1, &value)) { 402 if (GetValue(arg1, &value)) {
404 cur = reinterpret_cast<byte*>(sim_->get_pc()); 403 cur = reinterpret_cast<byte*>(sim_->get_pc());
405 // Disassemble <arg1> instructions. 404 // Disassemble <arg1> instructions.
406 end = cur + (value * Instr::kInstrSize); 405 end = cur + (value * Instruction::kInstrSize);
407 } 406 }
408 } else { 407 } else {
409 int32_t value1; 408 int32_t value1;
410 int32_t value2; 409 int32_t value2;
411 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 410 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
412 cur = reinterpret_cast<byte*>(value1); 411 cur = reinterpret_cast<byte*>(value1);
413 end = cur + (value2 * Instr::kInstrSize); 412 end = cur + (value2 * Instruction::kInstrSize);
414 } 413 }
415 } 414 }
416 415
417 while (cur < end) { 416 while (cur < end) {
418 prev = cur; 417 prev = cur;
419 cur += dasm.InstructionDecode(buffer, cur); 418 cur += dasm.InstructionDecode(buffer, cur);
420 PrintF(" 0x%08x %s\n", 419 PrintF(" 0x%08x %s\n",
421 reinterpret_cast<intptr_t>(prev), buffer.start()); 420 reinterpret_cast<intptr_t>(prev), buffer.start());
422 } 421 }
423 } else if (strcmp(cmd, "gdb") == 0) { 422 } else if (strcmp(cmd, "gdb") == 0) {
424 PrintF("relinquishing control to gdb\n"); 423 PrintF("relinquishing control to gdb\n");
425 v8::internal::OS::DebugBreak(); 424 v8::internal::OS::DebugBreak();
426 PrintF("regaining control from gdb\n"); 425 PrintF("regaining control from gdb\n");
427 } else if (strcmp(cmd, "break") == 0) { 426 } else if (strcmp(cmd, "break") == 0) {
428 if (argc == 2) { 427 if (argc == 2) {
429 int32_t value; 428 int32_t value;
430 if (GetValue(arg1, &value)) { 429 if (GetValue(arg1, &value)) {
431 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) { 430 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
432 PrintF("setting breakpoint failed\n"); 431 PrintF("setting breakpoint failed\n");
433 } 432 }
434 } else { 433 } else {
435 PrintF("%s unrecognized\n", arg1); 434 PrintF("%s unrecognized\n", arg1);
436 } 435 }
437 } else { 436 } else {
438 PrintF("break <address>\n"); 437 PrintF("break <address>\n");
439 } 438 }
440 } else if (strcmp(cmd, "del") == 0) { 439 } else if (strcmp(cmd, "del") == 0) {
441 if (!DeleteBreakpoint(NULL)) { 440 if (!DeleteBreakpoint(NULL)) {
442 PrintF("deleting breakpoint failed\n"); 441 PrintF("deleting breakpoint failed\n");
443 } 442 }
444 } else if (strcmp(cmd, "flags") == 0) { 443 } else if (strcmp(cmd, "flags") == 0) {
445 PrintF("N flag: %d; ", sim_->n_flag_); 444 PrintF("N flag: %d; ", sim_->n_flag_);
446 PrintF("Z flag: %d; ", sim_->z_flag_); 445 PrintF("Z flag: %d; ", sim_->z_flag_);
447 PrintF("C flag: %d; ", sim_->c_flag_); 446 PrintF("C flag: %d; ", sim_->c_flag_);
448 PrintF("V flag: %d\n", sim_->v_flag_); 447 PrintF("V flag: %d\n", sim_->v_flag_);
449 PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_); 448 PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_);
450 PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_); 449 PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_);
451 PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_); 450 PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
452 PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_); 451 PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
453 PrintF("INEXACT flag: %d; ", sim_->inexact_vfp_flag_); 452 PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_);
454 } else if (strcmp(cmd, "stop") == 0) { 453 } else if (strcmp(cmd, "stop") == 0) {
455 int32_t value; 454 int32_t value;
456 intptr_t stop_pc = sim_->get_pc() - 2 * Instr::kInstrSize; 455 intptr_t stop_pc = sim_->get_pc() - 2 * Instruction::kInstrSize;
457 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 456 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
458 Instr* msg_address = 457 Instruction* msg_address =
459 reinterpret_cast<Instr*>(stop_pc + Instr::kInstrSize); 458 reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
460 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) { 459 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
461 // Remove the current stop. 460 // Remove the current stop.
462 if (sim_->isStopInstruction(stop_instr)) { 461 if (sim_->isStopInstruction(stop_instr)) {
463 stop_instr->SetInstructionBits(kNopInstr); 462 stop_instr->SetInstructionBits(kNopInstr);
464 msg_address->SetInstructionBits(kNopInstr); 463 msg_address->SetInstructionBits(kNopInstr);
465 } else { 464 } else {
466 PrintF("Not at debugger stop.\n"); 465 PrintF("Not at debugger stop.\n");
467 } 466 }
468 } else if (argc == 3) { 467 } else if (argc == 3) {
469 // Print information about all/the specified breakpoint(s). 468 // Print information about all/the specified breakpoint(s).
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 ASSERT((start & CachePage::kLineMask) == 0); 633 ASSERT((start & CachePage::kLineMask) == 0);
635 ASSERT((size & CachePage::kLineMask) == 0); 634 ASSERT((size & CachePage::kLineMask) == 0);
636 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); 635 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
637 int offset = (start & CachePage::kPageMask); 636 int offset = (start & CachePage::kPageMask);
638 CachePage* cache_page = GetCachePage(page); 637 CachePage* cache_page = GetCachePage(page);
639 char* valid_bytemap = cache_page->ValidityByte(offset); 638 char* valid_bytemap = cache_page->ValidityByte(offset);
640 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); 639 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
641 } 640 }
642 641
643 642
644 void Simulator::CheckICache(Instr* instr) { 643 void Simulator::CheckICache(Instruction* instr) {
645 intptr_t address = reinterpret_cast<intptr_t>(instr); 644 intptr_t address = reinterpret_cast<intptr_t>(instr);
646 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); 645 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
647 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); 646 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
648 int offset = (address & CachePage::kPageMask); 647 int offset = (address & CachePage::kPageMask);
649 CachePage* cache_page = GetCachePage(page); 648 CachePage* cache_page = GetCachePage(page);
650 char* cache_valid_byte = cache_page->ValidityByte(offset); 649 char* cache_valid_byte = cache_page->ValidityByte(offset);
651 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); 650 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
652 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); 651 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
653 if (cache_hit) { 652 if (cache_hit) {
654 // Check that the data in memory matches the contents of the I-cache. 653 // Check that the data in memory matches the contents of the I-cache.
655 CHECK(memcmp(reinterpret_cast<void*>(instr), 654 CHECK(memcmp(reinterpret_cast<void*>(instr),
656 cache_page->CachedData(offset), 655 cache_page->CachedData(offset),
657 Instr::kInstrSize) == 0); 656 Instruction::kInstrSize) == 0);
658 } else { 657 } else {
659 // Cache miss. Load memory into the cache. 658 // Cache miss. Load memory into the cache.
660 memcpy(cached_line, line, CachePage::kLineLength); 659 memcpy(cached_line, line, CachePage::kLineLength);
661 *cache_valid_byte = CachePage::LINE_VALID; 660 *cache_valid_byte = CachePage::LINE_VALID;
662 } 661 }
663 } 662 }
664 663
665 664
666 // Create one simulator per thread and keep it in thread local storage. 665 // Create one simulator per thread and keep it in thread local storage.
667 static v8::internal::Thread::LocalStorageKey simulator_key; 666 static v8::internal::Thread::LocalStorageKey simulator_key;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 737
739 // When the generated code calls an external reference we need to catch that in 738 // When the generated code calls an external reference we need to catch that in
740 // the simulator. The external reference will be a function compiled for the 739 // the simulator. The external reference will be a function compiled for the
741 // host architecture. We need to call that function instead of trying to 740 // host architecture. We need to call that function instead of trying to
742 // execute it with the simulator. We do that by redirecting the external 741 // execute it with the simulator. We do that by redirecting the external
743 // reference to a svc (Supervisor Call) instruction that is handled by 742 // reference to a svc (Supervisor Call) instruction that is handled by
744 // the simulator. We write the original destination of the jump just at a known 743 // the simulator. We write the original destination of the jump just at a known
745 // offset from the svc instruction so the simulator knows what to call. 744 // offset from the svc instruction so the simulator knows what to call.
746 class Redirection { 745 class Redirection {
747 public: 746 public:
748 Redirection(void* external_function, bool fp_return) 747 Redirection(void* external_function, ExternalReference::Type type)
749 : external_function_(external_function), 748 : external_function_(external_function),
750 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 749 swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
751 fp_return_(fp_return), 750 type_(type),
752 next_(list_) { 751 next_(list_) {
753 Simulator::current()-> 752 Simulator::current()->
754 FlushICache(reinterpret_cast<void*>(&swi_instruction_), 753 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
755 Instr::kInstrSize); 754 Instruction::kInstrSize);
756 list_ = this; 755 list_ = this;
757 } 756 }
758 757
759 void* address_of_swi_instruction() { 758 void* address_of_swi_instruction() {
760 return reinterpret_cast<void*>(&swi_instruction_); 759 return reinterpret_cast<void*>(&swi_instruction_);
761 } 760 }
762 761
763 void* external_function() { return external_function_; } 762 void* external_function() { return external_function_; }
764 bool fp_return() { return fp_return_; } 763 ExternalReference::Type type() { return type_; }
765 764
766 static Redirection* Get(void* external_function, bool fp_return) { 765 static Redirection* Get(void* external_function,
766 ExternalReference::Type type) {
767 Redirection* current; 767 Redirection* current;
768 for (current = list_; current != NULL; current = current->next_) { 768 for (current = list_; current != NULL; current = current->next_) {
769 if (current->external_function_ == external_function) return current; 769 if (current->external_function_ == external_function) return current;
770 } 770 }
771 return new Redirection(external_function, fp_return); 771 return new Redirection(external_function, type);
772 } 772 }
773 773
774 static Redirection* FromSwiInstruction(Instr* swi_instruction) { 774 static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
775 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 775 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
776 char* addr_of_redirection = 776 char* addr_of_redirection =
777 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 777 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
778 return reinterpret_cast<Redirection*>(addr_of_redirection); 778 return reinterpret_cast<Redirection*>(addr_of_redirection);
779 } 779 }
780 780
781 private: 781 private:
782 void* external_function_; 782 void* external_function_;
783 uint32_t swi_instruction_; 783 uint32_t swi_instruction_;
784 bool fp_return_; 784 ExternalReference::Type type_;
785 Redirection* next_; 785 Redirection* next_;
786 static Redirection* list_; 786 static Redirection* list_;
787 }; 787 };
788 788
789 789
790 Redirection* Redirection::list_ = NULL; 790 Redirection* Redirection::list_ = NULL;
791 791
792 792
793 void* Simulator::RedirectExternalReference(void* external_function, 793 void* Simulator::RedirectExternalReference(void* external_function,
794 bool fp_return) { 794 ExternalReference::Type type) {
795 Redirection* redirection = Redirection::Get(external_function, fp_return); 795 Redirection* redirection = Redirection::Get(external_function, type);
796 return redirection->address_of_swi_instruction(); 796 return redirection->address_of_swi_instruction();
797 } 797 }
798 798
799 799
800 // Get the active Simulator for the current thread. 800 // Get the active Simulator for the current thread.
801 Simulator* Simulator::current() { 801 Simulator* Simulator::current() {
802 Initialize(); 802 Initialize();
803 Simulator* sim = reinterpret_cast<Simulator*>( 803 Simulator* sim = reinterpret_cast<Simulator*>(
804 v8::internal::Thread::GetThreadLocal(simulator_key)); 804 v8::internal::Thread::GetThreadLocal(simulator_key));
805 if (sim == NULL) { 805 if (sim == NULL) {
(...skipping 17 matching lines...) Expand all
823 823
824 824
825 // Get the register from the architecture state. This function does handle 825 // Get the register from the architecture state. This function does handle
826 // the special case of accessing the PC register. 826 // the special case of accessing the PC register.
827 int32_t Simulator::get_register(int reg) const { 827 int32_t Simulator::get_register(int reg) const {
828 ASSERT((reg >= 0) && (reg < num_registers)); 828 ASSERT((reg >= 0) && (reg < num_registers));
829 // Stupid code added to avoid bug in GCC. 829 // Stupid code added to avoid bug in GCC.
830 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 830 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
831 if (reg >= num_registers) return 0; 831 if (reg >= num_registers) return 0;
832 // End stupid code. 832 // End stupid code.
833 return registers_[reg] + ((reg == pc) ? Instr::kPCReadOffset : 0); 833 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
834 } 834 }
835 835
836 836
837 void Simulator::set_dw_register(int dreg, const int* dbl) { 837 void Simulator::set_dw_register(int dreg, const int* dbl) {
838 ASSERT((dreg >= 0) && (dreg < num_d_registers)); 838 ASSERT((dreg >= 0) && (dreg < num_d_registers));
839 registers_[dreg] = dbl[0]; 839 registers_[dreg] = dbl[0];
840 registers_[dreg + 1] = dbl[1]; 840 registers_[dreg + 1] = dbl[1];
841 } 841 }
842 842
843 843
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // that don't support unaligned access. 989 // that don't support unaligned access.
990 // Some ARM platforms raise an interrupt on detecting unaligned access. 990 // Some ARM platforms raise an interrupt on detecting unaligned access.
991 // On others it does a funky rotation thing. For now we 991 // On others it does a funky rotation thing. For now we
992 // simply disallow unaligned reads. Note that simulator runs have the runtime 992 // simply disallow unaligned reads. Note that simulator runs have the runtime
993 // system running directly on the host system and only generated code is 993 // system running directly on the host system and only generated code is
994 // executed in the simulator. Since the host is typically IA32 we will not 994 // executed in the simulator. Since the host is typically IA32 we will not
995 // get the correct ARM-like behaviour on unaligned accesses for those ARM 995 // get the correct ARM-like behaviour on unaligned accesses for those ARM
996 // targets that don't support unaligned loads and stores. 996 // targets that don't support unaligned loads and stores.
997 997
998 998
999 int Simulator::ReadW(int32_t addr, Instr* instr) { 999 int Simulator::ReadW(int32_t addr, Instruction* instr) {
1000 #if V8_TARGET_CAN_READ_UNALIGNED 1000 #if V8_TARGET_CAN_READ_UNALIGNED
1001 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1001 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1002 return *ptr; 1002 return *ptr;
1003 #else 1003 #else
1004 if ((addr & 3) == 0) { 1004 if ((addr & 3) == 0) {
1005 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1005 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1006 return *ptr; 1006 return *ptr;
1007 } 1007 }
1008 PrintF("Unaligned read at 0x%08x, pc=%p\n", addr, instr); 1008 PrintF("Unaligned read at 0x%08x, pc=%p\n", addr, instr);
1009 UNIMPLEMENTED(); 1009 UNIMPLEMENTED();
1010 return 0; 1010 return 0;
1011 #endif 1011 #endif
1012 } 1012 }
1013 1013
1014 1014
1015 void Simulator::WriteW(int32_t addr, int value, Instr* instr) { 1015 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
1016 #if V8_TARGET_CAN_READ_UNALIGNED 1016 #if V8_TARGET_CAN_READ_UNALIGNED
1017 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1017 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1018 *ptr = value; 1018 *ptr = value;
1019 return; 1019 return;
1020 #else 1020 #else
1021 if ((addr & 3) == 0) { 1021 if ((addr & 3) == 0) {
1022 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1022 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1023 *ptr = value; 1023 *ptr = value;
1024 return; 1024 return;
1025 } 1025 }
1026 PrintF("Unaligned write at 0x%08x, pc=%p\n", addr, instr); 1026 PrintF("Unaligned write at 0x%08x, pc=%p\n", addr, instr);
1027 UNIMPLEMENTED(); 1027 UNIMPLEMENTED();
1028 #endif 1028 #endif
1029 } 1029 }
1030 1030
1031 1031
1032 uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) { 1032 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
1033 #if V8_TARGET_CAN_READ_UNALIGNED 1033 #if V8_TARGET_CAN_READ_UNALIGNED
1034 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1034 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1035 return *ptr; 1035 return *ptr;
1036 #else 1036 #else
1037 if ((addr & 1) == 0) { 1037 if ((addr & 1) == 0) {
1038 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1038 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1039 return *ptr; 1039 return *ptr;
1040 } 1040 }
1041 PrintF("Unaligned unsigned halfword read at 0x%08x, pc=%p\n", addr, instr); 1041 PrintF("Unaligned unsigned halfword read at 0x%08x, pc=%p\n", addr, instr);
1042 UNIMPLEMENTED(); 1042 UNIMPLEMENTED();
1043 return 0; 1043 return 0;
1044 #endif 1044 #endif
1045 } 1045 }
1046 1046
1047 1047
1048 int16_t Simulator::ReadH(int32_t addr, Instr* instr) { 1048 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
1049 #if V8_TARGET_CAN_READ_UNALIGNED 1049 #if V8_TARGET_CAN_READ_UNALIGNED
1050 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1050 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1051 return *ptr; 1051 return *ptr;
1052 #else 1052 #else
1053 if ((addr & 1) == 0) { 1053 if ((addr & 1) == 0) {
1054 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1054 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1055 return *ptr; 1055 return *ptr;
1056 } 1056 }
1057 PrintF("Unaligned signed halfword read at 0x%08x\n", addr); 1057 PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
1058 UNIMPLEMENTED(); 1058 UNIMPLEMENTED();
1059 return 0; 1059 return 0;
1060 #endif 1060 #endif
1061 } 1061 }
1062 1062
1063 1063
1064 void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) { 1064 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
1065 #if V8_TARGET_CAN_READ_UNALIGNED 1065 #if V8_TARGET_CAN_READ_UNALIGNED
1066 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1066 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1067 *ptr = value; 1067 *ptr = value;
1068 return; 1068 return;
1069 #else 1069 #else
1070 if ((addr & 1) == 0) { 1070 if ((addr & 1) == 0) {
1071 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1071 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1072 *ptr = value; 1072 *ptr = value;
1073 return; 1073 return;
1074 } 1074 }
1075 PrintF("Unaligned unsigned halfword write at 0x%08x, pc=%p\n", addr, instr); 1075 PrintF("Unaligned unsigned halfword write at 0x%08x, pc=%p\n", addr, instr);
1076 UNIMPLEMENTED(); 1076 UNIMPLEMENTED();
1077 #endif 1077 #endif
1078 } 1078 }
1079 1079
1080 1080
1081 void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) { 1081 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
1082 #if V8_TARGET_CAN_READ_UNALIGNED 1082 #if V8_TARGET_CAN_READ_UNALIGNED
1083 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1083 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1084 *ptr = value; 1084 *ptr = value;
1085 return; 1085 return;
1086 #else 1086 #else
1087 if ((addr & 1) == 0) { 1087 if ((addr & 1) == 0) {
1088 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1088 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1089 *ptr = value; 1089 *ptr = value;
1090 return; 1090 return;
1091 } 1091 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 1156
1157 // Returns the limit of the stack area to enable checking for stack overflows. 1157 // Returns the limit of the stack area to enable checking for stack overflows.
1158 uintptr_t Simulator::StackLimit() const { 1158 uintptr_t Simulator::StackLimit() const {
1159 // Leave a safety margin of 256 bytes to prevent overrunning the stack when 1159 // Leave a safety margin of 256 bytes to prevent overrunning the stack when
1160 // pushing values. 1160 // pushing values.
1161 return reinterpret_cast<uintptr_t>(stack_) + 256; 1161 return reinterpret_cast<uintptr_t>(stack_) + 256;
1162 } 1162 }
1163 1163
1164 1164
1165 // Unsupported instructions use Format to print an error and stop execution. 1165 // Unsupported instructions use Format to print an error and stop execution.
1166 void Simulator::Format(Instr* instr, const char* format) { 1166 void Simulator::Format(Instruction* instr, const char* format) {
1167 PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n", 1167 PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
1168 reinterpret_cast<intptr_t>(instr), format); 1168 reinterpret_cast<intptr_t>(instr), format);
1169 UNIMPLEMENTED(); 1169 UNIMPLEMENTED();
1170 } 1170 }
1171 1171
1172 1172
1173 // Checks if the current instruction should be executed based on its 1173 // Checks if the current instruction should be executed based on its
1174 // condition bits. 1174 // condition bits.
1175 bool Simulator::ConditionallyExecute(Instr* instr) { 1175 bool Simulator::ConditionallyExecute(Instruction* instr) {
1176 switch (instr->ConditionField()) { 1176 switch (instr->ConditionField()) {
1177 case EQ: return z_flag_; 1177 case eq: return z_flag_;
1178 case NE: return !z_flag_; 1178 case ne: return !z_flag_;
1179 case CS: return c_flag_; 1179 case cs: return c_flag_;
1180 case CC: return !c_flag_; 1180 case cc: return !c_flag_;
1181 case MI: return n_flag_; 1181 case mi: return n_flag_;
1182 case PL: return !n_flag_; 1182 case pl: return !n_flag_;
1183 case VS: return v_flag_; 1183 case vs: return v_flag_;
1184 case VC: return !v_flag_; 1184 case vc: return !v_flag_;
1185 case HI: return c_flag_ && !z_flag_; 1185 case hi: return c_flag_ && !z_flag_;
1186 case LS: return !c_flag_ || z_flag_; 1186 case ls: return !c_flag_ || z_flag_;
1187 case GE: return n_flag_ == v_flag_; 1187 case ge: return n_flag_ == v_flag_;
1188 case LT: return n_flag_ != v_flag_; 1188 case lt: return n_flag_ != v_flag_;
1189 case GT: return !z_flag_ && (n_flag_ == v_flag_); 1189 case gt: return !z_flag_ && (n_flag_ == v_flag_);
1190 case LE: return z_flag_ || (n_flag_ != v_flag_); 1190 case le: return z_flag_ || (n_flag_ != v_flag_);
1191 case AL: return true; 1191 case al: return true;
1192 default: UNREACHABLE(); 1192 default: UNREACHABLE();
1193 } 1193 }
1194 return false; 1194 return false;
1195 } 1195 }
1196 1196
1197 1197
1198 // Calculate and set the Negative and Zero flags. 1198 // Calculate and set the Negative and Zero flags.
1199 void Simulator::SetNZFlags(int32_t val) { 1199 void Simulator::SetNZFlags(int32_t val) {
1200 n_flag_ = (val < 0); 1200 n_flag_ = (val < 0);
1201 z_flag_ = (val == 0); 1201 z_flag_ = (val == 0);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 void Simulator::Copy_FPSCR_to_APSR() { 1283 void Simulator::Copy_FPSCR_to_APSR() {
1284 n_flag_ = n_flag_FPSCR_; 1284 n_flag_ = n_flag_FPSCR_;
1285 z_flag_ = z_flag_FPSCR_; 1285 z_flag_ = z_flag_FPSCR_;
1286 c_flag_ = c_flag_FPSCR_; 1286 c_flag_ = c_flag_FPSCR_;
1287 v_flag_ = v_flag_FPSCR_; 1287 v_flag_ = v_flag_FPSCR_;
1288 } 1288 }
1289 1289
1290 1290
1291 // Addressing Mode 1 - Data-processing operands: 1291 // Addressing Mode 1 - Data-processing operands:
1292 // Get the value based on the shifter_operand with register. 1292 // Get the value based on the shifter_operand with register.
1293 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) { 1293 int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
1294 Shift shift = instr->ShiftField(); 1294 ShiftOp shift = instr->ShiftField();
1295 int shift_amount = instr->ShiftAmountField(); 1295 int shift_amount = instr->ShiftAmountValue();
1296 int32_t result = get_register(instr->RmField()); 1296 int32_t result = get_register(instr->RmValue());
1297 if (instr->Bit(4) == 0) { 1297 if (instr->Bit(4) == 0) {
1298 // by immediate 1298 // by immediate
1299 if ((shift == ROR) && (shift_amount == 0)) { 1299 if ((shift == ROR) && (shift_amount == 0)) {
1300 UNIMPLEMENTED(); 1300 UNIMPLEMENTED();
1301 return result; 1301 return result;
1302 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { 1302 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
1303 shift_amount = 32; 1303 shift_amount = 32;
1304 } 1304 }
1305 switch (shift) { 1305 switch (shift) {
1306 case ASR: { 1306 case ASR: {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 break; 1350 break;
1351 } 1351 }
1352 1352
1353 default: { 1353 default: {
1354 UNREACHABLE(); 1354 UNREACHABLE();
1355 break; 1355 break;
1356 } 1356 }
1357 } 1357 }
1358 } else { 1358 } else {
1359 // by register 1359 // by register
1360 int rs = instr->RsField(); 1360 int rs = instr->RsValue();
1361 shift_amount = get_register(rs) &0xff; 1361 shift_amount = get_register(rs) &0xff;
1362 switch (shift) { 1362 switch (shift) {
1363 case ASR: { 1363 case ASR: {
1364 if (shift_amount == 0) { 1364 if (shift_amount == 0) {
1365 *carry_out = c_flag_; 1365 *carry_out = c_flag_;
1366 } else if (shift_amount < 32) { 1366 } else if (shift_amount < 32) {
1367 result >>= (shift_amount - 1); 1367 result >>= (shift_amount - 1);
1368 *carry_out = (result & 1) == 1; 1368 *carry_out = (result & 1) == 1;
1369 result >>= 1; 1369 result >>= 1;
1370 } else { 1370 } else {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 break; 1427 break;
1428 } 1428 }
1429 } 1429 }
1430 } 1430 }
1431 return result; 1431 return result;
1432 } 1432 }
1433 1433
1434 1434
1435 // Addressing Mode 1 - Data-processing operands: 1435 // Addressing Mode 1 - Data-processing operands:
1436 // Get the value based on the shifter_operand with immediate. 1436 // Get the value based on the shifter_operand with immediate.
1437 int32_t Simulator::GetImm(Instr* instr, bool* carry_out) { 1437 int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
1438 int rotate = instr->RotateField() * 2; 1438 int rotate = instr->RotateValue() * 2;
1439 int immed8 = instr->Immed8Field(); 1439 int immed8 = instr->Immed8Value();
1440 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 1440 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
1441 *carry_out = (rotate == 0) ? c_flag_ : (imm < 0); 1441 *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
1442 return imm; 1442 return imm;
1443 } 1443 }
1444 1444
1445 1445
1446 static int count_bits(int bit_vector) { 1446 static int count_bits(int bit_vector) {
1447 int count = 0; 1447 int count = 0;
1448 while (bit_vector != 0) { 1448 while (bit_vector != 0) {
1449 if ((bit_vector & 1) != 0) { 1449 if ((bit_vector & 1) != 0) {
1450 count++; 1450 count++;
1451 } 1451 }
1452 bit_vector >>= 1; 1452 bit_vector >>= 1;
1453 } 1453 }
1454 return count; 1454 return count;
1455 } 1455 }
1456 1456
1457 1457
1458 // Addressing Mode 4 - Load and Store Multiple 1458 // Addressing Mode 4 - Load and Store Multiple
1459 void Simulator::HandleRList(Instr* instr, bool load) { 1459 void Simulator::HandleRList(Instruction* instr, bool load) {
1460 int rn = instr->RnField(); 1460 int rn = instr->RnValue();
1461 int32_t rn_val = get_register(rn); 1461 int32_t rn_val = get_register(rn);
1462 int rlist = instr->RlistField(); 1462 int rlist = instr->RlistValue();
1463 int num_regs = count_bits(rlist); 1463 int num_regs = count_bits(rlist);
1464 1464
1465 intptr_t start_address = 0; 1465 intptr_t start_address = 0;
1466 intptr_t end_address = 0; 1466 intptr_t end_address = 0;
1467 switch (instr->PUField()) { 1467 switch (instr->PUField()) {
1468 case 0: { 1468 case da_x: {
1469 // Print("da");
1470 UNIMPLEMENTED(); 1469 UNIMPLEMENTED();
1471 break; 1470 break;
1472 } 1471 }
1473 case 1: { 1472 case ia_x: {
1474 // Print("ia");
1475 start_address = rn_val; 1473 start_address = rn_val;
1476 end_address = rn_val + (num_regs * 4) - 4; 1474 end_address = rn_val + (num_regs * 4) - 4;
1477 rn_val = rn_val + (num_regs * 4); 1475 rn_val = rn_val + (num_regs * 4);
1478 break; 1476 break;
1479 } 1477 }
1480 case 2: { 1478 case db_x: {
1481 // Print("db");
1482 start_address = rn_val - (num_regs * 4); 1479 start_address = rn_val - (num_regs * 4);
1483 end_address = rn_val - 4; 1480 end_address = rn_val - 4;
1484 rn_val = start_address; 1481 rn_val = start_address;
1485 break; 1482 break;
1486 } 1483 }
1487 case 3: { 1484 case ib_x: {
1488 // Print("ib");
1489 start_address = rn_val + 4; 1485 start_address = rn_val + 4;
1490 end_address = rn_val + (num_regs * 4); 1486 end_address = rn_val + (num_regs * 4);
1491 rn_val = end_address; 1487 rn_val = end_address;
1492 break; 1488 break;
1493 } 1489 }
1494 default: { 1490 default: {
1495 UNREACHABLE(); 1491 UNREACHABLE();
1496 break; 1492 break;
1497 } 1493 }
1498 } 1494 }
(...skipping 27 matching lines...) Expand all
1526 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1522 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1527 int32_t arg1, 1523 int32_t arg1,
1528 int32_t arg2, 1524 int32_t arg2,
1529 int32_t arg3, 1525 int32_t arg3,
1530 int32_t arg4); 1526 int32_t arg4);
1531 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, 1527 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
1532 int32_t arg1, 1528 int32_t arg1,
1533 int32_t arg2, 1529 int32_t arg2,
1534 int32_t arg3); 1530 int32_t arg3);
1535 1531
1532 // This signature supports direct call in to API function native callback
1533 // (refer to InvocationCallback in v8.h).
1534 typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0);
1536 1535
1537 // Software interrupt instructions are used by the simulator to call into the 1536 // Software interrupt instructions are used by the simulator to call into the
1538 // C-based V8 runtime. 1537 // C-based V8 runtime.
1539 void Simulator::SoftwareInterrupt(Instr* instr) { 1538 void Simulator::SoftwareInterrupt(Instruction* instr) {
1540 int svc = instr->SvcField(); 1539 int svc = instr->SvcValue();
1541 switch (svc) { 1540 switch (svc) {
1542 case call_rt_redirected: { 1541 case kCallRtRedirected: {
1543 // Check if stack is aligned. Error if not aligned is reported below to 1542 // Check if stack is aligned. Error if not aligned is reported below to
1544 // include information on the function called. 1543 // include information on the function called.
1545 bool stack_aligned = 1544 bool stack_aligned =
1546 (get_register(sp) 1545 (get_register(sp)
1547 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; 1546 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
1548 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1547 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1549 int32_t arg0 = get_register(r0); 1548 int32_t arg0 = get_register(r0);
1550 int32_t arg1 = get_register(r1); 1549 int32_t arg1 = get_register(r1);
1551 int32_t arg2 = get_register(r2); 1550 int32_t arg2 = get_register(r2);
1552 int32_t arg3 = get_register(r3); 1551 int32_t arg3 = get_register(r3);
1553 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1552 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1554 int32_t arg4 = *stack_pointer; 1553 int32_t arg4 = *stack_pointer;
1555 // This is dodgy but it works because the C entry stubs are never moved. 1554 // This is dodgy but it works because the C entry stubs are never moved.
1556 // See comment in codegen-arm.cc and bug 1242173. 1555 // See comment in codegen-arm.cc and bug 1242173.
1557 int32_t saved_lr = get_register(lr); 1556 int32_t saved_lr = get_register(lr);
1558 if (redirection->fp_return()) { 1557 intptr_t external =
1559 intptr_t external = 1558 reinterpret_cast<intptr_t>(redirection->external_function());
1560 reinterpret_cast<intptr_t>(redirection->external_function()); 1559 if (redirection->type() == ExternalReference::FP_RETURN_CALL) {
1561 SimulatorRuntimeFPCall target = 1560 SimulatorRuntimeFPCall target =
1562 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1561 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1563 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1562 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1564 double x, y; 1563 double x, y;
1565 GetFpArgs(&x, &y); 1564 GetFpArgs(&x, &y);
1566 PrintF("Call to host function at %p with args %f, %f", 1565 PrintF("Call to host function at %p with args %f, %f",
1567 FUNCTION_ADDR(target), x, y); 1566 FUNCTION_ADDR(target), x, y);
1568 if (!stack_aligned) { 1567 if (!stack_aligned) {
1569 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1568 PrintF(" with unaligned stack %08x\n", get_register(sp));
1570 } 1569 }
1571 PrintF("\n"); 1570 PrintF("\n");
1572 } 1571 }
1573 CHECK(stack_aligned); 1572 CHECK(stack_aligned);
1574 double result = target(arg0, arg1, arg2, arg3); 1573 double result = target(arg0, arg1, arg2, arg3);
1575 SetFpResult(result); 1574 SetFpResult(result);
1575 } else if (redirection->type() == ExternalReference::DIRECT_CALL) {
1576 SimulatorRuntimeApiCall target =
1577 reinterpret_cast<SimulatorRuntimeApiCall>(external);
1578 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1579 PrintF(
1580 "Call to host function at %p args %08x",
1581 FUNCTION_ADDR(target),
1582 arg0);
1583 if (!stack_aligned) {
1584 PrintF(" with unaligned stack %08x\n", get_register(sp));
1585 }
1586 PrintF("\n");
1587 }
1588 CHECK(stack_aligned);
1589 v8::Handle<v8::Value> result = target(arg0);
1590 if (::v8::internal::FLAG_trace_sim) {
1591 PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1592 }
1593 set_register(r0, (int32_t) *result);
1576 } else { 1594 } else {
1577 intptr_t external = 1595 // builtin call.
1578 reinterpret_cast<int32_t>(redirection->external_function()); 1596 ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
1579 SimulatorRuntimeCall target = 1597 SimulatorRuntimeCall target =
1580 reinterpret_cast<SimulatorRuntimeCall>(external); 1598 reinterpret_cast<SimulatorRuntimeCall>(external);
1581 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1599 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1582 PrintF( 1600 PrintF(
1583 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc", 1601 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc",
1584 FUNCTION_ADDR(target), 1602 FUNCTION_ADDR(target),
1585 arg0, 1603 arg0,
1586 arg1, 1604 arg1,
1587 arg2, 1605 arg2,
1588 arg3, 1606 arg3,
(...skipping 10 matching lines...) Expand all
1599 if (::v8::internal::FLAG_trace_sim) { 1617 if (::v8::internal::FLAG_trace_sim) {
1600 PrintF("Returned %08x\n", lo_res); 1618 PrintF("Returned %08x\n", lo_res);
1601 } 1619 }
1602 set_register(r0, lo_res); 1620 set_register(r0, lo_res);
1603 set_register(r1, hi_res); 1621 set_register(r1, hi_res);
1604 } 1622 }
1605 set_register(lr, saved_lr); 1623 set_register(lr, saved_lr);
1606 set_pc(get_register(lr)); 1624 set_pc(get_register(lr));
1607 break; 1625 break;
1608 } 1626 }
1609 case break_point: { 1627 case kBreakpoint: {
1610 Debugger dbg(this); 1628 Debugger dbg(this);
1611 dbg.Debug(); 1629 dbg.Debug();
1612 break; 1630 break;
1613 } 1631 }
1614 // stop uses all codes greater than 1 << 23. 1632 // stop uses all codes greater than 1 << 23.
1615 default: { 1633 default: {
1616 if (svc >= (1 << 23)) { 1634 if (svc >= (1 << 23)) {
1617 uint32_t code = svc & kStopCodeMask; 1635 uint32_t code = svc & kStopCodeMask;
1618 if (isWatchedStop(code)) { 1636 if (isWatchedStop(code)) {
1619 IncreaseStopCounter(code); 1637 IncreaseStopCounter(code);
1620 } 1638 }
1621 // Stop if it is enabled, otherwise go on jumping over the stop 1639 // Stop if it is enabled, otherwise go on jumping over the stop
1622 // and the message address. 1640 // and the message address.
1623 if (isEnabledStop(code)) { 1641 if (isEnabledStop(code)) {
1624 Debugger dbg(this); 1642 Debugger dbg(this);
1625 dbg.Stop(instr); 1643 dbg.Stop(instr);
1626 } else { 1644 } else {
1627 set_pc(get_pc() + 2 * Instr::kInstrSize); 1645 set_pc(get_pc() + 2 * Instruction::kInstrSize);
1628 } 1646 }
1629 } else { 1647 } else {
1630 // This is not a valid svc code. 1648 // This is not a valid svc code.
1631 UNREACHABLE(); 1649 UNREACHABLE();
1632 break; 1650 break;
1633 } 1651 }
1634 } 1652 }
1635 } 1653 }
1636 } 1654 }
1637 1655
1638 1656
1639 // Stop helper functions. 1657 // Stop helper functions.
1640 bool Simulator::isStopInstruction(Instr* instr) { 1658 bool Simulator::isStopInstruction(Instruction* instr) {
1641 return (instr->Bits(27, 24) == 0xF) && (instr->SvcField() >= stop); 1659 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
1642 } 1660 }
1643 1661
1644 1662
1645 bool Simulator::isWatchedStop(uint32_t code) { 1663 bool Simulator::isWatchedStop(uint32_t code) {
1646 ASSERT(code <= kMaxStopCode); 1664 ASSERT(code <= kMaxStopCode);
1647 return code < kNumOfWatchedStops; 1665 return code < kNumOfWatchedStops;
1648 } 1666 }
1649 1667
1650 1668
1651 bool Simulator::isEnabledStop(uint32_t code) { 1669 bool Simulator::isEnabledStop(uint32_t code) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 } 1723 }
1706 } 1724 }
1707 } 1725 }
1708 } 1726 }
1709 1727
1710 1728
1711 // Handle execution based on instruction types. 1729 // Handle execution based on instruction types.
1712 1730
1713 // Instruction types 0 and 1 are both rolled into one function because they 1731 // Instruction types 0 and 1 are both rolled into one function because they
1714 // only differ in the handling of the shifter_operand. 1732 // only differ in the handling of the shifter_operand.
1715 void Simulator::DecodeType01(Instr* instr) { 1733 void Simulator::DecodeType01(Instruction* instr) {
1716 int type = instr->TypeField(); 1734 int type = instr->TypeValue();
1717 if ((type == 0) && instr->IsSpecialType0()) { 1735 if ((type == 0) && instr->IsSpecialType0()) {
1718 // multiply instruction or extra loads and stores 1736 // multiply instruction or extra loads and stores
1719 if (instr->Bits(7, 4) == 9) { 1737 if (instr->Bits(7, 4) == 9) {
1720 if (instr->Bit(24) == 0) { 1738 if (instr->Bit(24) == 0) {
1721 // Raw field decoding here. Multiply instructions have their Rd in 1739 // Raw field decoding here. Multiply instructions have their Rd in
1722 // funny places. 1740 // funny places.
1723 int rn = instr->RnField(); 1741 int rn = instr->RnValue();
1724 int rm = instr->RmField(); 1742 int rm = instr->RmValue();
1725 int rs = instr->RsField(); 1743 int rs = instr->RsValue();
1726 int32_t rs_val = get_register(rs); 1744 int32_t rs_val = get_register(rs);
1727 int32_t rm_val = get_register(rm); 1745 int32_t rm_val = get_register(rm);
1728 if (instr->Bit(23) == 0) { 1746 if (instr->Bit(23) == 0) {
1729 if (instr->Bit(21) == 0) { 1747 if (instr->Bit(21) == 0) {
1730 // The MUL instruction description (A 4.1.33) refers to Rd as being 1748 // The MUL instruction description (A 4.1.33) refers to Rd as being
1731 // the destination for the operation, but it confusingly uses the 1749 // the destination for the operation, but it confusingly uses the
1732 // Rn field to encode it. 1750 // Rn field to encode it.
1733 // Format(instr, "mul'cond's 'rn, 'rm, 'rs"); 1751 // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
1734 int rd = rn; // Remap the rn field to the Rd register. 1752 int rd = rn; // Remap the rn field to the Rd register.
1735 int32_t alu_out = rm_val * rs_val; 1753 int32_t alu_out = rm_val * rs_val;
(...skipping 13 matching lines...) Expand all
1749 // when referring to the target registers. They are mapped to the Rn 1767 // when referring to the target registers. They are mapped to the Rn
1750 // and Rd fields as follows: 1768 // and Rd fields as follows:
1751 // RdLo == Rd 1769 // RdLo == Rd
1752 // RdHi == Rn (This is confusingly stored in variable rd here 1770 // RdHi == Rn (This is confusingly stored in variable rd here
1753 // because the mul instruction from above uses the 1771 // because the mul instruction from above uses the
1754 // Rn field to encode the Rd register. Good luck figuring 1772 // Rn field to encode the Rd register. Good luck figuring
1755 // this out without reading the ARM instruction manual 1773 // this out without reading the ARM instruction manual
1756 // at a very detailed level.) 1774 // at a very detailed level.)
1757 // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm"); 1775 // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
1758 int rd_hi = rn; // Remap the rn field to the RdHi register. 1776 int rd_hi = rn; // Remap the rn field to the RdHi register.
1759 int rd_lo = instr->RdField(); 1777 int rd_lo = instr->RdValue();
1760 int32_t hi_res = 0; 1778 int32_t hi_res = 0;
1761 int32_t lo_res = 0; 1779 int32_t lo_res = 0;
1762 if (instr->Bit(22) == 1) { 1780 if (instr->Bit(22) == 1) {
1763 int64_t left_op = static_cast<int32_t>(rm_val); 1781 int64_t left_op = static_cast<int32_t>(rm_val);
1764 int64_t right_op = static_cast<int32_t>(rs_val); 1782 int64_t right_op = static_cast<int32_t>(rs_val);
1765 uint64_t result = left_op * right_op; 1783 uint64_t result = left_op * right_op;
1766 hi_res = static_cast<int32_t>(result >> 32); 1784 hi_res = static_cast<int32_t>(result >> 32);
1767 lo_res = static_cast<int32_t>(result & 0xffffffff); 1785 lo_res = static_cast<int32_t>(result & 0xffffffff);
1768 } else { 1786 } else {
1769 // unsigned multiply 1787 // unsigned multiply
1770 uint64_t left_op = static_cast<uint32_t>(rm_val); 1788 uint64_t left_op = static_cast<uint32_t>(rm_val);
1771 uint64_t right_op = static_cast<uint32_t>(rs_val); 1789 uint64_t right_op = static_cast<uint32_t>(rs_val);
1772 uint64_t result = left_op * right_op; 1790 uint64_t result = left_op * right_op;
1773 hi_res = static_cast<int32_t>(result >> 32); 1791 hi_res = static_cast<int32_t>(result >> 32);
1774 lo_res = static_cast<int32_t>(result & 0xffffffff); 1792 lo_res = static_cast<int32_t>(result & 0xffffffff);
1775 } 1793 }
1776 set_register(rd_lo, lo_res); 1794 set_register(rd_lo, lo_res);
1777 set_register(rd_hi, hi_res); 1795 set_register(rd_hi, hi_res);
1778 if (instr->HasS()) { 1796 if (instr->HasS()) {
1779 UNIMPLEMENTED(); 1797 UNIMPLEMENTED();
1780 } 1798 }
1781 } 1799 }
1782 } else { 1800 } else {
1783 UNIMPLEMENTED(); // Not used by V8. 1801 UNIMPLEMENTED(); // Not used by V8.
1784 } 1802 }
1785 } else { 1803 } else {
1786 // extra load/store instructions 1804 // extra load/store instructions
1787 int rd = instr->RdField(); 1805 int rd = instr->RdValue();
1788 int rn = instr->RnField(); 1806 int rn = instr->RnValue();
1789 int32_t rn_val = get_register(rn); 1807 int32_t rn_val = get_register(rn);
1790 int32_t addr = 0; 1808 int32_t addr = 0;
1791 if (instr->Bit(22) == 0) { 1809 if (instr->Bit(22) == 0) {
1792 int rm = instr->RmField(); 1810 int rm = instr->RmValue();
1793 int32_t rm_val = get_register(rm); 1811 int32_t rm_val = get_register(rm);
1794 switch (instr->PUField()) { 1812 switch (instr->PUField()) {
1795 case 0: { 1813 case da_x: {
1796 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm"); 1814 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
1797 ASSERT(!instr->HasW()); 1815 ASSERT(!instr->HasW());
1798 addr = rn_val; 1816 addr = rn_val;
1799 rn_val -= rm_val; 1817 rn_val -= rm_val;
1800 set_register(rn, rn_val); 1818 set_register(rn, rn_val);
1801 break; 1819 break;
1802 } 1820 }
1803 case 1: { 1821 case ia_x: {
1804 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm"); 1822 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
1805 ASSERT(!instr->HasW()); 1823 ASSERT(!instr->HasW());
1806 addr = rn_val; 1824 addr = rn_val;
1807 rn_val += rm_val; 1825 rn_val += rm_val;
1808 set_register(rn, rn_val); 1826 set_register(rn, rn_val);
1809 break; 1827 break;
1810 } 1828 }
1811 case 2: { 1829 case db_x: {
1812 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w"); 1830 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
1813 rn_val -= rm_val; 1831 rn_val -= rm_val;
1814 addr = rn_val; 1832 addr = rn_val;
1815 if (instr->HasW()) { 1833 if (instr->HasW()) {
1816 set_register(rn, rn_val); 1834 set_register(rn, rn_val);
1817 } 1835 }
1818 break; 1836 break;
1819 } 1837 }
1820 case 3: { 1838 case ib_x: {
1821 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w"); 1839 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
1822 rn_val += rm_val; 1840 rn_val += rm_val;
1823 addr = rn_val; 1841 addr = rn_val;
1824 if (instr->HasW()) { 1842 if (instr->HasW()) {
1825 set_register(rn, rn_val); 1843 set_register(rn, rn_val);
1826 } 1844 }
1827 break; 1845 break;
1828 } 1846 }
1829 default: { 1847 default: {
1830 // The PU field is a 2-bit field. 1848 // The PU field is a 2-bit field.
1831 UNREACHABLE(); 1849 UNREACHABLE();
1832 break; 1850 break;
1833 } 1851 }
1834 } 1852 }
1835 } else { 1853 } else {
1836 int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField(); 1854 int32_t imm_val = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
1837 switch (instr->PUField()) { 1855 switch (instr->PUField()) {
1838 case 0: { 1856 case da_x: {
1839 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8"); 1857 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
1840 ASSERT(!instr->HasW()); 1858 ASSERT(!instr->HasW());
1841 addr = rn_val; 1859 addr = rn_val;
1842 rn_val -= imm_val; 1860 rn_val -= imm_val;
1843 set_register(rn, rn_val); 1861 set_register(rn, rn_val);
1844 break; 1862 break;
1845 } 1863 }
1846 case 1: { 1864 case ia_x: {
1847 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8"); 1865 // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
1848 ASSERT(!instr->HasW()); 1866 ASSERT(!instr->HasW());
1849 addr = rn_val; 1867 addr = rn_val;
1850 rn_val += imm_val; 1868 rn_val += imm_val;
1851 set_register(rn, rn_val); 1869 set_register(rn, rn_val);
1852 break; 1870 break;
1853 } 1871 }
1854 case 2: { 1872 case db_x: {
1855 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w"); 1873 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
1856 rn_val -= imm_val; 1874 rn_val -= imm_val;
1857 addr = rn_val; 1875 addr = rn_val;
1858 if (instr->HasW()) { 1876 if (instr->HasW()) {
1859 set_register(rn, rn_val); 1877 set_register(rn, rn_val);
1860 } 1878 }
1861 break; 1879 break;
1862 } 1880 }
1863 case 3: { 1881 case ib_x: {
1864 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w"); 1882 // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
1865 rn_val += imm_val; 1883 rn_val += imm_val;
1866 addr = rn_val; 1884 addr = rn_val;
1867 if (instr->HasW()) { 1885 if (instr->HasW()) {
1868 set_register(rn, rn_val); 1886 set_register(rn, rn_val);
1869 } 1887 }
1870 break; 1888 break;
1871 } 1889 }
1872 default: { 1890 default: {
1873 // The PU field is a 2-bit field. 1891 // The PU field is a 2-bit field.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 // signed byte loads 1928 // signed byte loads
1911 ASSERT(instr->HasSign()); 1929 ASSERT(instr->HasSign());
1912 ASSERT(instr->HasL()); 1930 ASSERT(instr->HasL());
1913 int8_t val = ReadB(addr); 1931 int8_t val = ReadB(addr);
1914 set_register(rd, val); 1932 set_register(rd, val);
1915 } 1933 }
1916 return; 1934 return;
1917 } 1935 }
1918 } else if ((type == 0) && instr->IsMiscType0()) { 1936 } else if ((type == 0) && instr->IsMiscType0()) {
1919 if (instr->Bits(22, 21) == 1) { 1937 if (instr->Bits(22, 21) == 1) {
1920 int rm = instr->RmField(); 1938 int rm = instr->RmValue();
1921 switch (instr->Bits(7, 4)) { 1939 switch (instr->BitField(7, 4)) {
1922 case BX: 1940 case BX:
1923 set_pc(get_register(rm)); 1941 set_pc(get_register(rm));
1924 break; 1942 break;
1925 case BLX: { 1943 case BLX: {
1926 uint32_t old_pc = get_pc(); 1944 uint32_t old_pc = get_pc();
1927 set_pc(get_register(rm)); 1945 set_pc(get_register(rm));
1928 set_register(lr, old_pc + Instr::kInstrSize); 1946 set_register(lr, old_pc + Instruction::kInstrSize);
1929 break; 1947 break;
1930 } 1948 }
1931 case BKPT: { 1949 case BKPT: {
1932 Debugger dbg(this); 1950 Debugger dbg(this);
1933 PrintF("Simulator hit BKPT.\n"); 1951 PrintF("Simulator hit BKPT.\n");
1934 dbg.Debug(); 1952 dbg.Debug();
1935 break; 1953 break;
1936 } 1954 }
1937 default: 1955 default:
1938 UNIMPLEMENTED(); 1956 UNIMPLEMENTED();
1939 } 1957 }
1940 } else if (instr->Bits(22, 21) == 3) { 1958 } else if (instr->Bits(22, 21) == 3) {
1941 int rm = instr->RmField(); 1959 int rm = instr->RmValue();
1942 int rd = instr->RdField(); 1960 int rd = instr->RdValue();
1943 switch (instr->Bits(7, 4)) { 1961 switch (instr->BitField(7, 4)) {
1944 case CLZ: { 1962 case CLZ: {
1945 uint32_t bits = get_register(rm); 1963 uint32_t bits = get_register(rm);
1946 int leading_zeros = 0; 1964 int leading_zeros = 0;
1947 if (bits == 0) { 1965 if (bits == 0) {
1948 leading_zeros = 32; 1966 leading_zeros = 32;
1949 } else { 1967 } else {
1950 while ((bits & 0x80000000u) == 0) { 1968 while ((bits & 0x80000000u) == 0) {
1951 bits <<= 1; 1969 bits <<= 1;
1952 leading_zeros++; 1970 leading_zeros++;
1953 } 1971 }
1954 } 1972 }
1955 set_register(rd, leading_zeros); 1973 set_register(rd, leading_zeros);
1956 break; 1974 break;
1957 } 1975 }
1958 default: 1976 default:
1959 UNIMPLEMENTED(); 1977 UNIMPLEMENTED();
1960 } 1978 }
1961 } else { 1979 } else {
1962 PrintF("%08x\n", instr->InstructionBits()); 1980 PrintF("%08x\n", instr->InstructionBits());
1963 UNIMPLEMENTED(); 1981 UNIMPLEMENTED();
1964 } 1982 }
1965 } else { 1983 } else {
1966 int rd = instr->RdField(); 1984 int rd = instr->RdValue();
1967 int rn = instr->RnField(); 1985 int rn = instr->RnValue();
1968 int32_t rn_val = get_register(rn); 1986 int32_t rn_val = get_register(rn);
1969 int32_t shifter_operand = 0; 1987 int32_t shifter_operand = 0;
1970 bool shifter_carry_out = 0; 1988 bool shifter_carry_out = 0;
1971 if (type == 0) { 1989 if (type == 0) {
1972 shifter_operand = GetShiftRm(instr, &shifter_carry_out); 1990 shifter_operand = GetShiftRm(instr, &shifter_carry_out);
1973 } else { 1991 } else {
1974 ASSERT(instr->TypeField() == 1); 1992 ASSERT(instr->TypeValue() == 1);
1975 shifter_operand = GetImm(instr, &shifter_carry_out); 1993 shifter_operand = GetImm(instr, &shifter_carry_out);
1976 } 1994 }
1977 int32_t alu_out; 1995 int32_t alu_out;
1978 1996
1979 switch (instr->OpcodeField()) { 1997 switch (instr->OpcodeField()) {
1980 case AND: { 1998 case AND: {
1981 // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm"); 1999 // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
1982 // Format(instr, "and'cond's 'rd, 'rn, 'imm"); 2000 // Format(instr, "and'cond's 'rd, 'rn, 'imm");
1983 alu_out = rn_val & shifter_operand; 2001 alu_out = rn_val & shifter_operand;
1984 set_register(rd, alu_out); 2002 set_register(rd, alu_out);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 2078
2061 case TST: { 2079 case TST: {
2062 if (instr->HasS()) { 2080 if (instr->HasS()) {
2063 // Format(instr, "tst'cond 'rn, 'shift_rm"); 2081 // Format(instr, "tst'cond 'rn, 'shift_rm");
2064 // Format(instr, "tst'cond 'rn, 'imm"); 2082 // Format(instr, "tst'cond 'rn, 'imm");
2065 alu_out = rn_val & shifter_operand; 2083 alu_out = rn_val & shifter_operand;
2066 SetNZFlags(alu_out); 2084 SetNZFlags(alu_out);
2067 SetCFlag(shifter_carry_out); 2085 SetCFlag(shifter_carry_out);
2068 } else { 2086 } else {
2069 // Format(instr, "movw'cond 'rd, 'imm"). 2087 // Format(instr, "movw'cond 'rd, 'imm").
2070 alu_out = instr->ImmedMovwMovtField(); 2088 alu_out = instr->ImmedMovwMovtValue();
2071 set_register(rd, alu_out); 2089 set_register(rd, alu_out);
2072 } 2090 }
2073 break; 2091 break;
2074 } 2092 }
2075 2093
2076 case TEQ: { 2094 case TEQ: {
2077 if (instr->HasS()) { 2095 if (instr->HasS()) {
2078 // Format(instr, "teq'cond 'rn, 'shift_rm"); 2096 // Format(instr, "teq'cond 'rn, 'shift_rm");
2079 // Format(instr, "teq'cond 'rn, 'imm"); 2097 // Format(instr, "teq'cond 'rn, 'imm");
2080 alu_out = rn_val ^ shifter_operand; 2098 alu_out = rn_val ^ shifter_operand;
(...skipping 11 matching lines...) Expand all
2092 if (instr->HasS()) { 2110 if (instr->HasS()) {
2093 // Format(instr, "cmp'cond 'rn, 'shift_rm"); 2111 // Format(instr, "cmp'cond 'rn, 'shift_rm");
2094 // Format(instr, "cmp'cond 'rn, 'imm"); 2112 // Format(instr, "cmp'cond 'rn, 'imm");
2095 alu_out = rn_val - shifter_operand; 2113 alu_out = rn_val - shifter_operand;
2096 SetNZFlags(alu_out); 2114 SetNZFlags(alu_out);
2097 SetCFlag(!BorrowFrom(rn_val, shifter_operand)); 2115 SetCFlag(!BorrowFrom(rn_val, shifter_operand));
2098 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); 2116 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
2099 } else { 2117 } else {
2100 // Format(instr, "movt'cond 'rd, 'imm"). 2118 // Format(instr, "movt'cond 'rd, 'imm").
2101 alu_out = (get_register(rd) & 0xffff) | 2119 alu_out = (get_register(rd) & 0xffff) |
2102 (instr->ImmedMovwMovtField() << 16); 2120 (instr->ImmedMovwMovtValue() << 16);
2103 set_register(rd, alu_out); 2121 set_register(rd, alu_out);
2104 } 2122 }
2105 break; 2123 break;
2106 } 2124 }
2107 2125
2108 case CMN: { 2126 case CMN: {
2109 if (instr->HasS()) { 2127 if (instr->HasS()) {
2110 // Format(instr, "cmn'cond 'rn, 'shift_rm"); 2128 // Format(instr, "cmn'cond 'rn, 'shift_rm");
2111 // Format(instr, "cmn'cond 'rn, 'imm"); 2129 // Format(instr, "cmn'cond 'rn, 'imm");
2112 alu_out = rn_val + shifter_operand; 2130 alu_out = rn_val + shifter_operand;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2171 2189
2172 default: { 2190 default: {
2173 UNREACHABLE(); 2191 UNREACHABLE();
2174 break; 2192 break;
2175 } 2193 }
2176 } 2194 }
2177 } 2195 }
2178 } 2196 }
2179 2197
2180 2198
2181 void Simulator::DecodeType2(Instr* instr) { 2199 void Simulator::DecodeType2(Instruction* instr) {
2182 int rd = instr->RdField(); 2200 int rd = instr->RdValue();
2183 int rn = instr->RnField(); 2201 int rn = instr->RnValue();
2184 int32_t rn_val = get_register(rn); 2202 int32_t rn_val = get_register(rn);
2185 int32_t im_val = instr->Offset12Field(); 2203 int32_t im_val = instr->Offset12Value();
2186 int32_t addr = 0; 2204 int32_t addr = 0;
2187 switch (instr->PUField()) { 2205 switch (instr->PUField()) {
2188 case 0: { 2206 case da_x: {
2189 // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); 2207 // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
2190 ASSERT(!instr->HasW()); 2208 ASSERT(!instr->HasW());
2191 addr = rn_val; 2209 addr = rn_val;
2192 rn_val -= im_val; 2210 rn_val -= im_val;
2193 set_register(rn, rn_val); 2211 set_register(rn, rn_val);
2194 break; 2212 break;
2195 } 2213 }
2196 case 1: { 2214 case ia_x: {
2197 // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); 2215 // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
2198 ASSERT(!instr->HasW()); 2216 ASSERT(!instr->HasW());
2199 addr = rn_val; 2217 addr = rn_val;
2200 rn_val += im_val; 2218 rn_val += im_val;
2201 set_register(rn, rn_val); 2219 set_register(rn, rn_val);
2202 break; 2220 break;
2203 } 2221 }
2204 case 2: { 2222 case db_x: {
2205 // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); 2223 // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
2206 rn_val -= im_val; 2224 rn_val -= im_val;
2207 addr = rn_val; 2225 addr = rn_val;
2208 if (instr->HasW()) { 2226 if (instr->HasW()) {
2209 set_register(rn, rn_val); 2227 set_register(rn, rn_val);
2210 } 2228 }
2211 break; 2229 break;
2212 } 2230 }
2213 case 3: { 2231 case ib_x: {
2214 // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); 2232 // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
2215 rn_val += im_val; 2233 rn_val += im_val;
2216 addr = rn_val; 2234 addr = rn_val;
2217 if (instr->HasW()) { 2235 if (instr->HasW()) {
2218 set_register(rn, rn_val); 2236 set_register(rn, rn_val);
2219 } 2237 }
2220 break; 2238 break;
2221 } 2239 }
2222 default: { 2240 default: {
2223 UNREACHABLE(); 2241 UNREACHABLE();
(...skipping 11 matching lines...) Expand all
2235 } else { 2253 } else {
2236 if (instr->HasL()) { 2254 if (instr->HasL()) {
2237 set_register(rd, ReadW(addr, instr)); 2255 set_register(rd, ReadW(addr, instr));
2238 } else { 2256 } else {
2239 WriteW(addr, get_register(rd), instr); 2257 WriteW(addr, get_register(rd), instr);
2240 } 2258 }
2241 } 2259 }
2242 } 2260 }
2243 2261
2244 2262
2245 void Simulator::DecodeType3(Instr* instr) { 2263 void Simulator::DecodeType3(Instruction* instr) {
2246 int rd = instr->RdField(); 2264 int rd = instr->RdValue();
2247 int rn = instr->RnField(); 2265 int rn = instr->RnValue();
2248 int32_t rn_val = get_register(rn); 2266 int32_t rn_val = get_register(rn);
2249 bool shifter_carry_out = 0; 2267 bool shifter_carry_out = 0;
2250 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); 2268 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
2251 int32_t addr = 0; 2269 int32_t addr = 0;
2252 switch (instr->PUField()) { 2270 switch (instr->PUField()) {
2253 case 0: { 2271 case da_x: {
2254 ASSERT(!instr->HasW()); 2272 ASSERT(!instr->HasW());
2255 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 2273 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
2256 UNIMPLEMENTED(); 2274 UNIMPLEMENTED();
2257 break; 2275 break;
2258 } 2276 }
2259 case 1: { 2277 case ia_x: {
2260 if (instr->HasW()) { 2278 if (instr->HasW()) {
2261 ASSERT(instr->Bits(5, 4) == 0x1); 2279 ASSERT(instr->Bits(5, 4) == 0x1);
2262 2280
2263 if (instr->Bit(22) == 0x1) { // USAT. 2281 if (instr->Bit(22) == 0x1) { // USAT.
2264 int32_t sat_pos = instr->Bits(20, 16); 2282 int32_t sat_pos = instr->Bits(20, 16);
2265 int32_t sat_val = (1 << sat_pos) - 1; 2283 int32_t sat_val = (1 << sat_pos) - 1;
2266 int32_t shift = instr->Bits(11, 7); 2284 int32_t shift = instr->Bits(11, 7);
2267 int32_t shift_type = instr->Bit(6); 2285 int32_t shift_type = instr->Bit(6);
2268 int32_t rm_val = get_register(instr->RmField()); 2286 int32_t rm_val = get_register(instr->RmValue());
2269 if (shift_type == 0) { // LSL 2287 if (shift_type == 0) { // LSL
2270 rm_val <<= shift; 2288 rm_val <<= shift;
2271 } else { // ASR 2289 } else { // ASR
2272 rm_val >>= shift; 2290 rm_val >>= shift;
2273 } 2291 }
2274 // If saturation occurs, the Q flag should be set in the CPSR. 2292 // If saturation occurs, the Q flag should be set in the CPSR.
2275 // There is no Q flag yet, and no instruction (MRS) to read the 2293 // There is no Q flag yet, and no instruction (MRS) to read the
2276 // CPSR directly. 2294 // CPSR directly.
2277 if (rm_val > sat_val) { 2295 if (rm_val > sat_val) {
2278 rm_val = sat_val; 2296 rm_val = sat_val;
2279 } else if (rm_val < 0) { 2297 } else if (rm_val < 0) {
2280 rm_val = 0; 2298 rm_val = 0;
2281 } 2299 }
2282 set_register(rd, rm_val); 2300 set_register(rd, rm_val);
2283 } else { // SSAT. 2301 } else { // SSAT.
2284 UNIMPLEMENTED(); 2302 UNIMPLEMENTED();
2285 } 2303 }
2286 return; 2304 return;
2287 } else { 2305 } else {
2288 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); 2306 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
2289 UNIMPLEMENTED(); 2307 UNIMPLEMENTED();
2290 } 2308 }
2291 break; 2309 break;
2292 } 2310 }
2293 case 2: { 2311 case db_x: {
2294 // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); 2312 // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
2295 addr = rn_val - shifter_operand; 2313 addr = rn_val - shifter_operand;
2296 if (instr->HasW()) { 2314 if (instr->HasW()) {
2297 set_register(rn, addr); 2315 set_register(rn, addr);
2298 } 2316 }
2299 break; 2317 break;
2300 } 2318 }
2301 case 3: { 2319 case ib_x: {
2302 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { 2320 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
2303 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); 2321 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
2304 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); 2322 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
2305 uint32_t msbit = widthminus1 + lsbit; 2323 uint32_t msbit = widthminus1 + lsbit;
2306 if (msbit <= 31) { 2324 if (msbit <= 31) {
2307 if (instr->Bit(22)) { 2325 if (instr->Bit(22)) {
2308 // ubfx - unsigned bitfield extract. 2326 // ubfx - unsigned bitfield extract.
2309 uint32_t rm_val = 2327 uint32_t rm_val =
2310 static_cast<uint32_t>(get_register(instr->RmField())); 2328 static_cast<uint32_t>(get_register(instr->RmValue()));
2311 uint32_t extr_val = rm_val << (31 - msbit); 2329 uint32_t extr_val = rm_val << (31 - msbit);
2312 extr_val = extr_val >> (31 - widthminus1); 2330 extr_val = extr_val >> (31 - widthminus1);
2313 set_register(instr->RdField(), extr_val); 2331 set_register(instr->RdValue(), extr_val);
2314 } else { 2332 } else {
2315 // sbfx - signed bitfield extract. 2333 // sbfx - signed bitfield extract.
2316 int32_t rm_val = get_register(instr->RmField()); 2334 int32_t rm_val = get_register(instr->RmValue());
2317 int32_t extr_val = rm_val << (31 - msbit); 2335 int32_t extr_val = rm_val << (31 - msbit);
2318 extr_val = extr_val >> (31 - widthminus1); 2336 extr_val = extr_val >> (31 - widthminus1);
2319 set_register(instr->RdField(), extr_val); 2337 set_register(instr->RdValue(), extr_val);
2320 } 2338 }
2321 } else { 2339 } else {
2322 UNREACHABLE(); 2340 UNREACHABLE();
2323 } 2341 }
2324 return; 2342 return;
2325 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) { 2343 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
2326 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); 2344 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
2327 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16)); 2345 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
2328 if (msbit >= lsbit) { 2346 if (msbit >= lsbit) {
2329 // bfc or bfi - bitfield clear/insert. 2347 // bfc or bfi - bitfield clear/insert.
2330 uint32_t rd_val = 2348 uint32_t rd_val =
2331 static_cast<uint32_t>(get_register(instr->RdField())); 2349 static_cast<uint32_t>(get_register(instr->RdValue()));
2332 uint32_t bitcount = msbit - lsbit + 1; 2350 uint32_t bitcount = msbit - lsbit + 1;
2333 uint32_t mask = (1 << bitcount) - 1; 2351 uint32_t mask = (1 << bitcount) - 1;
2334 rd_val &= ~(mask << lsbit); 2352 rd_val &= ~(mask << lsbit);
2335 if (instr->RmField() != 15) { 2353 if (instr->RmValue() != 15) {
2336 // bfi - bitfield insert. 2354 // bfi - bitfield insert.
2337 uint32_t rm_val = 2355 uint32_t rm_val =
2338 static_cast<uint32_t>(get_register(instr->RmField())); 2356 static_cast<uint32_t>(get_register(instr->RmValue()));
2339 rm_val &= mask; 2357 rm_val &= mask;
2340 rd_val |= rm_val << lsbit; 2358 rd_val |= rm_val << lsbit;
2341 } 2359 }
2342 set_register(instr->RdField(), rd_val); 2360 set_register(instr->RdValue(), rd_val);
2343 } else { 2361 } else {
2344 UNREACHABLE(); 2362 UNREACHABLE();
2345 } 2363 }
2346 return; 2364 return;
2347 } else { 2365 } else {
2348 // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); 2366 // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
2349 addr = rn_val + shifter_operand; 2367 addr = rn_val + shifter_operand;
2350 if (instr->HasW()) { 2368 if (instr->HasW()) {
2351 set_register(rn, addr); 2369 set_register(rn, addr);
2352 } 2370 }
(...skipping 16 matching lines...) Expand all
2369 } else { 2387 } else {
2370 if (instr->HasL()) { 2388 if (instr->HasL()) {
2371 set_register(rd, ReadW(addr, instr)); 2389 set_register(rd, ReadW(addr, instr));
2372 } else { 2390 } else {
2373 WriteW(addr, get_register(rd), instr); 2391 WriteW(addr, get_register(rd), instr);
2374 } 2392 }
2375 } 2393 }
2376 } 2394 }
2377 2395
2378 2396
2379 void Simulator::DecodeType4(Instr* instr) { 2397 void Simulator::DecodeType4(Instruction* instr) {
2380 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode 2398 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode
2381 if (instr->HasL()) { 2399 if (instr->HasL()) {
2382 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); 2400 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
2383 HandleRList(instr, true); 2401 HandleRList(instr, true);
2384 } else { 2402 } else {
2385 // Format(instr, "stm'cond'pu 'rn'w, 'rlist"); 2403 // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
2386 HandleRList(instr, false); 2404 HandleRList(instr, false);
2387 } 2405 }
2388 } 2406 }
2389 2407
2390 2408
2391 void Simulator::DecodeType5(Instr* instr) { 2409 void Simulator::DecodeType5(Instruction* instr) {
2392 // Format(instr, "b'l'cond 'target"); 2410 // Format(instr, "b'l'cond 'target");
2393 int off = (instr->SImmed24Field() << 2); 2411 int off = (instr->SImmed24Value() << 2);
2394 intptr_t pc_address = get_pc(); 2412 intptr_t pc_address = get_pc();
2395 if (instr->HasLink()) { 2413 if (instr->HasLink()) {
2396 set_register(lr, pc_address + Instr::kInstrSize); 2414 set_register(lr, pc_address + Instruction::kInstrSize);
2397 } 2415 }
2398 int pc_reg = get_register(pc); 2416 int pc_reg = get_register(pc);
2399 set_pc(pc_reg + off); 2417 set_pc(pc_reg + off);
2400 } 2418 }
2401 2419
2402 2420
2403 void Simulator::DecodeType6(Instr* instr) { 2421 void Simulator::DecodeType6(Instruction* instr) {
2404 DecodeType6CoprocessorIns(instr); 2422 DecodeType6CoprocessorIns(instr);
2405 } 2423 }
2406 2424
2407 2425
2408 void Simulator::DecodeType7(Instr* instr) { 2426 void Simulator::DecodeType7(Instruction* instr) {
2409 if (instr->Bit(24) == 1) { 2427 if (instr->Bit(24) == 1) {
2410 SoftwareInterrupt(instr); 2428 SoftwareInterrupt(instr);
2411 } else { 2429 } else {
2412 DecodeTypeVFP(instr); 2430 DecodeTypeVFP(instr);
2413 } 2431 }
2414 } 2432 }
2415 2433
2416 2434
2417 // void Simulator::DecodeTypeVFP(Instr* instr) 2435 // void Simulator::DecodeTypeVFP(Instruction* instr)
2418 // The Following ARMv7 VFPv instructions are currently supported. 2436 // The Following ARMv7 VFPv instructions are currently supported.
2419 // vmov :Sn = Rt 2437 // vmov :Sn = Rt
2420 // vmov :Rt = Sn 2438 // vmov :Rt = Sn
2421 // vcvt: Dd = Sm 2439 // vcvt: Dd = Sm
2422 // vcvt: Sd = Dm 2440 // vcvt: Sd = Dm
2423 // Dd = vadd(Dn, Dm) 2441 // Dd = vadd(Dn, Dm)
2424 // Dd = vsub(Dn, Dm) 2442 // Dd = vsub(Dn, Dm)
2425 // Dd = vmul(Dn, Dm) 2443 // Dd = vmul(Dn, Dm)
2426 // Dd = vdiv(Dn, Dm) 2444 // Dd = vdiv(Dn, Dm)
2427 // vcmp(Dd, Dm) 2445 // vcmp(Dd, Dm)
2428 // vmrs 2446 // vmrs
2429 // Dd = vsqrt(Dm) 2447 // Dd = vsqrt(Dm)
2430 void Simulator::DecodeTypeVFP(Instr* instr) { 2448 void Simulator::DecodeTypeVFP(Instruction* instr) {
2431 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); 2449 ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
2432 ASSERT(instr->Bits(11, 9) == 0x5); 2450 ASSERT(instr->Bits(11, 9) == 0x5);
2433 2451
2434 // Obtain double precision register codes. 2452 // Obtain double precision register codes.
2435 int vm = instr->VFPMRegCode(kDoublePrecision); 2453 int vm = instr->VFPMRegValue(kDoublePrecision);
2436 int vd = instr->VFPDRegCode(kDoublePrecision); 2454 int vd = instr->VFPDRegValue(kDoublePrecision);
2437 int vn = instr->VFPNRegCode(kDoublePrecision); 2455 int vn = instr->VFPNRegValue(kDoublePrecision);
2438 2456
2439 if (instr->Bit(4) == 0) { 2457 if (instr->Bit(4) == 0) {
2440 if (instr->Opc1Field() == 0x7) { 2458 if (instr->Opc1Value() == 0x7) {
2441 // Other data processing instructions 2459 // Other data processing instructions
2442 if ((instr->Opc2Field() == 0x0) && (instr->Opc3Field() == 0x1)) { 2460 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
2443 // vmov register to register. 2461 // vmov register to register.
2444 if (instr->SzField() == 0x1) { 2462 if (instr->SzValue() == 0x1) {
2445 int m = instr->VFPMRegCode(kDoublePrecision); 2463 int m = instr->VFPMRegValue(kDoublePrecision);
2446 int d = instr->VFPDRegCode(kDoublePrecision); 2464 int d = instr->VFPDRegValue(kDoublePrecision);
2447 set_d_register_from_double(d, get_double_from_d_register(m)); 2465 set_d_register_from_double(d, get_double_from_d_register(m));
2448 } else { 2466 } else {
2449 int m = instr->VFPMRegCode(kSinglePrecision); 2467 int m = instr->VFPMRegValue(kSinglePrecision);
2450 int d = instr->VFPDRegCode(kSinglePrecision); 2468 int d = instr->VFPDRegValue(kSinglePrecision);
2451 set_s_register_from_float(d, get_float_from_s_register(m)); 2469 set_s_register_from_float(d, get_float_from_s_register(m));
2452 } 2470 }
2453 } else if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) { 2471 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
2472 // vabs
2473 double dm_value = get_double_from_d_register(vm);
2474 double dd_value = fabs(dm_value);
2475 set_d_register_from_double(vd, dd_value);
2476 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
2454 DecodeVCVTBetweenDoubleAndSingle(instr); 2477 DecodeVCVTBetweenDoubleAndSingle(instr);
2455 } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) { 2478 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
2456 DecodeVCVTBetweenFloatingPointAndInteger(instr); 2479 DecodeVCVTBetweenFloatingPointAndInteger(instr);
2457 } else if (((instr->Opc2Field() >> 1) == 0x6) && 2480 } else if (((instr->Opc2Value() >> 1) == 0x6) &&
2458 (instr->Opc3Field() & 0x1)) { 2481 (instr->Opc3Value() & 0x1)) {
2459 DecodeVCVTBetweenFloatingPointAndInteger(instr); 2482 DecodeVCVTBetweenFloatingPointAndInteger(instr);
2460 } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && 2483 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
2461 (instr->Opc3Field() & 0x1)) { 2484 (instr->Opc3Value() & 0x1)) {
2462 DecodeVCMP(instr); 2485 DecodeVCMP(instr);
2463 } else if (((instr->Opc2Field() == 0x1)) && (instr->Opc3Field() == 0x3)) { 2486 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
2464 // vsqrt 2487 // vsqrt
2465 double dm_value = get_double_from_d_register(vm); 2488 double dm_value = get_double_from_d_register(vm);
2466 double dd_value = sqrt(dm_value); 2489 double dd_value = sqrt(dm_value);
2467 set_d_register_from_double(vd, dd_value); 2490 set_d_register_from_double(vd, dd_value);
2468 } else if (instr->Opc3Field() == 0x0) { 2491 } else if (instr->Opc3Value() == 0x0) {
2469 // vmov immediate. 2492 // vmov immediate.
2470 if (instr->SzField() == 0x1) { 2493 if (instr->SzValue() == 0x1) {
2471 set_d_register_from_double(vd, instr->DoubleImmedVmov()); 2494 set_d_register_from_double(vd, instr->DoubleImmedVmov());
2472 } else { 2495 } else {
2473 UNREACHABLE(); // Not used by v8. 2496 UNREACHABLE(); // Not used by v8.
2474 } 2497 }
2475 } else { 2498 } else {
2476 UNREACHABLE(); // Not used by V8. 2499 UNREACHABLE(); // Not used by V8.
2477 } 2500 }
2478 } else if (instr->Opc1Field() == 0x3) { 2501 } else if (instr->Opc1Value() == 0x3) {
2479 if (instr->SzField() != 0x1) { 2502 if (instr->SzValue() != 0x1) {
2480 UNREACHABLE(); // Not used by V8. 2503 UNREACHABLE(); // Not used by V8.
2481 } 2504 }
2482 2505
2483 if (instr->Opc3Field() & 0x1) { 2506 if (instr->Opc3Value() & 0x1) {
2484 // vsub 2507 // vsub
2485 double dn_value = get_double_from_d_register(vn); 2508 double dn_value = get_double_from_d_register(vn);
2486 double dm_value = get_double_from_d_register(vm); 2509 double dm_value = get_double_from_d_register(vm);
2487 double dd_value = dn_value - dm_value; 2510 double dd_value = dn_value - dm_value;
2488 set_d_register_from_double(vd, dd_value); 2511 set_d_register_from_double(vd, dd_value);
2489 } else { 2512 } else {
2490 // vadd 2513 // vadd
2491 double dn_value = get_double_from_d_register(vn); 2514 double dn_value = get_double_from_d_register(vn);
2492 double dm_value = get_double_from_d_register(vm); 2515 double dm_value = get_double_from_d_register(vm);
2493 double dd_value = dn_value + dm_value; 2516 double dd_value = dn_value + dm_value;
2494 set_d_register_from_double(vd, dd_value); 2517 set_d_register_from_double(vd, dd_value);
2495 } 2518 }
2496 } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) { 2519 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
2497 // vmul 2520 // vmul
2498 if (instr->SzField() != 0x1) { 2521 if (instr->SzValue() != 0x1) {
2499 UNREACHABLE(); // Not used by V8. 2522 UNREACHABLE(); // Not used by V8.
2500 } 2523 }
2501 2524
2502 double dn_value = get_double_from_d_register(vn); 2525 double dn_value = get_double_from_d_register(vn);
2503 double dm_value = get_double_from_d_register(vm); 2526 double dm_value = get_double_from_d_register(vm);
2504 double dd_value = dn_value * dm_value; 2527 double dd_value = dn_value * dm_value;
2505 set_d_register_from_double(vd, dd_value); 2528 set_d_register_from_double(vd, dd_value);
2506 } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) { 2529 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
2507 // vdiv 2530 // vdiv
2508 if (instr->SzField() != 0x1) { 2531 if (instr->SzValue() != 0x1) {
2509 UNREACHABLE(); // Not used by V8. 2532 UNREACHABLE(); // Not used by V8.
2510 } 2533 }
2511 2534
2512 double dn_value = get_double_from_d_register(vn); 2535 double dn_value = get_double_from_d_register(vn);
2513 double dm_value = get_double_from_d_register(vm); 2536 double dm_value = get_double_from_d_register(vm);
2514 double dd_value = dn_value / dm_value; 2537 double dd_value = dn_value / dm_value;
2515 set_d_register_from_double(vd, dd_value); 2538 set_d_register_from_double(vd, dd_value);
2516 } else { 2539 } else {
2517 UNIMPLEMENTED(); // Not used by V8. 2540 UNIMPLEMENTED(); // Not used by V8.
2518 } 2541 }
2519 } else { 2542 } else {
2520 if ((instr->VCField() == 0x0) && 2543 if ((instr->VCValue() == 0x0) &&
2521 (instr->VAField() == 0x0)) { 2544 (instr->VAValue() == 0x0)) {
2522 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 2545 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
2523 } else if ((instr->VLField() == 0x1) && 2546 } else if ((instr->VLValue() == 0x1) &&
2524 (instr->VCField() == 0x0) && 2547 (instr->VCValue() == 0x0) &&
2525 (instr->VAField() == 0x7) && 2548 (instr->VAValue() == 0x7) &&
2526 (instr->Bits(19, 16) == 0x1)) { 2549 (instr->Bits(19, 16) == 0x1)) {
2527 // vmrs 2550 // vmrs
2528 uint32_t rt = instr->RtField(); 2551 uint32_t rt = instr->RtValue();
2529 if (rt == 0xF) { 2552 if (rt == 0xF) {
2530 Copy_FPSCR_to_APSR(); 2553 Copy_FPSCR_to_APSR();
2531 } else { 2554 } else {
2532 // Emulate FPSCR from the Simulator flags. 2555 // Emulate FPSCR from the Simulator flags.
2533 uint32_t fpscr = (n_flag_FPSCR_ << 31) | 2556 uint32_t fpscr = (n_flag_FPSCR_ << 31) |
2534 (z_flag_FPSCR_ << 30) | 2557 (z_flag_FPSCR_ << 30) |
2535 (c_flag_FPSCR_ << 29) | 2558 (c_flag_FPSCR_ << 29) |
2536 (v_flag_FPSCR_ << 28) | 2559 (v_flag_FPSCR_ << 28) |
2537 (inexact_vfp_flag_ << 4) | 2560 (inexact_vfp_flag_ << 4) |
2538 (underflow_vfp_flag_ << 3) | 2561 (underflow_vfp_flag_ << 3) |
2539 (overflow_vfp_flag_ << 2) | 2562 (overflow_vfp_flag_ << 2) |
2540 (div_zero_vfp_flag_ << 1) | 2563 (div_zero_vfp_flag_ << 1) |
2541 (inv_op_vfp_flag_ << 0) | 2564 (inv_op_vfp_flag_ << 0) |
2542 (FPSCR_rounding_mode_ << 22); 2565 (FPSCR_rounding_mode_);
2543 set_register(rt, fpscr); 2566 set_register(rt, fpscr);
2544 } 2567 }
2545 } else if ((instr->VLField() == 0x0) && 2568 } else if ((instr->VLValue() == 0x0) &&
2546 (instr->VCField() == 0x0) && 2569 (instr->VCValue() == 0x0) &&
2547 (instr->VAField() == 0x7) && 2570 (instr->VAValue() == 0x7) &&
2548 (instr->Bits(19, 16) == 0x1)) { 2571 (instr->Bits(19, 16) == 0x1)) {
2549 // vmsr 2572 // vmsr
2550 uint32_t rt = instr->RtField(); 2573 uint32_t rt = instr->RtValue();
2551 if (rt == pc) { 2574 if (rt == pc) {
2552 UNREACHABLE(); 2575 UNREACHABLE();
2553 } else { 2576 } else {
2554 uint32_t rt_value = get_register(rt); 2577 uint32_t rt_value = get_register(rt);
2555 n_flag_FPSCR_ = (rt_value >> 31) & 1; 2578 n_flag_FPSCR_ = (rt_value >> 31) & 1;
2556 z_flag_FPSCR_ = (rt_value >> 30) & 1; 2579 z_flag_FPSCR_ = (rt_value >> 30) & 1;
2557 c_flag_FPSCR_ = (rt_value >> 29) & 1; 2580 c_flag_FPSCR_ = (rt_value >> 29) & 1;
2558 v_flag_FPSCR_ = (rt_value >> 28) & 1; 2581 v_flag_FPSCR_ = (rt_value >> 28) & 1;
2559 inexact_vfp_flag_ = (rt_value >> 4) & 1; 2582 inexact_vfp_flag_ = (rt_value >> 4) & 1;
2560 underflow_vfp_flag_ = (rt_value >> 3) & 1; 2583 underflow_vfp_flag_ = (rt_value >> 3) & 1;
2561 overflow_vfp_flag_ = (rt_value >> 2) & 1; 2584 overflow_vfp_flag_ = (rt_value >> 2) & 1;
2562 div_zero_vfp_flag_ = (rt_value >> 1) & 1; 2585 div_zero_vfp_flag_ = (rt_value >> 1) & 1;
2563 inv_op_vfp_flag_ = (rt_value >> 0) & 1; 2586 inv_op_vfp_flag_ = (rt_value >> 0) & 1;
2564 FPSCR_rounding_mode_ = 2587 FPSCR_rounding_mode_ =
2565 static_cast<FPSCRRoundingModes>((rt_value >> 22) & 3); 2588 static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask);
2566 } 2589 }
2567 } else { 2590 } else {
2568 UNIMPLEMENTED(); // Not used by V8. 2591 UNIMPLEMENTED(); // Not used by V8.
2569 } 2592 }
2570 } 2593 }
2571 } 2594 }
2572 2595
2573 2596
2574 void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) { 2597 void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
2575 ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) && 2598 Instruction* instr) {
2576 (instr->VAField() == 0x0)); 2599 ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
2600 (instr->VAValue() == 0x0));
2577 2601
2578 int t = instr->RtField(); 2602 int t = instr->RtValue();
2579 int n = instr->VFPNRegCode(kSinglePrecision); 2603 int n = instr->VFPNRegValue(kSinglePrecision);
2580 bool to_arm_register = (instr->VLField() == 0x1); 2604 bool to_arm_register = (instr->VLValue() == 0x1);
2581 2605
2582 if (to_arm_register) { 2606 if (to_arm_register) {
2583 int32_t int_value = get_sinteger_from_s_register(n); 2607 int32_t int_value = get_sinteger_from_s_register(n);
2584 set_register(t, int_value); 2608 set_register(t, int_value);
2585 } else { 2609 } else {
2586 int32_t rs_val = get_register(t); 2610 int32_t rs_val = get_register(t);
2587 set_s_register_from_sinteger(n, rs_val); 2611 set_s_register_from_sinteger(n, rs_val);
2588 } 2612 }
2589 } 2613 }
2590 2614
2591 2615
2592 void Simulator::DecodeVCMP(Instr* instr) { 2616 void Simulator::DecodeVCMP(Instruction* instr) {
2593 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); 2617 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
2594 ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && 2618 ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
2595 (instr->Opc3Field() & 0x1)); 2619 (instr->Opc3Value() & 0x1));
2596 // Comparison. 2620 // Comparison.
2597 2621
2598 VFPRegPrecision precision = kSinglePrecision; 2622 VFPRegPrecision precision = kSinglePrecision;
2599 if (instr->SzField() == 1) { 2623 if (instr->SzValue() == 1) {
2600 precision = kDoublePrecision; 2624 precision = kDoublePrecision;
2601 } 2625 }
2602 2626
2603 if (instr->Bit(7) != 0) { 2627 int d = instr->VFPDRegValue(precision);
2604 // Raising exceptions for quiet NaNs are not supported.
2605 UNIMPLEMENTED(); // Not used by V8.
2606 }
2607
2608 int d = instr->VFPDRegCode(precision);
2609 int m = 0; 2628 int m = 0;
2610 if (instr->Opc2Field() == 0x4) { 2629 if (instr->Opc2Value() == 0x4) {
2611 m = instr->VFPMRegCode(precision); 2630 m = instr->VFPMRegValue(precision);
2612 } 2631 }
2613 2632
2614 if (precision == kDoublePrecision) { 2633 if (precision == kDoublePrecision) {
2615 double dd_value = get_double_from_d_register(d); 2634 double dd_value = get_double_from_d_register(d);
2616 double dm_value = 0.0; 2635 double dm_value = 0.0;
2617 if (instr->Opc2Field() == 0x4) { 2636 if (instr->Opc2Value() == 0x4) {
2618 dm_value = get_double_from_d_register(m); 2637 dm_value = get_double_from_d_register(m);
2619 } 2638 }
2620 2639
2640 // Raise exceptions for quiet NaNs if necessary.
2641 if (instr->Bit(7) == 1) {
2642 if (isnan(dd_value)) {
2643 inv_op_vfp_flag_ = true;
2644 }
2645 }
2646
2621 Compute_FPSCR_Flags(dd_value, dm_value); 2647 Compute_FPSCR_Flags(dd_value, dm_value);
2622 } else { 2648 } else {
2623 UNIMPLEMENTED(); // Not used by V8. 2649 UNIMPLEMENTED(); // Not used by V8.
2624 } 2650 }
2625 } 2651 }
2626 2652
2627 2653
2628 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) { 2654 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
2629 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); 2655 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
2630 ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)); 2656 ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
2631 2657
2632 VFPRegPrecision dst_precision = kDoublePrecision; 2658 VFPRegPrecision dst_precision = kDoublePrecision;
2633 VFPRegPrecision src_precision = kSinglePrecision; 2659 VFPRegPrecision src_precision = kSinglePrecision;
2634 if (instr->SzField() == 1) { 2660 if (instr->SzValue() == 1) {
2635 dst_precision = kSinglePrecision; 2661 dst_precision = kSinglePrecision;
2636 src_precision = kDoublePrecision; 2662 src_precision = kDoublePrecision;
2637 } 2663 }
2638 2664
2639 int dst = instr->VFPDRegCode(dst_precision); 2665 int dst = instr->VFPDRegValue(dst_precision);
2640 int src = instr->VFPMRegCode(src_precision); 2666 int src = instr->VFPMRegValue(src_precision);
2641 2667
2642 if (dst_precision == kSinglePrecision) { 2668 if (dst_precision == kSinglePrecision) {
2643 double val = get_double_from_d_register(src); 2669 double val = get_double_from_d_register(src);
2644 set_s_register_from_float(dst, static_cast<float>(val)); 2670 set_s_register_from_float(dst, static_cast<float>(val));
2645 } else { 2671 } else {
2646 float val = get_float_from_s_register(src); 2672 float val = get_float_from_s_register(src);
2647 set_d_register_from_double(dst, static_cast<double>(val)); 2673 set_d_register_from_double(dst, static_cast<double>(val));
2648 } 2674 }
2649 } 2675 }
2650 2676
2677 bool get_inv_op_vfp_flag(VFPRoundingMode mode,
2678 double val,
2679 bool unsigned_) {
2680 ASSERT((mode == RN) || (mode == RM) || (mode == RZ));
2681 double max_uint = static_cast<double>(0xffffffffu);
2682 double max_int = static_cast<double>(kMaxInt);
2683 double min_int = static_cast<double>(kMinInt);
2684
2685 // Check for NaN.
2686 if (val != val) {
2687 return true;
2688 }
2689
2690 // Check for overflow. This code works because 32bit integers can be
2691 // exactly represented by ieee-754 64bit floating-point values.
2692 switch (mode) {
2693 case RN:
2694 return unsigned_ ? (val >= (max_uint + 0.5)) ||
2695 (val < -0.5)
2696 : (val >= (max_int + 0.5)) ||
2697 (val < (min_int - 0.5));
2698
2699 case RM:
2700 return unsigned_ ? (val >= (max_uint + 1.0)) ||
2701 (val < 0)
2702 : (val >= (max_int + 1.0)) ||
2703 (val < min_int);
2704
2705 case RZ:
2706 return unsigned_ ? (val >= (max_uint + 1.0)) ||
2707 (val <= -1)
2708 : (val >= (max_int + 1.0)) ||
2709 (val <= (min_int - 1.0));
2710 default:
2711 UNREACHABLE();
2712 return true;
2713 }
2714 }
2715
2651 2716
2652 void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) { 2717 // We call this function only if we had a vfp invalid exception.
2653 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); 2718 // It returns the correct saturated value.
2654 ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) || 2719 int VFPConversionSaturate(double val, bool unsigned_res) {
2655 (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1))); 2720 if (val != val) {
2721 return 0;
2722 } else {
2723 if (unsigned_res) {
2724 return (val < 0) ? 0 : 0xffffffffu;
2725 } else {
2726 return (val < 0) ? kMinInt : kMaxInt;
2727 }
2728 }
2729 }
2730
2731
2732 void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
2733 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7) &&
2734 (instr->Bits(27, 23) == 0x1D));
2735 ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
2736 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
2656 2737
2657 // Conversion between floating-point and integer. 2738 // Conversion between floating-point and integer.
2658 bool to_integer = (instr->Bit(18) == 1); 2739 bool to_integer = (instr->Bit(18) == 1);
2659 2740
2660 VFPRegPrecision src_precision = kSinglePrecision; 2741 VFPRegPrecision src_precision = (instr->SzValue() == 1) ? kDoublePrecision
2661 if (instr->SzField() == 1) { 2742 : kSinglePrecision;
2662 src_precision = kDoublePrecision;
2663 }
2664 2743
2665 if (to_integer) { 2744 if (to_integer) {
2745 // We are playing with code close to the C++ standard's limits below,
2746 // hence the very simple code and heavy checks.
2747 //
2748 // Note:
2749 // C++ defines default type casting from floating point to integer as
2750 // (close to) rounding toward zero ("fractional part discarded").
2751
2752 int dst = instr->VFPDRegValue(kSinglePrecision);
2753 int src = instr->VFPMRegValue(src_precision);
2754
2755 // Bit 7 in vcvt instructions indicates if we should use the FPSCR rounding
2756 // mode or the default Round to Zero mode.
2757 VFPRoundingMode mode = (instr->Bit(7) != 1) ? FPSCR_rounding_mode_
2758 : RZ;
2759 ASSERT((mode == RM) || (mode == RZ) || (mode == RN));
2760
2666 bool unsigned_integer = (instr->Bit(16) == 0); 2761 bool unsigned_integer = (instr->Bit(16) == 0);
2667 FPSCRRoundingModes mode; 2762 bool double_precision = (src_precision == kDoublePrecision);
2668 if (instr->Bit(7) != 1) { 2763
2669 // Use FPSCR defined rounding mode. 2764 double val = double_precision ? get_double_from_d_register(src)
2670 mode = FPSCR_rounding_mode_; 2765 : get_float_from_s_register(src);
2671 // Only RZ and RM modes are supported. 2766
2672 ASSERT((mode == RM) || (mode == RZ)); 2767 int temp = unsigned_integer ? static_cast<uint32_t>(val)
2768 : static_cast<int32_t>(val);
2769
2770 inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer);
2771
2772 if (inv_op_vfp_flag_) {
2773 temp = VFPConversionSaturate(val, unsigned_integer);
2673 } else { 2774 } else {
2674 // VFP uses round towards zero by default. 2775 switch (mode) {
2675 mode = RZ; 2776 case RN: {
2777 double abs_diff =
2778 unsigned_integer ? fabs(val - static_cast<uint32_t>(temp))
2779 : fabs(val - temp);
2780 int val_sign = (val > 0) ? 1 : -1;
2781 if (abs_diff > 0.5) {
2782 temp += val_sign;
2783 } else if (abs_diff == 0.5) {
2784 // Round to even if exactly halfway.
2785 temp = ((temp % 2) == 0) ? temp : temp + val_sign;
2786 }
2787 break;
2788 }
2789
2790 case RM:
2791 temp = temp > val ? temp - 1 : temp;
2792 break;
2793
2794 case RZ:
2795 // Nothing to do.
2796 break;
2797
2798 default:
2799 UNREACHABLE();
2800 }
2676 } 2801 }
2677 2802
2678 int dst = instr->VFPDRegCode(kSinglePrecision); 2803 // Update the destination register.
2679 int src = instr->VFPMRegCode(src_precision); 2804 set_s_register_from_sinteger(dst, temp);
2680 int32_t kMaxInt = v8::internal::kMaxInt;
2681 int32_t kMinInt = v8::internal::kMinInt;
2682 switch (mode) {
2683 case RM:
2684 if (src_precision == kDoublePrecision) {
2685 double val = get_double_from_d_register(src);
2686
2687 inv_op_vfp_flag_ = (val > kMaxInt) || (val < kMinInt) || (val != val);
2688
2689 int sint = unsigned_integer ? static_cast<uint32_t>(val) :
2690 static_cast<int32_t>(val);
2691 sint = sint > val ? sint - 1 : sint;
2692
2693 set_s_register_from_sinteger(dst, sint);
2694 } else {
2695 float val = get_float_from_s_register(src);
2696
2697 inv_op_vfp_flag_ = (val > kMaxInt) || (val < kMinInt) || (val != val);
2698
2699 int sint = unsigned_integer ? static_cast<uint32_t>(val) :
2700 static_cast<int32_t>(val);
2701 sint = sint > val ? sint - 1 : sint;
2702
2703 set_s_register_from_sinteger(dst, sint);
2704 }
2705 break;
2706 case RZ:
2707 if (src_precision == kDoublePrecision) {
2708 double val = get_double_from_d_register(src);
2709
2710 inv_op_vfp_flag_ = (val > kMaxInt) || (val < kMinInt) || (val != val);
2711
2712 int sint = unsigned_integer ? static_cast<uint32_t>(val) :
2713 static_cast<int32_t>(val);
2714
2715 set_s_register_from_sinteger(dst, sint);
2716 } else {
2717 float val = get_float_from_s_register(src);
2718
2719 inv_op_vfp_flag_ = (val > kMaxInt) || (val < kMinInt) || (val != val);
2720
2721 int sint = unsigned_integer ? static_cast<uint32_t>(val) :
2722 static_cast<int32_t>(val);
2723
2724 set_s_register_from_sinteger(dst, sint);
2725 }
2726 break;
2727
2728 default:
2729 UNREACHABLE();
2730 }
2731 2805
2732 } else { 2806 } else {
2733 bool unsigned_integer = (instr->Bit(7) == 0); 2807 bool unsigned_integer = (instr->Bit(7) == 0);
2734 2808
2735 int dst = instr->VFPDRegCode(src_precision); 2809 int dst = instr->VFPDRegValue(src_precision);
2736 int src = instr->VFPMRegCode(kSinglePrecision); 2810 int src = instr->VFPMRegValue(kSinglePrecision);
2737 2811
2738 int val = get_sinteger_from_s_register(src); 2812 int val = get_sinteger_from_s_register(src);
2739 2813
2740 if (src_precision == kDoublePrecision) { 2814 if (src_precision == kDoublePrecision) {
2741 if (unsigned_integer) { 2815 if (unsigned_integer) {
2742 set_d_register_from_double(dst, 2816 set_d_register_from_double(dst,
2743 static_cast<double>((uint32_t)val)); 2817 static_cast<double>((uint32_t)val));
2744 } else { 2818 } else {
2745 set_d_register_from_double(dst, static_cast<double>(val)); 2819 set_d_register_from_double(dst, static_cast<double>(val));
2746 } 2820 }
2747 } else { 2821 } else {
2748 if (unsigned_integer) { 2822 if (unsigned_integer) {
2749 set_s_register_from_float(dst, 2823 set_s_register_from_float(dst,
2750 static_cast<float>((uint32_t)val)); 2824 static_cast<float>((uint32_t)val));
2751 } else { 2825 } else {
2752 set_s_register_from_float(dst, static_cast<float>(val)); 2826 set_s_register_from_float(dst, static_cast<float>(val));
2753 } 2827 }
2754 } 2828 }
2755 } 2829 }
2756 } 2830 }
2757 2831
2758 2832
2759 // void Simulator::DecodeType6CoprocessorIns(Instr* instr) 2833 // void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
2760 // Decode Type 6 coprocessor instructions. 2834 // Decode Type 6 coprocessor instructions.
2761 // Dm = vmov(Rt, Rt2) 2835 // Dm = vmov(Rt, Rt2)
2762 // <Rt, Rt2> = vmov(Dm) 2836 // <Rt, Rt2> = vmov(Dm)
2763 // Ddst = MEM(Rbase + 4*offset). 2837 // Ddst = MEM(Rbase + 4*offset).
2764 // MEM(Rbase + 4*offset) = Dsrc. 2838 // MEM(Rbase + 4*offset) = Dsrc.
2765 void Simulator::DecodeType6CoprocessorIns(Instr* instr) { 2839 void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
2766 ASSERT((instr->TypeField() == 6)); 2840 ASSERT((instr->TypeValue() == 6));
2767 2841
2768 if (instr->CoprocessorField() == 0xA) { 2842 if (instr->CoprocessorValue() == 0xA) {
2769 switch (instr->OpcodeField()) { 2843 switch (instr->OpcodeValue()) {
2770 case 0x8: 2844 case 0x8:
2771 case 0xA: 2845 case 0xA:
2772 case 0xC: 2846 case 0xC:
2773 case 0xE: { // Load and store single precision float to memory. 2847 case 0xE: { // Load and store single precision float to memory.
2774 int rn = instr->RnField(); 2848 int rn = instr->RnValue();
2775 int vd = instr->VFPDRegCode(kSinglePrecision); 2849 int vd = instr->VFPDRegValue(kSinglePrecision);
2776 int offset = instr->Immed8Field(); 2850 int offset = instr->Immed8Value();
2777 if (!instr->HasU()) { 2851 if (!instr->HasU()) {
2778 offset = -offset; 2852 offset = -offset;
2779 } 2853 }
2780 2854
2781 int32_t address = get_register(rn) + 4 * offset; 2855 int32_t address = get_register(rn) + 4 * offset;
2782 if (instr->HasL()) { 2856 if (instr->HasL()) {
2783 // Load double from memory: vldr. 2857 // Load double from memory: vldr.
2784 set_s_register_from_sinteger(vd, ReadW(address, instr)); 2858 set_s_register_from_sinteger(vd, ReadW(address, instr));
2785 } else { 2859 } else {
2786 // Store double to memory: vstr. 2860 // Store double to memory: vstr.
2787 WriteW(address, get_sinteger_from_s_register(vd), instr); 2861 WriteW(address, get_sinteger_from_s_register(vd), instr);
2788 } 2862 }
2789 break; 2863 break;
2790 } 2864 }
2791 default: 2865 default:
2792 UNIMPLEMENTED(); // Not used by V8. 2866 UNIMPLEMENTED(); // Not used by V8.
2793 break; 2867 break;
2794 } 2868 }
2795 } else if (instr->CoprocessorField() == 0xB) { 2869 } else if (instr->CoprocessorValue() == 0xB) {
2796 switch (instr->OpcodeField()) { 2870 switch (instr->OpcodeValue()) {
2797 case 0x2: 2871 case 0x2:
2798 // Load and store double to two GP registers 2872 // Load and store double to two GP registers
2799 if (instr->Bits(7, 4) != 0x1) { 2873 if (instr->Bits(7, 4) != 0x1) {
2800 UNIMPLEMENTED(); // Not used by V8. 2874 UNIMPLEMENTED(); // Not used by V8.
2801 } else { 2875 } else {
2802 int rt = instr->RtField(); 2876 int rt = instr->RtValue();
2803 int rn = instr->RnField(); 2877 int rn = instr->RnValue();
2804 int vm = instr->VmField(); 2878 int vm = instr->VmValue();
2805 if (instr->HasL()) { 2879 if (instr->HasL()) {
2806 int32_t rt_int_value = get_sinteger_from_s_register(2*vm); 2880 int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
2807 int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1); 2881 int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
2808 2882
2809 set_register(rt, rt_int_value); 2883 set_register(rt, rt_int_value);
2810 set_register(rn, rn_int_value); 2884 set_register(rn, rn_int_value);
2811 } else { 2885 } else {
2812 int32_t rs_val = get_register(rt); 2886 int32_t rs_val = get_register(rt);
2813 int32_t rn_val = get_register(rn); 2887 int32_t rn_val = get_register(rn);
2814 2888
2815 set_s_register_from_sinteger(2*vm, rs_val); 2889 set_s_register_from_sinteger(2*vm, rs_val);
2816 set_s_register_from_sinteger((2*vm+1), rn_val); 2890 set_s_register_from_sinteger((2*vm+1), rn_val);
2817 } 2891 }
2818 } 2892 }
2819 break; 2893 break;
2820 case 0x8: 2894 case 0x8:
2821 case 0xC: { // Load and store double to memory. 2895 case 0xC: { // Load and store double to memory.
2822 int rn = instr->RnField(); 2896 int rn = instr->RnValue();
2823 int vd = instr->VdField(); 2897 int vd = instr->VdValue();
2824 int offset = instr->Immed8Field(); 2898 int offset = instr->Immed8Value();
2825 if (!instr->HasU()) { 2899 if (!instr->HasU()) {
2826 offset = -offset; 2900 offset = -offset;
2827 } 2901 }
2828 int32_t address = get_register(rn) + 4 * offset; 2902 int32_t address = get_register(rn) + 4 * offset;
2829 if (instr->HasL()) { 2903 if (instr->HasL()) {
2830 // Load double from memory: vldr. 2904 // Load double from memory: vldr.
2831 set_s_register_from_sinteger(2*vd, ReadW(address, instr)); 2905 set_s_register_from_sinteger(2*vd, ReadW(address, instr));
2832 set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr)); 2906 set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr));
2833 } else { 2907 } else {
2834 // Store double to memory: vstr. 2908 // Store double to memory: vstr.
2835 WriteW(address, get_sinteger_from_s_register(2*vd), instr); 2909 WriteW(address, get_sinteger_from_s_register(2*vd), instr);
2836 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr); 2910 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr);
2837 } 2911 }
2838 break; 2912 break;
2839 } 2913 }
2840 default: 2914 default:
2841 UNIMPLEMENTED(); // Not used by V8. 2915 UNIMPLEMENTED(); // Not used by V8.
2842 break; 2916 break;
2843 } 2917 }
2844 } else { 2918 } else {
2845 UNIMPLEMENTED(); // Not used by V8. 2919 UNIMPLEMENTED(); // Not used by V8.
2846 } 2920 }
2847 } 2921 }
2848 2922
2849 2923
2850 // Executes the current instruction. 2924 // Executes the current instruction.
2851 void Simulator::InstructionDecode(Instr* instr) { 2925 void Simulator::InstructionDecode(Instruction* instr) {
2852 if (v8::internal::FLAG_check_icache) { 2926 if (v8::internal::FLAG_check_icache) {
2853 CheckICache(instr); 2927 CheckICache(instr);
2854 } 2928 }
2855 pc_modified_ = false; 2929 pc_modified_ = false;
2856 if (::v8::internal::FLAG_trace_sim) { 2930 if (::v8::internal::FLAG_trace_sim) {
2857 disasm::NameConverter converter; 2931 disasm::NameConverter converter;
2858 disasm::Disassembler dasm(converter); 2932 disasm::Disassembler dasm(converter);
2859 // use a reasonably large buffer 2933 // use a reasonably large buffer
2860 v8::internal::EmbeddedVector<char, 256> buffer; 2934 v8::internal::EmbeddedVector<char, 256> buffer;
2861 dasm.InstructionDecode(buffer, 2935 dasm.InstructionDecode(buffer,
2862 reinterpret_cast<byte*>(instr)); 2936 reinterpret_cast<byte*>(instr));
2863 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); 2937 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
2864 } 2938 }
2865 if (instr->ConditionField() == special_condition) { 2939 if (instr->ConditionField() == kSpecialCondition) {
2866 UNIMPLEMENTED(); 2940 UNIMPLEMENTED();
2867 } else if (ConditionallyExecute(instr)) { 2941 } else if (ConditionallyExecute(instr)) {
2868 switch (instr->TypeField()) { 2942 switch (instr->TypeValue()) {
2869 case 0: 2943 case 0:
2870 case 1: { 2944 case 1: {
2871 DecodeType01(instr); 2945 DecodeType01(instr);
2872 break; 2946 break;
2873 } 2947 }
2874 case 2: { 2948 case 2: {
2875 DecodeType2(instr); 2949 DecodeType2(instr);
2876 break; 2950 break;
2877 } 2951 }
2878 case 3: { 2952 case 3: {
(...skipping 14 matching lines...) Expand all
2893 } 2967 }
2894 case 7: { 2968 case 7: {
2895 DecodeType7(instr); 2969 DecodeType7(instr);
2896 break; 2970 break;
2897 } 2971 }
2898 default: { 2972 default: {
2899 UNIMPLEMENTED(); 2973 UNIMPLEMENTED();
2900 break; 2974 break;
2901 } 2975 }
2902 } 2976 }
2977 // If the instruction is a non taken conditional stop, we need to skip the
2978 // inlined message address.
2979 } else if (instr->IsStop()) {
2980 set_pc(get_pc() + 2 * Instruction::kInstrSize);
2903 } 2981 }
2904 if (!pc_modified_) { 2982 if (!pc_modified_) {
2905 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); 2983 set_register(pc, reinterpret_cast<int32_t>(instr)
2984 + Instruction::kInstrSize);
2906 } 2985 }
2907 } 2986 }
2908 2987
2909 2988
2910 void Simulator::Execute() { 2989 void Simulator::Execute() {
2911 // Get the PC to simulate. Cannot use the accessor here as we need the 2990 // Get the PC to simulate. Cannot use the accessor here as we need the
2912 // raw PC value and not the one used as input to arithmetic instructions. 2991 // raw PC value and not the one used as input to arithmetic instructions.
2913 int program_counter = get_pc(); 2992 int program_counter = get_pc();
2914 2993
2915 if (::v8::internal::FLAG_stop_sim_at == 0) { 2994 if (::v8::internal::FLAG_stop_sim_at == 0) {
2916 // Fast version of the dispatch loop without checking whether the simulator 2995 // Fast version of the dispatch loop without checking whether the simulator
2917 // should be stopping at a particular executed instruction. 2996 // should be stopping at a particular executed instruction.
2918 while (program_counter != end_sim_pc) { 2997 while (program_counter != end_sim_pc) {
2919 Instr* instr = reinterpret_cast<Instr*>(program_counter); 2998 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
2920 icount_++; 2999 icount_++;
2921 InstructionDecode(instr); 3000 InstructionDecode(instr);
2922 program_counter = get_pc(); 3001 program_counter = get_pc();
2923 } 3002 }
2924 } else { 3003 } else {
2925 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 3004 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
2926 // we reach the particular instuction count. 3005 // we reach the particular instuction count.
2927 while (program_counter != end_sim_pc) { 3006 while (program_counter != end_sim_pc) {
2928 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3007 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
2929 icount_++; 3008 icount_++;
2930 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { 3009 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
2931 Debugger dbg(this); 3010 Debugger dbg(this);
2932 dbg.Debug(); 3011 dbg.Debug();
2933 } else { 3012 } else {
2934 InstructionDecode(instr); 3013 InstructionDecode(instr);
2935 } 3014 }
2936 program_counter = get_pc(); 3015 program_counter = get_pc();
2937 } 3016 }
2938 } 3017 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 3118
3040 3119
3041 uintptr_t Simulator::PopAddress() { 3120 uintptr_t Simulator::PopAddress() {
3042 int current_sp = get_register(sp); 3121 int current_sp = get_register(sp);
3043 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 3122 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
3044 uintptr_t address = *stack_slot; 3123 uintptr_t address = *stack_slot;
3045 set_register(sp, current_sp + sizeof(uintptr_t)); 3124 set_register(sp, current_sp + sizeof(uintptr_t));
3046 return address; 3125 return address;
3047 } 3126 }
3048 3127
3049 } } // namespace assembler::arm 3128 } } // namespace v8::internal
3050 3129
3051 #endif // USE_SIMULATOR 3130 #endif // USE_SIMULATOR
3052 3131
3053 #endif // V8_TARGET_ARCH_ARM 3132 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/arm/stub-cache-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698