Fix bugs in softfloat code path.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/13008018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14119 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 502063c4
...@@ -2634,8 +2634,8 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, ...@@ -2634,8 +2634,8 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
OverwriteMode mode) { OverwriteMode mode) {
Register left = r1; Register left = r1;
Register right = r0; Register right = r0;
Register scratch1 = r7; Register scratch1 = r6;
Register scratch2 = r9; Register scratch2 = r7;
Register scratch3 = r4; Register scratch3 = r4;
ASSERT(smi_operands || (not_numbers != NULL)); ASSERT(smi_operands || (not_numbers != NULL));
...@@ -2650,7 +2650,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, ...@@ -2650,7 +2650,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
__ JumpIfNotSmi(right, miss); __ JumpIfNotSmi(right, miss);
} }
Register heap_number_map = r6; Register heap_number_map = r9;
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
switch (op) { switch (op) {
......
...@@ -4903,10 +4903,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { ...@@ -4903,10 +4903,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
// Convert unsigned integer with specified number of leading zeroes in binary // Convert unsigned integer with specified number of leading zeroes in binary
// representation to IEEE 754 double. // representation to IEEE 754 double.
// Integer to convert is passed in register hiword. // Integer to convert is passed in register src.
// Resulting double is returned in registers hiword:loword. // Resulting double is returned in registers hiword:loword.
// This functions does not work correctly for 0. // This functions does not work correctly for 0.
static void GenerateUInt2Double(MacroAssembler* masm, static void GenerateUInt2Double(MacroAssembler* masm,
Register src,
Register hiword, Register hiword,
Register loword, Register loword,
Register scratch, Register scratch,
...@@ -4920,13 +4921,13 @@ static void GenerateUInt2Double(MacroAssembler* masm, ...@@ -4920,13 +4921,13 @@ static void GenerateUInt2Double(MacroAssembler* masm,
kBitsPerInt - mantissa_shift_for_hi_word; kBitsPerInt - mantissa_shift_for_hi_word;
masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
if (mantissa_shift_for_hi_word > 0) { if (mantissa_shift_for_hi_word > 0) {
masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word)); masm->mov(loword, Operand(src, LSL, mantissa_shift_for_lo_word));
masm->orr(hiword, scratch, masm->orr(hiword, scratch,
Operand(hiword, LSR, mantissa_shift_for_hi_word)); Operand(src, LSR, mantissa_shift_for_hi_word));
} else { } else {
masm->mov(loword, Operand::Zero()); masm->mov(loword, Operand::Zero());
masm->orr(hiword, scratch, masm->orr(hiword, scratch,
Operand(hiword, LSL, -mantissa_shift_for_hi_word)); Operand(src, LSL, -mantissa_shift_for_hi_word));
} }
// If least significant bit of biased exponent was not 1 it was corrupted // If least significant bit of biased exponent was not 1 it was corrupted
...@@ -4975,17 +4976,17 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, ...@@ -4975,17 +4976,17 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
__ vmov(flt_scratch, src); __ vmov(flt_scratch, src);
__ vcvt_f64_u32(dbl_scratch, flt_scratch); __ vcvt_f64_u32(dbl_scratch, flt_scratch);
} else { } else {
Label no_leading_zero, done; Label no_leading_zero, convert_done;
__ tst(src, Operand(0x80000000)); __ tst(src, Operand(0x80000000));
__ b(ne, &no_leading_zero); __ b(ne, &no_leading_zero);
// Integer has one leading zeros. // Integer has one leading zeros.
GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1);
__ b(&done); __ b(&convert_done);
__ bind(&no_leading_zero); __ bind(&no_leading_zero);
GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0); GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0);
__ b(&done); __ bind(&convert_done);
} }
} }
...@@ -5002,10 +5003,18 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, ...@@ -5002,10 +5003,18 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
// TODO(3095996): Put a valid pointer value in the stack slot where the result // TODO(3095996): Put a valid pointer value in the stack slot where the result
// register is stored, as this register is in the pointer map, but contains an // register is stored, as this register is in the pointer map, but contains an
// integer value. // integer value.
if (!CpuFeatures::IsSupported(VFP2)) {
// Preserve sfpd_lo.
__ mov(r9, sfpd_lo);
}
__ mov(ip, Operand::Zero()); __ mov(ip, Operand::Zero());
__ StoreToSafepointRegisterSlot(ip, dst); __ StoreToSafepointRegisterSlot(ip, dst);
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
__ Move(dst, r0); __ Move(dst, r0);
if (!CpuFeatures::IsSupported(VFP2)) {
// Restore sfpd_lo.
__ mov(sfpd_lo, r9);
}
__ sub(dst, dst, Operand(kHeapObjectTag)); __ sub(dst, dst, Operand(kHeapObjectTag));
// Done. Put the value in dbl_scratch into the value of the allocated heap // Done. Put the value in dbl_scratch into the value of the allocated heap
......
...@@ -708,15 +708,14 @@ void MacroAssembler::Ldrd(Register dst1, Register dst2, ...@@ -708,15 +708,14 @@ void MacroAssembler::Ldrd(Register dst1, Register dst2,
const MemOperand& src, Condition cond) { const MemOperand& src, Condition cond) {
ASSERT(src.rm().is(no_reg)); ASSERT(src.rm().is(no_reg));
ASSERT(!dst1.is(lr)); // r14. ASSERT(!dst1.is(lr)); // r14.
ASSERT_EQ(0, dst1.code() % 2);
ASSERT_EQ(dst1.code() + 1, dst2.code());
// V8 does not use this addressing mode, so the fallback code // V8 does not use this addressing mode, so the fallback code
// below doesn't support it yet. // below doesn't support it yet.
ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex)); ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
// Generate two ldr instructions if ldrd is not available. // Generate two ldr instructions if ldrd is not available.
if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
(dst1.code() % 2 == 0) && (dst1.code() + 1 == dst2.code())) {
CpuFeatureScope scope(this, ARMv7); CpuFeatureScope scope(this, ARMv7);
ldrd(dst1, dst2, src, cond); ldrd(dst1, dst2, src, cond);
} else { } else {
...@@ -750,15 +749,14 @@ void MacroAssembler::Strd(Register src1, Register src2, ...@@ -750,15 +749,14 @@ void MacroAssembler::Strd(Register src1, Register src2,
const MemOperand& dst, Condition cond) { const MemOperand& dst, Condition cond) {
ASSERT(dst.rm().is(no_reg)); ASSERT(dst.rm().is(no_reg));
ASSERT(!src1.is(lr)); // r14. ASSERT(!src1.is(lr)); // r14.
ASSERT_EQ(0, src1.code() % 2);
ASSERT_EQ(src1.code() + 1, src2.code());
// V8 does not use this addressing mode, so the fallback code // V8 does not use this addressing mode, so the fallback code
// below doesn't support it yet. // below doesn't support it yet.
ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex)); ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
// Generate two str instructions if strd is not available. // Generate two str instructions if strd is not available.
if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
(src1.code() % 2 == 0) && (src1.code() + 1 == src2.code())) {
CpuFeatureScope scope(this, ARMv7); CpuFeatureScope scope(this, ARMv7);
strd(src1, src2, dst, cond); strd(src1, src2, dst, cond);
} else { } else {
...@@ -2499,9 +2497,9 @@ void MacroAssembler::TryInt32Floor(Register result, ...@@ -2499,9 +2497,9 @@ void MacroAssembler::TryInt32Floor(Register result,
void MacroAssembler::ECMAConvertNumberToInt32(Register source, void MacroAssembler::ECMAConvertNumberToInt32(Register source,
Register result, Register result,
Register scratch,
Register input_high,
Register input_low, Register input_low,
Register input_high,
Register scratch,
DwVfpRegister double_scratch1, DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2) { DwVfpRegister double_scratch2) {
if (CpuFeatures::IsSupported(VFP2)) { if (CpuFeatures::IsSupported(VFP2)) {
...@@ -2578,24 +2576,26 @@ void MacroAssembler::ECMAToInt32NoVFP(Register result, ...@@ -2578,24 +2576,26 @@ void MacroAssembler::ECMAToInt32NoVFP(Register result,
Ubfx(scratch, input_high, Ubfx(scratch, input_high,
HeapNumber::kExponentShift, HeapNumber::kExponentBits); HeapNumber::kExponentShift, HeapNumber::kExponentBits);
// Load scratch with exponent - 1. This is faster than loading // Load scratch with exponent.
// with exponent because Bias + 1 = 1024 which is an *ARM* immediate value. sub(scratch, scratch, Operand(HeapNumber::kExponentBias));
sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
// If exponent is negative, 0 < input < 1, the result is 0. // If exponent is negative, 0 < input < 1, the result is 0.
// If exponent is greater than or equal to 84, the 32 less significant // If exponent is greater than or equal to 84, the 32 less significant
// bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits), // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits),
// the result is 0. // the result is 0.
// This test also catch Nan and infinities which also return 0. // This test also catch Nan and infinities which also return 0.
// Compare exponent with 84 (compare exponent - 1 with 83). cmp(scratch, Operand(84));
cmp(scratch, Operand(83));
// We do an unsigned comparison so negative numbers are treated as big // We do an unsigned comparison so negative numbers are treated as big
// positive number and the two tests above are done in one test. // positive number and the two tests above are done in one test.
b(hs, &out_of_range); b(hs, &out_of_range);
// Load scratch with 20 - exponent (load with 19 - (exponent - 1)). // Load scratch with 20 - exponent.
rsb(scratch, scratch, Operand(19), SetCC); rsb(scratch, scratch, Operand(20), SetCC);
b(mi, &both); b(mi, &both);
// Test 0 and -0.
bic(result, input_high, Operand(HeapNumber::kSignMask));
orr(result, result, Operand(input_low), SetCC);
b(eq, &done);
// 0 <= exponent <= 20, shift only input_high. // 0 <= exponent <= 20, shift only input_high.
// Scratch contains: 20 - exponent. // Scratch contains: 20 - exponent.
Ubfx(result, input_high, Ubfx(result, input_high,
......
...@@ -960,9 +960,9 @@ class MacroAssembler: public Assembler { ...@@ -960,9 +960,9 @@ class MacroAssembler: public Assembler {
// Exits with 'result' holding the answer. // Exits with 'result' holding the answer.
void ECMAConvertNumberToInt32(Register source, void ECMAConvertNumberToInt32(Register source,
Register result, Register result,
Register scratch,
Register input_high,
Register input_low, Register input_low,
Register input_high,
Register scratch,
DwVfpRegister double_scratch1, DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2); DwVfpRegister double_scratch2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment