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

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

Issue 2077533002: [builtins] Introduce proper Float64Exp operator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Import tests from Raymond. Created 4 years, 6 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 "src/arm/codegen-arm.h" 5 #include "src/arm/codegen-arm.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/arm/simulator-arm.h" 9 #include "src/arm/simulator-arm.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
11 #include "src/macro-assembler.h" 11 #include "src/macro-assembler.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 #define __ masm. 17 #define __ masm.
18 18
19
20 #if defined(USE_SIMULATOR)
21 byte* fast_exp_arm_machine_code = nullptr;
22 double fast_exp_simulator(double x, Isolate* isolate) {
23 return Simulator::current(isolate)
24 ->CallFPReturnsDouble(fast_exp_arm_machine_code, x, 0);
25 }
26 #endif
27
28
29 UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) {
30 size_t actual_size;
31 byte* buffer =
32 static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
33 if (buffer == nullptr) return nullptr;
34 ExternalReference::InitializeMathExpData();
35
36 MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
37 CodeObjectRequired::kNo);
38
39 {
40 DwVfpRegister input = d0;
41 DwVfpRegister result = d1;
42 DwVfpRegister double_scratch1 = d2;
43 DwVfpRegister double_scratch2 = d3;
44 Register temp1 = r4;
45 Register temp2 = r5;
46 Register temp3 = r6;
47
48 if (masm.use_eabi_hardfloat()) {
49 // Input value is in d0 anyway, nothing to do.
50 } else {
51 __ vmov(input, r0, r1);
52 }
53 __ Push(temp3, temp2, temp1);
54 MathExpGenerator::EmitMathExp(
55 &masm, input, result, double_scratch1, double_scratch2,
56 temp1, temp2, temp3);
57 __ Pop(temp3, temp2, temp1);
58 if (masm.use_eabi_hardfloat()) {
59 __ vmov(d0, result);
60 } else {
61 __ vmov(r0, r1, result);
62 }
63 __ Ret();
64 }
65
66 CodeDesc desc;
67 masm.GetCode(&desc);
68 DCHECK(!RelocInfo::RequiresRelocation(desc));
69
70 Assembler::FlushICache(isolate, buffer, actual_size);
71 base::OS::ProtectCode(buffer, actual_size);
72
73 #if !defined(USE_SIMULATOR)
74 return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
75 #else
76 fast_exp_arm_machine_code = buffer;
77 return &fast_exp_simulator;
78 #endif
79 }
80
81 #if defined(V8_HOST_ARCH_ARM) 19 #if defined(V8_HOST_ARCH_ARM)
82 MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate, 20 MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
83 MemCopyUint8Function stub) { 21 MemCopyUint8Function stub) {
84 #if defined(USE_SIMULATOR) 22 #if defined(USE_SIMULATOR)
85 return stub; 23 return stub;
86 #else 24 #else
87 if (!CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) return stub; 25 if (!CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) return stub;
88 size_t actual_size; 26 size_t actual_size;
89 byte* buffer = 27 byte* buffer =
90 static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 28 static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 __ b(ne, &one_byte); 725 __ b(ne, &one_byte);
788 // Two-byte string. 726 // Two-byte string.
789 __ ldrh(result, MemOperand(string, index, LSL, 1)); 727 __ ldrh(result, MemOperand(string, index, LSL, 1));
790 __ jmp(&done); 728 __ jmp(&done);
791 __ bind(&one_byte); 729 __ bind(&one_byte);
792 // One-byte string. 730 // One-byte string.
793 __ ldrb(result, MemOperand(string, index)); 731 __ ldrb(result, MemOperand(string, index));
794 __ bind(&done); 732 __ bind(&done);
795 } 733 }
796 734
797
798 static MemOperand ExpConstant(int index, Register base) {
799 return MemOperand(base, index * kDoubleSize);
800 }
801
802
803 void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
804 DwVfpRegister input,
805 DwVfpRegister result,
806 DwVfpRegister double_scratch1,
807 DwVfpRegister double_scratch2,
808 Register temp1,
809 Register temp2,
810 Register temp3) {
811 DCHECK(!input.is(result));
812 DCHECK(!input.is(double_scratch1));
813 DCHECK(!input.is(double_scratch2));
814 DCHECK(!result.is(double_scratch1));
815 DCHECK(!result.is(double_scratch2));
816 DCHECK(!double_scratch1.is(double_scratch2));
817 DCHECK(!temp1.is(temp2));
818 DCHECK(!temp1.is(temp3));
819 DCHECK(!temp2.is(temp3));
820 DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
821 DCHECK(!masm->serializer_enabled()); // External references not serializable.
822
823 Label zero, infinity, done;
824
825 __ mov(temp3, Operand(ExternalReference::math_exp_constants(0)));
826
827 __ vldr(double_scratch1, ExpConstant(0, temp3));
828 __ VFPCompareAndSetFlags(double_scratch1, input);
829 __ b(ge, &zero);
830
831 __ vldr(double_scratch2, ExpConstant(1, temp3));
832 __ VFPCompareAndSetFlags(input, double_scratch2);
833 __ b(ge, &infinity);
834
835 __ vldr(double_scratch1, ExpConstant(3, temp3));
836 __ vldr(result, ExpConstant(4, temp3));
837 __ vmul(double_scratch1, double_scratch1, input);
838 __ vadd(double_scratch1, double_scratch1, result);
839 __ VmovLow(temp2, double_scratch1);
840 __ vsub(double_scratch1, double_scratch1, result);
841 __ vldr(result, ExpConstant(6, temp3));
842 __ vldr(double_scratch2, ExpConstant(5, temp3));
843 __ vmul(double_scratch1, double_scratch1, double_scratch2);
844 __ vsub(double_scratch1, double_scratch1, input);
845 __ vsub(result, result, double_scratch1);
846 __ vmul(double_scratch2, double_scratch1, double_scratch1);
847 __ vmul(result, result, double_scratch2);
848 __ vldr(double_scratch2, ExpConstant(7, temp3));
849 __ vmul(result, result, double_scratch2);
850 __ vsub(result, result, double_scratch1);
851 // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
852 DCHECK(*reinterpret_cast<double*>
853 (ExternalReference::math_exp_constants(8).address()) == 1);
854 __ vmov(double_scratch2, 1);
855 __ vadd(result, result, double_scratch2);
856 __ mov(temp1, Operand(temp2, LSR, 11));
857 __ Ubfx(temp2, temp2, 0, 11);
858 __ add(temp1, temp1, Operand(0x3ff));
859
860 // Must not call ExpConstant() after overwriting temp3!
861 __ mov(temp3, Operand(ExternalReference::math_exp_log_table()));
862 __ add(temp3, temp3, Operand(temp2, LSL, 3));
863 __ ldm(ia, temp3, temp2.bit() | temp3.bit());
864 // The first word is loaded is the lower number register.
865 if (temp2.code() < temp3.code()) {
866 __ orr(temp1, temp3, Operand(temp1, LSL, 20));
867 __ vmov(double_scratch1, temp2, temp1);
868 } else {
869 __ orr(temp1, temp2, Operand(temp1, LSL, 20));
870 __ vmov(double_scratch1, temp3, temp1);
871 }
872 __ vmul(result, result, double_scratch1);
873 __ b(&done);
874
875 __ bind(&zero);
876 __ vmov(result, kDoubleRegZero);
877 __ b(&done);
878
879 __ bind(&infinity);
880 __ vldr(result, ExpConstant(2, temp3));
881
882 __ bind(&done);
883 }
884
885 #undef __ 735 #undef __
886 736
887 #ifdef DEBUG 737 #ifdef DEBUG
888 // add(r0, pc, Operand(-8)) 738 // add(r0, pc, Operand(-8))
889 static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008; 739 static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008;
890 #endif 740 #endif
891 741
892 CodeAgingHelper::CodeAgingHelper(Isolate* isolate) { 742 CodeAgingHelper::CodeAgingHelper(Isolate* isolate) {
893 USE(isolate); 743 USE(isolate);
894 DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); 744 DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 patcher.masm()->ldr(pc, MemOperand(pc, -4)); 800 patcher.masm()->ldr(pc, MemOperand(pc, -4));
951 patcher.masm()->emit_code_stub_address(stub); 801 patcher.masm()->emit_code_stub_address(stub);
952 } 802 }
953 } 803 }
954 804
955 805
956 } // namespace internal 806 } // namespace internal
957 } // namespace v8 807 } // namespace v8
958 808
959 #endif // V8_TARGET_ARCH_ARM 809 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698