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

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

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

Powered by Google App Engine
This is Rietveld 408576698