Simplify IA32 code generator API.

Cut down on the number of arguments passed to the various binary operation
code generator functions by passing along the expression itself, rather than
a subset of its fields.

Review URL: http://codereview.chromium.org/1592001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4319 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6d3cdbbf
...@@ -852,13 +852,11 @@ UnaryOperation::UnaryOperation(UnaryOperation* other, Expression* expression) ...@@ -852,13 +852,11 @@ UnaryOperation::UnaryOperation(UnaryOperation* other, Expression* expression)
: Expression(other), op_(other->op_), expression_(expression) {} : Expression(other), op_(other->op_), expression_(expression) {}
BinaryOperation::BinaryOperation(BinaryOperation* other, BinaryOperation::BinaryOperation(Expression* other,
Token::Value op,
Expression* left, Expression* left,
Expression* right) Expression* right)
: Expression(other), : Expression(other), op_(op), left_(left), right_(right) {}
op_(other->op_),
left_(left),
right_(right) {}
CountOperation::CountOperation(CountOperation* other, Expression* expression) CountOperation::CountOperation(CountOperation* other, Expression* expression)
...@@ -1110,6 +1108,7 @@ void CopyAstVisitor::VisitCountOperation(CountOperation* expr) { ...@@ -1110,6 +1108,7 @@ void CopyAstVisitor::VisitCountOperation(CountOperation* expr) {
void CopyAstVisitor::VisitBinaryOperation(BinaryOperation* expr) { void CopyAstVisitor::VisitBinaryOperation(BinaryOperation* expr) {
expr_ = new BinaryOperation(expr, expr_ = new BinaryOperation(expr,
expr->op(),
DeepCopyExpr(expr->left()), DeepCopyExpr(expr->left()),
DeepCopyExpr(expr->right())); DeepCopyExpr(expr->right()));
} }
......
...@@ -1369,7 +1369,13 @@ class BinaryOperation: public Expression { ...@@ -1369,7 +1369,13 @@ class BinaryOperation: public Expression {
ASSERT(Token::IsBinaryOp(op)); ASSERT(Token::IsBinaryOp(op));
} }
BinaryOperation(BinaryOperation* other, Expression* left, Expression* right); // Construct a binary operation with a given operator and left and right
// subexpressions. The rest of the expression state is copied from
// another expression.
BinaryOperation(Expression* other,
Token::Value op,
Expression* left,
Expression* right);
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
......
...@@ -1221,11 +1221,10 @@ static TypeInfo CalculateTypeInfo(TypeInfo operands_type, ...@@ -1221,11 +1221,10 @@ static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
} }
void CodeGenerator::GenericBinaryOperation(Token::Value op, void CodeGenerator::GenericBinaryOperation(BinaryOperation* expr,
StaticType* type, OverwriteMode overwrite_mode) {
OverwriteMode overwrite_mode,
bool no_negative_zero) {
Comment cmnt(masm_, "[ BinaryOperation"); Comment cmnt(masm_, "[ BinaryOperation");
Token::Value op = expr->op();
Comment cmnt_token(masm_, Token::String(op)); Comment cmnt_token(masm_, Token::String(op));
if (op == Token::COMMA) { if (op == Token::COMMA) {
...@@ -1298,13 +1297,11 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, ...@@ -1298,13 +1297,11 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
operands_type); operands_type);
answer = stub.GenerateCall(masm_, frame_, &left, &right); answer = stub.GenerateCall(masm_, frame_, &left, &right);
} else if (right_is_smi_constant) { } else if (right_is_smi_constant) {
answer = ConstantSmiBinaryOperation(op, &left, right.handle(), answer = ConstantSmiBinaryOperation(expr, &left, right.handle(),
type, false, overwrite_mode, false, overwrite_mode);
no_negative_zero);
} else if (left_is_smi_constant) { } else if (left_is_smi_constant) {
answer = ConstantSmiBinaryOperation(op, &right, left.handle(), answer = ConstantSmiBinaryOperation(expr, &right, left.handle(),
type, true, overwrite_mode, true, overwrite_mode);
no_negative_zero);
} else { } else {
// Set the flags based on the operation, type and loop nesting level. // Set the flags based on the operation, type and loop nesting level.
// Bit operations always assume they likely operate on Smis. Still only // Bit operations always assume they likely operate on Smis. Still only
...@@ -1314,9 +1311,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, ...@@ -1314,9 +1311,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
if (loop_nesting() > 0 && if (loop_nesting() > 0 &&
(Token::IsBitOp(op) || (Token::IsBitOp(op) ||
operands_type.IsInteger32() || operands_type.IsInteger32() ||
type->IsLikelySmi())) { expr->type()->IsLikelySmi())) {
answer = LikelySmiBinaryOperation(op, &left, &right, answer = LikelySmiBinaryOperation(expr, &left, &right, overwrite_mode);
overwrite_mode, no_negative_zero);
} else { } else {
GenericBinaryOpStub stub(op, GenericBinaryOpStub stub(op,
overwrite_mode, overwrite_mode,
...@@ -1420,11 +1416,11 @@ static void CheckTwoForSminess(MacroAssembler* masm, ...@@ -1420,11 +1416,11 @@ static void CheckTwoForSminess(MacroAssembler* masm,
// Implements a binary operation using a deferred code object and some // Implements a binary operation using a deferred code object and some
// inline code to operate on smis quickly. // inline code to operate on smis quickly.
Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
Result* left, Result* left,
Result* right, Result* right,
OverwriteMode overwrite_mode, OverwriteMode overwrite_mode) {
bool no_negative_zero) { Token::Value op = expr->op();
Result answer; Result answer;
// Special handling of div and mod because they use fixed registers. // Special handling of div and mod because they use fixed registers.
if (op == Token::DIV || op == Token::MOD) { if (op == Token::DIV || op == Token::MOD) {
...@@ -1530,7 +1526,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1530,7 +1526,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// virtual frame is unchanged in this block, so local control flow // virtual frame is unchanged in this block, so local control flow
// can use a Label rather than a JumpTarget. If the context of this // can use a Label rather than a JumpTarget. If the context of this
// expression will treat -0 like 0, do not do this test. // expression will treat -0 like 0, do not do this test.
if (!no_negative_zero) { if (!expr->no_negative_zero()) {
Label non_zero_result; Label non_zero_result;
__ test(left->reg(), Operand(left->reg())); __ test(left->reg(), Operand(left->reg()));
__ j(not_zero, &non_zero_result); __ j(not_zero, &non_zero_result);
...@@ -1559,7 +1555,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1559,7 +1555,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// the dividend is negative, return a floating point negative // the dividend is negative, return a floating point negative
// zero. The frame is unchanged in this block, so local control // zero. The frame is unchanged in this block, so local control
// flow can use a Label rather than a JumpTarget. // flow can use a Label rather than a JumpTarget.
if (!no_negative_zero) { if (!expr->no_negative_zero()) {
Label non_zero_result; Label non_zero_result;
__ test(edx, Operand(edx)); __ test(edx, Operand(edx));
__ j(not_zero, &non_zero_result, taken); __ j(not_zero, &non_zero_result, taken);
...@@ -1743,7 +1739,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1743,7 +1739,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// argument is negative, go to slow case. The frame is unchanged // argument is negative, go to slow case. The frame is unchanged
// in this block, so local control flow can use a Label rather // in this block, so local control flow can use a Label rather
// than a JumpTarget. // than a JumpTarget.
if (!no_negative_zero) { if (!expr->no_negative_zero()) {
Label non_zero_result; Label non_zero_result;
__ test(answer.reg(), Operand(answer.reg())); __ test(answer.reg(), Operand(answer.reg()));
__ j(not_zero, &non_zero_result, taken); __ j(not_zero, &non_zero_result, taken);
...@@ -1986,13 +1982,12 @@ void DeferredInlineSmiSub::Generate() { ...@@ -1986,13 +1982,12 @@ void DeferredInlineSmiSub::Generate() {
} }
Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, Result CodeGenerator::ConstantSmiBinaryOperation(
Result* operand, BinaryOperation* expr,
Handle<Object> value, Result* operand,
StaticType* type, Handle<Object> value,
bool reversed, bool reversed,
OverwriteMode overwrite_mode, OverwriteMode overwrite_mode) {
bool no_negative_zero) {
// NOTE: This is an attempt to inline (a bit) more of the code for // NOTE: This is an attempt to inline (a bit) more of the code for
// some possible smi operations (like + and -) when (at least) one // some possible smi operations (like + and -) when (at least) one
// of the operands is a constant smi. // of the operands is a constant smi.
...@@ -2002,11 +1997,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2002,11 +1997,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
if (IsUnsafeSmi(value)) { if (IsUnsafeSmi(value)) {
Result unsafe_operand(value); Result unsafe_operand(value);
if (reversed) { if (reversed) {
return LikelySmiBinaryOperation(op, &unsafe_operand, operand, return LikelySmiBinaryOperation(expr, &unsafe_operand, operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} else { } else {
return LikelySmiBinaryOperation(op, operand, &unsafe_operand, return LikelySmiBinaryOperation(expr, operand, &unsafe_operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} }
} }
...@@ -2014,6 +2009,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2014,6 +2009,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
Smi* smi_value = Smi::cast(*value); Smi* smi_value = Smi::cast(*value);
int int_value = smi_value->value(); int int_value = smi_value->value();
Token::Value op = expr->op();
Result answer; Result answer;
switch (op) { switch (op) {
case Token::ADD: { case Token::ADD: {
...@@ -2089,8 +2085,8 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2089,8 +2085,8 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
case Token::SAR: case Token::SAR:
if (reversed) { if (reversed) {
Result constant_operand(value); Result constant_operand(value);
answer = LikelySmiBinaryOperation(op, &constant_operand, operand, answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} else { } else {
// Only the least significant 5 bits of the shift value are used. // Only the least significant 5 bits of the shift value are used.
// In the slow case, this masking is done inside the runtime call. // In the slow case, this masking is done inside the runtime call.
...@@ -2126,8 +2122,8 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2126,8 +2122,8 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
case Token::SHR: case Token::SHR:
if (reversed) { if (reversed) {
Result constant_operand(value); Result constant_operand(value);
answer = LikelySmiBinaryOperation(op, &constant_operand, operand, answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} else { } else {
// Only the least significant 5 bits of the shift value are used. // Only the least significant 5 bits of the shift value are used.
// In the slow case, this masking is done inside the runtime call. // In the slow case, this masking is done inside the runtime call.
...@@ -2327,11 +2323,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2327,11 +2323,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
// default case here. // default case here.
Result constant_operand(value); Result constant_operand(value);
if (reversed) { if (reversed) {
answer = LikelySmiBinaryOperation(op, &constant_operand, operand, answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} else { } else {
answer = LikelySmiBinaryOperation(op, operand, &constant_operand, answer = LikelySmiBinaryOperation(expr, operand, &constant_operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} }
} }
break; break;
...@@ -2367,11 +2363,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -2367,11 +2363,11 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
default: { default: {
Result constant_operand(value); Result constant_operand(value);
if (reversed) { if (reversed) {
answer = LikelySmiBinaryOperation(op, &constant_operand, operand, answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} else { } else {
answer = LikelySmiBinaryOperation(op, operand, &constant_operand, answer = LikelySmiBinaryOperation(expr, operand, &constant_operand,
overwrite_mode, no_negative_zero); overwrite_mode);
} }
break; break;
} }
...@@ -5371,10 +5367,11 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) { ...@@ -5371,10 +5367,11 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) {
bool overwrite_value = bool overwrite_value =
(node->value()->AsBinaryOperation() != NULL && (node->value()->AsBinaryOperation() != NULL &&
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericBinaryOperation(node->binary_op(), // Construct the implicit binary operation.
node->type(), BinaryOperation expr(node, node->binary_op(), node->target(),
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, node->value());
node->no_negative_zero()); GenericBinaryOperation(&expr,
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
Load(node->value()); Load(node->value());
} }
...@@ -5449,10 +5446,11 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5449,10 +5446,11 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
bool overwrite_value = bool overwrite_value =
(node->value()->AsBinaryOperation() != NULL && (node->value()->AsBinaryOperation() != NULL &&
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericBinaryOperation(node->binary_op(), // Construct the implicit binary operation.
node->type(), BinaryOperation expr(node, node->binary_op(), node->target(),
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, node->value());
node->no_negative_zero()); GenericBinaryOperation(&expr,
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
Load(node->value()); Load(node->value());
} }
...@@ -5529,10 +5527,10 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { ...@@ -5529,10 +5527,10 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
bool overwrite_value = bool overwrite_value =
(node->value()->AsBinaryOperation() != NULL && (node->value()->AsBinaryOperation() != NULL &&
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericBinaryOperation(node->binary_op(), BinaryOperation expr(node, node->binary_op(), node->target(),
node->type(), node->value());
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, GenericBinaryOperation(&expr,
node->no_negative_zero()); overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
Load(node->value()); Load(node->value());
} }
...@@ -7636,8 +7634,7 @@ void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { ...@@ -7636,8 +7634,7 @@ void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
Load(node->left()); Load(node->left());
Load(node->right()); Load(node->right());
} }
GenericBinaryOperation(node->op(), node->type(), GenericBinaryOperation(node, overwrite_mode);
overwrite_mode, node->no_negative_zero());
} }
} }
......
...@@ -492,11 +492,8 @@ class CodeGenerator: public AstVisitor { ...@@ -492,11 +492,8 @@ class CodeGenerator: public AstVisitor {
// Generate code that computes a shortcutting logical operation. // Generate code that computes a shortcutting logical operation.
void GenerateLogicalBooleanOperation(BinaryOperation* node); void GenerateLogicalBooleanOperation(BinaryOperation* node);
void GenericBinaryOperation( void GenericBinaryOperation(BinaryOperation* expr,
Token::Value op, OverwriteMode overwrite_mode);
StaticType* type,
OverwriteMode overwrite_mode,
bool no_negative_zero);
// If possible, combine two constant smi values using op to produce // If possible, combine two constant smi values using op to produce
// a smi result, and push it on the virtual frame, all at compile time. // a smi result, and push it on the virtual frame, all at compile time.
...@@ -505,22 +502,19 @@ class CodeGenerator: public AstVisitor { ...@@ -505,22 +502,19 @@ class CodeGenerator: public AstVisitor {
// Emit code to perform a binary operation on a constant // Emit code to perform a binary operation on a constant
// smi and a likely smi. Consumes the Result operand. // smi and a likely smi. Consumes the Result operand.
Result ConstantSmiBinaryOperation(Token::Value op, Result ConstantSmiBinaryOperation(BinaryOperation* expr,
Result* operand, Result* operand,
Handle<Object> constant_operand, Handle<Object> constant_operand,
StaticType* type,
bool reversed, bool reversed,
OverwriteMode overwrite_mode, OverwriteMode overwrite_mode);
bool no_negative_zero);
// Emit code to perform a binary operation on two likely smis. // Emit code to perform a binary operation on two likely smis.
// The code to handle smi arguments is produced inline. // The code to handle smi arguments is produced inline.
// Consumes the Results left and right. // Consumes the Results left and right.
Result LikelySmiBinaryOperation(Token::Value op, Result LikelySmiBinaryOperation(BinaryOperation* expr,
Result* left, Result* left,
Result* right, Result* right,
OverwriteMode overwrite_mode, OverwriteMode overwrite_mode);
bool no_negative_zero);
// Emit code to perform a binary operation on two untagged int32 values. // Emit code to perform a binary operation on two untagged int32 values.
......
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