Add support for unary plus in hydrogen compiler.
Also strength-reduction of unary minus. Fixes issue 1248. BUG=1248 Review URL: http://codereview.chromium.org/6685045 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7217 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
1a343b3004
commit
2038178fbe
@ -4552,7 +4552,13 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForEffect(expr->expression());
|
||||
}
|
||||
|
||||
} else if (op == Token::BIT_NOT || op == Token::SUB) {
|
||||
} else if (op == Token::TYPEOF) {
|
||||
VisitForTypeOf(expr->expression());
|
||||
if (HasStackOverflow()) return;
|
||||
HValue* value = Pop();
|
||||
ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
|
||||
|
||||
} else {
|
||||
VISIT_FOR_VALUE(expr->expression());
|
||||
HValue* value = Pop();
|
||||
HInstruction* instr = NULL;
|
||||
@ -4561,20 +4567,16 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
instr = new HBitNot(value);
|
||||
break;
|
||||
case Token::SUB:
|
||||
instr = new HMul(graph_->GetConstantMinus1(), value);
|
||||
instr = new HMul(value, graph_->GetConstantMinus1());
|
||||
break;
|
||||
case Token::ADD:
|
||||
instr = new HMul(value, graph_->GetConstant1());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
BAILOUT("Value: unsupported unary operation");
|
||||
break;
|
||||
}
|
||||
ast_context()->ReturnInstruction(instr, expr->id());
|
||||
} else if (op == Token::TYPEOF) {
|
||||
VisitForTypeOf(expr->expression());
|
||||
if (HasStackOverflow()) return;
|
||||
HValue* value = Pop();
|
||||
ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
|
||||
} else {
|
||||
BAILOUT("Value: unsupported unary operation");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,7 +893,49 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
||||
}
|
||||
|
||||
if (right->IsConstantOperand()) {
|
||||
__ imul(left, left, ToInteger32(LConstantOperand::cast(right)));
|
||||
// Try strength reductions on the multiplication.
|
||||
// All replacement instructions are at most as long as the imul
|
||||
// and have better latency.
|
||||
int constant = ToInteger32(LConstantOperand::cast(right));
|
||||
if (constant == -1) {
|
||||
__ neg(left);
|
||||
} else if (constant == 0) {
|
||||
__ xor_(left, Operand(left));
|
||||
} else if (constant == 2) {
|
||||
__ add(left, Operand(left));
|
||||
} else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
|
||||
// If we know that the multiplication can't overflow, it's safe to
|
||||
// use instructions that don't set the overflow flag for the
|
||||
// multiplication.
|
||||
switch (constant) {
|
||||
case 1:
|
||||
// Do nothing.
|
||||
break;
|
||||
case 3:
|
||||
__ lea(left, Operand(left, left, times_2, 0));
|
||||
break;
|
||||
case 4:
|
||||
__ shl(left, 2);
|
||||
break;
|
||||
case 5:
|
||||
__ lea(left, Operand(left, left, times_4, 0));
|
||||
break;
|
||||
case 8:
|
||||
__ shl(left, 3);
|
||||
break;
|
||||
case 9:
|
||||
__ lea(left, Operand(left, left, times_8, 0));
|
||||
break;
|
||||
case 16:
|
||||
__ shl(left, 4);
|
||||
break;
|
||||
default:
|
||||
__ imul(left, left, constant);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
__ imul(left, left, constant);
|
||||
}
|
||||
} else {
|
||||
__ imul(left, ToOperand(right));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user