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

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

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

Powered by Google App Engine
This is Rietveld 408576698