DoubleToIStub can't use ip on armv6, because the ubfx impl will clobber it

This previous change broke DoubleToIStub on armv6:
https://code.google.com/p/v8/source/detail?r=16322

The problem is that DoubleToIStub::Generate assumed that it could safely use the ip register, but on armv6 the ubfx implementation will clobber any previous value stored there.  So instead, pick another register.

Test case:
for (var i=0; i<2; i++) {
	v = 4294967295;
	v &= -2;
	print(v)
	}

This should print -2 twice, but on armv6 without this patch, it prints -2 followed by 2046.

This problem causes sunspider's bitops-nsieve-bit, crypto-md5 and crypto-sha1 tests to generate incorrect results (but the results are not checked for validity in sunspider-1.0 as available in chromium, but are checked and reported as incorrect in sunspider-1.0.2).

Thanks to Tomasz Kilarski for helping out with this.

R=bmeurer@chromium.org, rmcilroy@chromium.org

Review URL: https://codereview.chromium.org/131823004

Patch from Mostyn Bramley-Moore <mostynb@opera.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18688 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rmcilroy@chromium.org 2014-01-20 11:30:48 +00:00
parent 5b7b4b99b7
commit 6eb9e02b00

View File

@ -665,17 +665,16 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
int double_offset = offset(); int double_offset = offset();
// Account for saved regs if input is sp. // Account for saved regs if input is sp.
if (input_reg.is(sp)) double_offset += 2 * kPointerSize; if (input_reg.is(sp)) double_offset += 3 * kPointerSize;
// Immediate values for this stub fit in instructions, so it's safe to use ip. Register scratch = GetRegisterThatIsNotOneOf(input_reg, result_reg);
Register scratch = ip;
Register scratch_low = Register scratch_low =
GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch); GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch);
Register scratch_high = Register scratch_high =
GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch_low); GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch_low);
LowDwVfpRegister double_scratch = kScratchDoubleReg; LowDwVfpRegister double_scratch = kScratchDoubleReg;
__ Push(scratch_high, scratch_low); __ Push(scratch_high, scratch_low, scratch);
if (!skip_fastpath()) { if (!skip_fastpath()) {
// Load double input. // Load double input.
@ -758,7 +757,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ bind(&done); __ bind(&done);
__ Pop(scratch_high, scratch_low); __ Pop(scratch_high, scratch_low, scratch);
__ Ret(); __ Ret();
} }