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,
OverwriteMode mode) {
Register left = r1;
Register right = r0;
Register scratch1 = r7;
Register scratch2 = r9;
Register scratch1 = r6;
Register scratch2 = r7;
Register scratch3 = r4;
ASSERT(smi_operands || (not_numbers != NULL));
......@@ -2650,7 +2650,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
__ JumpIfNotSmi(right, miss);
}
Register heap_number_map = r6;
Register heap_number_map = r9;
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
switch (op) {
......
......@@ -4903,10 +4903,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
// Convert unsigned integer with specified number of leading zeroes in binary
// 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.
// This functions does not work correctly for 0.
static void GenerateUInt2Double(MacroAssembler* masm,
Register src,
Register hiword,
Register loword,
Register scratch,
......@@ -4920,13 +4921,13 @@ static void GenerateUInt2Double(MacroAssembler* masm,
kBitsPerInt - mantissa_shift_for_hi_word;
masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
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,
Operand(hiword, LSR, mantissa_shift_for_hi_word));
Operand(src, LSR, mantissa_shift_for_hi_word));
} else {
masm->mov(loword, Operand::Zero());
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
......@@ -4975,17 +4976,17 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
__ vmov(flt_scratch, src);
__ vcvt_f64_u32(dbl_scratch, flt_scratch);
} else {
Label no_leading_zero, done;
Label no_leading_zero, convert_done;
__ tst(src, Operand(0x80000000));
__ b(ne, &no_leading_zero);
// Integer has one leading zeros.
GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1);
__ b(&done);
GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1);
__ b(&convert_done);
__ bind(&no_leading_zero);
GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0);
__ b(&done);
GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0);
__ bind(&convert_done);
}
}
......@@ -5002,10 +5003,18 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
// 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
// integer value.
if (!CpuFeatures::IsSupported(VFP2)) {
// Preserve sfpd_lo.
__ mov(r9, sfpd_lo);
}
__ mov(ip, Operand::Zero());
__ StoreToSafepointRegisterSlot(ip, dst);
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
__ Move(dst, r0);
if (!CpuFeatures::IsSupported(VFP2)) {
// Restore sfpd_lo.
__ mov(sfpd_lo, r9);
}
__ sub(dst, dst, Operand(kHeapObjectTag));
// 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,
const MemOperand& src, Condition cond) {
ASSERT(src.rm().is(no_reg));
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
// below doesn't support it yet.
ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
// 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);
ldrd(dst1, dst2, src, cond);
} else {
......@@ -750,15 +749,14 @@ void MacroAssembler::Strd(Register src1, Register src2,
const MemOperand& dst, Condition cond) {
ASSERT(dst.rm().is(no_reg));
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
// below doesn't support it yet.
ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
// 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);
strd(src1, src2, dst, cond);
} else {
......@@ -2499,9 +2497,9 @@ void MacroAssembler::TryInt32Floor(Register result,
void MacroAssembler::ECMAConvertNumberToInt32(Register source,
Register result,
Register scratch,
Register input_high,
Register input_low,
Register input_high,
Register scratch,
DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2) {
if (CpuFeatures::IsSupported(VFP2)) {
......@@ -2578,24 +2576,26 @@ void MacroAssembler::ECMAToInt32NoVFP(Register result,
Ubfx(scratch, input_high,
HeapNumber::kExponentShift, HeapNumber::kExponentBits);
// Load scratch with exponent - 1. This is faster than loading
// with exponent because Bias + 1 = 1024 which is an *ARM* immediate value.
sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
// Load scratch with exponent.
sub(scratch, scratch, Operand(HeapNumber::kExponentBias));
// If exponent is negative, 0 < input < 1, the result is 0.
// 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),
// the result is 0.
// This test also catch Nan and infinities which also return 0.
// Compare exponent with 84 (compare exponent - 1 with 83).
cmp(scratch, Operand(83));
cmp(scratch, Operand(84));
// We do an unsigned comparison so negative numbers are treated as big
// positive number and the two tests above are done in one test.
b(hs, &out_of_range);
// Load scratch with 20 - exponent (load with 19 - (exponent - 1)).
rsb(scratch, scratch, Operand(19), SetCC);
// Load scratch with 20 - exponent.
rsb(scratch, scratch, Operand(20), SetCC);
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.
// Scratch contains: 20 - exponent.
Ubfx(result, input_high,
......
......@@ -960,9 +960,9 @@ class MacroAssembler: public Assembler {
// Exits with 'result' holding the answer.
void ECMAConvertNumberToInt32(Register source,
Register result,
Register scratch,
Register input_high,
Register input_low,
Register input_high,
Register scratch,
DwVfpRegister double_scratch1,
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