Revision: 2661
Author: [email protected]
Date: Tue Aug 11 05:49:27 2009
Log: X64: Implement remaining constant smi optimizations. Enable mozilla
tests that now pass.
Review URL: http://codereview.chromium.org/164317
http://code.google.com/p/v8/source/detail?r=2661
Modified:
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/test/mozilla/mozilla.status
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Mon Aug 10 07:35:20 2009
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Tue Aug 11 05:49:27 2009
@@ -5192,7 +5192,158 @@
}
break;
}
- // TODO(X64): Move other implementations from ia32 to here.
+
+ case Token::SAR:
+ if (reversed) {
+ Result constant_operand(value);
+ LikelySmiBinaryOperation(op, &constant_operand, operand,
+ overwrite_mode);
+ } else {
+ // Only the least significant 5 bits of the shift value are used.
+ // In the slow case, this masking is done inside the runtime call.
+ int shift_value = int_value & 0x1f;
+ operand->ToRegister();
+ frame_->Spill(operand->reg());
+ DeferredInlineSmiOperation* deferred =
+ new DeferredInlineSmiOperation(op,
+ operand->reg(),
+ operand->reg(),
+ smi_value,
+ overwrite_mode);
+ __ testl(operand->reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ if (shift_value > 0) {
+ __ sarl(operand->reg(), Immediate(shift_value));
+ __ and_(operand->reg(), Immediate(~kSmiTagMask));
+ }
+ deferred->BindExit();
+ frame_->Push(operand);
+ }
+ break;
+
+ case Token::SHR:
+ if (reversed) {
+ Result constant_operand(value);
+ LikelySmiBinaryOperation(op, &constant_operand, operand,
+ overwrite_mode);
+ } else {
+ // Only the least significant 5 bits of the shift value are used.
+ // In the slow case, this masking is done inside the runtime call.
+ int shift_value = int_value & 0x1f;
+ operand->ToRegister();
+ Result answer = allocator()->Allocate();
+ ASSERT(answer.is_valid());
+ DeferredInlineSmiOperation* deferred =
+ new DeferredInlineSmiOperation(op,
+ answer.reg(),
+ operand->reg(),
+ smi_value,
+ overwrite_mode);
+ __ testl(operand->reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ __ movl(answer.reg(), operand->reg());
+ __ sarl(answer.reg(), Immediate(kSmiTagSize));
+ __ shrl(answer.reg(), Immediate(shift_value));
+ // A negative Smi shifted right two is in the positive Smi range.
+ if (shift_value < 2) {
+ __ testl(answer.reg(), Immediate(0xc0000000));
+ deferred->Branch(not_zero);
+ }
+ operand->Unuse();
+ ASSERT(kSmiTag == 0);
+ ASSERT(kSmiTagSize == 1);
+ __ addl(answer.reg(), answer.reg());
+ deferred->BindExit();
+ frame_->Push(&answer);
+ }
+ break;
+
+ case Token::SHL:
+ if (reversed) {
+ Result constant_operand(value);
+ LikelySmiBinaryOperation(op, &constant_operand, operand,
+ overwrite_mode);
+ } else {
+ // Only the least significant 5 bits of the shift value are used.
+ // In the slow case, this masking is done inside the runtime call.
+ int shift_value = int_value & 0x1f;
+ operand->ToRegister();
+ if (shift_value == 0) {
+ // Spill operand so it can be overwritten in the slow case.
+ frame_->Spill(operand->reg());
+ DeferredInlineSmiOperation* deferred =
+ new DeferredInlineSmiOperation(op,
+ operand->reg(),
+ operand->reg(),
+ smi_value,
+ overwrite_mode);
+ __ testl(operand->reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ deferred->BindExit();
+ frame_->Push(operand);
+ } else {
+ // Use a fresh temporary for nonzero shift values.
+ Result answer = allocator()->Allocate();
+ ASSERT(answer.is_valid());
+ DeferredInlineSmiOperation* deferred =
+ new DeferredInlineSmiOperation(op,
+ answer.reg(),
+ operand->reg(),
+ smi_value,
+ overwrite_mode);
+ __ testl(operand->reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ __ movl(answer.reg(), operand->reg());
+ ASSERT(kSmiTag == 0); // adjust code if not the case
+ // We do no shifts, only the Smi conversion, if shift_value is 1.
+ if (shift_value > 1) {
+ __ shll(answer.reg(), Immediate(shift_value - 1));
+ }
+ // Convert int result to Smi, checking that it is in int range.
+ ASSERT(kSmiTagSize == 1); // adjust code if not the case
+ __ addl(answer.reg(), answer.reg());
+ deferred->Branch(overflow);
+ deferred->BindExit();
+ operand->Unuse();
+ frame_->Push(&answer);
+ }
+ }
+ break;
+
+ case Token::BIT_OR:
+ case Token::BIT_XOR:
+ case Token::BIT_AND: {
+ operand->ToRegister();
+ frame_->Spill(operand->reg());
+ if (reversed) {
+ // Bit operations with a constant smi are commutative.
+ // We can swap left and right operands with no problem.
+ // Swap left and right overwrite modes. 0->0, 1->2, 2->1.
+ overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) %
3);
+ }
+ DeferredCode* deferred = new DeferredInlineSmiOperation(op,
+
operand->reg(),
+
operand->reg(),
+ smi_value,
+
overwrite_mode);
+ __ testl(operand->reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ if (op == Token::BIT_AND) {
+ __ and_(operand->reg(), Immediate(smi_value));
+ } else if (op == Token::BIT_XOR) {
+ if (int_value != 0) {
+ __ xor_(operand->reg(), Immediate(smi_value));
+ }
+ } else {
+ ASSERT(op == Token::BIT_OR);
+ if (int_value != 0) {
+ __ or_(operand->reg(), Immediate(smi_value));
+ }
+ }
+ deferred->BindExit();
+ frame_->Push(operand);
+ break;
+ }
// Generate inline code for mod of powers of 2 and negative powers of
2.
case Token::MOD:
=======================================
--- /branches/bleeding_edge/test/mozilla/mozilla.status Wed Aug 5 04:08:24
2009
+++ /branches/bleeding_edge/test/mozilla/mozilla.status Tue Aug 11 05:49:27
2009
@@ -810,9 +810,3 @@
# when the 64-bit port is fully debugged.
js1_2/regexp/regress-9141: FAIL
-js1_5/Regress/regress-211590: CRASH
-js1_5/Regress/regress-303213: PASS || CRASH
-js1_5/extensions/regress-336410-2: CRASH
-js1_5/extensions/regress-336410-1: CRASH
-js1_5/Function/regress-338001: FAIL || CRASH
-js1_5/extensions/regress-371636: CRASH
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---