Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 1089004: Add binary operations with constants to the safe-int32 expression compiler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 7001 matching lines...) Expand 10 before | Expand all | Expand 10 after
7012 7012
7013 switch (op) { 7013 switch (op) {
7014 case Token::COMMA: 7014 case Token::COMMA:
7015 case Token::OR: 7015 case Token::OR:
7016 case Token::AND: 7016 case Token::AND:
7017 UNREACHABLE(); 7017 UNREACHABLE();
7018 break; 7018 break;
7019 case Token::BIT_OR: 7019 case Token::BIT_OR:
7020 case Token::BIT_XOR: 7020 case Token::BIT_XOR:
7021 case Token::BIT_AND: 7021 case Token::BIT_AND:
7022 left.ToRegister(); 7022 if (left.is_constant() || right.is_constant()) {
7023 right.ToRegister(); 7023 int32_t value; // Put constant in value, non-constant in left.
7024 if (op == Token::BIT_OR) { 7024 // Constants are known to be int32 values, from static analysis,
7025 __ or_(left.reg(), Operand(right.reg())); 7025 // or else will be converted to int32 by implicit ECMA [[ToInt32]].
7026 } else if (op == Token::BIT_XOR) { 7026 if (left.is_constant()) {
7027 __ xor_(left.reg(), Operand(right.reg())); 7027 ASSERT(left.handle()->IsSmi() || left.handle()->IsHeapNumber());
7028 value = NumberToInt32(*left.handle());
7029 left = right;
7030 } else {
7031 ASSERT(right.handle()->IsSmi() || right.handle()->IsHeapNumber());
7032 value = NumberToInt32(*right.handle());
7033 }
7034
7035 left.ToRegister();
7036 if (op == Token::BIT_OR) {
7037 __ or_(Operand(left.reg()), Immediate(value));
7038 } else if (op == Token::BIT_XOR) {
7039 __ xor_(Operand(left.reg()), Immediate(value));
7040 } else {
7041 ASSERT(op == Token::BIT_AND);
7042 __ and_(Operand(left.reg()), Immediate(value));
7043 }
7028 } else { 7044 } else {
7029 ASSERT(op == Token::BIT_AND); 7045 ASSERT(left.is_register());
7030 __ and_(left.reg(), Operand(right.reg())); 7046 ASSERT(right.is_register());
7047 if (op == Token::BIT_OR) {
7048 __ or_(left.reg(), Operand(right.reg()));
7049 } else if (op == Token::BIT_XOR) {
7050 __ xor_(left.reg(), Operand(right.reg()));
7051 } else {
7052 ASSERT(op == Token::BIT_AND);
7053 __ and_(left.reg(), Operand(right.reg()));
7054 }
7031 } 7055 }
7032 frame_->Push(&left); 7056 frame_->Push(&left);
7033 right.Unuse(); 7057 right.Unuse();
7034 break; 7058 break;
7035 case Token::SAR: 7059 case Token::SAR:
7036 case Token::SHL: 7060 case Token::SHL:
7037 case Token::SHR: { 7061 case Token::SHR: {
7038 bool test_shr_overflow = false; 7062 bool test_shr_overflow = false;
7039 left.ToRegister(); 7063 left.ToRegister();
7040 if (right.is_constant()) { 7064 if (right.is_constant()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
7079 // Test is needed because shr with shift amount 0 does not set flags. 7103 // Test is needed because shr with shift amount 0 does not set flags.
7080 __ test(left_reg, Operand(left_reg)); 7104 __ test(left_reg, Operand(left_reg));
7081 unsafe_bailout_->Branch(sign); 7105 unsafe_bailout_->Branch(sign);
7082 } 7106 }
7083 } 7107 }
7084 break; 7108 break;
7085 } 7109 }
7086 case Token::ADD: 7110 case Token::ADD:
7087 case Token::SUB: 7111 case Token::SUB:
7088 case Token::MUL: 7112 case Token::MUL:
7089 left.ToRegister(); 7113 if ((left.is_constant() && op != Token::SUB) || right.is_constant()) {
7090 right.ToRegister(); 7114 int32_t value; // Put constant in value, non-constant in left.
7091 if (op == Token::ADD) { 7115 if (right.is_constant()) {
7092 __ add(left.reg(), Operand(right.reg())); 7116 ASSERT(right.handle()->IsSmi() || right.handle()->IsHeapNumber());
7093 } else if (op == Token::SUB) { 7117 value = NumberToInt32(*right.handle());
7094 __ sub(left.reg(), Operand(right.reg())); 7118 } else {
7119 ASSERT(left.handle()->IsSmi() || left.handle()->IsHeapNumber());
7120 value = NumberToInt32(*left.handle());
7121 left = right;
7122 }
7123
7124 left.ToRegister();
7125 if (op == Token::ADD) {
7126 __ add(Operand(left.reg()), Immediate(value));
7127 } else if (op == Token::SUB) {
7128 __ sub(Operand(left.reg()), Immediate(value));
7129 } else {
7130 ASSERT(op == Token::MUL);
7131 __ imul(left.reg(), left.reg(), value);
7132 }
7095 } else { 7133 } else {
7096 ASSERT(op == Token::MUL); 7134 left.ToRegister();
fschneider 2010/03/22 10:30:42 Do we need right.ToRegister() here as well?
William Hesse 2010/03/23 10:19:45 No. If right is a constant we never get to this b
7097 // We have statically verified that a negative zero can be ignored. 7135 ASSERT(left.is_register());
7098 __ imul(left.reg(), Operand(right.reg())); 7136 ASSERT(right.is_register());
7137 if (op == Token::ADD) {
7138 __ add(left.reg(), Operand(right.reg()));
7139 } else if (op == Token::SUB) {
7140 __ sub(left.reg(), Operand(right.reg()));
7141 } else {
7142 ASSERT(op == Token::MUL);
7143 // We have statically verified that a negative zero can be ignored.
7144 __ imul(left.reg(), Operand(right.reg()));
7145 }
7099 } 7146 }
7100 right.Unuse(); 7147 right.Unuse();
7101 frame_->Push(&left); 7148 frame_->Push(&left);
7102 if (!node->to_int32()) { 7149 if (!node->to_int32()) {
7103 // If ToInt32 is called on the result of ADD, SUB, or MUL, we don't 7150 // If ToInt32 is called on the result of ADD, SUB, or MUL, we don't
7104 // care about overflows. 7151 // care about overflows.
7105 unsafe_bailout_->Branch(overflow); 7152 unsafe_bailout_->Branch(overflow);
7106 } 7153 }
7107 break; 7154 break;
7108 case Token::DIV: 7155 case Token::DIV:
(...skipping 5161 matching lines...) Expand 10 before | Expand all | Expand 10 after
12270 12317
12271 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 12318 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
12272 // tagged as a small integer. 12319 // tagged as a small integer.
12273 __ bind(&runtime); 12320 __ bind(&runtime);
12274 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 12321 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
12275 } 12322 }
12276 12323
12277 #undef __ 12324 #undef __
12278 12325
12279 } } // namespace v8::internal 12326 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698