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

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

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | src/arm64/stub-cache-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <cmath> 6 #include <cmath>
7 #include <cstdarg> 7 #include <cstdarg>
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #if V8_TARGET_ARCH_ARM64 10 #if V8_TARGET_ARCH_ARM64
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 va_end(arguments); 66 va_end(arguments);
67 } 67 }
68 } 68 }
69 69
70 70
71 const Instruction* Simulator::kEndOfSimAddress = NULL; 71 const Instruction* Simulator::kEndOfSimAddress = NULL;
72 72
73 73
74 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) { 74 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) {
75 int width = msb - lsb + 1; 75 int width = msb - lsb + 1;
76 ASSERT(is_uintn(bits, width) || is_intn(bits, width)); 76 DCHECK(is_uintn(bits, width) || is_intn(bits, width));
77 77
78 bits <<= lsb; 78 bits <<= lsb;
79 uint32_t mask = ((1 << width) - 1) << lsb; 79 uint32_t mask = ((1 << width) - 1) << lsb;
80 ASSERT((mask & write_ignore_mask_) == 0); 80 DCHECK((mask & write_ignore_mask_) == 0);
81 81
82 value_ = (value_ & ~mask) | (bits & mask); 82 value_ = (value_ & ~mask) | (bits & mask);
83 } 83 }
84 84
85 85
86 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) { 86 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) {
87 switch (id) { 87 switch (id) {
88 case NZCV: 88 case NZCV:
89 return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask); 89 return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask);
90 case FPCR: 90 case FPCR:
91 return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask); 91 return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask);
92 default: 92 default:
93 UNREACHABLE(); 93 UNREACHABLE();
94 return SimSystemRegister(); 94 return SimSystemRegister();
95 } 95 }
96 } 96 }
97 97
98 98
99 void Simulator::Initialize(Isolate* isolate) { 99 void Simulator::Initialize(Isolate* isolate) {
100 if (isolate->simulator_initialized()) return; 100 if (isolate->simulator_initialized()) return;
101 isolate->set_simulator_initialized(true); 101 isolate->set_simulator_initialized(true);
102 ExternalReference::set_redirector(isolate, &RedirectExternalReference); 102 ExternalReference::set_redirector(isolate, &RedirectExternalReference);
103 } 103 }
104 104
105 105
106 // Get the active Simulator for the current thread. 106 // Get the active Simulator for the current thread.
107 Simulator* Simulator::current(Isolate* isolate) { 107 Simulator* Simulator::current(Isolate* isolate) {
108 Isolate::PerIsolateThreadData* isolate_data = 108 Isolate::PerIsolateThreadData* isolate_data =
109 isolate->FindOrAllocatePerThreadDataForThisThread(); 109 isolate->FindOrAllocatePerThreadDataForThisThread();
110 ASSERT(isolate_data != NULL); 110 DCHECK(isolate_data != NULL);
111 111
112 Simulator* sim = isolate_data->simulator(); 112 Simulator* sim = isolate_data->simulator();
113 if (sim == NULL) { 113 if (sim == NULL) {
114 if (FLAG_trace_sim || FLAG_log_instruction_stats || FLAG_debug_sim) { 114 if (FLAG_trace_sim || FLAG_log_instruction_stats || FLAG_debug_sim) {
115 sim = new Simulator(new Decoder<DispatchingDecoderVisitor>(), isolate); 115 sim = new Simulator(new Decoder<DispatchingDecoderVisitor>(), isolate);
116 } else { 116 } else {
117 sim = new Decoder<Simulator>(); 117 sim = new Decoder<Simulator>();
118 sim->isolate_ = isolate; 118 sim->isolate_ = isolate;
119 } 119 }
120 isolate_data->set_simulator(sim); 120 isolate_data->set_simulator(sim);
121 } 121 }
122 return sim; 122 return sim;
123 } 123 }
124 124
125 125
126 void Simulator::CallVoid(byte* entry, CallArgument* args) { 126 void Simulator::CallVoid(byte* entry, CallArgument* args) {
127 int index_x = 0; 127 int index_x = 0;
128 int index_d = 0; 128 int index_d = 0;
129 129
130 std::vector<int64_t> stack_args(0); 130 std::vector<int64_t> stack_args(0);
131 for (int i = 0; !args[i].IsEnd(); i++) { 131 for (int i = 0; !args[i].IsEnd(); i++) {
132 CallArgument arg = args[i]; 132 CallArgument arg = args[i];
133 if (arg.IsX() && (index_x < 8)) { 133 if (arg.IsX() && (index_x < 8)) {
134 set_xreg(index_x++, arg.bits()); 134 set_xreg(index_x++, arg.bits());
135 } else if (arg.IsD() && (index_d < 8)) { 135 } else if (arg.IsD() && (index_d < 8)) {
136 set_dreg_bits(index_d++, arg.bits()); 136 set_dreg_bits(index_d++, arg.bits());
137 } else { 137 } else {
138 ASSERT(arg.IsD() || arg.IsX()); 138 DCHECK(arg.IsD() || arg.IsX());
139 stack_args.push_back(arg.bits()); 139 stack_args.push_back(arg.bits());
140 } 140 }
141 } 141 }
142 142
143 // Process stack arguments, and make sure the stack is suitably aligned. 143 // Process stack arguments, and make sure the stack is suitably aligned.
144 uintptr_t original_stack = sp(); 144 uintptr_t original_stack = sp();
145 uintptr_t entry_stack = original_stack - 145 uintptr_t entry_stack = original_stack -
146 stack_args.size() * sizeof(stack_args[0]); 146 stack_args.size() * sizeof(stack_args[0]);
147 if (base::OS::ActivationFrameAlignment() != 0) { 147 if (base::OS::ActivationFrameAlignment() != 0) {
148 entry_stack &= -base::OS::ActivationFrameAlignment(); 148 entry_stack &= -base::OS::ActivationFrameAlignment();
149 } 149 }
150 char * stack = reinterpret_cast<char*>(entry_stack); 150 char * stack = reinterpret_cast<char*>(entry_stack);
151 std::vector<int64_t>::const_iterator it; 151 std::vector<int64_t>::const_iterator it;
152 for (it = stack_args.begin(); it != stack_args.end(); it++) { 152 for (it = stack_args.begin(); it != stack_args.end(); it++) {
153 memcpy(stack, &(*it), sizeof(*it)); 153 memcpy(stack, &(*it), sizeof(*it));
154 stack += sizeof(*it); 154 stack += sizeof(*it);
155 } 155 }
156 156
157 ASSERT(reinterpret_cast<uintptr_t>(stack) <= original_stack); 157 DCHECK(reinterpret_cast<uintptr_t>(stack) <= original_stack);
158 set_sp(entry_stack); 158 set_sp(entry_stack);
159 159
160 // Call the generated code. 160 // Call the generated code.
161 set_pc(entry); 161 set_pc(entry);
162 set_lr(kEndOfSimAddress); 162 set_lr(kEndOfSimAddress);
163 CheckPCSComplianceAndRun(); 163 CheckPCSComplianceAndRun();
164 164
165 set_sp(original_stack); 165 set_sp(original_stack);
166 } 166 }
167 167
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 Run(); 249 Run();
250 #ifdef DEBUG 250 #ifdef DEBUG
251 CHECK_EQ(original_stack, sp()); 251 CHECK_EQ(original_stack, sp());
252 // Check that callee-saved registers have been preserved. 252 // Check that callee-saved registers have been preserved.
253 register_list = kCalleeSaved; 253 register_list = kCalleeSaved;
254 fpregister_list = kCalleeSavedFP; 254 fpregister_list = kCalleeSavedFP;
255 for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) { 255 for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) {
256 CHECK_EQ(saved_registers[i], xreg(register_list.PopLowestIndex().code())); 256 CHECK_EQ(saved_registers[i], xreg(register_list.PopLowestIndex().code()));
257 } 257 }
258 for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) { 258 for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) {
259 ASSERT(saved_fpregisters[i] == 259 DCHECK(saved_fpregisters[i] ==
260 dreg_bits(fpregister_list.PopLowestIndex().code())); 260 dreg_bits(fpregister_list.PopLowestIndex().code()));
261 } 261 }
262 262
263 // Corrupt caller saved register minus the return regiters. 263 // Corrupt caller saved register minus the return regiters.
264 264
265 // In theory x0 to x7 can be used for return values, but V8 only uses x0, x1 265 // In theory x0 to x7 can be used for return values, but V8 only uses x0, x1
266 // for now . 266 // for now .
267 register_list = kCallerSaved; 267 register_list = kCallerSaved;
268 register_list.Remove(x0); 268 register_list.Remove(x0);
269 register_list.Remove(x1); 269 register_list.Remove(x1);
(...skipping 12 matching lines...) Expand all
282 #ifdef DEBUG 282 #ifdef DEBUG
283 // The least significant byte of the curruption value holds the corresponding 283 // The least significant byte of the curruption value holds the corresponding
284 // register's code. 284 // register's code.
285 void Simulator::CorruptRegisters(CPURegList* list, uint64_t value) { 285 void Simulator::CorruptRegisters(CPURegList* list, uint64_t value) {
286 if (list->type() == CPURegister::kRegister) { 286 if (list->type() == CPURegister::kRegister) {
287 while (!list->IsEmpty()) { 287 while (!list->IsEmpty()) {
288 unsigned code = list->PopLowestIndex().code(); 288 unsigned code = list->PopLowestIndex().code();
289 set_xreg(code, value | code); 289 set_xreg(code, value | code);
290 } 290 }
291 } else { 291 } else {
292 ASSERT(list->type() == CPURegister::kFPRegister); 292 DCHECK(list->type() == CPURegister::kFPRegister);
293 while (!list->IsEmpty()) { 293 while (!list->IsEmpty()) {
294 unsigned code = list->PopLowestIndex().code(); 294 unsigned code = list->PopLowestIndex().code();
295 set_dreg_bits(code, value | code); 295 set_dreg_bits(code, value | code);
296 } 296 }
297 } 297 }
298 } 298 }
299 299
300 300
301 void Simulator::CorruptAllCallerSavedCPURegisters() { 301 void Simulator::CorruptAllCallerSavedCPURegisters() {
302 // Corrupt alters its parameter so copy them first. 302 // Corrupt alters its parameter so copy them first.
303 CPURegList register_list = kCallerSaved; 303 CPURegList register_list = kCallerSaved;
304 CPURegList fpregister_list = kCallerSavedFP; 304 CPURegList fpregister_list = kCallerSavedFP;
305 305
306 CorruptRegisters(&register_list, kCallerSavedRegisterCorruptionValue); 306 CorruptRegisters(&register_list, kCallerSavedRegisterCorruptionValue);
307 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue); 307 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue);
308 } 308 }
309 #endif 309 #endif
310 310
311 311
312 // Extending the stack by 2 * 64 bits is required for stack alignment purposes. 312 // Extending the stack by 2 * 64 bits is required for stack alignment purposes.
313 uintptr_t Simulator::PushAddress(uintptr_t address) { 313 uintptr_t Simulator::PushAddress(uintptr_t address) {
314 ASSERT(sizeof(uintptr_t) < 2 * kXRegSize); 314 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize);
315 intptr_t new_sp = sp() - 2 * kXRegSize; 315 intptr_t new_sp = sp() - 2 * kXRegSize;
316 uintptr_t* alignment_slot = 316 uintptr_t* alignment_slot =
317 reinterpret_cast<uintptr_t*>(new_sp + kXRegSize); 317 reinterpret_cast<uintptr_t*>(new_sp + kXRegSize);
318 memcpy(alignment_slot, &kSlotsZapValue, kPointerSize); 318 memcpy(alignment_slot, &kSlotsZapValue, kPointerSize);
319 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); 319 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
320 memcpy(stack_slot, &address, kPointerSize); 320 memcpy(stack_slot, &address, kPointerSize);
321 set_sp(new_sp); 321 set_sp(new_sp);
322 return new_sp; 322 return new_sp;
323 } 323 }
324 324
325 325
326 uintptr_t Simulator::PopAddress() { 326 uintptr_t Simulator::PopAddress() {
327 intptr_t current_sp = sp(); 327 intptr_t current_sp = sp();
328 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 328 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
329 uintptr_t address = *stack_slot; 329 uintptr_t address = *stack_slot;
330 ASSERT(sizeof(uintptr_t) < 2 * kXRegSize); 330 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize);
331 set_sp(current_sp + 2 * kXRegSize); 331 set_sp(current_sp + 2 * kXRegSize);
332 return address; 332 return address;
333 } 333 }
334 334
335 335
336 // Returns the limit of the stack area to enable checking for stack overflows. 336 // Returns the limit of the stack area to enable checking for stack overflows.
337 uintptr_t Simulator::StackLimit() const { 337 uintptr_t Simulator::StackLimit() const {
338 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when 338 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
339 // pushing values. 339 // pushing values.
340 return reinterpret_cast<uintptr_t>(stack_limit_) + 1024; 340 return reinterpret_cast<uintptr_t>(stack_limit_) + 1024;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 T external_function() { return reinterpret_cast<T>(external_function_); } 474 T external_function() { return reinterpret_cast<T>(external_function_); }
475 475
476 ExternalReference::Type type() { return type_; } 476 ExternalReference::Type type() { return type_; }
477 477
478 static Redirection* Get(void* external_function, 478 static Redirection* Get(void* external_function,
479 ExternalReference::Type type) { 479 ExternalReference::Type type) {
480 Isolate* isolate = Isolate::Current(); 480 Isolate* isolate = Isolate::Current();
481 Redirection* current = isolate->simulator_redirection(); 481 Redirection* current = isolate->simulator_redirection();
482 for (; current != NULL; current = current->next_) { 482 for (; current != NULL; current = current->next_) {
483 if (current->external_function_ == external_function) { 483 if (current->external_function_ == external_function) {
484 ASSERT_EQ(current->type(), type); 484 DCHECK_EQ(current->type(), type);
485 return current; 485 return current;
486 } 486 }
487 } 487 }
488 return new Redirection(external_function, type); 488 return new Redirection(external_function, type);
489 } 489 }
490 490
491 static Redirection* FromHltInstruction(Instruction* redirect_call) { 491 static Redirection* FromHltInstruction(Instruction* redirect_call) {
492 char* addr_of_hlt = reinterpret_cast<char*>(redirect_call); 492 char* addr_of_hlt = reinterpret_cast<char*>(redirect_call);
493 char* addr_of_redirection = 493 char* addr_of_redirection =
494 addr_of_hlt - OFFSET_OF(Redirection, redirect_call_); 494 addr_of_hlt - OFFSET_OF(Redirection, redirect_call_);
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; 758 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
759 759
760 const char* Simulator::vreg_names[] = { 760 const char* Simulator::vreg_names[] = {
761 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 761 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
762 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 762 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
763 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 763 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
764 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; 764 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
765 765
766 766
767 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) { 767 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) {
768 ASSERT(code < kNumberOfRegisters); 768 DCHECK(code < kNumberOfRegisters);
769 // If the code represents the stack pointer, index the name after zr. 769 // If the code represents the stack pointer, index the name after zr.
770 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 770 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
771 code = kZeroRegCode + 1; 771 code = kZeroRegCode + 1;
772 } 772 }
773 return wreg_names[code]; 773 return wreg_names[code];
774 } 774 }
775 775
776 776
777 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) { 777 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) {
778 ASSERT(code < kNumberOfRegisters); 778 DCHECK(code < kNumberOfRegisters);
779 // If the code represents the stack pointer, index the name after zr. 779 // If the code represents the stack pointer, index the name after zr.
780 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 780 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
781 code = kZeroRegCode + 1; 781 code = kZeroRegCode + 1;
782 } 782 }
783 return xreg_names[code]; 783 return xreg_names[code];
784 } 784 }
785 785
786 786
787 const char* Simulator::SRegNameForCode(unsigned code) { 787 const char* Simulator::SRegNameForCode(unsigned code) {
788 ASSERT(code < kNumberOfFPRegisters); 788 DCHECK(code < kNumberOfFPRegisters);
789 return sreg_names[code]; 789 return sreg_names[code];
790 } 790 }
791 791
792 792
793 const char* Simulator::DRegNameForCode(unsigned code) { 793 const char* Simulator::DRegNameForCode(unsigned code) {
794 ASSERT(code < kNumberOfFPRegisters); 794 DCHECK(code < kNumberOfFPRegisters);
795 return dreg_names[code]; 795 return dreg_names[code];
796 } 796 }
797 797
798 798
799 const char* Simulator::VRegNameForCode(unsigned code) { 799 const char* Simulator::VRegNameForCode(unsigned code) {
800 ASSERT(code < kNumberOfFPRegisters); 800 DCHECK(code < kNumberOfFPRegisters);
801 return vreg_names[code]; 801 return vreg_names[code];
802 } 802 }
803 803
804 804
805 int Simulator::CodeFromName(const char* name) { 805 int Simulator::CodeFromName(const char* name) {
806 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 806 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
807 if ((strcmp(xreg_names[i], name) == 0) || 807 if ((strcmp(xreg_names[i], name) == 0) ||
808 (strcmp(wreg_names[i], name) == 0)) { 808 (strcmp(wreg_names[i], name) == 0)) {
809 return i; 809 return i;
810 } 810 }
(...skipping 12 matching lines...) Expand all
823 } 823 }
824 824
825 825
826 // Helpers --------------------------------------------------------------------- 826 // Helpers ---------------------------------------------------------------------
827 template <typename T> 827 template <typename T>
828 T Simulator::AddWithCarry(bool set_flags, 828 T Simulator::AddWithCarry(bool set_flags,
829 T src1, 829 T src1,
830 T src2, 830 T src2,
831 T carry_in) { 831 T carry_in) {
832 typedef typename make_unsigned<T>::type unsignedT; 832 typedef typename make_unsigned<T>::type unsignedT;
833 ASSERT((carry_in == 0) || (carry_in == 1)); 833 DCHECK((carry_in == 0) || (carry_in == 1));
834 834
835 T signed_sum = src1 + src2 + carry_in; 835 T signed_sum = src1 + src2 + carry_in;
836 T result = signed_sum; 836 T result = signed_sum;
837 837
838 bool N, Z, C, V; 838 bool N, Z, C, V;
839 839
840 // Compute the C flag 840 // Compute the C flag
841 unsignedT u1 = static_cast<unsignedT>(src1); 841 unsignedT u1 = static_cast<unsignedT>(src1);
842 unsignedT u2 = static_cast<unsignedT>(src2); 842 unsignedT u2 = static_cast<unsignedT>(src2);
843 unsignedT urest = std::numeric_limits<unsignedT>::max() - u1; 843 unsignedT urest = std::numeric_limits<unsignedT>::max() - u1;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 last_nzcv = nzcv(); 1058 last_nzcv = nzcv();
1059 1059
1060 static SimSystemRegister last_fpcr; 1060 static SimSystemRegister last_fpcr;
1061 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) { 1061 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) {
1062 static const char * rmode[] = { 1062 static const char * rmode[] = {
1063 "0b00 (Round to Nearest)", 1063 "0b00 (Round to Nearest)",
1064 "0b01 (Round towards Plus Infinity)", 1064 "0b01 (Round towards Plus Infinity)",
1065 "0b10 (Round towards Minus Infinity)", 1065 "0b10 (Round towards Minus Infinity)",
1066 "0b11 (Round towards Zero)" 1066 "0b11 (Round towards Zero)"
1067 }; 1067 };
1068 ASSERT(fpcr().RMode() <= (sizeof(rmode) / sizeof(rmode[0]))); 1068 DCHECK(fpcr().RMode() <= (sizeof(rmode) / sizeof(rmode[0])));
1069 fprintf(stream_, "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n", 1069 fprintf(stream_, "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
1070 clr_flag_name, 1070 clr_flag_name,
1071 clr_flag_value, 1071 clr_flag_value,
1072 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()], 1072 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
1073 clr_normal); 1073 clr_normal);
1074 } 1074 }
1075 last_fpcr = fpcr(); 1075 last_fpcr = fpcr();
1076 1076
1077 first_run = false; 1077 first_run = false;
1078 } 1078 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 case B: 1198 case B:
1199 set_pc(instr->ImmPCOffsetTarget()); 1199 set_pc(instr->ImmPCOffsetTarget());
1200 break; 1200 break;
1201 default: 1201 default:
1202 UNREACHABLE(); 1202 UNREACHABLE();
1203 } 1203 }
1204 } 1204 }
1205 1205
1206 1206
1207 void Simulator::VisitConditionalBranch(Instruction* instr) { 1207 void Simulator::VisitConditionalBranch(Instruction* instr) {
1208 ASSERT(instr->Mask(ConditionalBranchMask) == B_cond); 1208 DCHECK(instr->Mask(ConditionalBranchMask) == B_cond);
1209 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) { 1209 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) {
1210 set_pc(instr->ImmPCOffsetTarget()); 1210 set_pc(instr->ImmPCOffsetTarget());
1211 } 1211 }
1212 } 1212 }
1213 1213
1214 1214
1215 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { 1215 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) {
1216 Instruction* target = reg<Instruction*>(instr->Rn()); 1216 Instruction* target = reg<Instruction*>(instr->Rn());
1217 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 1217 switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
1218 case BLR: { 1218 case BLR: {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 template<typename T> 1411 template<typename T>
1412 void Simulator::ConditionalCompareHelper(Instruction* instr, T op2) { 1412 void Simulator::ConditionalCompareHelper(Instruction* instr, T op2) {
1413 T op1 = reg<T>(instr->Rn()); 1413 T op1 = reg<T>(instr->Rn());
1414 1414
1415 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 1415 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
1416 // If the condition passes, set the status flags to the result of comparing 1416 // If the condition passes, set the status flags to the result of comparing
1417 // the operands. 1417 // the operands.
1418 if (instr->Mask(ConditionalCompareMask) == CCMP) { 1418 if (instr->Mask(ConditionalCompareMask) == CCMP) {
1419 AddWithCarry<T>(true, op1, ~op2, 1); 1419 AddWithCarry<T>(true, op1, ~op2, 1);
1420 } else { 1420 } else {
1421 ASSERT(instr->Mask(ConditionalCompareMask) == CCMN); 1421 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN);
1422 AddWithCarry<T>(true, op1, op2, 0); 1422 AddWithCarry<T>(true, op1, op2, 0);
1423 } 1423 }
1424 } else { 1424 } else {
1425 // If the condition fails, set the status flags to the nzcv immediate. 1425 // If the condition fails, set the status flags to the nzcv immediate.
1426 nzcv().SetFlags(instr->Nzcv()); 1426 nzcv().SetFlags(instr->Nzcv());
1427 } 1427 }
1428 } 1428 }
1429 1429
1430 1430
1431 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 1431 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
(...skipping 12 matching lines...) Expand all
1444 } 1444 }
1445 1445
1446 1446
1447 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { 1447 void Simulator::VisitLoadStorePostIndex(Instruction* instr) {
1448 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); 1448 LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1449 } 1449 }
1450 1450
1451 1451
1452 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { 1452 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) {
1453 Extend ext = static_cast<Extend>(instr->ExtendMode()); 1453 Extend ext = static_cast<Extend>(instr->ExtendMode());
1454 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); 1454 DCHECK((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
1455 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); 1455 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS();
1456 1456
1457 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount); 1457 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount);
1458 LoadStoreHelper(instr, offset, Offset); 1458 LoadStoreHelper(instr, offset, Offset);
1459 } 1459 }
1460 1460
1461 1461
1462 void Simulator::LoadStoreHelper(Instruction* instr, 1462 void Simulator::LoadStoreHelper(Instruction* instr,
1463 int64_t offset, 1463 int64_t offset,
1464 AddrMode addrmode) { 1464 AddrMode addrmode) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 1579
1580 // For store the address post writeback is used to check access below the 1580 // For store the address post writeback is used to check access below the
1581 // stack. 1581 // stack.
1582 stack = reinterpret_cast<uint8_t*>(sp()); 1582 stack = reinterpret_cast<uint8_t*>(sp());
1583 } 1583 }
1584 1584
1585 LoadStorePairOp op = 1585 LoadStorePairOp op =
1586 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); 1586 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask));
1587 1587
1588 // 'rt' and 'rt2' can only be aliased for stores. 1588 // 'rt' and 'rt2' can only be aliased for stores.
1589 ASSERT(((op & LoadStorePairLBit) == 0) || (rt != rt2)); 1589 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2));
1590 1590
1591 switch (op) { 1591 switch (op) {
1592 case LDP_w: { 1592 case LDP_w: {
1593 set_wreg(rt, MemoryRead32(address)); 1593 set_wreg(rt, MemoryRead32(address));
1594 set_wreg(rt2, MemoryRead32(address + kWRegSize)); 1594 set_wreg(rt2, MemoryRead32(address + kWRegSize));
1595 break; 1595 break;
1596 } 1596 }
1597 case LDP_s: { 1597 case LDP_s: {
1598 set_sreg(rt, MemoryReadFP32(address)); 1598 set_sreg(rt, MemoryReadFP32(address));
1599 set_sreg(rt2, MemoryReadFP32(address + kSRegSize)); 1599 set_sreg(rt2, MemoryReadFP32(address + kSRegSize));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 } 1687 }
1688 1688
1689 return reinterpret_cast<uint8_t*>(address); 1689 return reinterpret_cast<uint8_t*>(address);
1690 } 1690 }
1691 1691
1692 1692
1693 void Simulator::LoadStoreWriteBack(unsigned addr_reg, 1693 void Simulator::LoadStoreWriteBack(unsigned addr_reg,
1694 int64_t offset, 1694 int64_t offset,
1695 AddrMode addrmode) { 1695 AddrMode addrmode) {
1696 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 1696 if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1697 ASSERT(offset != 0); 1697 DCHECK(offset != 0);
1698 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1698 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1699 set_reg(addr_reg, address + offset, Reg31IsStackPointer); 1699 set_reg(addr_reg, address + offset, Reg31IsStackPointer);
1700 } 1700 }
1701 } 1701 }
1702 1702
1703 1703
1704 void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) { 1704 void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) {
1705 if ((address >= stack_limit_) && (address < stack)) { 1705 if ((address >= stack_limit_) && (address < stack)) {
1706 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n"); 1706 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n");
1707 fprintf(stream_, " sp is here: 0x%16p\n", stack); 1707 fprintf(stream_, " sp is here: 0x%16p\n", stack);
1708 fprintf(stream_, " access was here: 0x%16p\n", address); 1708 fprintf(stream_, " access was here: 0x%16p\n", address);
1709 fprintf(stream_, " stack limit is here: 0x%16p\n", stack_limit_); 1709 fprintf(stream_, " stack limit is here: 0x%16p\n", stack_limit_);
1710 fprintf(stream_, "\n"); 1710 fprintf(stream_, "\n");
1711 FATAL("ACCESS BELOW STACK POINTER"); 1711 FATAL("ACCESS BELOW STACK POINTER");
1712 } 1712 }
1713 } 1713 }
1714 1714
1715 1715
1716 uint64_t Simulator::MemoryRead(uint8_t* address, unsigned num_bytes) { 1716 uint64_t Simulator::MemoryRead(uint8_t* address, unsigned num_bytes) {
1717 ASSERT(address != NULL); 1717 DCHECK(address != NULL);
1718 ASSERT((num_bytes > 0) && (num_bytes <= sizeof(uint64_t))); 1718 DCHECK((num_bytes > 0) && (num_bytes <= sizeof(uint64_t)));
1719 uint64_t read = 0; 1719 uint64_t read = 0;
1720 memcpy(&read, address, num_bytes); 1720 memcpy(&read, address, num_bytes);
1721 return read; 1721 return read;
1722 } 1722 }
1723 1723
1724 1724
1725 uint8_t Simulator::MemoryRead8(uint8_t* address) { 1725 uint8_t Simulator::MemoryRead8(uint8_t* address) {
1726 return MemoryRead(address, sizeof(uint8_t)); 1726 return MemoryRead(address, sizeof(uint8_t));
1727 } 1727 }
1728 1728
(...skipping 19 matching lines...) Expand all
1748 1748
1749 1749
1750 double Simulator::MemoryReadFP64(uint8_t* address) { 1750 double Simulator::MemoryReadFP64(uint8_t* address) {
1751 return rawbits_to_double(MemoryRead64(address)); 1751 return rawbits_to_double(MemoryRead64(address));
1752 } 1752 }
1753 1753
1754 1754
1755 void Simulator::MemoryWrite(uint8_t* address, 1755 void Simulator::MemoryWrite(uint8_t* address,
1756 uint64_t value, 1756 uint64_t value,
1757 unsigned num_bytes) { 1757 unsigned num_bytes) {
1758 ASSERT(address != NULL); 1758 DCHECK(address != NULL);
1759 ASSERT((num_bytes > 0) && (num_bytes <= sizeof(uint64_t))); 1759 DCHECK((num_bytes > 0) && (num_bytes <= sizeof(uint64_t)));
1760 1760
1761 LogWrite(address, value, num_bytes); 1761 LogWrite(address, value, num_bytes);
1762 memcpy(address, &value, num_bytes); 1762 memcpy(address, &value, num_bytes);
1763 } 1763 }
1764 1764
1765 1765
1766 void Simulator::MemoryWrite32(uint8_t* address, uint32_t value) { 1766 void Simulator::MemoryWrite32(uint8_t* address, uint32_t value) {
1767 MemoryWrite(address, value, sizeof(uint32_t)); 1767 MemoryWrite(address, value, sizeof(uint32_t));
1768 } 1768 }
1769 1769
(...skipping 13 matching lines...) Expand all
1783 } 1783 }
1784 1784
1785 1785
1786 void Simulator::VisitMoveWideImmediate(Instruction* instr) { 1786 void Simulator::VisitMoveWideImmediate(Instruction* instr) {
1787 MoveWideImmediateOp mov_op = 1787 MoveWideImmediateOp mov_op =
1788 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); 1788 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
1789 int64_t new_xn_val = 0; 1789 int64_t new_xn_val = 0;
1790 1790
1791 bool is_64_bits = instr->SixtyFourBits() == 1; 1791 bool is_64_bits = instr->SixtyFourBits() == 1;
1792 // Shift is limited for W operations. 1792 // Shift is limited for W operations.
1793 ASSERT(is_64_bits || (instr->ShiftMoveWide() < 2)); 1793 DCHECK(is_64_bits || (instr->ShiftMoveWide() < 2));
1794 1794
1795 // Get the shifted immediate. 1795 // Get the shifted immediate.
1796 int64_t shift = instr->ShiftMoveWide() * 16; 1796 int64_t shift = instr->ShiftMoveWide() * 16;
1797 int64_t shifted_imm16 = instr->ImmMoveWide() << shift; 1797 int64_t shifted_imm16 = instr->ImmMoveWide() << shift;
1798 1798
1799 // Compute the new value. 1799 // Compute the new value.
1800 switch (mov_op) { 1800 switch (mov_op) {
1801 case MOVN_w: 1801 case MOVN_w:
1802 case MOVN_x: { 1802 case MOVN_x: {
1803 new_xn_val = ~shifted_imm16; 1803 new_xn_val = ~shifted_imm16;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 case CLS_x: { 1873 case CLS_x: {
1874 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits)); 1874 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits));
1875 break; 1875 break;
1876 } 1876 }
1877 default: UNIMPLEMENTED(); 1877 default: UNIMPLEMENTED();
1878 } 1878 }
1879 } 1879 }
1880 1880
1881 1881
1882 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { 1882 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) {
1883 ASSERT((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits)); 1883 DCHECK((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits));
1884 uint64_t result = 0; 1884 uint64_t result = 0;
1885 for (unsigned i = 0; i < num_bits; i++) { 1885 for (unsigned i = 0; i < num_bits; i++) {
1886 result = (result << 1) | (value & 1); 1886 result = (result << 1) | (value & 1);
1887 value >>= 1; 1887 value >>= 1;
1888 } 1888 }
1889 return result; 1889 return result;
1890 } 1890 }
1891 1891
1892 1892
1893 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { 1893 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) {
1894 // Split the 64-bit value into an 8-bit array, where b[0] is the least 1894 // Split the 64-bit value into an 8-bit array, where b[0] is the least
1895 // significant byte, and b[7] is the most significant. 1895 // significant byte, and b[7] is the most significant.
1896 uint8_t bytes[8]; 1896 uint8_t bytes[8];
1897 uint64_t mask = 0xff00000000000000UL; 1897 uint64_t mask = 0xff00000000000000UL;
1898 for (int i = 7; i >= 0; i--) { 1898 for (int i = 7; i >= 0; i--) {
1899 bytes[i] = (value & mask) >> (i * 8); 1899 bytes[i] = (value & mask) >> (i * 8);
1900 mask >>= 8; 1900 mask >>= 8;
1901 } 1901 }
1902 1902
1903 // Permutation tables for REV instructions. 1903 // Permutation tables for REV instructions.
1904 // permute_table[Reverse16] is used by REV16_x, REV16_w 1904 // permute_table[Reverse16] is used by REV16_x, REV16_w
1905 // permute_table[Reverse32] is used by REV32_x, REV_w 1905 // permute_table[Reverse32] is used by REV32_x, REV_w
1906 // permute_table[Reverse64] is used by REV_x 1906 // permute_table[Reverse64] is used by REV_x
1907 ASSERT((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2)); 1907 DCHECK((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2));
1908 static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1}, 1908 static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1},
1909 {4, 5, 6, 7, 0, 1, 2, 3}, 1909 {4, 5, 6, 7, 0, 1, 2, 3},
1910 {0, 1, 2, 3, 4, 5, 6, 7} }; 1910 {0, 1, 2, 3, 4, 5, 6, 7} };
1911 uint64_t result = 0; 1911 uint64_t result = 0;
1912 for (int i = 0; i < 8; i++) { 1912 for (int i = 0; i < 8; i++) {
1913 result <<= 8; 1913 result <<= 8;
1914 result |= bytes[permute_table[mode][i]]; 1914 result |= bytes[permute_table[mode][i]];
1915 } 1915 }
1916 return result; 1916 return result;
1917 } 1917 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 break; 2020 break;
2021 case MSUB_w: 2021 case MSUB_w:
2022 case MSUB_x: 2022 case MSUB_x:
2023 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm())); 2023 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm()));
2024 break; 2024 break;
2025 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break; 2025 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break;
2026 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break; 2026 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break;
2027 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break; 2027 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break;
2028 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break; 2028 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break;
2029 case SMULH_x: 2029 case SMULH_x:
2030 ASSERT(instr->Ra() == kZeroRegCode); 2030 DCHECK(instr->Ra() == kZeroRegCode);
2031 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); 2031 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm()));
2032 break; 2032 break;
2033 default: UNIMPLEMENTED(); 2033 default: UNIMPLEMENTED();
2034 } 2034 }
2035 2035
2036 if (instr->SixtyFourBits()) { 2036 if (instr->SixtyFourBits()) {
2037 set_xreg(instr->Rd(), result); 2037 set_xreg(instr->Rd(), result);
2038 } else { 2038 } else {
2039 set_wreg(instr->Rd(), result); 2039 set_wreg(instr->Rd(), result);
2040 } 2040 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 // The input value is assumed to be a normalized value. That is, the input may 2400 // The input value is assumed to be a normalized value. That is, the input may
2401 // not be infinity or NaN. If the source value is subnormal, it must be 2401 // not be infinity or NaN. If the source value is subnormal, it must be
2402 // normalized before calling this function such that the highest set bit in the 2402 // normalized before calling this function such that the highest set bit in the
2403 // mantissa has the value 'pow(2, exponent)'. 2403 // mantissa has the value 'pow(2, exponent)'.
2404 // 2404 //
2405 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than 2405 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
2406 // calling a templated FPRound. 2406 // calling a templated FPRound.
2407 template <class T, int ebits, int mbits> 2407 template <class T, int ebits, int mbits>
2408 static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, 2408 static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa,
2409 FPRounding round_mode) { 2409 FPRounding round_mode) {
2410 ASSERT((sign == 0) || (sign == 1)); 2410 DCHECK((sign == 0) || (sign == 1));
2411 2411
2412 // Only the FPTieEven rounding mode is implemented. 2412 // Only the FPTieEven rounding mode is implemented.
2413 ASSERT(round_mode == FPTieEven); 2413 DCHECK(round_mode == FPTieEven);
2414 USE(round_mode); 2414 USE(round_mode);
2415 2415
2416 // Rounding can promote subnormals to normals, and normals to infinities. For 2416 // Rounding can promote subnormals to normals, and normals to infinities. For
2417 // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be 2417 // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
2418 // encodable as a float, but rounding based on the low-order mantissa bits 2418 // encodable as a float, but rounding based on the low-order mantissa bits
2419 // could make it overflow. With ties-to-even rounding, this value would become 2419 // could make it overflow. With ties-to-even rounding, this value would become
2420 // an infinity. 2420 // an infinity.
2421 2421
2422 // ---- Rounding Method ---- 2422 // ---- Rounding Method ----
2423 // 2423 //
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 } 2720 }
2721 } 2721 }
2722 2722
2723 UNREACHABLE(); 2723 UNREACHABLE();
2724 return static_cast<double>(value); 2724 return static_cast<double>(value);
2725 } 2725 }
2726 2726
2727 2727
2728 float Simulator::FPToFloat(double value, FPRounding round_mode) { 2728 float Simulator::FPToFloat(double value, FPRounding round_mode) {
2729 // Only the FPTieEven rounding mode is implemented. 2729 // Only the FPTieEven rounding mode is implemented.
2730 ASSERT(round_mode == FPTieEven); 2730 DCHECK(round_mode == FPTieEven);
2731 USE(round_mode); 2731 USE(round_mode);
2732 2732
2733 switch (std::fpclassify(value)) { 2733 switch (std::fpclassify(value)) {
2734 case FP_NAN: { 2734 case FP_NAN: {
2735 if (fpcr().DN()) return kFP32DefaultNaN; 2735 if (fpcr().DN()) return kFP32DefaultNaN;
2736 2736
2737 // Convert NaNs as the processor would: 2737 // Convert NaNs as the processor would:
2738 // - The sign is propagated. 2738 // - The sign is propagated.
2739 // - The payload (mantissa) is transferred as much as possible, except 2739 // - The payload (mantissa) is transferred as much as possible, except
2740 // that the top bit is forced to '1', making the result a quiet NaN. 2740 // that the top bit is forced to '1', making the result a quiet NaN.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm))); 2849 set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm)));
2850 break; 2850 break;
2851 default: UNIMPLEMENTED(); 2851 default: UNIMPLEMENTED();
2852 } 2852 }
2853 } 2853 }
2854 2854
2855 2855
2856 template <typename T> 2856 template <typename T>
2857 T Simulator::FPAdd(T op1, T op2) { 2857 T Simulator::FPAdd(T op1, T op2) {
2858 // NaNs should be handled elsewhere. 2858 // NaNs should be handled elsewhere.
2859 ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2859 DCHECK(!std::isnan(op1) && !std::isnan(op2));
2860 2860
2861 if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) { 2861 if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
2862 // inf + -inf returns the default NaN. 2862 // inf + -inf returns the default NaN.
2863 return FPDefaultNaN<T>(); 2863 return FPDefaultNaN<T>();
2864 } else { 2864 } else {
2865 // Other cases should be handled by standard arithmetic. 2865 // Other cases should be handled by standard arithmetic.
2866 return op1 + op2; 2866 return op1 + op2;
2867 } 2867 }
2868 } 2868 }
2869 2869
2870 2870
2871 template <typename T> 2871 template <typename T>
2872 T Simulator::FPDiv(T op1, T op2) { 2872 T Simulator::FPDiv(T op1, T op2) {
2873 // NaNs should be handled elsewhere. 2873 // NaNs should be handled elsewhere.
2874 ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2874 DCHECK(!std::isnan(op1) && !std::isnan(op2));
2875 2875
2876 if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) { 2876 if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
2877 // inf / inf and 0.0 / 0.0 return the default NaN. 2877 // inf / inf and 0.0 / 0.0 return the default NaN.
2878 return FPDefaultNaN<T>(); 2878 return FPDefaultNaN<T>();
2879 } else { 2879 } else {
2880 // Other cases should be handled by standard arithmetic. 2880 // Other cases should be handled by standard arithmetic.
2881 return op1 / op2; 2881 return op1 / op2;
2882 } 2882 }
2883 } 2883 }
2884 2884
2885 2885
2886 template <typename T> 2886 template <typename T>
2887 T Simulator::FPMax(T a, T b) { 2887 T Simulator::FPMax(T a, T b) {
2888 // NaNs should be handled elsewhere. 2888 // NaNs should be handled elsewhere.
2889 ASSERT(!std::isnan(a) && !std::isnan(b)); 2889 DCHECK(!std::isnan(a) && !std::isnan(b));
2890 2890
2891 if ((a == 0.0) && (b == 0.0) && 2891 if ((a == 0.0) && (b == 0.0) &&
2892 (copysign(1.0, a) != copysign(1.0, b))) { 2892 (copysign(1.0, a) != copysign(1.0, b))) {
2893 // a and b are zero, and the sign differs: return +0.0. 2893 // a and b are zero, and the sign differs: return +0.0.
2894 return 0.0; 2894 return 0.0;
2895 } else { 2895 } else {
2896 return (a > b) ? a : b; 2896 return (a > b) ? a : b;
2897 } 2897 }
2898 } 2898 }
2899 2899
2900 2900
2901 template <typename T> 2901 template <typename T>
2902 T Simulator::FPMaxNM(T a, T b) { 2902 T Simulator::FPMaxNM(T a, T b) {
2903 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 2903 if (IsQuietNaN(a) && !IsQuietNaN(b)) {
2904 a = kFP64NegativeInfinity; 2904 a = kFP64NegativeInfinity;
2905 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 2905 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
2906 b = kFP64NegativeInfinity; 2906 b = kFP64NegativeInfinity;
2907 } 2907 }
2908 2908
2909 T result = FPProcessNaNs(a, b); 2909 T result = FPProcessNaNs(a, b);
2910 return std::isnan(result) ? result : FPMax(a, b); 2910 return std::isnan(result) ? result : FPMax(a, b);
2911 } 2911 }
2912 2912
2913 template <typename T> 2913 template <typename T>
2914 T Simulator::FPMin(T a, T b) { 2914 T Simulator::FPMin(T a, T b) {
2915 // NaNs should be handled elsewhere. 2915 // NaNs should be handled elsewhere.
2916 ASSERT(!std::isnan(a) && !std::isnan(b)); 2916 DCHECK(!std::isnan(a) && !std::isnan(b));
2917 2917
2918 if ((a == 0.0) && (b == 0.0) && 2918 if ((a == 0.0) && (b == 0.0) &&
2919 (copysign(1.0, a) != copysign(1.0, b))) { 2919 (copysign(1.0, a) != copysign(1.0, b))) {
2920 // a and b are zero, and the sign differs: return -0.0. 2920 // a and b are zero, and the sign differs: return -0.0.
2921 return -0.0; 2921 return -0.0;
2922 } else { 2922 } else {
2923 return (a < b) ? a : b; 2923 return (a < b) ? a : b;
2924 } 2924 }
2925 } 2925 }
2926 2926
2927 2927
2928 template <typename T> 2928 template <typename T>
2929 T Simulator::FPMinNM(T a, T b) { 2929 T Simulator::FPMinNM(T a, T b) {
2930 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 2930 if (IsQuietNaN(a) && !IsQuietNaN(b)) {
2931 a = kFP64PositiveInfinity; 2931 a = kFP64PositiveInfinity;
2932 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 2932 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
2933 b = kFP64PositiveInfinity; 2933 b = kFP64PositiveInfinity;
2934 } 2934 }
2935 2935
2936 T result = FPProcessNaNs(a, b); 2936 T result = FPProcessNaNs(a, b);
2937 return std::isnan(result) ? result : FPMin(a, b); 2937 return std::isnan(result) ? result : FPMin(a, b);
2938 } 2938 }
2939 2939
2940 2940
2941 template <typename T> 2941 template <typename T>
2942 T Simulator::FPMul(T op1, T op2) { 2942 T Simulator::FPMul(T op1, T op2) {
2943 // NaNs should be handled elsewhere. 2943 // NaNs should be handled elsewhere.
2944 ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2944 DCHECK(!std::isnan(op1) && !std::isnan(op2));
2945 2945
2946 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) { 2946 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
2947 // inf * 0.0 returns the default NaN. 2947 // inf * 0.0 returns the default NaN.
2948 return FPDefaultNaN<T>(); 2948 return FPDefaultNaN<T>();
2949 } else { 2949 } else {
2950 // Other cases should be handled by standard arithmetic. 2950 // Other cases should be handled by standard arithmetic.
2951 return op1 * op2; 2951 return op1 * op2;
2952 } 2952 }
2953 } 2953 }
2954 2954
(...skipping 24 matching lines...) Expand all
2979 return FPDefaultNaN<T>(); 2979 return FPDefaultNaN<T>();
2980 } 2980 }
2981 2981
2982 // Work around broken fma implementations for exact zero results: The sign of 2982 // Work around broken fma implementations for exact zero results: The sign of
2983 // exact 0.0 results is positive unless both a and op1 * op2 are negative. 2983 // exact 0.0 results is positive unless both a and op1 * op2 are negative.
2984 if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) { 2984 if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
2985 return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0; 2985 return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
2986 } 2986 }
2987 2987
2988 result = FusedMultiplyAdd(op1, op2, a); 2988 result = FusedMultiplyAdd(op1, op2, a);
2989 ASSERT(!std::isnan(result)); 2989 DCHECK(!std::isnan(result));
2990 2990
2991 // Work around broken fma implementations for rounded zero results: If a is 2991 // Work around broken fma implementations for rounded zero results: If a is
2992 // 0.0, the sign of the result is the sign of op1 * op2 before rounding. 2992 // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
2993 if ((a == 0.0) && (result == 0.0)) { 2993 if ((a == 0.0) && (result == 0.0)) {
2994 return copysign(0.0, sign_prod); 2994 return copysign(0.0, sign_prod);
2995 } 2995 }
2996 2996
2997 return result; 2997 return result;
2998 } 2998 }
2999 2999
3000 3000
3001 template <typename T> 3001 template <typename T>
3002 T Simulator::FPSqrt(T op) { 3002 T Simulator::FPSqrt(T op) {
3003 if (std::isnan(op)) { 3003 if (std::isnan(op)) {
3004 return FPProcessNaN(op); 3004 return FPProcessNaN(op);
3005 } else if (op < 0.0) { 3005 } else if (op < 0.0) {
3006 return FPDefaultNaN<T>(); 3006 return FPDefaultNaN<T>();
3007 } else { 3007 } else {
3008 return std::sqrt(op); 3008 return std::sqrt(op);
3009 } 3009 }
3010 } 3010 }
3011 3011
3012 3012
3013 template <typename T> 3013 template <typename T>
3014 T Simulator::FPSub(T op1, T op2) { 3014 T Simulator::FPSub(T op1, T op2) {
3015 // NaNs should be handled elsewhere. 3015 // NaNs should be handled elsewhere.
3016 ASSERT(!std::isnan(op1) && !std::isnan(op2)); 3016 DCHECK(!std::isnan(op1) && !std::isnan(op2));
3017 3017
3018 if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) { 3018 if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
3019 // inf - inf returns the default NaN. 3019 // inf - inf returns the default NaN.
3020 return FPDefaultNaN<T>(); 3020 return FPDefaultNaN<T>();
3021 } else { 3021 } else {
3022 // Other cases should be handled by standard arithmetic. 3022 // Other cases should be handled by standard arithmetic.
3023 return op1 - op2; 3023 return op1 - op2;
3024 } 3024 }
3025 } 3025 }
3026 3026
3027 3027
3028 template <typename T> 3028 template <typename T>
3029 T Simulator::FPProcessNaN(T op) { 3029 T Simulator::FPProcessNaN(T op) {
3030 ASSERT(std::isnan(op)); 3030 DCHECK(std::isnan(op));
3031 return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 3031 return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
3032 } 3032 }
3033 3033
3034 3034
3035 template <typename T> 3035 template <typename T>
3036 T Simulator::FPProcessNaNs(T op1, T op2) { 3036 T Simulator::FPProcessNaNs(T op1, T op2) {
3037 if (IsSignallingNaN(op1)) { 3037 if (IsSignallingNaN(op1)) {
3038 return FPProcessNaN(op1); 3038 return FPProcessNaN(op1);
3039 } else if (IsSignallingNaN(op2)) { 3039 } else if (IsSignallingNaN(op2)) {
3040 return FPProcessNaN(op2); 3040 return FPProcessNaN(op2);
3041 } else if (std::isnan(op1)) { 3041 } else if (std::isnan(op1)) {
3042 ASSERT(IsQuietNaN(op1)); 3042 DCHECK(IsQuietNaN(op1));
3043 return FPProcessNaN(op1); 3043 return FPProcessNaN(op1);
3044 } else if (std::isnan(op2)) { 3044 } else if (std::isnan(op2)) {
3045 ASSERT(IsQuietNaN(op2)); 3045 DCHECK(IsQuietNaN(op2));
3046 return FPProcessNaN(op2); 3046 return FPProcessNaN(op2);
3047 } else { 3047 } else {
3048 return 0.0; 3048 return 0.0;
3049 } 3049 }
3050 } 3050 }
3051 3051
3052 3052
3053 template <typename T> 3053 template <typename T>
3054 T Simulator::FPProcessNaNs3(T op1, T op2, T op3) { 3054 T Simulator::FPProcessNaNs3(T op1, T op2, T op3) {
3055 if (IsSignallingNaN(op1)) { 3055 if (IsSignallingNaN(op1)) {
3056 return FPProcessNaN(op1); 3056 return FPProcessNaN(op1);
3057 } else if (IsSignallingNaN(op2)) { 3057 } else if (IsSignallingNaN(op2)) {
3058 return FPProcessNaN(op2); 3058 return FPProcessNaN(op2);
3059 } else if (IsSignallingNaN(op3)) { 3059 } else if (IsSignallingNaN(op3)) {
3060 return FPProcessNaN(op3); 3060 return FPProcessNaN(op3);
3061 } else if (std::isnan(op1)) { 3061 } else if (std::isnan(op1)) {
3062 ASSERT(IsQuietNaN(op1)); 3062 DCHECK(IsQuietNaN(op1));
3063 return FPProcessNaN(op1); 3063 return FPProcessNaN(op1);
3064 } else if (std::isnan(op2)) { 3064 } else if (std::isnan(op2)) {
3065 ASSERT(IsQuietNaN(op2)); 3065 DCHECK(IsQuietNaN(op2));
3066 return FPProcessNaN(op2); 3066 return FPProcessNaN(op2);
3067 } else if (std::isnan(op3)) { 3067 } else if (std::isnan(op3)) {
3068 ASSERT(IsQuietNaN(op3)); 3068 DCHECK(IsQuietNaN(op3));
3069 return FPProcessNaN(op3); 3069 return FPProcessNaN(op3);
3070 } else { 3070 } else {
3071 return 0.0; 3071 return 0.0;
3072 } 3072 }
3073 } 3073 }
3074 3074
3075 3075
3076 bool Simulator::FPProcessNaNs(Instruction* instr) { 3076 bool Simulator::FPProcessNaNs(Instruction* instr) {
3077 unsigned fd = instr->Rd(); 3077 unsigned fd = instr->Rd();
3078 unsigned fn = instr->Rn(); 3078 unsigned fn = instr->Rn();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3114 case MSR: { 3114 case MSR: {
3115 switch (instr->ImmSystemRegister()) { 3115 switch (instr->ImmSystemRegister()) {
3116 case NZCV: nzcv().SetRawValue(xreg(instr->Rt())); break; 3116 case NZCV: nzcv().SetRawValue(xreg(instr->Rt())); break;
3117 case FPCR: fpcr().SetRawValue(xreg(instr->Rt())); break; 3117 case FPCR: fpcr().SetRawValue(xreg(instr->Rt())); break;
3118 default: UNIMPLEMENTED(); 3118 default: UNIMPLEMENTED();
3119 } 3119 }
3120 break; 3120 break;
3121 } 3121 }
3122 } 3122 }
3123 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 3123 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
3124 ASSERT(instr->Mask(SystemHintMask) == HINT); 3124 DCHECK(instr->Mask(SystemHintMask) == HINT);
3125 switch (instr->ImmHint()) { 3125 switch (instr->ImmHint()) {
3126 case NOP: break; 3126 case NOP: break;
3127 default: UNIMPLEMENTED(); 3127 default: UNIMPLEMENTED();
3128 } 3128 }
3129 } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { 3129 } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) {
3130 __sync_synchronize(); 3130 __sync_synchronize();
3131 } else { 3131 } else {
3132 UNIMPLEMENTED(); 3132 UNIMPLEMENTED();
3133 } 3133 }
3134 } 3134 }
(...skipping 22 matching lines...) Expand all
3157 reinterpret_cast<uint64_t*>(value)) == 1; 3157 reinterpret_cast<uint64_t*>(value)) == 1;
3158 } else { 3158 } else {
3159 return SScanF(desc, "%" SCNu64, 3159 return SScanF(desc, "%" SCNu64,
3160 reinterpret_cast<uint64_t*>(value)) == 1; 3160 reinterpret_cast<uint64_t*>(value)) == 1;
3161 } 3161 }
3162 } 3162 }
3163 3163
3164 3164
3165 bool Simulator::PrintValue(const char* desc) { 3165 bool Simulator::PrintValue(const char* desc) {
3166 if (strcmp(desc, "csp") == 0) { 3166 if (strcmp(desc, "csp") == 0) {
3167 ASSERT(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode)); 3167 DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
3168 PrintF(stream_, "%s csp:%s 0x%016" PRIx64 "%s\n", 3168 PrintF(stream_, "%s csp:%s 0x%016" PRIx64 "%s\n",
3169 clr_reg_name, clr_reg_value, xreg(31, Reg31IsStackPointer), clr_normal); 3169 clr_reg_name, clr_reg_value, xreg(31, Reg31IsStackPointer), clr_normal);
3170 return true; 3170 return true;
3171 } else if (strcmp(desc, "wcsp") == 0) { 3171 } else if (strcmp(desc, "wcsp") == 0) {
3172 ASSERT(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode)); 3172 DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
3173 PrintF(stream_, "%s wcsp:%s 0x%08" PRIx32 "%s\n", 3173 PrintF(stream_, "%s wcsp:%s 0x%08" PRIx32 "%s\n",
3174 clr_reg_name, clr_reg_value, wreg(31, Reg31IsStackPointer), clr_normal); 3174 clr_reg_name, clr_reg_value, wreg(31, Reg31IsStackPointer), clr_normal);
3175 return true; 3175 return true;
3176 } 3176 }
3177 3177
3178 int i = CodeFromName(desc); 3178 int i = CodeFromName(desc);
3179 STATIC_ASSERT(kNumberOfRegisters == kNumberOfFPRegisters); 3179 STATIC_ASSERT(kNumberOfRegisters == kNumberOfFPRegisters);
3180 if (i < 0 || static_cast<unsigned>(i) >= kNumberOfFPRegisters) return false; 3180 if (i < 0 || static_cast<unsigned>(i) >= kNumberOfFPRegisters) return false;
3181 3181
3182 if (desc[0] == 'v') { 3182 if (desc[0] == 'v') {
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
3554 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); } 3554 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); }
3555 break; 3555 break;
3556 case TRACE_DISABLE: 3556 case TRACE_DISABLE:
3557 set_log_parameters(log_parameters() & ~parameters); 3557 set_log_parameters(log_parameters() & ~parameters);
3558 break; 3558 break;
3559 case TRACE_OVERRIDE: 3559 case TRACE_OVERRIDE:
3560 set_log_parameters(parameters); 3560 set_log_parameters(parameters);
3561 break; 3561 break;
3562 default: 3562 default:
3563 // We don't support a one-shot LOG_DISASM. 3563 // We don't support a one-shot LOG_DISASM.
3564 ASSERT((parameters & LOG_DISASM) == 0); 3564 DCHECK((parameters & LOG_DISASM) == 0);
3565 // Don't print information that is already being traced. 3565 // Don't print information that is already being traced.
3566 parameters &= ~log_parameters(); 3566 parameters &= ~log_parameters();
3567 // Print the requested information. 3567 // Print the requested information.
3568 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true); 3568 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true);
3569 if (parameters & LOG_REGS) PrintRegisters(true); 3569 if (parameters & LOG_REGS) PrintRegisters(true);
3570 if (parameters & LOG_FP_REGS) PrintFPRegisters(true); 3570 if (parameters & LOG_FP_REGS) PrintFPRegisters(true);
3571 } 3571 }
3572 3572
3573 // The stop parameters are inlined in the code. Skip them: 3573 // The stop parameters are inlined in the code. Skip them:
3574 // - Skip to the end of the message string. 3574 // - Skip to the end of the message string.
3575 size_t size = kDebugMessageOffset + strlen(message) + 1; 3575 size_t size = kDebugMessageOffset + strlen(message) + 1;
3576 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize)); 3576 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize));
3577 // - Verify that the unreachable marker is present. 3577 // - Verify that the unreachable marker is present.
3578 ASSERT(pc_->Mask(ExceptionMask) == HLT); 3578 DCHECK(pc_->Mask(ExceptionMask) == HLT);
3579 ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable); 3579 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable);
3580 // - Skip past the unreachable marker. 3580 // - Skip past the unreachable marker.
3581 set_pc(pc_->following()); 3581 set_pc(pc_->following());
3582 3582
3583 // Check if the debugger should break. 3583 // Check if the debugger should break.
3584 if (parameters & BREAK) Debug(); 3584 if (parameters & BREAK) Debug();
3585 3585
3586 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { 3586 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) {
3587 DoRuntimeCall(instr); 3587 DoRuntimeCall(instr);
3588 } else if (instr->ImmException() == kImmExceptionIsPrintf) { 3588 } else if (instr->ImmException() == kImmExceptionIsPrintf) {
3589 DoPrintf(instr); 3589 DoPrintf(instr);
3590 3590
3591 } else if (instr->ImmException() == kImmExceptionIsUnreachable) { 3591 } else if (instr->ImmException() == kImmExceptionIsUnreachable) {
3592 fprintf(stream_, "Hit UNREACHABLE marker at PC=%p.\n", 3592 fprintf(stream_, "Hit UNREACHABLE marker at PC=%p.\n",
3593 reinterpret_cast<void*>(pc_)); 3593 reinterpret_cast<void*>(pc_));
3594 abort(); 3594 abort();
3595 3595
3596 } else { 3596 } else {
3597 base::OS::DebugBreak(); 3597 base::OS::DebugBreak();
3598 } 3598 }
3599 break; 3599 break;
3600 } 3600 }
3601 3601
3602 default: 3602 default:
3603 UNIMPLEMENTED(); 3603 UNIMPLEMENTED();
3604 } 3604 }
3605 } 3605 }
3606 3606
3607 3607
3608 void Simulator::DoPrintf(Instruction* instr) { 3608 void Simulator::DoPrintf(Instruction* instr) {
3609 ASSERT((instr->Mask(ExceptionMask) == HLT) && 3609 DCHECK((instr->Mask(ExceptionMask) == HLT) &&
3610 (instr->ImmException() == kImmExceptionIsPrintf)); 3610 (instr->ImmException() == kImmExceptionIsPrintf));
3611 3611
3612 // Read the arguments encoded inline in the instruction stream. 3612 // Read the arguments encoded inline in the instruction stream.
3613 uint32_t arg_count; 3613 uint32_t arg_count;
3614 uint32_t arg_pattern_list; 3614 uint32_t arg_pattern_list;
3615 STATIC_ASSERT(sizeof(*instr) == 1); 3615 STATIC_ASSERT(sizeof(*instr) == 1);
3616 memcpy(&arg_count, 3616 memcpy(&arg_count,
3617 instr + kPrintfArgCountOffset, 3617 instr + kPrintfArgCountOffset,
3618 sizeof(arg_count)); 3618 sizeof(arg_count));
3619 memcpy(&arg_pattern_list, 3619 memcpy(&arg_pattern_list,
3620 instr + kPrintfArgPatternListOffset, 3620 instr + kPrintfArgPatternListOffset,
3621 sizeof(arg_pattern_list)); 3621 sizeof(arg_pattern_list));
3622 3622
3623 ASSERT(arg_count <= kPrintfMaxArgCount); 3623 DCHECK(arg_count <= kPrintfMaxArgCount);
3624 ASSERT((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0); 3624 DCHECK((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0);
3625 3625
3626 // We need to call the host printf function with a set of arguments defined by 3626 // We need to call the host printf function with a set of arguments defined by
3627 // arg_pattern_list. Because we don't know the types and sizes of the 3627 // arg_pattern_list. Because we don't know the types and sizes of the
3628 // arguments, this is very difficult to do in a robust and portable way. To 3628 // arguments, this is very difficult to do in a robust and portable way. To
3629 // work around the problem, we pick apart the format string, and print one 3629 // work around the problem, we pick apart the format string, and print one
3630 // format placeholder at a time. 3630 // format placeholder at a time.
3631 3631
3632 // Allocate space for the format string. We take a copy, so we can modify it. 3632 // Allocate space for the format string. We take a copy, so we can modify it.
3633 // Leave enough space for one extra character per expected argument (plus the 3633 // Leave enough space for one extra character per expected argument (plus the
3634 // '\0' termination). 3634 // '\0' termination).
3635 const char * format_base = reg<const char *>(0); 3635 const char * format_base = reg<const char *>(0);
3636 ASSERT(format_base != NULL); 3636 DCHECK(format_base != NULL);
3637 size_t length = strlen(format_base) + 1; 3637 size_t length = strlen(format_base) + 1;
3638 char * const format = new char[length + arg_count]; 3638 char * const format = new char[length + arg_count];
3639 3639
3640 // A list of chunks, each with exactly one format placeholder. 3640 // A list of chunks, each with exactly one format placeholder.
3641 const char * chunks[kPrintfMaxArgCount]; 3641 const char * chunks[kPrintfMaxArgCount];
3642 3642
3643 // Copy the format string and search for format placeholders. 3643 // Copy the format string and search for format placeholders.
3644 uint32_t placeholder_count = 0; 3644 uint32_t placeholder_count = 0;
3645 char * format_scratch = format; 3645 char * format_scratch = format;
3646 for (size_t i = 0; i < length; i++) { 3646 for (size_t i = 0; i < length; i++) {
(...skipping 14 matching lines...) Expand all
3661 } 3661 }
3662 } else { 3662 } else {
3663 CHECK(placeholder_count < arg_count); 3663 CHECK(placeholder_count < arg_count);
3664 // Insert '\0' before placeholders, and store their locations. 3664 // Insert '\0' before placeholders, and store their locations.
3665 *format_scratch++ = '\0'; 3665 *format_scratch++ = '\0';
3666 chunks[placeholder_count++] = format_scratch; 3666 chunks[placeholder_count++] = format_scratch;
3667 *format_scratch++ = format_base[i]; 3667 *format_scratch++ = format_base[i];
3668 } 3668 }
3669 } 3669 }
3670 } 3670 }
3671 ASSERT(format_scratch <= (format + length + arg_count)); 3671 DCHECK(format_scratch <= (format + length + arg_count));
3672 CHECK(placeholder_count == arg_count); 3672 CHECK(placeholder_count == arg_count);
3673 3673
3674 // Finally, call printf with each chunk, passing the appropriate register 3674 // Finally, call printf with each chunk, passing the appropriate register
3675 // argument. Normally, printf returns the number of bytes transmitted, so we 3675 // argument. Normally, printf returns the number of bytes transmitted, so we
3676 // can emulate a single printf call by adding the result from each chunk. If 3676 // can emulate a single printf call by adding the result from each chunk. If
3677 // any call returns a negative (error) value, though, just return that value. 3677 // any call returns a negative (error) value, though, just return that value.
3678 3678
3679 fprintf(stream_, "%s", clr_printf); 3679 fprintf(stream_, "%s", clr_printf);
3680 3680
3681 // Because '\0' is inserted before each placeholder, the first string in 3681 // Because '\0' is inserted before each placeholder, the first string in
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3729 3729
3730 delete[] format; 3730 delete[] format;
3731 } 3731 }
3732 3732
3733 3733
3734 #endif // USE_SIMULATOR 3734 #endif // USE_SIMULATOR
3735 3735
3736 } } // namespace v8::internal 3736 } } // namespace v8::internal
3737 3737
3738 #endif // V8_TARGET_ARCH_ARM64 3738 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | src/arm64/stub-cache-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698