Chromium Code Reviews| Index: src/arm/macro-assembler-arm.cc |
| =================================================================== |
| --- src/arm/macro-assembler-arm.cc (revision 6953) |
| +++ src/arm/macro-assembler-arm.cc (working copy) |
| @@ -271,6 +271,27 @@ |
| } |
| +void MacroAssembler::Bfi(Register dst, |
| + Register src, |
| + Register scratch, |
| + int lsb, |
| + int width, |
| + Condition cond) { |
| + ASSERT(lsb < 32); |
|
Søren Thygesen Gjesse
2011/02/28 09:54:32
ASSERT lsb >= 0
ASSERT on with and with + lsb as w
Søren Thygesen Gjesse
2011/03/02 09:33:08
Done.
|
| + ASSERT(!scratch.is(dst)); |
| + if (width == 0) return; |
| + if (!CpuFeatures::IsSupported(ARMv7)) { |
| + int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); |
| + bic(dst, dst, Operand(mask)); |
| + and_(scratch, src, Operand((1 << width) - 1)); |
| + mov(scratch, Operand(scratch, LSL, lsb)); |
| + orr(dst, dst, scratch); |
| + } else { |
| + bfi(dst, src, lsb, width, cond); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) { |
| ASSERT(lsb < 32); |
| if (!CpuFeatures::IsSupported(ARMv7)) { |
| @@ -1818,9 +1839,9 @@ |
| ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); |
| // Get exponent alone in scratch2. |
| Ubfx(scratch2, |
| - scratch, |
| - HeapNumber::kExponentShift, |
| - HeapNumber::kExponentBits); |
| + scratch, |
| + HeapNumber::kExponentShift, |
| + HeapNumber::kExponentBits); |
| // Load dest with zero. We use this either for the final shift or |
| // for the answer. |
| mov(dest, Operand(0, RelocInfo::NONE)); |
| @@ -1883,6 +1904,52 @@ |
| } |
| +void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode, |
| + SwVfpRegister result, |
| + DwVfpRegister double_input, |
| + Register scratch1, |
| + Register scratch2, |
| + CheckForInexactConversion check_inexact) { |
| + ASSERT(CpuFeatures::IsSupported(VFP3)); |
| + CpuFeatures::Scope scope(VFP3); |
| + Register prev_fpscr = scratch1; |
| + Register scratch = scratch2; |
| + |
| + int32_t check_inexact_conversion = |
| + (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0; |
| + |
| + // Set custom FPCSR: |
| + // - Set rounding mode. |
| + // - Clear vfp cumulative exception flags. |
| + // - Make sure Flush-to-zero mode control bit is unset. |
| + vmrs(prev_fpscr); |
| + bic(scratch, |
| + prev_fpscr, |
| + Operand(kVFPExceptionMask | |
| + check_inexact_conversion | |
| + kVFPRoundingModeMask | |
| + kVFPFlushToZeroMask)); |
| + // 'Round To Nearest' is encoded by 0b00 so no bits need to be set. |
| + if (rounding_mode != kRoundToNearest) { |
| + orr(scratch, scratch, Operand(rounding_mode)); |
| + } |
| + vmsr(scratch); |
| + |
| + // Convert the argument to an integer. |
| + vcvt_s32_f64(result, |
| + double_input, |
| + (rounding_mode == kRoundToZero) ? kDefaultRoundToZero |
| + : kFPSCRRounding); |
| + |
| + // Retrieve FPSCR. |
| + vmrs(scratch); |
| + // Restore FPSCR. |
| + vmsr(prev_fpscr); |
| + // Check for vfp exceptions. |
| + tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion)); |
| +} |
| + |
| + |
| void MacroAssembler::GetLeastBitsFromSmi(Register dst, |
| Register src, |
| int num_least_bits) { |