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

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

Issue 67163: Avoid a call to the runtime system when doing binary fp ops on ARM... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 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/simulator-arm.h ('k') | src/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 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 Debugger::Debugger(Simulator* sim) { 84 Debugger::Debugger(Simulator* sim) {
85 sim_ = sim; 85 sim_ = sim;
86 } 86 }
87 87
88 88
89 Debugger::~Debugger() { 89 Debugger::~Debugger() {
90 } 90 }
91 91
92 92
93
94 #ifdef ARM_GENERATED_CODE_COVERAGE
95 static FILE* coverage_log = NULL;
96
97
98 static void InitializeCoverage() {
99 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
100 if (file_name != NULL) {
101 coverage_log = fopen(file_name, "aw+");
102 }
103 }
104
105
106 void Debugger::Stop(Instr* instr) {
107 char* str = reinterpret_cast<char*>(instr->InstructionBits() & 0x0fffffff);
108 if (strlen(str) > 0) {
109 if (coverage_log != NULL) {
110 fprintf(coverage_log, "Simulator hit %s\n", str);
111 fflush(coverage_log);
112 }
113 instr->SetInstructionBits(0xe1a00000); // Overwrite with nop.
114 }
115 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
116 }
117
118 #else // ndef ARM_GENERATED_CODE_COVERAGE
119
120 static void InitializeCoverage() {
121 }
122
123
93 void Debugger::Stop(Instr* instr) { 124 void Debugger::Stop(Instr* instr) {
94 const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff); 125 const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
95 PrintF("Simulator hit %s\n", str); 126 PrintF("Simulator hit %s\n", str);
96 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize); 127 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
97 Debug(); 128 Debug();
98 } 129 }
130 #endif
99 131
100 132
101 static const char* reg_names[] = { "r0", "r1", "r2", "r3", 133 static const char* reg_names[] = { "r0", "r1", "r2", "r3",
102 "r4", "r5", "r6", "r7", 134 "r4", "r5", "r6", "r7",
103 "r8", "r9", "r10", "r11", 135 "r8", "r9", "r10", "r11",
104 "r12", "r13", "r14", "r15", 136 "r12", "r13", "r14", "r15",
105 "pc", "lr", "sp", "ip", 137 "pc", "lr", "sp", "ip",
106 "fp", "sl", ""}; 138 "fp", "sl", ""};
107 139
108 static int reg_nums[] = { 0, 1, 2, 3, 140 static int reg_nums[] = { 0, 1, 2, 3,
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 v_flag_ = false; 400 v_flag_ = false;
369 401
370 // The sp is initialized to point to the bottom (high address) of the 402 // The sp is initialized to point to the bottom (high address) of the
371 // allocated stack area. To be safe in potential stack underflows we leave 403 // allocated stack area. To be safe in potential stack underflows we leave
372 // some buffer below. 404 // some buffer below.
373 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; 405 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;
374 // The lr and pc are initialized to a known bad value that will cause an 406 // The lr and pc are initialized to a known bad value that will cause an
375 // access violation if the simulator ever tries to execute it. 407 // access violation if the simulator ever tries to execute it.
376 registers_[pc] = bad_lr; 408 registers_[pc] = bad_lr;
377 registers_[lr] = bad_lr; 409 registers_[lr] = bad_lr;
410 InitializeCoverage();
378 } 411 }
379 412
380 413
381 // Create one simulator per thread and keep it in thread local storage. 414 // Create one simulator per thread and keep it in thread local storage.
382 static v8::internal::Thread::LocalStorageKey simulator_key = 415 static v8::internal::Thread::LocalStorageKey simulator_key =
383 v8::internal::Thread::CreateThreadLocalKey(); 416 v8::internal::Thread::CreateThreadLocalKey();
384 417
385 // Get the active Simulator for the current thread. 418 // Get the active Simulator for the current thread.
386 Simulator* Simulator::current() { 419 Simulator* Simulator::current() {
387 Simulator* sim = reinterpret_cast<Simulator*>( 420 Simulator* sim = reinterpret_cast<Simulator*>(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 registers_[pc] = value; 453 registers_[pc] = value;
421 } 454 }
422 455
423 456
424 // Raw access to the PC register without the special adjustment when reading. 457 // Raw access to the PC register without the special adjustment when reading.
425 int32_t Simulator::get_pc() const { 458 int32_t Simulator::get_pc() const {
426 return registers_[pc]; 459 return registers_[pc];
427 } 460 }
428 461
429 462
463 // For use in calls that take two double values, constructed from r0, r1, r2
464 // and r3.
465 void Simulator::GetFpArgs(double* x, double* y) {
466 // We use a char buffer to get around the strict-aliasing rules which
467 // otherwise allow the compiler to optimize away the copy.
468 char buffer[2 * sizeof(registers_[0])];
469 // Registers 0 and 1 -> x.
470 memcpy(buffer, registers_, sizeof(buffer));
471 memcpy(x, buffer, sizeof(buffer));
472 // Registers 2 and 3 -> y.
473 memcpy(buffer, registers_ + 2, sizeof(buffer));
474 memcpy(y, buffer, sizeof(buffer));
475 }
476
477
478 void Simulator::SetFpResult(const double& result) {
479 char buffer[2 * sizeof(registers_[0])];
480 memcpy(buffer, &result, sizeof(buffer));
481 // result -> registers 0 and 1.
482 memcpy(registers_, buffer, sizeof(buffer));
483 }
484
485
486 void Simulator::TrashCallerSaveRegisters() {
487 // We don't trash the registers with the return value.
488 registers_[2] = 0x50Bad4U;
489 registers_[3] = 0x50Bad4U;
490 registers_[12] = 0x50Bad4U;
491 }
492
493
430 // The ARM cannot do unaligned reads and writes. On some ARM platforms an 494 // The ARM cannot do unaligned reads and writes. On some ARM platforms an
431 // interrupt is caused. On others it does a funky rotation thing. For now we 495 // interrupt is caused. On others it does a funky rotation thing. For now we
432 // simply disallow unaligned reads, but at some point we may want to move to 496 // simply disallow unaligned reads, but at some point we may want to move to
433 // emulating the rotate behaviour. Note that simulator runs have the runtime 497 // emulating the rotate behaviour. Note that simulator runs have the runtime
434 // system running directly on the host system and only generated code is 498 // system running directly on the host system and only generated code is
435 // executed in the simulator. Since the host is typically IA32 we will not 499 // executed in the simulator. Since the host is typically IA32 we will not
436 // get the correct ARM-like behaviour on unaligned accesses. 500 // get the correct ARM-like behaviour on unaligned accesses.
437 501
438 int Simulator::ReadW(int32_t addr, Instr* instr) { 502 int Simulator::ReadW(int32_t addr, Instr* instr) {
439 if ((addr & 3) == 0) { 503 if ((addr & 3) == 0) {
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // uses the ObjectPair which is essentially two 32-bit values stuffed into a 919 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
856 // 64-bit value. With the code below we assume that all runtime calls return 920 // 64-bit value. With the code below we assume that all runtime calls return
857 // 64 bits of result. If they don't, the r1 result register contains a bogus 921 // 64 bits of result. If they don't, the r1 result register contains a bogus
858 // value, which is fine because it is caller-saved. 922 // value, which is fine because it is caller-saved.
859 typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1); 923 typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1);
860 924
861 925
862 // Software interrupt instructions are used by the simulator to call into the 926 // Software interrupt instructions are used by the simulator to call into the
863 // C-based V8 runtime. 927 // C-based V8 runtime.
864 void Simulator::SoftwareInterrupt(Instr* instr) { 928 void Simulator::SoftwareInterrupt(Instr* instr) {
865 switch (instr->SwiField()) { 929 int swi = instr->SwiField();
930 switch (swi) {
866 case call_rt_r5: { 931 case call_rt_r5: {
867 SimulatorRuntimeCall target = 932 SimulatorRuntimeCall target =
868 reinterpret_cast<SimulatorRuntimeCall>(get_register(r5)); 933 reinterpret_cast<SimulatorRuntimeCall>(get_register(r5));
869 intptr_t arg0 = get_register(r0); 934 intptr_t arg0 = get_register(r0);
870 intptr_t arg1 = get_register(r1); 935 intptr_t arg1 = get_register(r1);
871 int64_t result = target(arg0, arg1); 936 int64_t result = target(arg0, arg1);
872 int32_t lo_res = static_cast<int32_t>(result); 937 int32_t lo_res = static_cast<int32_t>(result);
873 int32_t hi_res = static_cast<int32_t>(result >> 32); 938 int32_t hi_res = static_cast<int32_t>(result >> 32);
874 set_register(r0, lo_res); 939 set_register(r0, lo_res);
875 set_register(r1, hi_res); 940 set_register(r1, hi_res);
(...skipping 11 matching lines...) Expand all
887 set_register(r0, lo_res); 952 set_register(r0, lo_res);
888 set_register(r1, hi_res); 953 set_register(r1, hi_res);
889 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); 954 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
890 break; 955 break;
891 } 956 }
892 case break_point: { 957 case break_point: {
893 Debugger dbg(this); 958 Debugger dbg(this);
894 dbg.Debug(); 959 dbg.Debug();
895 break; 960 break;
896 } 961 }
962 {
963 double x, y, z;
964 case simulator_fp_add:
965 GetFpArgs(&x, &y);
966 z = x + y;
967 SetFpResult(z);
968 TrashCallerSaveRegisters();
969 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
970 break;
971 case simulator_fp_sub:
972 GetFpArgs(&x, &y);
973 z = x - y;
974 SetFpResult(z);
975 TrashCallerSaveRegisters();
976 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
977 break;
978 case simulator_fp_mul:
979 GetFpArgs(&x, &y);
980 z = x * y;
981 SetFpResult(z);
982 TrashCallerSaveRegisters();
983 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
984 break;
985 }
897 default: { 986 default: {
898 UNREACHABLE(); 987 UNREACHABLE();
899 break; 988 break;
900 } 989 }
901 } 990 }
902 } 991 }
903 992
904 993
905 // Handle execution based on instruction types. 994 // Handle execution based on instruction types.
906 995
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 set_register(r10, r10_val); 1678 set_register(r10, r10_val);
1590 set_register(r11, r11_val); 1679 set_register(r11, r11_val);
1591 1680
1592 int result = get_register(r0); 1681 int result = get_register(r0);
1593 return reinterpret_cast<Object*>(result); 1682 return reinterpret_cast<Object*>(result);
1594 } 1683 }
1595 1684
1596 } } // namespace assembler::arm 1685 } } // namespace assembler::arm
1597 1686
1598 #endif // !defined(__arm__) 1687 #endif // !defined(__arm__)
OLDNEW
« no previous file with comments | « src/simulator-arm.h ('k') | src/stub-cache-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698