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

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

Issue 164317: X64: Implement remaining constant smi optimizations. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 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 | test/mozilla/mozilla.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 5174 matching lines...) Expand 10 before | Expand all | Expand 10 after
5185 Label add_success; 5185 Label add_success;
5186 __ j(no_overflow, &add_success); 5186 __ j(no_overflow, &add_success);
5187 __ addl(operand->reg(), Immediate(smi_value)); 5187 __ addl(operand->reg(), Immediate(smi_value));
5188 deferred->Jump(); 5188 deferred->Jump();
5189 __ bind(&add_success); 5189 __ bind(&add_success);
5190 deferred->BindExit(); 5190 deferred->BindExit();
5191 frame_->Push(operand); 5191 frame_->Push(operand);
5192 } 5192 }
5193 break; 5193 break;
5194 } 5194 }
5195 // TODO(X64): Move other implementations from ia32 to here. 5195
5196 case Token::SAR:
5197 if (reversed) {
5198 Result constant_operand(value);
5199 LikelySmiBinaryOperation(op, &constant_operand, operand,
5200 overwrite_mode);
5201 } else {
5202 // Only the least significant 5 bits of the shift value are used.
5203 // In the slow case, this masking is done inside the runtime call.
5204 int shift_value = int_value & 0x1f;
5205 operand->ToRegister();
5206 frame_->Spill(operand->reg());
5207 DeferredInlineSmiOperation* deferred =
5208 new DeferredInlineSmiOperation(op,
5209 operand->reg(),
5210 operand->reg(),
5211 smi_value,
5212 overwrite_mode);
5213 __ testl(operand->reg(), Immediate(kSmiTagMask));
5214 deferred->Branch(not_zero);
5215 if (shift_value > 0) {
5216 __ sarl(operand->reg(), Immediate(shift_value));
5217 __ and_(operand->reg(), Immediate(~kSmiTagMask));
5218 }
5219 deferred->BindExit();
5220 frame_->Push(operand);
5221 }
5222 break;
5223
5224 case Token::SHR:
5225 if (reversed) {
5226 Result constant_operand(value);
5227 LikelySmiBinaryOperation(op, &constant_operand, operand,
5228 overwrite_mode);
5229 } else {
5230 // Only the least significant 5 bits of the shift value are used.
5231 // In the slow case, this masking is done inside the runtime call.
5232 int shift_value = int_value & 0x1f;
5233 operand->ToRegister();
5234 Result answer = allocator()->Allocate();
5235 ASSERT(answer.is_valid());
5236 DeferredInlineSmiOperation* deferred =
5237 new DeferredInlineSmiOperation(op,
5238 answer.reg(),
5239 operand->reg(),
5240 smi_value,
5241 overwrite_mode);
5242 __ testl(operand->reg(), Immediate(kSmiTagMask));
5243 deferred->Branch(not_zero);
5244 __ movl(answer.reg(), operand->reg());
5245 __ sarl(answer.reg(), Immediate(kSmiTagSize));
5246 __ shrl(answer.reg(), Immediate(shift_value));
5247 // A negative Smi shifted right two is in the positive Smi range.
5248 if (shift_value < 2) {
5249 __ testl(answer.reg(), Immediate(0xc0000000));
5250 deferred->Branch(not_zero);
5251 }
5252 operand->Unuse();
5253 ASSERT(kSmiTagSize == times_2); // Adjust the code if not true.
5254 __ lea(answer.reg(),
5255 Operand(answer.reg(), answer.reg(), times_1, kSmiTag));
5256 deferred->BindExit();
5257 frame_->Push(&answer);
5258 }
5259 break;
5260
5261 case Token::SHL:
5262 if (reversed) {
5263 Result constant_operand(value);
5264 LikelySmiBinaryOperation(op, &constant_operand, operand,
5265 overwrite_mode);
5266 } else {
5267 // Only the least significant 5 bits of the shift value are used.
5268 // In the slow case, this masking is done inside the runtime call.
5269 int shift_value = int_value & 0x1f;
5270 operand->ToRegister();
5271 if (shift_value == 0) {
5272 // Spill operand so it can be overwritten in the slow case.
5273 frame_->Spill(operand->reg());
5274 DeferredInlineSmiOperation* deferred =
5275 new DeferredInlineSmiOperation(op,
5276 operand->reg(),
5277 operand->reg(),
5278 smi_value,
5279 overwrite_mode);
5280 __ testl(operand->reg(), Immediate(kSmiTagMask));
5281 deferred->Branch(not_zero);
5282 deferred->BindExit();
5283 frame_->Push(operand);
5284 } else {
5285 // Use a fresh temporary for nonzero shift values.
5286 Result answer = allocator()->Allocate();
5287 ASSERT(answer.is_valid());
5288 DeferredInlineSmiOperation* deferred =
5289 new DeferredInlineSmiOperation(op,
5290 answer.reg(),
5291 operand->reg(),
5292 smi_value,
5293 overwrite_mode);
5294 __ testl(operand->reg(), Immediate(kSmiTagMask));
5295 deferred->Branch(not_zero);
5296 __ movl(answer.reg(), operand->reg());
5297 ASSERT(kSmiTag == 0); // adjust code if not the case
5298 // We do no shifts, only the Smi conversion, if shift_value is 1.
5299 if (shift_value > 1) {
5300 __ shll(answer.reg(), Immediate(shift_value - 1));
5301 }
5302 // Convert int result to Smi, checking that it is in int range.
5303 ASSERT(kSmiTagSize == 1); // adjust code if not the case
5304 __ addl(answer.reg(), answer.reg());
5305 deferred->Branch(overflow);
5306 deferred->BindExit();
5307 operand->Unuse();
5308 frame_->Push(&answer);
5309 }
5310 }
5311 break;
5312
5313 case Token::BIT_OR:
5314 case Token::BIT_XOR:
5315 case Token::BIT_AND: {
5316 operand->ToRegister();
5317 frame_->Spill(operand->reg());
5318 if (reversed) {
5319 // Bit operations with a constant smi are commutative.
5320 // We can swap left and right operands with no problem.
5321 // Swap left and right overwrite modes. 0->0, 1->2, 2->1.
5322 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3);
5323 }
5324 DeferredCode* deferred = new DeferredInlineSmiOperation(op,
5325 operand->reg(),
5326 operand->reg(),
5327 smi_value,
5328 overwrite_mode);
5329 __ testl(operand->reg(), Immediate(kSmiTagMask));
5330 deferred->Branch(not_zero);
5331 if (op == Token::BIT_AND) {
5332 __ and_(operand->reg(), Immediate(smi_value));
5333 } else if (op == Token::BIT_XOR) {
5334 if (int_value != 0) {
5335 __ xor_(operand->reg(), Immediate(smi_value));
5336 }
5337 } else {
5338 ASSERT(op == Token::BIT_OR);
5339 if (int_value != 0) {
5340 __ or_(operand->reg(), Immediate(smi_value));
5341 }
5342 }
5343 deferred->BindExit();
5344 frame_->Push(operand);
5345 break;
5346 }
5196 5347
5197 // Generate inline code for mod of powers of 2 and negative powers of 2. 5348 // Generate inline code for mod of powers of 2 and negative powers of 2.
5198 case Token::MOD: 5349 case Token::MOD:
5199 if (!reversed && 5350 if (!reversed &&
5200 int_value != 0 && 5351 int_value != 0 &&
5201 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { 5352 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
5202 operand->ToRegister(); 5353 operand->ToRegister();
5203 frame_->Spill(operand->reg()); 5354 frame_->Spill(operand->reg());
5204 DeferredCode* deferred = new DeferredInlineSmiOperation(op, 5355 DeferredCode* deferred = new DeferredInlineSmiOperation(op,
5205 operand->reg(), 5356 operand->reg(),
(...skipping 2335 matching lines...) Expand 10 before | Expand all | Expand 10 after
7541 int CompareStub::MinorKey() { 7692 int CompareStub::MinorKey() {
7542 // Encode the two parameters in a unique 16 bit value. 7693 // Encode the two parameters in a unique 16 bit value.
7543 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7694 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
7544 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7695 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
7545 } 7696 }
7546 7697
7547 7698
7548 #undef __ 7699 #undef __
7549 7700
7550 } } // namespace v8::internal 7701 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mozilla/mozilla.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698