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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 13008018: ARM: Fix bugs in softfloat code path. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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/arm/macro-assembler-arm.h ('k') | no next file » | 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize; 701 int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize;
702 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; 702 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
703 return MemOperand(sp, doubles_size + register_offset); 703 return MemOperand(sp, doubles_size + register_offset);
704 } 704 }
705 705
706 706
707 void MacroAssembler::Ldrd(Register dst1, Register dst2, 707 void MacroAssembler::Ldrd(Register dst1, Register dst2,
708 const MemOperand& src, Condition cond) { 708 const MemOperand& src, Condition cond) {
709 ASSERT(src.rm().is(no_reg)); 709 ASSERT(src.rm().is(no_reg));
710 ASSERT(!dst1.is(lr)); // r14. 710 ASSERT(!dst1.is(lr)); // r14.
711 ASSERT_EQ(0, dst1.code() % 2);
712 ASSERT_EQ(dst1.code() + 1, dst2.code());
713 711
714 // V8 does not use this addressing mode, so the fallback code 712 // V8 does not use this addressing mode, so the fallback code
715 // below doesn't support it yet. 713 // below doesn't support it yet.
716 ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex)); 714 ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
717 715
718 // Generate two ldr instructions if ldrd is not available. 716 // Generate two ldr instructions if ldrd is not available.
719 if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { 717 if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
718 (dst1.code() % 2 == 0) && (dst1.code() + 1 == dst2.code())) {
720 CpuFeatureScope scope(this, ARMv7); 719 CpuFeatureScope scope(this, ARMv7);
721 ldrd(dst1, dst2, src, cond); 720 ldrd(dst1, dst2, src, cond);
722 } else { 721 } else {
723 if ((src.am() == Offset) || (src.am() == NegOffset)) { 722 if ((src.am() == Offset) || (src.am() == NegOffset)) {
724 MemOperand src2(src); 723 MemOperand src2(src);
725 src2.set_offset(src2.offset() + 4); 724 src2.set_offset(src2.offset() + 4);
726 if (dst1.is(src.rn())) { 725 if (dst1.is(src.rn())) {
727 ldr(dst2, src2, cond); 726 ldr(dst2, src2, cond);
728 ldr(dst1, src, cond); 727 ldr(dst1, src, cond);
729 } else { 728 } else {
(...skipping 13 matching lines...) Expand all
743 } 742 }
744 } 743 }
745 } 744 }
746 } 745 }
747 746
748 747
749 void MacroAssembler::Strd(Register src1, Register src2, 748 void MacroAssembler::Strd(Register src1, Register src2,
750 const MemOperand& dst, Condition cond) { 749 const MemOperand& dst, Condition cond) {
751 ASSERT(dst.rm().is(no_reg)); 750 ASSERT(dst.rm().is(no_reg));
752 ASSERT(!src1.is(lr)); // r14. 751 ASSERT(!src1.is(lr)); // r14.
753 ASSERT_EQ(0, src1.code() % 2);
754 ASSERT_EQ(src1.code() + 1, src2.code());
755 752
756 // V8 does not use this addressing mode, so the fallback code 753 // V8 does not use this addressing mode, so the fallback code
757 // below doesn't support it yet. 754 // below doesn't support it yet.
758 ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex)); 755 ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
759 756
760 // Generate two str instructions if strd is not available. 757 // Generate two str instructions if strd is not available.
761 if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { 758 if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
759 (src1.code() % 2 == 0) && (src1.code() + 1 == src2.code())) {
762 CpuFeatureScope scope(this, ARMv7); 760 CpuFeatureScope scope(this, ARMv7);
763 strd(src1, src2, dst, cond); 761 strd(src1, src2, dst, cond);
764 } else { 762 } else {
765 MemOperand dst2(dst); 763 MemOperand dst2(dst);
766 if ((dst.am() == Offset) || (dst.am() == NegOffset)) { 764 if ((dst.am() == Offset) || (dst.am() == NegOffset)) {
767 dst2.set_offset(dst2.offset() + 4); 765 dst2.set_offset(dst2.offset() + 4);
768 str(src1, dst, cond); 766 str(src1, dst, cond);
769 str(src2, dst2, cond); 767 str(src2, dst2, cond);
770 } else { // PostIndex or NegPostIndex. 768 } else { // PostIndex or NegPostIndex.
771 ASSERT((dst.am() == PostIndex) || (dst.am() == NegPostIndex)); 769 ASSERT((dst.am() == PostIndex) || (dst.am() == NegPostIndex));
(...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 sub(result, result, Operand(1), SetCC); 2490 sub(result, result, Operand(1), SetCC);
2493 // If result is still negative, go to done, result fetched. 2491 // If result is still negative, go to done, result fetched.
2494 // Else, we had an overflow and we fall through exception. 2492 // Else, we had an overflow and we fall through exception.
2495 b(mi, done); 2493 b(mi, done);
2496 bind(&exception); 2494 bind(&exception);
2497 } 2495 }
2498 2496
2499 2497
2500 void MacroAssembler::ECMAConvertNumberToInt32(Register source, 2498 void MacroAssembler::ECMAConvertNumberToInt32(Register source,
2501 Register result, 2499 Register result,
2500 Register input_low,
2501 Register input_high,
2502 Register scratch, 2502 Register scratch,
2503 Register input_high,
2504 Register input_low,
2505 DwVfpRegister double_scratch1, 2503 DwVfpRegister double_scratch1,
2506 DwVfpRegister double_scratch2) { 2504 DwVfpRegister double_scratch2) {
2507 if (CpuFeatures::IsSupported(VFP2)) { 2505 if (CpuFeatures::IsSupported(VFP2)) {
2508 CpuFeatureScope scope(this, VFP2); 2506 CpuFeatureScope scope(this, VFP2);
2509 vldr(double_scratch1, FieldMemOperand(source, HeapNumber::kValueOffset)); 2507 vldr(double_scratch1, FieldMemOperand(source, HeapNumber::kValueOffset));
2510 ECMAToInt32VFP(result, double_scratch1, double_scratch2, 2508 ECMAToInt32VFP(result, double_scratch1, double_scratch2,
2511 scratch, input_high, input_low); 2509 scratch, input_high, input_low);
2512 } else { 2510 } else {
2513 Ldrd(input_low, input_high, 2511 Ldrd(input_low, input_high,
2514 FieldMemOperand(source, HeapNumber::kValueOffset)); 2512 FieldMemOperand(source, HeapNumber::kValueOffset));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2571 ASSERT(!result.is(input_high)); 2569 ASSERT(!result.is(input_high));
2572 ASSERT(!result.is(input_low)); 2570 ASSERT(!result.is(input_low));
2573 ASSERT(!scratch.is(input_high)); 2571 ASSERT(!scratch.is(input_high));
2574 ASSERT(!scratch.is(input_low)); 2572 ASSERT(!scratch.is(input_low));
2575 ASSERT(!input_high.is(input_low)); 2573 ASSERT(!input_high.is(input_low));
2576 2574
2577 Label both, out_of_range, negate, done; 2575 Label both, out_of_range, negate, done;
2578 2576
2579 Ubfx(scratch, input_high, 2577 Ubfx(scratch, input_high,
2580 HeapNumber::kExponentShift, HeapNumber::kExponentBits); 2578 HeapNumber::kExponentShift, HeapNumber::kExponentBits);
2581 // Load scratch with exponent - 1. This is faster than loading 2579 // Load scratch with exponent.
2582 // with exponent because Bias + 1 = 1024 which is an *ARM* immediate value. 2580 sub(scratch, scratch, Operand(HeapNumber::kExponentBias));
2583 sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
2584 // If exponent is negative, 0 < input < 1, the result is 0. 2581 // If exponent is negative, 0 < input < 1, the result is 0.
2585 // If exponent is greater than or equal to 84, the 32 less significant 2582 // If exponent is greater than or equal to 84, the 32 less significant
2586 // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits), 2583 // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits),
2587 // the result is 0. 2584 // the result is 0.
2588 // This test also catch Nan and infinities which also return 0. 2585 // This test also catch Nan and infinities which also return 0.
2589 // Compare exponent with 84 (compare exponent - 1 with 83). 2586 cmp(scratch, Operand(84));
2590 cmp(scratch, Operand(83));
2591 // We do an unsigned comparison so negative numbers are treated as big 2587 // We do an unsigned comparison so negative numbers are treated as big
2592 // positive number and the two tests above are done in one test. 2588 // positive number and the two tests above are done in one test.
2593 b(hs, &out_of_range); 2589 b(hs, &out_of_range);
2594 2590
2595 // Load scratch with 20 - exponent (load with 19 - (exponent - 1)). 2591 // Load scratch with 20 - exponent.
2596 rsb(scratch, scratch, Operand(19), SetCC); 2592 rsb(scratch, scratch, Operand(20), SetCC);
2597 b(mi, &both); 2593 b(mi, &both);
2598 2594
2595 // Test 0 and -0.
2596 bic(result, input_high, Operand(HeapNumber::kSignMask));
2597 orr(result, result, Operand(input_low), SetCC);
2598 b(eq, &done);
2599 // 0 <= exponent <= 20, shift only input_high. 2599 // 0 <= exponent <= 20, shift only input_high.
2600 // Scratch contains: 20 - exponent. 2600 // Scratch contains: 20 - exponent.
2601 Ubfx(result, input_high, 2601 Ubfx(result, input_high,
2602 0, HeapNumber::kMantissaBitsInTopWord); 2602 0, HeapNumber::kMantissaBitsInTopWord);
2603 // Set the implicit 1 before the mantissa part in input_high. 2603 // Set the implicit 1 before the mantissa part in input_high.
2604 orr(result, result, Operand(1 << HeapNumber::kMantissaBitsInTopWord)); 2604 orr(result, result, Operand(1 << HeapNumber::kMantissaBitsInTopWord));
2605 mov(result, Operand(result, LSR, scratch)); 2605 mov(result, Operand(result, LSR, scratch));
2606 b(&negate); 2606 b(&negate);
2607 2607
2608 bind(&both); 2608 bind(&both);
(...skipping 1340 matching lines...) Expand 10 before | Expand all | Expand 10 after
3949 void CodePatcher::EmitCondition(Condition cond) { 3949 void CodePatcher::EmitCondition(Condition cond) {
3950 Instr instr = Assembler::instr_at(masm_.pc_); 3950 Instr instr = Assembler::instr_at(masm_.pc_);
3951 instr = (instr & ~kCondMask) | cond; 3951 instr = (instr & ~kCondMask) | cond;
3952 masm_.emit(instr); 3952 masm_.emit(instr);
3953 } 3953 }
3954 3954
3955 3955
3956 } } // namespace v8::internal 3956 } } // namespace v8::internal
3957 3957
3958 #endif // V8_TARGET_ARCH_ARM 3958 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698