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

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

Issue 164399: X64: Add an SHL optimization, fix a floating-point bug, fix xchg rax,r8 and p... (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 | src/x64/disasm-x64.cc » ('j') | src/x64/disasm-x64.cc » ('J')
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 5240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5251 } 5251 }
5252 operand->Unuse(); 5252 operand->Unuse();
5253 ASSERT(kSmiTag == 0); 5253 ASSERT(kSmiTag == 0);
5254 ASSERT(kSmiTagSize == 1); 5254 ASSERT(kSmiTagSize == 1);
5255 __ addl(answer.reg(), answer.reg()); 5255 __ addl(answer.reg(), answer.reg());
5256 deferred->BindExit(); 5256 deferred->BindExit();
5257 frame_->Push(&answer); 5257 frame_->Push(&answer);
5258 } 5258 }
5259 break; 5259 break;
5260 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
5261 case Token::BIT_OR: 5313 case Token::BIT_OR:
5262 case Token::BIT_XOR: 5314 case Token::BIT_XOR:
5263 case Token::BIT_AND: { 5315 case Token::BIT_AND: {
5264 operand->ToRegister(); 5316 operand->ToRegister();
5265 frame_->Spill(operand->reg()); 5317 frame_->Spill(operand->reg());
5266 if (reversed) { 5318 if (reversed) {
5267 // Bit operations with a constant smi are commutative. 5319 // Bit operations with a constant smi are commutative.
5268 // We can swap left and right operands with no problem. 5320 // We can swap left and right operands with no problem.
5269 // Swap left and right overwrite modes. 0->0, 1->2, 2->1. 5321 // Swap left and right overwrite modes. 0->0, 1->2, 2->1.
5270 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3); 5322 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3);
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
6006 // We can skip the write barrier for smis and constants. 6058 // We can skip the write barrier for smis and constants.
6007 if (!value_is_constant) { 6059 if (!value_is_constant) {
6008 __ testl(value.reg(), Immediate(kSmiTagMask)); 6060 __ testl(value.reg(), Immediate(kSmiTagMask));
6009 deferred->Branch(not_zero); 6061 deferred->Branch(not_zero);
6010 } 6062 }
6011 6063
6012 // Check that the key is a non-negative smi. 6064 // Check that the key is a non-negative smi.
6013 __ testl(key.reg(), 6065 __ testl(key.reg(),
6014 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); 6066 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U)));
6015 deferred->Branch(not_zero); 6067 deferred->Branch(not_zero);
6068 // Ensure that the smi is zero-extended. This is not guaranteed.
6069 __ movl(key.reg(), key.reg());
6016 6070
6017 // Check that the receiver is not a smi. 6071 // Check that the receiver is not a smi.
6018 __ testl(receiver.reg(), Immediate(kSmiTagMask)); 6072 __ testl(receiver.reg(), Immediate(kSmiTagMask));
6019 deferred->Branch(zero); 6073 deferred->Branch(zero);
6020 6074
6021 // Check that the receiver is a JSArray. 6075 // Check that the receiver is a JSArray.
6022 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister); 6076 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister);
6023 deferred->Branch(not_equal); 6077 deferred->Branch(not_equal);
6024 6078
6025 // Check that the key is within bounds. Both the key and the 6079 // Check that the key is within bounds. Both the key and the
(...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after
7165 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); 7219 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset));
7166 __ bind(&done_load_1); 7220 __ bind(&done_load_1);
7167 7221
7168 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); 7222 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
7169 __ testl(kScratchRegister, Immediate(kSmiTagMask)); 7223 __ testl(kScratchRegister, Immediate(kSmiTagMask));
7170 __ j(zero, &load_smi_2); 7224 __ j(zero, &load_smi_2);
7171 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); 7225 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset));
7172 __ jmp(&done); 7226 __ jmp(&done);
7173 7227
7174 __ bind(&load_smi_1); 7228 __ bind(&load_smi_1);
7175 __ sar(kScratchRegister, Immediate(kSmiTagSize)); 7229 __ sarl(kScratchRegister, Immediate(kSmiTagSize));
7176 __ push(kScratchRegister); 7230 __ push(kScratchRegister);
7177 __ fild_s(Operand(rsp, 0)); 7231 __ fild_s(Operand(rsp, 0));
7178 __ pop(kScratchRegister); 7232 __ pop(kScratchRegister);
7179 __ jmp(&done_load_1); 7233 __ jmp(&done_load_1);
7180 7234
7181 __ bind(&load_smi_2); 7235 __ bind(&load_smi_2);
7182 __ sar(kScratchRegister, Immediate(kSmiTagSize)); 7236 __ sarl(kScratchRegister, Immediate(kSmiTagSize));
7183 __ push(kScratchRegister); 7237 __ push(kScratchRegister);
7184 __ fild_s(Operand(rsp, 0)); 7238 __ fild_s(Operand(rsp, 0));
7185 __ pop(kScratchRegister); 7239 __ pop(kScratchRegister);
7186 7240
7187 __ bind(&done); 7241 __ bind(&done);
7188 } 7242 }
7189 7243
7190 7244
7191 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, 7245 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
7192 Register lhs, 7246 Register lhs,
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
7527 if (op_ == Token::SHR) { 7581 if (op_ == Token::SHR) {
7528 // Check if result is non-negative and fits in a smi. 7582 // Check if result is non-negative and fits in a smi.
7529 __ testl(rax, Immediate(0xc0000000)); 7583 __ testl(rax, Immediate(0xc0000000));
7530 __ j(not_zero, &non_smi_result); 7584 __ j(not_zero, &non_smi_result);
7531 } else { 7585 } else {
7532 // Check if result fits in a smi. 7586 // Check if result fits in a smi.
7533 __ cmpl(rax, Immediate(0xc0000000)); 7587 __ cmpl(rax, Immediate(0xc0000000));
7534 __ j(negative, &non_smi_result); 7588 __ j(negative, &non_smi_result);
7535 } 7589 }
7536 // Tag smi result and return. 7590 // Tag smi result and return.
7537 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 7591 ASSERT(kSmiTagSize == 1); // adjust code if not the case
7538 __ lea(rax, Operand(rax, rax, times_1, kSmiTag)); 7592 __ lea(rax, Operand(rax, rax, times_1, kSmiTag));
7539 __ ret(2 * kPointerSize); 7593 __ ret(2 * kPointerSize);
7540 7594
7541 // All ops except SHR return a signed int32 that we load in a HeapNumber. 7595 // All ops except SHR return a signed int32 that we load in a HeapNumber.
7542 if (op_ != Token::SHR) { 7596 if (op_ != Token::SHR) {
7543 __ bind(&non_smi_result); 7597 __ bind(&non_smi_result);
7544 // Allocate a heap number if needed. 7598 // Allocate a heap number if needed.
7545 __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result 7599 __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result
7546 switch (mode_) { 7600 switch (mode_) {
7547 case OVERWRITE_LEFT: 7601 case OVERWRITE_LEFT:
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
7640 int CompareStub::MinorKey() { 7694 int CompareStub::MinorKey() {
7641 // Encode the two parameters in a unique 16 bit value. 7695 // Encode the two parameters in a unique 16 bit value.
7642 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7696 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
7643 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7697 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
7644 } 7698 }
7645 7699
7646 7700
7647 #undef __ 7701 #undef __
7648 7702
7649 } } // namespace v8::internal 7703 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/x64/disasm-x64.cc » ('j') | src/x64/disasm-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698