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

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

Issue 155279: X64: Fix bug in left-shift. (Closed)
Patch Set: Created 11 years, 5 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
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 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0 1285 frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0
1286 1286
1287 // Condition. 1287 // Condition.
1288 entry.Bind(); 1288 entry.Bind();
1289 // Grab the current frame's height for the break and continue 1289 // Grab the current frame's height for the break and continue
1290 // targets only after all the state is pushed on the frame. 1290 // targets only after all the state is pushed on the frame.
1291 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1291 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1292 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); 1292 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1293 1293
1294 __ movq(rax, frame_->ElementAt(0)); // load the current count 1294 __ movq(rax, frame_->ElementAt(0)); // load the current count
1295 __ cmpq(rax, frame_->ElementAt(1)); // compare to the array length 1295 __ cmpl(rax, frame_->ElementAt(1)); // compare to the array length
1296 node->break_target()->Branch(above_equal); 1296 node->break_target()->Branch(above_equal);
1297 1297
1298 // Get the i'th entry of the array. 1298 // Get the i'th entry of the array.
1299 __ movq(rdx, frame_->ElementAt(2)); 1299 __ movq(rdx, frame_->ElementAt(2));
1300 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 1300 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1301 // Multiplier is times_4 since rax is already a Smi. 1301 // Multiplier is times_4 since rax is already a Smi.
1302 __ movq(rbx, FieldOperand(rdx, rax, times_4, FixedArray::kHeaderSize)); 1302 __ movq(rbx, FieldOperand(rdx, rax, times_4, FixedArray::kHeaderSize));
1303 1303
1304 // Get the expected map from the stack or a zero map in the 1304 // Get the expected map from the stack or a zero map in the
1305 // permanent slow case rax: current iteration count rbx: i'th entry 1305 // permanent slow case rax: current iteration count rbx: i'th entry
(...skipping 3796 matching lines...) Expand 10 before | Expand all | Expand 10 after
5102 ASSERT(kSmiTag == 0); 5102 ASSERT(kSmiTag == 0);
5103 __ shl(rcx, Immediate(kSmiTagSize)); 5103 __ shl(rcx, Immediate(kSmiTagSize));
5104 deferred->Jump(); 5104 deferred->Jump();
5105 __ bind(&result_ok); 5105 __ bind(&result_ok);
5106 break; 5106 break;
5107 } 5107 }
5108 case Token::SHL: { 5108 case Token::SHL: {
5109 Label result_ok; 5109 Label result_ok;
5110 __ shl(answer.reg()); 5110 __ shl(answer.reg());
5111 // Check that the *signed* result fits in a smi. 5111 // Check that the *signed* result fits in a smi.
5112 __ cmpq(answer.reg(), Immediate(0xc0000000)); 5112 __ cmpl(answer.reg(), Immediate(0xc0000000));
5113 __ j(positive, &result_ok); 5113 __ j(positive, &result_ok);
5114 ASSERT(kSmiTag == 0); 5114 ASSERT(kSmiTag == 0);
5115 __ shl(rcx, Immediate(kSmiTagSize)); 5115 __ shl(rcx, Immediate(kSmiTagSize));
5116 deferred->Jump(); 5116 deferred->Jump();
5117 __ bind(&result_ok); 5117 __ bind(&result_ok);
5118 break; 5118 break;
5119 } 5119 }
5120 default: 5120 default:
5121 UNREACHABLE(); 5121 UNREACHABLE();
5122 } 5122 }
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
6668 ASSERT_EQ(0, kSmiTag); 6668 ASSERT_EQ(0, kSmiTag);
6669 __ xor_(rax, rbx); 6669 __ xor_(rax, rbx);
6670 break; 6670 break;
6671 6671
6672 case Token::SHL: 6672 case Token::SHL:
6673 case Token::SHR: 6673 case Token::SHR:
6674 case Token::SAR: 6674 case Token::SAR:
6675 // Move the second operand into register ecx. 6675 // Move the second operand into register ecx.
6676 __ movq(rcx, rbx); 6676 __ movq(rcx, rbx);
6677 // Remove tags from operands (but keep sign). 6677 // Remove tags from operands (but keep sign).
6678 __ sar(rax, Immediate(kSmiTagSize)); 6678 __ sarl(rax, Immediate(kSmiTagSize));
6679 __ sar(rcx, Immediate(kSmiTagSize)); 6679 __ sarl(rcx, Immediate(kSmiTagSize));
6680 // Perform the operation. 6680 // Perform the operation.
6681 switch (op_) { 6681 switch (op_) {
6682 case Token::SAR: 6682 case Token::SAR:
6683 __ sar(rax); 6683 __ sarl(rax);
6684 // No checks of result necessary 6684 // No checks of result necessary
6685 break; 6685 break;
6686 case Token::SHR: 6686 case Token::SHR:
6687 __ shrl(rax); // rcx is implicit shift register 6687 __ shrl(rax); // rcx is implicit shift register
6688 // Check that the *unsigned* result fits in a smi. 6688 // Check that the *unsigned* result fits in a smi.
6689 // Neither of the two high-order bits can be set: 6689 // Neither of the two high-order bits can be set:
6690 // - 0x80000000: high bit would be lost when smi tagging. 6690 // - 0x80000000: high bit would be lost when smi tagging.
6691 // - 0x40000000: this number would convert to negative when 6691 // - 0x40000000: this number would convert to negative when
6692 // Smi tagging these two cases can only happen with shifts 6692 // Smi tagging these two cases can only happen with shifts
6693 // by 0 or 1 when handed a valid smi. 6693 // by 0 or 1 when handed a valid smi.
6694 __ testq(rax, Immediate(0xc0000000)); 6694 __ testl(rax, Immediate(0xc0000000));
6695 __ j(not_zero, slow); 6695 __ j(not_zero, slow);
6696 break; 6696 break;
6697 case Token::SHL: 6697 case Token::SHL:
6698 __ shll(rax); 6698 __ shll(rax);
6699 // TODO(Smi): Significant change if Smi changes.
6700 // Check that the *signed* result fits in a smi. 6699 // Check that the *signed* result fits in a smi.
6701 // It does, if the 30th and 31st bits are equal, since then 6700 // It does, if the 30th and 31st bits are equal, since then
6702 // shifting the SmiTag in at the bottom doesn't change the sign. 6701 // shifting the SmiTag in at the bottom doesn't change the sign.
6703 ASSERT(kSmiTagSize == 1); 6702 ASSERT(kSmiTagSize == 1);
6704 __ cmpl(rax, Immediate(0xc0000000)); 6703 __ cmpl(rax, Immediate(0xc0000000));
6705 __ j(sign, slow); 6704 __ j(sign, slow);
6706 __ movsxlq(rax, rax); // Extend new sign of eax into rax.
6707 break; 6705 break;
6708 default: 6706 default:
6709 UNREACHABLE(); 6707 UNREACHABLE();
6710 } 6708 }
6711 // Tag the result and store it in register eax. 6709 // Tag the result and store it in register eax.
6712 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 6710 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
6713 __ lea(rax, Operand(rax, rax, times_1, kSmiTag)); 6711 __ lea(rax, Operand(rax, rax, times_1, kSmiTag));
6714 break; 6712 break;
6715 6713
6716 default: 6714 default:
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
6963 int CompareStub::MinorKey() { 6961 int CompareStub::MinorKey() {
6964 // Encode the two parameters in a unique 16 bit value. 6962 // Encode the two parameters in a unique 16 bit value.
6965 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 6963 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
6966 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 6964 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
6967 } 6965 }
6968 6966
6969 6967
6970 #undef __ 6968 #undef __
6971 6969
6972 } } // namespace v8::internal 6970 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | test/mjsunit/apply.js » ('j') | test/mjsunit/apply.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698