OLD | NEW |
---|---|
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 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
768 ASSERT(!input.is(double_scratch1)); | 768 ASSERT(!input.is(double_scratch1)); |
769 ASSERT(!input.is(double_scratch2)); | 769 ASSERT(!input.is(double_scratch2)); |
770 ASSERT(!result.is(double_scratch1)); | 770 ASSERT(!result.is(double_scratch1)); |
771 ASSERT(!result.is(double_scratch2)); | 771 ASSERT(!result.is(double_scratch2)); |
772 ASSERT(!double_scratch1.is(double_scratch2)); | 772 ASSERT(!double_scratch1.is(double_scratch2)); |
773 ASSERT(!temp1.is(temp2)); | 773 ASSERT(!temp1.is(temp2)); |
774 ASSERT(!temp1.is(temp3)); | 774 ASSERT(!temp1.is(temp3)); |
775 ASSERT(!temp2.is(temp3)); | 775 ASSERT(!temp2.is(temp3)); |
776 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL); | 776 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL); |
777 | 777 |
778 Label done; | 778 Label zero, infinity, done; |
779 | 779 |
780 __ mov(temp3, Operand(ExternalReference::math_exp_constants(0))); | 780 __ mov(temp3, Operand(ExternalReference::math_exp_constants(0))); |
781 | 781 |
782 __ vldr(double_scratch1, ExpConstant(0, temp3)); | 782 __ vldr(double_scratch1, ExpConstant(0, temp3)); |
783 __ vmov(result, kDoubleRegZero); | |
784 __ VFPCompareAndSetFlags(double_scratch1, input); | 783 __ VFPCompareAndSetFlags(double_scratch1, input); |
785 __ b(ge, &done); | 784 __ b(ge, &zero); |
785 | |
786 __ vldr(double_scratch2, ExpConstant(1, temp3)); | 786 __ vldr(double_scratch2, ExpConstant(1, temp3)); |
787 __ VFPCompareAndSetFlags(input, double_scratch2); | 787 __ VFPCompareAndSetFlags(input, double_scratch2); |
788 __ vldr(result, ExpConstant(2, temp3)); | 788 __ b(ge, &infinity); |
789 __ b(ge, &done); | 789 |
790 __ vldr(double_scratch1, ExpConstant(3, temp3)); | 790 __ vldr(double_scratch1, ExpConstant(3, temp3)); |
791 __ vldr(result, ExpConstant(4, temp3)); | 791 __ vldr(result, ExpConstant(4, temp3)); |
792 __ vmul(double_scratch1, double_scratch1, input); | 792 __ vmul(double_scratch1, double_scratch1, input); |
793 __ vadd(double_scratch1, double_scratch1, result); | 793 __ vadd(double_scratch1, double_scratch1, result); |
794 __ vmov(temp2, temp1, double_scratch1); | 794 __ VmovLow(temp2, double_scratch1); |
795 __ vsub(double_scratch1, double_scratch1, result); | 795 __ vsub(double_scratch1, double_scratch1, result); |
796 __ vldr(result, ExpConstant(6, temp3)); | 796 __ vldr(result, ExpConstant(6, temp3)); |
797 __ vldr(double_scratch2, ExpConstant(5, temp3)); | 797 __ vldr(double_scratch2, ExpConstant(5, temp3)); |
798 __ vmul(double_scratch1, double_scratch1, double_scratch2); | 798 __ vmul(double_scratch1, double_scratch1, double_scratch2); |
799 __ vsub(double_scratch1, double_scratch1, input); | 799 __ vsub(double_scratch1, double_scratch1, input); |
800 __ vsub(result, result, double_scratch1); | 800 __ vsub(result, result, double_scratch1); |
801 __ vmul(input, double_scratch1, double_scratch1); | 801 __ vmul(double_scratch2, double_scratch1, double_scratch1); |
802 __ vmul(result, result, input); | 802 __ vmul(result, result, double_scratch2); |
803 __ mov(temp1, Operand(temp2, LSR, 11)); | |
804 __ vldr(double_scratch2, ExpConstant(7, temp3)); | 803 __ vldr(double_scratch2, ExpConstant(7, temp3)); |
805 __ vmul(result, result, double_scratch2); | 804 __ vmul(result, result, double_scratch2); |
806 __ vsub(result, result, double_scratch1); | 805 __ vsub(result, result, double_scratch1); |
807 __ vldr(double_scratch2, ExpConstant(8, temp3)); | 806 // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1. |
ulan
2013/09/24 08:44:39
Can we assert this in code?
Rodolph Perfetta
2013/09/24 10:39:36
Done.
| |
807 __ vmov(double_scratch2, 1); | |
808 __ vadd(result, result, double_scratch2); | 808 __ vadd(result, result, double_scratch2); |
809 __ movw(ip, 0x7ff); | 809 __ mov(temp1, Operand(temp2, LSR, 11)); |
810 __ and_(temp2, temp2, Operand(ip)); | 810 __ Ubfx(temp2, temp2, 0, 11); |
811 __ add(temp1, temp1, Operand(0x3ff)); | 811 __ add(temp1, temp1, Operand(0x3ff)); |
812 __ mov(temp1, Operand(temp1, LSL, 20)); | |
813 | 812 |
814 // Must not call ExpConstant() after overwriting temp3! | 813 // Must not call ExpConstant() after overwriting temp3! |
815 __ mov(temp3, Operand(ExternalReference::math_exp_log_table())); | 814 __ mov(temp3, Operand(ExternalReference::math_exp_log_table())); |
816 __ ldr(ip, MemOperand(temp3, temp2, LSL, 3)); | 815 __ add(temp3, temp3, Operand(temp2, LSL, 3)); |
817 __ add(temp3, temp3, Operand(kPointerSize)); | 816 __ ldm(ia, temp3, temp2.bit() | temp3.bit()); |
818 __ ldr(temp2, MemOperand(temp3, temp2, LSL, 3)); | 817 // The first word is loaded is the lower number register. |
819 __ orr(temp1, temp1, temp2); | 818 if (temp2.code() < temp3.code()) { |
820 __ vmov(input, ip, temp1); | 819 __ orr(temp1, temp3, Operand(temp1, LSL, 20)); |
821 __ vmul(result, result, input); | 820 __ vmov(double_scratch1, temp2, temp1); |
821 } else { | |
822 __ orr(temp1, temp2, Operand(temp1, LSL, 20)); | |
823 __ vmov(double_scratch1, temp3, temp1); | |
824 } | |
825 __ vmul(result, result, double_scratch1); | |
826 __ b(&done); | |
827 | |
828 __ bind(&zero); | |
829 __ vmov(result, kDoubleRegZero); | |
830 __ b(&done); | |
831 | |
832 __ bind(&infinity); | |
833 __ vldr(result, ExpConstant(2, temp3)); | |
834 | |
822 __ bind(&done); | 835 __ bind(&done); |
823 } | 836 } |
824 | 837 |
825 #undef __ | 838 #undef __ |
826 | 839 |
827 // add(r0, pc, Operand(-8)) | 840 // add(r0, pc, Operand(-8)) |
828 static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008; | 841 static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008; |
829 | 842 |
830 static byte* GetNoCodeAgeSequence(uint32_t* length) { | 843 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
831 // The sequence of instructions that is patched out for aging code is the | 844 // The sequence of instructions that is patched out for aging code is the |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 patcher.masm()->add(r0, pc, Operand(-8)); | 898 patcher.masm()->add(r0, pc, Operand(-8)); |
886 patcher.masm()->ldr(pc, MemOperand(pc, -4)); | 899 patcher.masm()->ldr(pc, MemOperand(pc, -4)); |
887 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); | 900 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); |
888 } | 901 } |
889 } | 902 } |
890 | 903 |
891 | 904 |
892 } } // namespace v8::internal | 905 } } // namespace v8::internal |
893 | 906 |
894 #endif // V8_TARGET_ARCH_ARM | 907 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |