Revert revision 7582.

The changes caused mozilla date test failures on ARM.

TBR=ager
Review URL: http://codereview.chromium.org/6833020

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7594 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 09dfc4b5
......@@ -2375,11 +2375,9 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// DIV just falls through to allocating a heap number.
}
__ bind(&return_heap_number);
// Return a heap number, or fall through to type transition or runtime
// call if we can't.
if (result_type_ >= (op_ == Token::DIV) ? TRBinaryOpIC::HEAP_NUMBER
: TRBinaryOpIC::INT32) {
__ bind(&return_heap_number);
// We are using vfp registers so r5 is available.
heap_number_result = r5;
GenerateHeapResultAllocation(masm,
......@@ -2542,11 +2540,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
UNREACHABLE();
}
// We never expect DIV to yield an integer result, so we always generate
// type transition code for DIV operations expecting an integer result: the
// code will fall through to this type transition.
if (transition.is_linked() ||
((op_ == Token::DIV) && (result_type_ <= TRBinaryOpIC::INT32))) {
if (transition.is_linked()) {
__ bind(&transition);
GenerateTypeTransition(masm);
}
......
......@@ -1069,130 +1069,40 @@ void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
void LCodeGen::DoMulI(LMulI* instr) {
LOperand* left_op = instr->InputAt(0);
LOperand* right_op = instr->InputAt(1);
Register scratch = scratch0();
Register left = ToRegister(left_op);
ASSERT(left_op->Equals(instr->result()));
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero =
instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
if (right_op->IsConstantOperand()) {
// Use optimized code for specific constants.
int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
Condition overflow_deopt_cond = kNoCondition;
switch (constant) {
case -1:
overflow_deopt_cond = can_overflow ? vs : kNoCondition;
__ rsb(left,
left,
Operand(0),
can_overflow ? SetCC : LeaveCC);
break;
case 0:
if (bailout_on_minus_zero) {
// If left is strictly negative and the constant is null, the
// result is -0. Deoptimize if required, otherwise return 0.
__ cmp(left, Operand(0));
DeoptimizeIf(mi, instr->environment());
}
__ mov(left, Operand(0));
break;
case 1:
// Do nothing.
break;
default:
// Multiplying by powers of two and powers of two plus or minus
// one can be done faster with shifted operands.
// For other constants we emit standard code.
int32_t mask = constant >> 31;
uint32_t constant_abs = (constant + mask) ^ mask;
if (IsPowerOf2(constant_abs)) {
if (!can_overflow) {
int32_t shift = WhichPowerOf2(constant_abs);
__ mov(left, Operand(left, LSL, shift));
if (constant < 0) __ rsb(left, left, Operand(0));
} else {
// scratch:left = left * constant.
__ mov(ip, Operand(constant));
__ smull(left, scratch, left, ip);
__ cmp(scratch, Operand(left, ASR, 31));
overflow_deopt_cond = ne;
}
} else if (IsPowerOf2(constant_abs - 1)) {
int32_t shift = WhichPowerOf2(constant_abs - 1);
__ add(left,
left,
Operand(left, LSL, shift),
can_overflow ? SetCC : LeaveCC);
overflow_deopt_cond = can_overflow ? vs : kNoCondition;
if (constant < 0) __ rsb(left, left, Operand(0));
} else if (IsPowerOf2(constant_abs + 1)) {
int32_t shift = WhichPowerOf2(constant_abs + 1);
__ rsb(left,
left,
Operand(left, LSL, shift),
can_overflow ? SetCC : LeaveCC);
overflow_deopt_cond = can_overflow ? vs : kNoCondition;
if (constant < 0) __ rsb(left, left, Operand(0));
} else {
if (!can_overflow) {
__ mov(ip, Operand(constant));
__ mul(left, left, ip);
} else {
// scratch:left = left * constant.
__ mov(ip, Operand(constant));
__ smull(left, scratch, left, ip);
__ cmp(scratch, Operand(left, ASR, 31));
overflow_deopt_cond = ne;
}
}
break;
}
if (can_overflow && (constant != 0) && (constant != 1)) {
ASSERT(overflow_deopt_cond != kNoCondition);
DeoptimizeIf(overflow_deopt_cond, instr->environment());
}
Register left = ToRegister(instr->InputAt(0));
Register right = EmitLoadRegister(instr->InputAt(1), scratch);
if (bailout_on_minus_zero && (constant < 0)) {
// The case of a null constant was handled separately.
// If constant is negative and left is null, the result should be -0.
__ cmp(left, Operand(0));
DeoptimizeIf(eq, instr->environment());
}
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
!instr->InputAt(1)->IsConstantOperand()) {
__ orr(ToRegister(instr->TempAt(0)), left, right);
}
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
// scratch:left = left * right.
__ smull(left, scratch, left, right);
__ mov(ip, Operand(left, ASR, 31));
__ cmp(ip, Operand(scratch));
DeoptimizeIf(ne, instr->environment());
} else {
Register right = EmitLoadRegister(right_op, scratch);
if (bailout_on_minus_zero) {
__ orr(ToRegister(instr->TempAt(0)), left, right);
}
__ mul(left, left, right);
}
if (can_overflow) {
// scratch:left = left * right.
__ smull(left, scratch, left, right);
__ cmp(scratch, Operand(left, ASR, 31));
DeoptimizeIf(ne, instr->environment());
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
Label done;
__ cmp(left, Operand(0));
__ b(ne, &done);
if (instr->InputAt(1)->IsConstantOperand()) {
if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
DeoptimizeIf(al, instr->environment());
}
} else {
__ mul(left, left, right);
}
if (bailout_on_minus_zero) {
// Bail out if the result is supposed to be negative zero.
Label done;
__ cmp(left, Operand(0));
__ b(ne, &done);
// Test the non-zero operand for negative sign.
__ cmp(ToRegister(instr->TempAt(0)), Operand(0));
DeoptimizeIf(mi, instr->environment());
__ bind(&done);
}
__ bind(&done);
}
}
......
......@@ -297,8 +297,7 @@ void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
!src2.must_use_constant_pool() &&
CpuFeatures::IsSupported(ARMv7) &&
IsPowerOf2(src2.immediate() + 1)) {
ubfx(dst, src1, 0,
WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond);
ubfx(dst, src1, 0, WhichPowerOf2(src2.immediate() + 1), cond);
} else {
and_(dst, src1, src2, LeaveCC, cond);
......
......@@ -52,9 +52,11 @@ static inline bool IsPowerOf2(T x) {
// X must be a power of 2. Returns the number of trailing zeros.
static inline int WhichPowerOf2(uint32_t x) {
template <typename T>
static inline int WhichPowerOf2(T x) {
ASSERT(IsPowerOf2(x));
ASSERT(x != 0);
if (x < 0) return 31;
int bits = 0;
#ifdef DEBUG
int original_x = x;
......
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