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:
parent
5b7b4b99b7
commit
6eb9e02b00
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user