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

Side by Side Diff: src/mips/codegen-mips.cc

Issue 11415192: MIPS: Faster implementation of Math.exp() (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years 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/mips/codegen-mips.h ('k') | src/mips/lithium-codegen-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #if defined(V8_TARGET_ARCH_MIPS) 30 #if defined(V8_TARGET_ARCH_MIPS)
31 31
32 #include "codegen.h" 32 #include "codegen.h"
33 #include "macro-assembler.h" 33 #include "macro-assembler.h"
34 #include "simulator-mips.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 #define __ ACCESS_MASM(masm)
39 39
40 UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) { 40 UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
41 switch (type) { 41 switch (type) {
42 case TranscendentalCache::SIN: return &sin; 42 case TranscendentalCache::SIN: return &sin;
43 case TranscendentalCache::COS: return &cos; 43 case TranscendentalCache::COS: return &cos;
44 case TranscendentalCache::TAN: return &tan; 44 case TranscendentalCache::TAN: return &tan;
45 case TranscendentalCache::LOG: return &log; 45 case TranscendentalCache::LOG: return &log;
46 default: UNIMPLEMENTED(); 46 default: UNIMPLEMENTED();
47 } 47 }
48 return NULL; 48 return NULL;
49 } 49 }
50 50
51 51
52 #define __ masm.
53
54
55 #if defined(USE_SIMULATOR)
56 byte* fast_exp_mips_machine_code = NULL;
57 double fast_exp_simulator(double x) {
58 return Simulator::current(Isolate::Current())->CallFP(
59 fast_exp_mips_machine_code, x, 0);
60 }
61 #endif
62
63
64 UnaryMathFunction CreateExpFunction() {
65 if (!CpuFeatures::IsSupported(FPU)) return &exp;
66 if (!FLAG_fast_math) return &exp;
67 size_t actual_size;
68 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
69 if (buffer == NULL) return &exp;
70 ExternalReference::InitializeMathExpData();
71
72 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
73
74 {
75 CpuFeatures::Scope use_fpu(FPU);
76 DoubleRegister input = f12;
77 DoubleRegister result = f0;
78 DoubleRegister double_scratch1 = f4;
79 DoubleRegister double_scratch2 = f6;
80 Register temp1 = t0;
81 Register temp2 = t1;
82 Register temp3 = t2;
83
84 if (!IsMipsSoftFloatABI) {
85 // Input value is in f12 anyway, nothing to do.
86 } else {
87 __ Move(input, a0, a1);
88 }
89 __ Push(temp3, temp2, temp1);
90 MathExpGenerator::EmitMathExp(
91 &masm, input, result, double_scratch1, double_scratch2,
92 temp1, temp2, temp3);
93 __ Pop(temp3, temp2, temp1);
94 if (!IsMipsSoftFloatABI) {
95 // Result is already in f0, nothing to do.
96 } else {
97 __ Move(a0, a1, result);
98 }
99 __ Ret();
100 }
101
102 CodeDesc desc;
103 masm.GetCode(&desc);
104
105 CPU::FlushICache(buffer, actual_size);
106 OS::ProtectCode(buffer, actual_size);
107
108 #if !defined(USE_SIMULATOR)
109 return FUNCTION_CAST<UnaryMathFunction>(buffer);
110 #else
111 fast_exp_mips_machine_code = buffer;
112 return &fast_exp_simulator;
113 #endif
114 }
115
116
117 #undef __
118
119
52 UnaryMathFunction CreateSqrtFunction() { 120 UnaryMathFunction CreateSqrtFunction() {
53 return &sqrt; 121 return &sqrt;
54 } 122 }
55 123
56 // ------------------------------------------------------------------------- 124 // -------------------------------------------------------------------------
57 // Platform-specific RuntimeCallHelper functions. 125 // Platform-specific RuntimeCallHelper functions.
58 126
59 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { 127 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
60 masm->EnterFrame(StackFrame::INTERNAL); 128 masm->EnterFrame(StackFrame::INTERNAL);
61 ASSERT(!masm->has_frame()); 129 ASSERT(!masm->has_frame());
62 masm->set_has_frame(true); 130 masm->set_has_frame(true);
63 } 131 }
64 132
65 133
66 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { 134 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
67 masm->LeaveFrame(StackFrame::INTERNAL); 135 masm->LeaveFrame(StackFrame::INTERNAL);
68 ASSERT(masm->has_frame()); 136 ASSERT(masm->has_frame());
69 masm->set_has_frame(false); 137 masm->set_has_frame(false);
70 } 138 }
71 139
72 // ------------------------------------------------------------------------- 140 // -------------------------------------------------------------------------
73 // Code generators 141 // Code generators
74 142
143 #define __ ACCESS_MASM(masm)
144
75 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 145 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
76 MacroAssembler* masm) { 146 MacroAssembler* masm) {
77 // ----------- S t a t e ------------- 147 // ----------- S t a t e -------------
78 // -- a0 : value 148 // -- a0 : value
79 // -- a1 : key 149 // -- a1 : key
80 // -- a2 : receiver 150 // -- a2 : receiver
81 // -- ra : return address 151 // -- ra : return address
82 // -- a3 : target map, scratch for subsequent call 152 // -- a3 : target map, scratch for subsequent call
83 // -- t0 : scratch (elements) 153 // -- t0 : scratch (elements)
84 // ----------------------------------- 154 // -----------------------------------
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 __ Addu(at, string, at); 509 __ Addu(at, string, at);
440 __ lhu(result, MemOperand(at)); 510 __ lhu(result, MemOperand(at));
441 __ jmp(&done); 511 __ jmp(&done);
442 __ bind(&ascii); 512 __ bind(&ascii);
443 // Ascii string. 513 // Ascii string.
444 __ Addu(at, string, index); 514 __ Addu(at, string, index);
445 __ lbu(result, MemOperand(at)); 515 __ lbu(result, MemOperand(at));
446 __ bind(&done); 516 __ bind(&done);
447 } 517 }
448 518
519
520 static MemOperand ExpConstant(int index, Register base) {
521 return MemOperand(base, index * kDoubleSize);
522 }
523
524
525 void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
526 DoubleRegister input,
527 DoubleRegister result,
528 DoubleRegister double_scratch1,
529 DoubleRegister double_scratch2,
530 Register temp1,
531 Register temp2,
532 Register temp3) {
533 ASSERT(!input.is(result));
534 ASSERT(!input.is(double_scratch1));
535 ASSERT(!input.is(double_scratch2));
536 ASSERT(!result.is(double_scratch1));
537 ASSERT(!result.is(double_scratch2));
538 ASSERT(!double_scratch1.is(double_scratch2));
539 ASSERT(!temp1.is(temp2));
540 ASSERT(!temp1.is(temp3));
541 ASSERT(!temp2.is(temp3));
542 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
543
544 Label done;
545
546 __ li(temp3, Operand(ExternalReference::math_exp_constants(0)));
547
548 __ ldc1(double_scratch1, ExpConstant(0, temp3));
549 __ Move(result, kDoubleRegZero);
550 __ BranchF(&done, NULL, ge, double_scratch1, input);
551 __ ldc1(double_scratch2, ExpConstant(1, temp3));
552 __ ldc1(result, ExpConstant(2, temp3));
553 __ BranchF(&done, NULL, ge, input, double_scratch2);
554 __ ldc1(double_scratch1, ExpConstant(3, temp3));
555 __ ldc1(result, ExpConstant(4, temp3));
556 __ mul_d(double_scratch1, double_scratch1, input);
557 __ add_d(double_scratch1, double_scratch1, result);
558 __ Move(temp2, temp1, double_scratch1);
559 __ sub_d(double_scratch1, double_scratch1, result);
560 __ ldc1(result, ExpConstant(6, temp3));
561 __ ldc1(double_scratch2, ExpConstant(5, temp3));
562 __ mul_d(double_scratch1, double_scratch1, double_scratch2);
563 __ sub_d(double_scratch1, double_scratch1, input);
564 __ sub_d(result, result, double_scratch1);
565 __ mul_d(input, double_scratch1, double_scratch1);
566 __ mul_d(result, result, input);
567 __ srl(temp1, temp2, 11);
568 __ ldc1(double_scratch2, ExpConstant(7, temp3));
569 __ mul_d(result, result, double_scratch2);
570 __ sub_d(result, result, double_scratch1);
571 __ ldc1(double_scratch2, ExpConstant(8, temp3));
572 __ add_d(result, result, double_scratch2);
573 __ li(at, 0x7ff);
574 __ And(temp2, temp2, at);
575 __ Addu(temp1, temp1, Operand(0x3ff));
576 __ sll(temp1, temp1, 20);
577
578 // Must not call ExpConstant() after overwriting temp3!
579 __ li(temp3, Operand(ExternalReference::math_exp_log_table()));
580 __ sll(at, temp2, 3);
581 __ addu(at, at, temp3);
582 __ lw(at, MemOperand(at));
583 __ Addu(temp3, temp3, Operand(kPointerSize));
584 __ sll(temp2, temp2, 3);
585 __ addu(temp2, temp2, temp3);
586 __ lw(temp2, MemOperand(temp2));
587 __ Or(temp1, temp1, temp2);
588 __ Move(input, at, temp1);
589 __ mul_d(result, result, input);
590 __ bind(&done);
591 }
592
593
449 // nop(CODE_AGE_MARKER_NOP) 594 // nop(CODE_AGE_MARKER_NOP)
450 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; 595 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
451 596
452 static byte* GetNoCodeAgeSequence(uint32_t* length) { 597 static byte* GetNoCodeAgeSequence(uint32_t* length) {
453 // The sequence of instructions that is patched out for aging code is the 598 // The sequence of instructions that is patched out for aging code is the
454 // following boilerplate stack-building prologue that is found in FUNCTIONS 599 // following boilerplate stack-building prologue that is found in FUNCTIONS
455 static bool initialized = false; 600 static bool initialized = false;
456 static uint32_t sequence[kNoCodeAgeSequenceLength]; 601 static uint32_t sequence[kNoCodeAgeSequenceLength];
457 byte* byte_sequence = reinterpret_cast<byte*>(sequence); 602 byte* byte_sequence = reinterpret_cast<byte*>(sequence);
458 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize; 603 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); 683 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start()));
539 } 684 }
540 } 685 }
541 686
542 687
543 #undef __ 688 #undef __
544 689
545 } } // namespace v8::internal 690 } } // namespace v8::internal
546 691
547 #endif // V8_TARGET_ARCH_MIPS 692 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/codegen-mips.h ('k') | src/mips/lithium-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698