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

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

Issue 597005: Ported ia32 optimization of revision 3487 to x64. (Closed)
Patch Set: Created 10 years, 10 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
« no previous file with comments | « src/x64/codegen-x64.h ('k') | src/x64/disasm-x64.cc » ('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 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 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 1214
1215 // Duplicate the switch value. 1215 // Duplicate the switch value.
1216 frame_->Dup(); 1216 frame_->Dup();
1217 1217
1218 // Compile the label expression. 1218 // Compile the label expression.
1219 Load(clause->label()); 1219 Load(clause->label());
1220 1220
1221 // Compare and branch to the body if true or the next test if 1221 // Compare and branch to the body if true or the next test if
1222 // false. Prefer the next test as a fall through. 1222 // false. Prefer the next test as a fall through.
1223 ControlDestination dest(clause->body_target(), &next_test, false); 1223 ControlDestination dest(clause->body_target(), &next_test, false);
1224 Comparison(equal, true, &dest); 1224 Comparison(node, equal, true, &dest);
1225 1225
1226 // If the comparison fell through to the true target, jump to the 1226 // If the comparison fell through to the true target, jump to the
1227 // actual body. 1227 // actual body.
1228 if (dest.true_was_fall_through()) { 1228 if (dest.true_was_fall_through()) {
1229 clause->body_target()->Unuse(); 1229 clause->body_target()->Unuse();
1230 clause->body_target()->Jump(); 1230 clause->body_target()->Jump();
1231 } 1231 }
1232 } 1232 }
1233 1233
1234 // If there was control flow to a next test from the last one 1234 // If there was control flow to a next test from the last one
(...skipping 2343 matching lines...) Expand 10 before | Expand all | Expand 10 after
3578 __ testq(answer.reg(), answer.reg()); 3578 __ testq(answer.reg(), answer.reg());
3579 answer.Unuse(); 3579 answer.Unuse();
3580 destination()->Split(zero); 3580 destination()->Split(zero);
3581 return; 3581 return;
3582 } 3582 }
3583 default: 3583 default:
3584 UNREACHABLE(); 3584 UNREACHABLE();
3585 } 3585 }
3586 Load(left); 3586 Load(left);
3587 Load(right); 3587 Load(right);
3588 Comparison(cc, strict, destination()); 3588 Comparison(node, cc, strict, destination());
3589 } 3589 }
3590 3590
3591 3591
3592 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 3592 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
3593 frame_->PushFunction(); 3593 frame_->PushFunction();
3594 } 3594 }
3595 3595
3596 3596
3597 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 3597 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
3598 ASSERT(args->length() == 1); 3598 ASSERT(args->length() == 1);
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
4860 // For a variable that rewrites to a slot, we signal it is the immediate 4860 // For a variable that rewrites to a slot, we signal it is the immediate
4861 // subexpression of a typeof. 4861 // subexpression of a typeof.
4862 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); 4862 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
4863 } else { 4863 } else {
4864 // Anything else can be handled normally. 4864 // Anything else can be handled normally.
4865 Load(expr); 4865 Load(expr);
4866 } 4866 }
4867 } 4867 }
4868 4868
4869 4869
4870 void CodeGenerator::Comparison(Condition cc, 4870 void CodeGenerator::Comparison(AstNode* node,
4871 Condition cc,
4871 bool strict, 4872 bool strict,
4872 ControlDestination* dest) { 4873 ControlDestination* dest) {
4873 // Strict only makes sense for equality comparisons. 4874 // Strict only makes sense for equality comparisons.
4874 ASSERT(!strict || cc == equal); 4875 ASSERT(!strict || cc == equal);
4875 4876
4876 Result left_side; 4877 Result left_side;
4877 Result right_side; 4878 Result right_side;
4878 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. 4879 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
4879 if (cc == greater || cc == less_equal) { 4880 if (cc == greater || cc == less_equal) {
4880 cc = ReverseCondition(cc); 4881 cc = ReverseCondition(cc);
(...skipping 26 matching lines...) Expand all
4907 break; 4908 break;
4908 case equal: 4909 case equal:
4909 dest->Goto(left_value == right_value); 4910 dest->Goto(left_value == right_value);
4910 break; 4911 break;
4911 case greater_equal: 4912 case greater_equal:
4912 dest->Goto(left_value >= right_value); 4913 dest->Goto(left_value >= right_value);
4913 break; 4914 break;
4914 default: 4915 default:
4915 UNREACHABLE(); 4916 UNREACHABLE();
4916 } 4917 }
4917 } else { // Only one side is a constant Smi. 4918 } else {
4919 // Only one side is a constant Smi.
4918 // If left side is a constant Smi, reverse the operands. 4920 // If left side is a constant Smi, reverse the operands.
4919 // Since one side is a constant Smi, conversion order does not matter. 4921 // Since one side is a constant Smi, conversion order does not matter.
4920 if (left_side_constant_smi) { 4922 if (left_side_constant_smi) {
4921 Result temp = left_side; 4923 Result temp = left_side;
4922 left_side = right_side; 4924 left_side = right_side;
4923 right_side = temp; 4925 right_side = temp;
4924 cc = ReverseCondition(cc); 4926 cc = ReverseCondition(cc);
4925 // This may reintroduce greater or less_equal as the value of cc. 4927 // This may reintroduce greater or less_equal as the value of cc.
4926 // CompareStub and the inline code both support all values of cc. 4928 // CompareStub and the inline code both support all values of cc.
4927 } 4929 }
4928 // Implement comparison against a constant Smi, inlining the case 4930 // Implement comparison against a constant Smi, inlining the case
4929 // where both sides are Smis. 4931 // where both sides are Smis.
4930 left_side.ToRegister(); 4932 left_side.ToRegister();
4933 Register left_reg = left_side.reg();
4934 Handle<Object> right_val = right_side.handle();
4931 4935
4932 // Here we split control flow to the stub call and inlined cases 4936 // Here we split control flow to the stub call and inlined cases
4933 // before finally splitting it to the control destination. We use 4937 // before finally splitting it to the control destination. We use
4934 // a jump target and branching to duplicate the virtual frame at 4938 // a jump target and branching to duplicate the virtual frame at
4935 // the first split. We manually handle the off-frame references 4939 // the first split. We manually handle the off-frame references
4936 // by reconstituting them on the non-fall-through path. 4940 // by reconstituting them on the non-fall-through path.
4937 JumpTarget is_smi; 4941 JumpTarget is_smi;
4938 Register left_reg = left_side.reg();
4939 Handle<Object> right_val = right_side.handle();
4940 4942
4941 Condition left_is_smi = masm_->CheckSmi(left_side.reg()); 4943 Condition left_is_smi = masm_->CheckSmi(left_side.reg());
4942 is_smi.Branch(left_is_smi); 4944 is_smi.Branch(left_is_smi);
4943 4945
4946 bool is_for_loop_compare = (node->AsCompareOperation() != NULL)
4947 && node->AsCompareOperation()->is_for_loop_condition();
4948 if (&& right_val->IsSmi()) {
Søren Thygesen Gjesse 2010/02/09 12:24:01 is_for_loop_compare missing before &&?
4949 // Right side is a constant smi and left side has been checked
4950 // not to be a smi.
4951 JumpTarget not_number;
4952 __ Cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
4953 Factory::heap_number_map());
4954 not_number.Branch(not_equal, &left_side);
4955 __ movsd(xmm1,
4956 FieldOperand(left_reg, HeapNumber::kValueOffset));
4957 int value = Smi::cast(*right_val)->value();
4958 if (value == 0) {
4959 __ xorpd(xmm0, xmm0);
4960 } else {
4961 Result temp = allocator()->Allocate();
4962 __ movl(temp.reg(), Immediate(value));
4963 __ cvtlsi2sd(xmm0, temp.reg());
4964 temp.Unuse();
4965 }
4966 __ ucomisd(xmm1, xmm0);
4967 // Jump to builtin for NaN.
4968 not_number.Branch(parity_even, &left_side);
4969 left_side.Unuse();
4970 Condition double_cc = cc;
4971 switch (cc) {
4972 case less: double_cc = below; break;
4973 case equal: double_cc = equal; break;
4974 case less_equal: double_cc = below_equal; break;
4975 case greater: double_cc = above; break;
4976 case greater_equal: double_cc = above_equal; break;
4977 default: UNREACHABLE();
4978 }
4979 dest->true_target()->Branch(double_cc);
4980 dest->false_target()->Jump();
4981 not_number.Bind(&left_side);
4982 }
4983
4944 // Setup and call the compare stub. 4984 // Setup and call the compare stub.
4945 CompareStub stub(cc, strict); 4985 CompareStub stub(cc, strict);
4946 Result result = frame_->CallStub(&stub, &left_side, &right_side); 4986 Result result = frame_->CallStub(&stub, &left_side, &right_side);
4947 result.ToRegister(); 4987 result.ToRegister();
4948 __ testq(result.reg(), result.reg()); 4988 __ testq(result.reg(), result.reg());
4949 result.Unuse(); 4989 result.Unuse();
4950 dest->true_target()->Branch(cc); 4990 dest->true_target()->Branch(cc);
4951 dest->false_target()->Jump(); 4991 dest->false_target()->Jump();
4952 4992
4953 is_smi.Bind(); 4993 is_smi.Bind();
(...skipping 4236 matching lines...) Expand 10 before | Expand all | Expand 10 after
9190 // Call the function from C++. 9230 // Call the function from C++.
9191 return FUNCTION_CAST<ModuloFunction>(buffer); 9231 return FUNCTION_CAST<ModuloFunction>(buffer);
9192 } 9232 }
9193 9233
9194 #endif 9234 #endif
9195 9235
9196 9236
9197 #undef __ 9237 #undef __
9198 9238
9199 } } // namespace v8::internal 9239 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698